1. Registration API

Collection of endpoints for registering users

1.1. Social method - Facebook and Google

1.1.1. Successful user signup (FACEBOOK method)

Request
POST /signup HTTP/1.1
Content-Type: application/json
Host: localhost:8080
Content-Length: 79

{
  "signup_method" : "FACEBOOK",
  "user_info" : {
    "token" : "token"
  }
}
Response
HTTP/1.1 200 OK
Pragma: no-cache
Content-Length: 185
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "id" : 137,
  "email" : "johnsmith@gmail.com",
  "first_name" : "John",
  "last_name" : "Smith",
  "country" : "Bosnia and Herzegovina",
  "phone_number" : null,
  "role" : "USER"
}

1.1.2. Successful user signup (GOOGLE method)

Request
POST /signup HTTP/1.1
Content-Length: 77
Content-Type: application/json
Host: localhost:8080

{
  "signup_method" : "GOOGLE",
  "user_info" : {
    "token" : "token"
  }
}
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Content-Length: 165
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "id" : 136,
  "email" : "johnsmith@gmail.com",
  "first_name" : "John",
  "last_name" : "Smith",
  "country" : null,
  "phone_number" : null,
  "role" : "USER"
}

1.2. Email method

1.2.1. Successful user signup

Request
POST /signup HTTP/1.1
Content-Length: 225
Content-Type: application/json
Host: localhost:8080

{
  "signup_method" : "EMAIL",
  "user_info" : {
    "email" : "john@smith.com",
    "password" : "abcdefgh",
    "first_name" : "John",
    "last_name" : "Smith",
    "country_id" : 1,
    "phone_number" : "0951234567"
  }
}
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Content-Length: 188
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "id" : 140,
  "email" : "john@smith.com",
  "first_name" : "John",
  "last_name" : "Smith",
  "country" : "Bosnia and Herzegovina",
  "phone_number" : "0951234567",
  "role" : "USER"
}

1.2.2. Incomplete signup information

Request
POST /signup HTTP/1.1
Content-Type: application/json
Content-Length: 89
Host: localhost:8080

{
  "signup_method" : "EMAIL",
  "user_info" : {
    "email" : "filipduj@gmail.com"
  }
}
Response
HTTP/1.1 400 Bad Request
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Content-Length: 155
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "description" : "Incomplete signup information",
  "err_code" : "0101",
  "message" : "Some fields missing or could not be parsed from JSON request."
}

1.2.3. Signup information complete but invalid

Invalid country id
Request
POST /signup HTTP/1.1
Content-Length: 236
Content-Type: application/json
Host: localhost:8080

{
  "signup_method" : "EMAIL",
  "user_info" : {
    "email" : "invalid@mail.com",
    "password" : "passsssword",
    "first_name" : "Name",
    "last_name" : "NoFirstName",
    "country_id" : 0,
    "phone_number" : "0981234567"
  }
}
Response
HTTP/1.1 400 Bad Request
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 136

{
  "description" : "Signup information complete but invalid",
  "err_code" : "0102",
  "message" : "Provided country does not exist."
}
Empty first name
Request
POST /signup HTTP/1.1
Content-Length: 230
Content-Type: application/json
Host: localhost:8080

{
  "signup_method" : "EMAIL",
  "user_info" : {
    "email" : "test@email.com",
    "password" : "passsssword",
    "first_name" : "",
    "last_name" : "NoFirstName",
    "country_id" : 1,
    "phone_number" : "0981234567"
  }
}
Response
HTTP/1.1 400 Bad Request
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Content-Length: 154
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "description" : "Signup information complete but invalid",
  "err_code" : "0102",
  "message" : "Name must have at least 1 or at most 30 characters"
}
Invalid email
Request
POST /signup HTTP/1.1
Content-Type: application/json
Host: localhost:8080
Content-Length: 235

{
  "signup_method" : "EMAIL",
  "user_info" : {
    "email" : "invalid-mail.com",
    "password" : "passssword",
    "first_name" : "Name",
    "last_name" : "NoFirstName",
    "country_id" : 1,
    "phone_number" : "0981234567"
  }
}
Response
HTTP/1.1 400 Bad Request
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 124

{
  "description" : "Signup information complete but invalid",
  "err_code" : "0102",
  "message" : "Invalid email format"
}
Short password
Request
POST /signup HTTP/1.1
Content-Length: 230
Content-Type: application/json
Host: localhost:8080

{
  "signup_method" : "EMAIL",
  "user_info" : {
    "email" : "invalid@mail.com",
    "password" : "short",
    "first_name" : "Name",
    "last_name" : "NoFirstName",
    "country_id" : 1,
    "phone_number" : "0981234567"
  }
}
Response
HTTP/1.1 400 Bad Request
Pragma: no-cache
Content-Length: 120
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "description" : "Signup information complete but invalid",
  "err_code" : "0102",
  "message" : "Invalid Password"
}
Invalid phone number
Request
POST /signup HTTP/1.1
Content-Type: application/json
Content-Length: 239
Host: localhost:8080

{
  "signup_method" : "EMAIL",
  "user_info" : {
    "email" : "invalid@mail.com",
    "password" : "passssword",
    "first_name" : "Name",
    "last_name" : "NoFirstName",
    "country_id" : 1,
    "phone_number" : "012abc345wrong"
  }
}
Response
HTTP/1.1 400 Bad Request
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 145

{
  "description" : "Signup information complete but invalid",
  "err_code" : "0102",
  "message" : "Phone number must consist of 8-12 digits."
}

1.2.4. Signup failed because user exists

Request
POST /signup HTTP/1.1
Content-Length: 225
Content-Type: application/json
Host: localhost:8080

{
  "signup_method" : "EMAIL",
  "user_info" : {
    "email" : "john@smith.com",
    "password" : "abcdefgh",
    "first_name" : "John",
    "last_name" : "Smith",
    "country_id" : 1,
    "phone_number" : "0951234567"
  }
}
Response
HTTP/1.1 400 Bad Request
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 145

{
  "description" : "Signup failed because user exists",
  "err_code" : "0103",
  "message" : "User with email: john@smith.com already exists!"
}

1.2.5. Email confirmation

Successful Email confirmation
Request
GET /mail-confirmation?token=e2d9de96-5368-4598-a59f-8ce508bf7d01 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Resend Email confirmation
Request
GET /mail-confirmation?token=02e7f917-d195-412c-9123-5252e018efba HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Failed Email confirmation, invalid token format
Request
GET /mail-confirmation?token=bezvezni-token-tak HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 400 Bad Request
Pragma: no-cache
Content-Length: 163
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "description" : "Failed Email confirmation, invalid token format",
  "err_code" : "0104",
  "message" : "Token: bezvezni-token-tak is not in a valid format."
}
Failed Email confirmation, non existing token
Request
GET /mail-confirmation?token=2558de41-4e0f-4391-9062-936fb8598573 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 404 Not Found
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Failed Email confirmation, token expired
Request
GET /mail-confirmation?token=387e0828-d65a-4083-b386-c00c1816dd62 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 400 Bad Request
Pragma: no-cache
Content-Length: 164
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "description" : "Failed Email confirmation, token expired",
  "err_code" : "0106",
  "message" : "The token: 387e0828-d65a-4083-b386-c00c1816dd62 has expired"
}

1.2.6. Check Email

Email used
Request
POST /mail-check HTTP/1.1
Content-Length: 32
Content-Type: application/json;charset=UTF-8
Host: localhost:8080

{
  "email" : "john@smith.com"
}
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 56

{
  "email" : "john@smith.com",
  "user_exists" : true
}
Email not used
Request
POST /mail-check HTTP/1.1
Content-Type: application/json;charset=UTF-8
Content-Length: 35
Host: localhost:8080

{
  "email" : "missing@email.com"
}
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Length: 60
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "email" : "missing@email.com",
  "user_exists" : false
}

2. Authentication API

2.1. Successful user signin (EMAIL method)

Request
POST /token HTTP/1.1
Content-Length: 119
Content-Type: application/json
Host: localhost:8080

{
  "login_method" : "EMAIL",
  "credentials" : {
    "email" : "john@smith.com",
    "password" : "Password175!"
  }
}
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Length: 407
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "token" : "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJqb2huQHNtaXRoLmNvbSIsInVzZXIiOiJ7XCJlbWFpbFwiOlwiam9obkBzbWl0aC5jb21cIixcImF1dGhvcml0aWVzXCI6W1wiUFJPX1BST0ZJTEVcIixcIlBXT19QUk9GSUxFXCIsXCJQUk9fT1JHX0lOVklURVwiLFwiUFdPX09SR19JTlZJVEVcIixcIlJPTEVfVVNFUlwiXSxcImNvbXBsZXRlX3Byb2ZpbGVcIjp0cnVlLFwiZW5hYmxlZFwiOnRydWV9IiwiaWF0IjoxNTU3MzE5OTUxLCJleHAiOjE1NTczMjM1NTF9.z8snfhUBDHr3hS-Zv5G4ls9DnZ3OyYC_1vUHyxwtSbQ"
}

2.2. Successful user signin (GOOGLE method)

Token in this case is obtained from Google on frontend, and then passed as request parameter.

Request
POST /token HTTP/1.1
Content-Type: application/json
Content-Length: 78
Host: localhost:8080

{
  "login_method" : "GOOGLE",
  "credentials" : {
    "token" : "token"
  }
}
Response
HTTP/1.1 200 OK
Content-Length: 409
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "token" : "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJqb2huQHNtaXRoLmNvbSIsInVzZXIiOiJ7XCJlbWFpbFwiOlwiam9obkBzbWl0aC5jb21cIixcImF1dGhvcml0aWVzXCI6W1wiUFJPX1BST0ZJTEVcIixcIlBXT19QUk9GSUxFXCIsXCJQUk9fT1JHX0lOVklURVwiLFwiUFdPX09SR19JTlZJVEVcIixcIlJPTEVfVVNFUlwiXSxcImNvbXBsZXRlX3Byb2ZpbGVcIjpmYWxzZSxcImVuYWJsZWRcIjp0cnVlfSIsImlhdCI6MTU1NzMxOTk1MiwiZXhwIjoxNTU3MzIzNTUyfQ.lOIq69VT20SV2jx5_9Or5d_P5GoTwYuJ6huFeWw9STY"
}

2.3. Successful user signin (FACEBOOK method)

Token in this case is obtained from Facebook on frontend, and then passed as request parameter.

Request
POST /token HTTP/1.1
Content-Type: application/json
Content-Length: 80
Host: localhost:8080

{
  "login_method" : "FACEBOOK",
  "credentials" : {
    "token" : "token"
  }
}
Response
HTTP/1.1 200 OK
Content-Length: 409
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "token" : "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJqb2huQHNtaXRoLmNvbSIsInVzZXIiOiJ7XCJlbWFpbFwiOlwiam9obkBzbWl0aC5jb21cIixcImF1dGhvcml0aWVzXCI6W1wiUFJPX1BST0ZJTEVcIixcIlBXT19QUk9GSUxFXCIsXCJQUk9fT1JHX0lOVklURVwiLFwiUFdPX09SR19JTlZJVEVcIixcIlJPTEVfVVNFUlwiXSxcImNvbXBsZXRlX3Byb2ZpbGVcIjpmYWxzZSxcImVuYWJsZWRcIjp0cnVlfSIsImlhdCI6MTU1NzMxOTk1MiwiZXhwIjoxNTU3MzIzNTUyfQ.lOIq69VT20SV2jx5_9Or5d_P5GoTwYuJ6huFeWw9STY"
}

2.4. Invalid credentials

Request
POST /token HTTP/1.1
Content-Length: 121
Content-Type: application/json
Host: localhost:8080

{
  "login_method" : "EMAIL",
  "credentials" : {
    "email" : "john@smith.com",
    "password" : "wrong-password"
  }
}
Response
HTTP/1.1 401 Unauthorized
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

2.5. Invalid login method

For example, user was registered using regular method (filling out email, password…​) but he is trying to login using Google oauth.

Request
POST /token HTTP/1.1
Content-Type: application/json
Content-Length: 78
Host: localhost:8080

{
  "login_method" : "GOOGLE",
  "credentials" : {
    "token" : "token"
  }
}
Response
HTTP/1.1 400 Bad Request
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 125

{
  "description" : "Invalid login method",
  "err_code" : "0201",
  "message" : "Invalid method. Try to login using EMAIL"
}

2.6. Non-existing user login

Request
POST /token HTTP/1.1
Content-Length: 119
Content-Type: application/json
Host: localhost:8080

{
  "login_method" : "EMAIL",
  "credentials" : {
    "email" : "john@smith.com",
    "password" : "Password175!"
  }
}
Response
HTTP/1.1 400 Bad Request
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Content-Length: 129
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "description" : "Non existing user",
  "err_code" : "0301",
  "message" : "User with email: john@smith.com does not exists"
}

3. Users API

Collection of endpoints for managing users

3.1. Get own profile

3.1.1. Successful fetch own profile

Request
GET /me HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
Content-Length: 187
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "id" : 161,
  "email" : "test@test.com",
  "first_name" : "John",
  "last_name" : "Smith",
  "country" : "Bosnia and Herzegovina",
  "phone_number" : "0951234567",
  "role" : "USER"
}

3.1.2. Successful update own profile

Request
POST /me HTTP/1.1
Content-Length: 142
Content-Type: application/json;charset=UTF-8
Host: localhost:8080

{
  "email" : "john@smith.com",
  "first_name" : "NewFirstName",
  "last_name" : "Smith",
  "country_id" : 1,
  "phone_number" : "099123123"
}
Response
HTTP/1.1 200 OK
Content-Length: 195
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "id" : 159,
  "email" : "john@smith.com",
  "first_name" : "NewFirstName",
  "last_name" : "Smith",
  "country" : "Bosnia and Herzegovina",
  "phone_number" : "099123123",
  "role" : "USER"
}

3.1.3. Failed to update others profile

Request
POST /me HTTP/1.1
Content-Type: application/json;charset=UTF-8
Host: localhost:8080
Content-Length: 135

{
  "email" : "john@smith.com",
  "first_name" : "John",
  "last_name" : "Smith",
  "country_id" : 1,
  "phone_number" : "0951234567"
}
Response
HTTP/1.1 403 Forbidden
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

3.2. Fetch users

3.2.1. Successful fetch list of users (admin)

Request
GET /users HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 224

{
  "users" : [ {
    "id" : 151,
    "email" : "john@smith.com",
    "first_name" : "John",
    "last_name" : "Smith",
    "country" : "Bosnia and Herzegovina",
    "phone_number" : "0951234567",
    "role" : "USER"
  } ]
}

3.2.2. Failed to fetch list of users

Missing privilege: PRA_PROFILE

Request
GET /users HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 403 Forbidden
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

3.3. Change user role

3.3.1. Successfully change

Request
POST /users/163/role HTTP/1.1
Content-Length: 22
Content-Type: application/json
Host: localhost:8080

{
  "role" : "ADMIN"
}
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Length: 160
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "id" : 163,
  "email" : "user@role.com",
  "first_name" : "First",
  "last_name" : "Last",
  "country" : null,
  "phone_number" : null,
  "role" : "ADMIN"
}

3.3.2. Missing privilege to change role

Missing privilege: PWA_PROFILE

Request
POST /users/160/role HTTP/1.1
Content-Length: 22
Content-Type: application/json
Host: localhost:8080

{
  "role" : "ADMIN"
}
Response
HTTP/1.1 403 Forbidden
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

3.4. Organization invites

3.4.1. Get a list of organization invites

Request
GET /me/invites HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Length: 171
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "organization_invites" : [ {
    "organization_id" : 112,
    "organization_name" : "Test org",
    "role" : "ORG_MEMBER",
    "invited_by_user" : "John Smith"
  } ]
}

3.4.2. Accept organization invite

/me/invites/{organizationId}/accept

Request
POST /me/invites/111/accept HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

3.4.3. Reject organization invite

/me/invites/{organizationId}/reject

Request
POST /me/invites/113/reject HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

4. Countries API

Collection of endpoints for fetching countries

4.1. Get all countries

Request
GET /countries HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Length: 835
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "countries" : [ {
    "id" : 1,
    "iso" : "BA",
    "name" : "BOSNIA AND HERZEGOVINA",
    "nicename" : "Bosnia and Herzegovina",
    "iso3" : "BIH",
    "numcode" : 70,
    "phonecode" : 387
  }, {
    "id" : 2,
    "iso" : "BG",
    "name" : "BULGARIA",
    "nicename" : "Bulgaria",
    "iso3" : "BGR",
    "numcode" : 100,
    "phonecode" : 359
  }, {
    "id" : 3,
    "iso" : "HR",
    "name" : "CROATIA",
    "nicename" : "Croatia",
    "iso3" : "HRV",
    "numcode" : 191,
    "phonecode" : 385
  }, {
    "id" : 4,
    "iso" : "EE",
    "name" : "ESTONIA",
    "nicename" : "Estonia",
    "iso3" : "EST",
    "numcode" : 233,
    "phonecode" : 372
  }, {
    "id" : 5,
    "iso" : "LI",
    "name" : "LIECHTENSTEIN",
    "nicename" : "Liechtenstein",
    "iso3" : "LIE",
    "numcode" : 438,
    "phonecode" : 423
  } ]
}

4.2. Get country by id

Request
GET /countries/3 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 136

{
  "id" : 3,
  "iso" : "HR",
  "name" : "CROATIA",
  "nicename" : "Croatia",
  "iso3" : "HRV",
  "numcode" : 191,
  "phonecode" : 385
}

4.3. Invalid country id

Request
GET /countries/0 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 404 Not Found
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

5. Wallet API

Collection of endpoints for managing wallets

5.1. User Wallet

Collection of endpoints for managing User wallet

5.1.1. Get wallet for active user

Request
GET /wallet HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Length: 203
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "id" : 62,
  "hash" : "0x4e4ee58ff3a9e9e78c2dfdbac0d1518e4e1039f9189267e1dc8d3e35cbdf7892",
  "type" : "USER",
  "balance" : 10000,
  "currency" : "EUR",
  "created_at" : "2019-05-08T12:52:39.185Z"
}

5.1.2. Active user does not have a wallet

Request
GET /wallet HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 404 Not Found
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

5.1.3. Create Wallet

Create wallet for active user
Request
POST /wallet HTTP/1.1
Content-Type: application/json
Host: localhost:8080
Content-Length: 125

{
  "address" : "0x14bC6a8219c798394726f8e86E040A878da1d99D",
  "public_key" : "0xC2D7CF95645D33006175B78989035C7c9061d3F9"
}
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 199

{
  "id" : 56,
  "hash" : "0x4e4ee58ff3a9e9e78c2dfdbac0d1518e4e1039f9189267e1dc8d3e35cbdf7892",
  "type" : "USER",
  "balance" : 0,
  "currency" : "EUR",
  "created_at" : "2019-05-08T12:52:38.792Z"
}
Invalid wallet address
Request
POST /wallet HTTP/1.1
Content-Length: 87
Content-Type: application/json
Host: localhost:8080

{
  "address" : "0x00",
  "public_key" : "0xC2D7CF95645D33006175B78989035C7c9061d3F9"
}
Response
HTTP/1.1 400 Bad Request
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Active user cannot create wallet with invalid wallet address
Request
POST /wallet HTTP/1.1
Content-Length: 87
Content-Type: application/json
Host: localhost:8080

{
  "address" : "0x00",
  "public_key" : "0xC2D7CF95645D33006175B78989035C7c9061d3F9"
}
Response
HTTP/1.1 400 Bad Request
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Active user cannot create additional wallet
Request
POST /wallet HTTP/1.1
Content-Type: application/json
Host: localhost:8080
Content-Length: 125

{
  "address" : "0x14bC6a8219c798394726f8e86E040A878da1d99D",
  "public_key" : "0xC2D7CF95645D33006175B78989035C7c9061d3F9"
}
Response
HTTP/1.1 400 Bad Request
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Length: 149
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "description" : "Active user cannot create additional wallet",
  "err_code" : "0502",
  "message" : "User: test@test.com already has a wallet."
}

5.2. Project Wallet

Collection of endpoints for managing Project wallet

5.2.1. Get project wallet

Successfully get wallet
Request
GET /wallet/project/58 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Length: 206
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "id" : 64,
  "hash" : "0x4e4ee58ff3a9e9e78c2dfdbac0d1518e4e1039f9189267e1dc8d3e35cbdf7892",
  "type" : "PROJECT",
  "balance" : 10000,
  "currency" : "EUR",
  "created_at" : "2019-05-08T12:52:39.323Z"
}
Project does not have a wallet
Request
GET /wallet/project/56 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 404 Not Found
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Project does not exists
Request
GET /wallet/project/55 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 403 Forbidden
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
User did not create the project

User can only access a wallet for project HE created

Request
GET /wallet/project/55 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 403 Forbidden
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Non existing project
Request
GET /wallet/project/0 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 400 Bad Request
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Content-Length: 110
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "description" : "Non existing project",
  "err_code" : "0701",
  "message" : "Missing project with id 0"
}

5.2.2. Generate transaction to create project wallet

Generate create project wallet transaction
Request
GET /wallet/project/53/transaction HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Length: 359
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "tx" : {
    "data" : "SignedTransaction",
    "to" : "to",
    "nonce" : 1,
    "gas_limit" : 1,
    "gas_price" : 1,
    "value" : 1,
    "public_key" : "public_key"
  },
  "tx_id" : 18,
  "info" : {
    "tx_type" : "CREATE_PROJECT",
    "title" : "Create Project",
    "description" : "You are signing transaction to create project: Test project"
  }
}
Cannot create project wallet

User can create project wallet only for his project

Request
GET /wallet/project/55 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 403 Forbidden
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Invalid address
Request
POST /wallet HTTP/1.1
Content-Length: 87
Content-Type: application/json
Host: localhost:8080

{
  "address" : "0x00",
  "public_key" : "0xC2D7CF95645D33006175B78989035C7c9061d3F9"
}
Response
HTTP/1.1 400 Bad Request
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

5.3. Organization Wallet

Collection of endpoints for managing Organization wallet

5.3.1. Get Organization wallet

Successfully get wallet
Request
GET /wallet/organization/123 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Content-Length: 198
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "id" : 57,
  "hash" : "0x4e4ee58ff3a9e9e78c2dfdbac0d1518e4e1039f9189267e1dc8d3e35cbdf7892",
  "type" : "ORG",
  "balance" : 0,
  "currency" : "EUR",
  "created_at" : "2019-05-08T12:52:38.863Z"
}
Missing organization
Request
GET /wallet/organization/0 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 400 Bad Request
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 113

{
  "description" : "Non existing organization",
  "err_code" : "0601",
  "message" : "Missing organization: 0"
}
Missing user wallet
Request
GET /wallet/organization/128 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 400 Bad Request
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Length: 115
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "description" : "Missing wallet",
  "err_code" : "0501",
  "message" : "Missing wallet for organization: 128"
}

5.3.2. Get transaction for creating organization wallet

Request
GET /wallet/organization/127/transaction HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
Content-Length: 361
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "tx" : {
    "data" : "SignedTransaction",
    "to" : "to",
    "nonce" : 1,
    "gas_limit" : 1,
    "gas_price" : 1,
    "value" : 1,
    "public_key" : "public_key"
  },
  "tx_id" : 19,
  "info" : {
    "tx_type" : "CREATE_ORG",
    "title" : "Create Organization",
    "description" : "You are signing transaction to create organization: Turk org"
  }
}

6. Organization API

Collection of endpoints for managing organization

6.1. Create organization

Request
POST /organization HTTP/1.1
Content-Type: application/json;charset=UTF-8
Content-Length: 78
Host: localhost:8080

{
  "name" : "Organization name",
  "legal_info" : "Organization legal info"
}
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Length: 238
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "id" : 89,
  "name" : "Organization name",
  "created_by_user" : "First Last",
  "created_at" : "2019-05-08T12:52:28.23Z",
  "approved" : false,
  "legal_info" : "Organization legal info",
  "documents" : [ ],
  "wallet_hash" : null
}

6.2. Get organization by id

Request
GET /organization/84 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
Content-Length: 450
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "id" : 84,
  "name" : "test organization",
  "created_by_user" : "First Last",
  "created_at" : "2019-05-08T12:52:27.88Z",
  "approved" : true,
  "legal_info" : "some legal info",
  "documents" : [ {
    "id" : 11,
    "link" : "link",
    "name" : "name",
    "type" : "document/type",
    "size" : 100,
    "created_at" : "2019-05-08T12:52:27.882Z"
  } ],
  "wallet_hash" : "0x4e4ee58ff3a9e9e78c2dfdbac0d1518e4e1039f9189267e1dc8d3e35cbdf7892"
}

6.3. Get all organizations

To get a list of all organization user must have a privilege: PrivilegeType.PRA_ORG

Request
GET /organization HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 685

{
  "organizations" : [ {
    "id" : 80,
    "name" : "test organization",
    "created_by_user" : "First Last",
    "created_at" : "2019-05-08T12:52:27.736Z",
    "approved" : true,
    "legal_info" : "some legal info",
    "wallet_hash" : null
  }, {
    "id" : 81,
    "name" : "test 2",
    "created_by_user" : "First Last",
    "created_at" : "2019-05-08T12:52:27.738Z",
    "approved" : true,
    "legal_info" : "some legal info",
    "wallet_hash" : null
  }, {
    "id" : 82,
    "name" : "test 3",
    "created_by_user" : "First Last",
    "created_at" : "2019-05-08T12:52:27.739Z",
    "approved" : true,
    "legal_info" : "some legal info",
    "wallet_hash" : null
  } ]
}

6.4. Get personal organizations

Request
GET /organization/personal HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Content-Length: 253
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "organizations" : [ {
    "id" : 77,
    "name" : "test organization",
    "created_by_user" : "First Last",
    "created_at" : "2019-05-08T12:52:27.579Z",
    "approved" : true,
    "legal_info" : "some legal info",
    "wallet_hash" : null
  } ]
}

6.5. Approve organization

To approve organization user must have a privilege: PrivilegeType.PWA_ORG_APPROVE

6.5.1. Approve organization with Admin role

Request
POST /organization/83/approve HTTP/1.1
Content-Type: application/json;charset=UTF-8
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Content-Length: 297
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "id" : 83,
  "name" : "Approve organization",
  "created_by_user" : "First Last",
  "created_at" : "2019-05-08T12:52:27.795Z",
  "approved" : true,
  "legal_info" : "some legal info",
  "documents" : [ ],
  "wallet_hash" : "0x4e4ee58ff3a9e9e78c2dfdbac0d1518e4e1039f9189267e1dc8d3e35cbdf7892"
}

6.5.2. Cannot approve organization without privilege

Request
POST /organization/72/approve HTTP/1.1
Content-Type: application/json;charset=UTF-8
Host: localhost:8080
Response
HTTP/1.1 403 Forbidden
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

6.6. Get organization members

Request
GET /organization/73/users HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 201

{
  "users" : [ {
    "name" : "First Last",
    "email" : "user@email.com",
    "role" : "ORG_ADMIN"
  }, {
    "name" : "First Last",
    "email" : "user2@test.com",
    "role" : "ORG_MEMBER"
  } ]
}

6.7. Invite user to organization

6.7.1. Successfully invite user to organization with organization admin role

User must have a privilege: OrganizationPrivilegeType.PW_USERS

Request
POST /organization/88/invite HTTP/1.1
Content-Length: 62
Content-Type: application/json;charset=UTF-8
Host: localhost:8080

{
  "email" : "user2@test.com",
  "role_type" : "ORG_MEMBER"
}
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 3

{ }

6.7.2. Failed invite user to organization without organization admin role

User missing a privilege: OrganizationPrivilegeType.PW_USERS

Request
POST /organization/86/invite HTTP/1.1
Content-Length: 61
Content-Type: application/json;charset=UTF-8
Host: localhost:8080

{
  "email" : "some@user.ocm",
  "role_type" : "ORG_MEMBER"
}
Response
HTTP/1.1 403 Forbidden
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

6.7.3. Revoke user invitation

/organization/{organizationId}/invite/{revokeUserId}/revoke

Request
POST /organization/87/invite/106/revoke HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 3

{ }

6.8. Get organization users

Request
GET /organization/73/users HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 201

{
  "users" : [ {
    "name" : "First Last",
    "email" : "user@email.com",
    "role" : "ORG_ADMIN"
  }, {
    "name" : "First Last",
    "email" : "user2@test.com",
    "role" : "ORG_MEMBER"
  } ]
}

6.9. Documents

6.9.1. Add document for organization

Request
POST /organization/75/document HTTP/1.1
Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
Host: localhost:8080

--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
Content-Disposition: form-data; name=file; filename=test.txt
Content-Type: text/plain

Some document data
--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm--
Response
HTTP/1.1 200 OK
Content-Length: 140
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "id" : 8,
  "link" : "link",
  "name" : "test.txt",
  "type" : "text/plain",
  "size" : 18,
  "created_at" : "2019-05-08T12:52:27.46Z"
}

6.9.2. Remove organization document

Request
DELETE /organization/79/document/9 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 3

{ }

7. Project API

Collection of endpoints for managing project

7.1. Get project

7.1.1. Project exists

Request
GET /project/36 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Length: 842
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "id" : 36,
  "name" : "My project",
  "description" : "description",
  "location" : "location",
  "location_text" : "locationText",
  "return_on_investment" : "0-1%",
  "start_date" : "2019-05-08T12:52:32.844Z",
  "end_date" : "2019-06-07T12:52:32.844Z",
  "expected_funding" : 10000000,
  "currency" : "EUR",
  "min_per_user" : 10,
  "max_per_user" : 10000,
  "main_image" : null,
  "gallery" : [ ],
  "documents" : [ ],
  "active" : true,
  "organization" : {
    "id" : 93,
    "name" : "Test organization",
    "created_by_user" : "First Last",
    "created_at" : "2019-05-08T12:52:32.836Z",
    "approved" : true,
    "legal_info" : "some legal info",
    "wallet_hash" : "0xc5825e732eda043b83ea19a3a1bd2f27a65d11d6e887fa52763bb069977aa292"
  },
  "create_by_user" : "First Last",
  "wallet_hash" : null,
  "current_funding" : null
}

7.1.2. Project missing

Request
GET /project/0 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 404 Not Found
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

7.2. Create project

7.2.1. Successfully create

Request
POST /project HTTP/1.1
Content-Type: application/json
Host: localhost:8080
Content-Length: 399

{
  "organization_id" : 96,
  "name" : "Das project",
  "description" : "description",
  "location" : "location",
  "location_text" : "locationText",
  "return_on_investment" : "1%-100%",
  "start_date" : "2019-05-08T12:52:34.616Z",
  "end_date" : "2019-06-07T12:52:34.616Z",
  "expected_funding" : 1000000,
  "currency" : "EUR",
  "min_per_user" : 1,
  "max_per_user" : 1000000,
  "active" : true
}
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
Content-Length: 846
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "id" : 39,
  "name" : "Das project",
  "description" : "description",
  "location" : "location",
  "location_text" : "locationText",
  "return_on_investment" : "1%-100%",
  "start_date" : "2019-05-08T12:52:34.616Z",
  "end_date" : "2019-06-07T12:52:34.616Z",
  "expected_funding" : 1000000,
  "currency" : "EUR",
  "min_per_user" : 1,
  "max_per_user" : 1000000,
  "main_image" : null,
  "gallery" : [ ],
  "documents" : [ ],
  "active" : true,
  "organization" : {
    "id" : 96,
    "name" : "Test organization",
    "created_by_user" : "First Last",
    "created_at" : "2019-05-08T12:52:34.604Z",
    "approved" : true,
    "legal_info" : "some legal info",
    "wallet_hash" : "0xc5825e732eda043b83ea19a3a1bd2f27a65d11d6e887fa52763bb069977aa292"
  },
  "create_by_user" : "First Last",
  "wallet_hash" : null,
  "current_funding" : null
}

7.2.2. Cannot create project without privilege

User cannot create project without admin role in organization, privilege: OrganizationPrivilegeType.PW_PROJECT

Request
POST /project HTTP/1.1
Content-Length: 402
Content-Type: application/json
Host: localhost:8080

{
  "organization_id" : 106,
  "name" : "Error project",
  "description" : "description",
  "location" : "location",
  "location_text" : "locationText",
  "return_on_investment" : "1%-100%",
  "start_date" : "2019-05-08T12:52:35.157Z",
  "end_date" : "2019-06-07T12:52:35.157Z",
  "expected_funding" : 1000000,
  "currency" : "EUR",
  "min_per_user" : 1,
  "max_per_user" : 1000000,
  "active" : true
}
Response
HTTP/1.1 403 Forbidden
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

7.3. Get all projects for organization

Request
GET /project/organization/104 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Content-Length: 1470
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "projects" : [ {
    "id" : 44,
    "name" : "Project 1",
    "description" : "description",
    "location" : "location",
    "location_text" : "locationText",
    "return_on_investment" : "0-1%",
    "start_date" : "2019-05-08T12:52:35.079Z",
    "end_date" : "2019-06-07T12:52:35.079Z",
    "expected_funding" : 10000000,
    "currency" : "EUR",
    "min_per_user" : 10,
    "max_per_user" : 10000,
    "main_image" : null,
    "gallery" : [ ],
    "active" : true,
    "wallet_hash" : null
  }, {
    "id" : 45,
    "name" : "Project 2",
    "description" : "description",
    "location" : "location",
    "location_text" : "locationText",
    "return_on_investment" : "0-1%",
    "start_date" : "2019-05-08T12:52:35.081Z",
    "end_date" : "2019-06-07T12:52:35.081Z",
    "expected_funding" : 10000000,
    "currency" : "EUR",
    "min_per_user" : 10,
    "max_per_user" : 10000,
    "main_image" : null,
    "gallery" : [ ],
    "active" : true,
    "wallet_hash" : null
  }, {
    "id" : 46,
    "name" : "Project 3",
    "description" : "description",
    "location" : "location",
    "location_text" : "locationText",
    "return_on_investment" : "0-1%",
    "start_date" : "2019-05-08T12:52:35.082Z",
    "end_date" : "2019-06-07T12:52:35.082Z",
    "expected_funding" : 10000000,
    "currency" : "EUR",
    "min_per_user" : 10,
    "max_per_user" : 10000,
    "main_image" : null,
    "gallery" : [ ],
    "active" : true,
    "wallet_hash" : null
  } ]
}

7.4. Documents

7.4.1. Add document for project

Request
POST /project/33/document HTTP/1.1
Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
Host: localhost:8080

--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
Content-Disposition: form-data; name=file; filename=test.txt
Content-Type: text/plain

Some document data
--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm--
Response
HTTP/1.1 200 OK
Pragma: no-cache
Content-Length: 142
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "id" : 12,
  "link" : "link",
  "name" : "test.txt",
  "type" : "text/plain",
  "size" : 18,
  "created_at" : "2019-05-08T12:52:32.566Z"
}

7.4.2. Remove project document

Request
DELETE /project/35/document/13 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 3

{ }

7.5. Project images

7.5.1. Add main image

Request
POST /project/41/image/main HTTP/1.1
Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
Host: localhost:8080

--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
Content-Disposition: form-data; name=image; filename=image.png
Content-Type: image/png

ImageData
--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm--
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 3

{ }
Request
POST /project/43/image/gallery HTTP/1.1
Content-Type: multipart/form-data; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
Host: localhost:8080

--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
Content-Disposition: form-data; name=image; filename=image.png
Content-Type: image/png

ImageData
--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm--
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 3

{ }
Request
DELETE /project/38/image/gallery HTTP/1.1
Content-Type: application/json;charset=UTF-8
Content-Length: 35
Host: localhost:8080

{
  "images" : [ "image-link-1" ]
}
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 3

{ }

7.6. Greenvest

7.6.1. Generate transaction to greenvest in project

Request
GET /project/34/invest?amount=1000 HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Content-Length: 375
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "tx" : {
    "data" : "data",
    "to" : "to",
    "nonce" : 22,
    "gas_limit" : 33,
    "gas_price" : 44,
    "value" : 1000,
    "public_key" : "pubg"
  },
  "tx_id" : 8,
  "info" : {
    "tx_type" : "INVEST_ALLOWANCE",
    "title" : "Invest Allowance",
    "description" : "You are signing transaction to allow investment to project: Project with amount 10.00"
  }
}

7.6.2. Generate transaction to approve greenvestment in project

Request
GET /project/37/invest/confirm HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
Content-Length: 339
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "tx" : {
    "data" : "data",
    "to" : "to",
    "nonce" : 22,
    "gas_limit" : 33,
    "gas_price" : 44,
    "value" : 1000,
    "public_key" : "pubg"
  },
  "tx_id" : 9,
  "info" : {
    "tx_type" : "INVEST",
    "title" : "Invest",
    "description" : "You are signing transaction to confirm investment to project: Project"
  }
}

8. Search API

8.1. Search organizations and projects by name

Request
GET /search?name=Pro HTTP/1.1
Host: localhost:8080
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Length: 1258
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "organizations" : [ {
    "id" : 109,
    "name" : "The Prospect Organization",
    "created_by_user" : "First Last",
    "created_at" : "2019-05-08T12:52:36.659Z",
    "approved" : true,
    "legal_info" : "some legal info",
    "wallet_hash" : null
  } ],
  "projects" : [ {
    "id" : 48,
    "name" : "The first project",
    "description" : "description",
    "location" : "location",
    "location_text" : "locationText",
    "return_on_investment" : "0-1%",
    "start_date" : "2019-05-08T12:52:36.662Z",
    "end_date" : "2019-06-07T12:52:36.662Z",
    "expected_funding" : 10000000,
    "currency" : "EUR",
    "min_per_user" : 10,
    "max_per_user" : 10000,
    "main_image" : null,
    "gallery" : [ ],
    "active" : true,
    "wallet_hash" : null
  }, {
    "id" : 49,
    "name" : "The projcccp",
    "description" : "description",
    "location" : "location",
    "location_text" : "locationText",
    "return_on_investment" : "0-1%",
    "start_date" : "2019-05-08T12:52:36.664Z",
    "end_date" : "2019-06-07T12:52:36.664Z",
    "expected_funding" : 10000000,
    "currency" : "EUR",
    "min_per_user" : 10,
    "max_per_user" : 10000,
    "main_image" : null,
    "gallery" : [ ],
    "active" : true,
    "wallet_hash" : null
  } ]
}

9. Broadcast API

9.1. Broadcast signed transaction

Request
POST /tx_broadcast HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded

tx_sig=SignedTransaction&tx_id=11
Response
HTTP/1.1 200 OK
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Length: 27
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate

{
  "tx_hash" : "tx_hash"
}

9.2. Broadcast non existing transaction

Request
POST /tx_broadcast HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded

tx_sig=SignedTransaction&tx_id=0
Response
HTTP/1.1 400 Bad Request
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Expires: 0
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 124

{
  "description" : "Non existing transaction",
  "err_code" : "0901",
  "message" : "Non existing transaction with id: 0"
}