Introduction
Our API makes it easy to integrate CEX.IO supported assets into both new and existing applications.
CEX.IO APIs enable a variety of capabilities, from gathering read-only data, to building something that’s never been done before.
Capabilities:
- Generate wallets and addresses
- Buy/sell and send/receive digital assets
- Securely store digital assets
- Retrieve real-time or historical price information
- Receive notifications when payments arrive
- Various client libraries and mobile SDKs.
Authentication
The CEX.IO API allows developers to use the OAuth2 protocol to allow a CEX.IO user to grant a 3rd party application full or partial access to his/her account, without sharing the account’s API key or login credentials. It is a slightly more complex integration than the API Key authentication method, but is more flexible. OAuth2 works well for web applications, as well as desktop and mobile apps.
API Auth
As we use OAuth2/Openid specification inside CEX.IO Platform, for been authorized in system any user MUST proceed Interaction Flow
Exist 2 ways for proceed flow: - Front-end way - API way
Front-end way
For init Front-end:
API way
API way performs from bunch of several calls, where responses will follow RP (Relying Party) through the flow.
API Interaction flow consist from 4 General steps or we call it Action.
Authorization Actions:
- Login
- Registration
- Email Confirmation
- Two-fa check
Additional Actions:
- Reset password
Login, Registration, Reset password - Init actions.
Init action means actions which could be triggered as first point for launch interaction flow.
Based on that, now available 3 interaction flow:
- Login flow
- Registration flow
- Reset Password flow
Api built in next way:
- First call: init - for token retrieve and identify initial data for chosen flow
- Next calls: flow specific calls: login/registration/email-confirmation
- init - for get metadata for actions
- flow call, like: submit credential data, sens sms, verify 2fa code, etc.
- Response: Next action required(201), Validation/RateLimit Errors
- Terminate phase: any Flow end-point could terminate flow and respond with result(200), with provided Authentication code
Authorization Flow
Result of Authorization(Login/Registration) flow always Authorization code, which as result should be exchanged to OAuth Tokens(AT/RT/IT).
Interaction Engine (State Machine)
- The Interaction Engine, functioning as a state machine, governs the flow and transitions between various account security states.
- Each API endpoint represents a distinct state in the account security process, ensuring a well-defined and secure user experience.
- Developers can leverage the Interaction Engine to manage and customize user interactions seamlessly.
Security best practices
Authentication API
Init
POST /auth/api/interaction/v1/init
Init Request
curl /auth/api/interaction/v1/init -X POST -d '
{
"client_id":"cex",
"response_type":"code",
"init_action":"registration"
"scope":"openid profile countries 2fa",
"redirect_uri":"",
"code_challenge":"GENERATE ME",
"code_challenge_method":"S256",
"state":""
}
'
Init Response
{
"data": {
"access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImludGVyYWN0aW9uIn0.eyJ0eXAiOiJqd3QiLCJleHBpcmVzSW4iOjg2NDAwLCJleHAiOjE2NjM5Mjg3NTQsImp0aSI6ImM1ZWMwNjcwLTk2Y2ItNDlmMi05ODQ1LWJkNWEzNzdjMjViOCIsImtpZCI6ImludGVyYWN0aW9uIiwic2NvcGUiOiIiLCJyZWRpcmVjdFVyaSI6Imh0dHA6Ly8xMjcuMC4wLjE6MzAwMS8iLCJpbml0QWN0aW9uIjoicmVnaXN0cmF0aW9uIiwiYXVkIjoibW9jayIsInJlc3BvbnNlVHlwZSI6ImNvZGUiLCJpYXQiOjE2NjM4NDIzNTR9.gfw3JFxzgBl1YA5_epWO-Jv8KBvPpotGdlw3_ihhPS4aLJCDv4sigWw0yZdNyZ9dtsgx5PqgIztC6lQaHuNUa3mNbfY8ptongcfdsAl1hOpliLwdaoucKrTzrojEuZbaUqfRlUAlIikZbG68qSOtQ9uvv_nj81KDfgFzCZCg5-itnEEvxjVCX43JfNBxRFkg5LiNEXmsfB5Sj4jkB284ZbnHga2E85L_YKYZtUttuHI5yPWP4l_aRxymiakiw1PchpWdcRf5V8oGz1rkxa5J3WvQ6BYvOUWMv547jmQI6BByiu8vVAm5wj96acIWsD6U6E6UiBqAPW6qRZGvuYZbdg",
"expires_in": 1662068165,
"token_type": "Bearer",
"scope": "openid profile countries 2fa"
}
}
Registration
Registration Request
POST /auth/api/interaction/v1/registration
Registration Request
curl /auth/api/interaction/v1/registration -X POST
-H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImludGVyYWN0aW9uIn0.eyJ0eXAiOiJqd3QiLCJleHBpcmVzSW4iOjg2NDAwLCJleHAiOjE2NjM5Mjg3NTQsImp0aSI6ImM1ZWMwNjcwLTk2Y2ItNDlmMi05ODQ1LWJkNWEzNzdjMjViOCIsImtpZCI6ImludGVyYWN0aW9uIiwic2NvcGUiOiIiLCJyZWRpcmVjdFVyaSI6Imh0dHA6Ly8xMjcuMC4wLjE6MzAwMS8iLCJpbml0QWN0aW9uIjoicmVnaXN0cmF0aW9uIiwiYXVkIjoibW9jayIsInJlc3BvbnNlVHlwZSI6ImNvZGUiLCJpYXQiOjE2NjM4NDIzNTR9.gfw3JFxzgBl1YA5_epWO-Jv8KBvPpotGdlw3_ihhPS4aLJCDv4sigWw0yZdNyZ9dtsgx5PqgIztC6lQaHuNUa3mNbfY8ptongcfdsAl1hOpliLwdaoucKrTzrojEuZbaUqfRlUAlIikZbG68qSOtQ9uvv_nj81KDfgFzCZCg5-itnEEvxjVCX43JfNBxRFkg5LiNEXmsfB5Sj4jkB284ZbnHga2E85L_YKYZtUttuHI5yPWP4l_aRxymiakiw1PchpWdcRf5V8oGz1rkxa5J3WvQ6BYvOUWMv547jmQI6BByiu8vVAm5wj96acIWsD6U6E6UiBqAPW6qRZGvuYZbdg'
-H 'Content-type: application/json'
-d '
{
"credentials": {
"email": "[email protected]",
"password": "0c748b9c43aaab6224efa08e19ec7a06ad94c20a46ab0e6462d27489f7b928ee",
"country": "US",
"region": "AL", <Only for US country>
"marketingEmailsAccepted": true,
"accountType": "<individual or business>",
"company": "<Only for business account type>",
"referralId": "",
"captcha": {
"response": "qweqweqweqwe",
"system": "mobile-invisible",
"version": "v2"
}
}
}
'
Registration Response
{
"path": "API POST /v1/registration",
"timestamp": "2022-12-20T15:32:03.028Z",
"rid": "bd699726-ac0f-489d-8001-c47a621ed5ce",
"reason": {
"key": "EMAIL_CONFIRMATION_REQUIRED",
"value": "EMAIL CONFIRMATION step required."
},
"details": {
"errors": [
{
"reason": "EMAIL CONFIRMATION step required."
}
]
}
}
Initial Data
GET /auth/api/interaction/v1/registration/initial-data
Registration Initial Data Request
curl /auth/api/interaction/v1/registration/initial-data -X GET
-H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImludGVyYWN0aW9uIn0.eyJ0eXAiOiJqd3QiLCJleHBpcmVzSW4iOjg2NDAwLCJleHAiOjE2NjM5Mjg3NTQsImp0aSI6ImM1ZWMwNjcwLTk2Y2ItNDlmMi05ODQ1LWJkNWEzNzdjMjViOCIsImtpZCI6ImludGVyYWN0aW9uIiwic2NvcGUiOiIiLCJyZWRpcmVjdFVyaSI6Imh0dHA6Ly8xMjcuMC4wLjE6MzAwMS8iLCJpbml0QWN0aW9uIjoicmVnaXN0cmF0aW9uIiwiYXVkIjoibW9jayIsInJlc3BvbnNlVHlwZSI6ImNvZGUiLCJpYXQiOjE2NjM4NDIzNTR9.gfw3JFxzgBl1YA5_epWO-Jv8KBvPpotGdlw3_ihhPS4aLJCDv4sigWw0yZdNyZ9dtsgx5PqgIztC6lQaHuNUa3mNbfY8ptongcfdsAl1hOpliLwdaoucKrTzrojEuZbaUqfRlUAlIikZbG68qSOtQ9uvv_nj81KDfgFzCZCg5-itnEEvxjVCX43JfNBxRFkg5LiNEXmsfB5Sj4jkB284ZbnHga2E85L_YKYZtUttuHI5yPWP4l_aRxymiakiw1PchpWdcRf5V8oGz1rkxa5J3WvQ6BYvOUWMv547jmQI6BByiu8vVAm5wj96acIWsD6U6E6UiBqAPW6qRZGvuYZbdg'
Registration Initial Data Response
{
"passwordSalt": "werwereytrhfgbbrgbgfegbsbb",
"captcha": {
"general": {
"v2": "6LfwbvAUAAAAAHZw9KtmbkBZ4IBNVF6WUVAYyPpO",
"v3": "6LfwbvAUAARuyHZw9KyrKkBZ4IBNVF6WUVAYyPpO"
},
"mobile-invisible": {
"v2": "6LfwbvAUAAAAAHZw9KtmbkBZ4IBNVF6WUVAYyPpO"
}
}
}
Email Confirmation
- Create
- Verify
- Resend
For Async email confirmation way: - Check
Email Confirmation Create Request
curl /auth/api/interaction/v1/email-confirmation/create -X POST
-H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImludGVyYWN0aW9uIn0.eyJ0eXAiOiJqd3QiLCJleHBpcmVzSW4iOjg2NDAwLCJleHAiOjE2NjM5Mjg3NTQsImp0aSI6ImM1ZWMwNjcwLTk2Y2ItNDlmMi05ODQ1LWJkNWEzNzdjMjViOCIsImtpZCI6ImludGVyYWN0aW9uIiwic2NvcGUiOiIiLCJyZWRpcmVjdFVyaSI6Imh0dHA6Ly8xMjcuMC4wLjE6MzAwMS8iLCJpbml0QWN0aW9uIjoicmVnaXN0cmF0aW9uIiwiYXVkIjoibW9jayIsInJlc3BvbnNlVHlwZSI6ImNvZGUiLCJpYXQiOjE2NjM4NDIzNTR9.gfw3JFxzgBl1YA5_epWO-Jv8KBvPpotGdlw3_ihhPS4aLJCDv4sigWw0yZdNyZ9dtsgx5PqgIztC6lQaHuNUa3mNbfY8ptongcfdsAl1hOpliLwdaoucKrTzrojEuZbaUqfRlUAlIikZbG68qSOtQ9uvv_nj81KDfgFzCZCg5-itnEEvxjVCX43JfNBxRFkg5LiNEXmsfB5Sj4jkB284ZbnHga2E85L_YKYZtUttuHI5yPWP4l_aRxymiakiw1PchpWdcRf5V8oGz1rkxa5J3WvQ6BYvOUWMv547jmQI6BByiu8vVAm5wj96acIWsD6U6E6UiBqAPW6qRZGvuYZbdg'
-H 'Content-type: application/json'
-d '
{
"fingerprint": {
"ip": "127.0.0.1",
"os": "MAC OS",
"platform": "Apple",
"browser": "Chrome"
}
}
'
Email Confirmation Create Response
200 Success
403
{
"path": "API POST /v1/email-confirmation/create",
"timestamp": "2022-12-20T15:32:03.028Z",
"details": {
"errors": [
{
"field": "token",
"reason": "signature verification failed"
}
]
},
"reason": {
"key": "INVALID_TOKEN",
"value": "Invalid token."
},
"uid": "XA51IydtDrNGGVBxOQsly",
"rid": "df03cf6e-28f8-4243-98a0-3e11aff5c7d1"
}
Email Confirmation Verify Request
curl /auth/api/interaction/v1/email-confirmation/verify -X POST
-H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImludGVyYWN0aW9uIn0.eyJ0eXAiOiJqd3QiLCJleHBpcmVzSW4iOjg2NDAwLCJleHAiOjE2NjM5Mjg3NTQsImp0aSI6ImM1ZWMwNjcwLTk2Y2ItNDlmMi05ODQ1LWJkNWEzNzdjMjViOCIsImtpZCI6ImludGVyYWN0aW9uIiwic2NvcGUiOiIiLCJyZWRpcmVjdFVyaSI6Imh0dHA6Ly8xMjcuMC4wLjE6MzAwMS8iLCJpbml0QWN0aW9uIjoicmVnaXN0cmF0aW9uIiwiYXVkIjoibW9jayIsInJlc3BvbnNlVHlwZSI6ImNvZGUiLCJpYXQiOjE2NjM4NDIzNTR9.gfw3JFxzgBl1YA5_epWO-Jv8KBvPpotGdlw3_ihhPS4aLJCDv4sigWw0yZdNyZ9dtsgx5PqgIztC6lQaHuNUa3mNbfY8ptongcfdsAl1hOpliLwdaoucKrTzrojEuZbaUqfRlUAlIikZbG68qSOtQ9uvv_nj81KDfgFzCZCg5-itnEEvxjVCX43JfNBxRFkg5LiNEXmsfB5Sj4jkB284ZbnHga2E85L_YKYZtUttuHI5yPWP4l_aRxymiakiw1PchpWdcRf5V8oGz1rkxa5J3WvQ6BYvOUWMv547jmQI6BByiu8vVAm5wj96acIWsD6U6E6UiBqAPW6qRZGvuYZbdg'
-H 'Content-type: application/json'
-d '
{
"code":"As31sa",
"fingerprint": {
"ip": "127.0.0.1",
"os": "MAC OS",
"platform": "Apple",
"browser": "Chrome"
}
}
'
Email Confirmation Verify Response
{
"code": "jsdhfjhsdf943w4j",
"exp": 1662068165
}
Email Confirmation Resend Request
curl /auth/api/interaction/v1/email-confirmation/create -X POST
-H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImludGVyYWN0aW9uIn0.eyJ0eXAiOiJqd3QiLCJleHBpcmVzSW4iOjg2NDAwLCJleHAiOjE2NjM5Mjg3NTQsImp0aSI6ImM1ZWMwNjcwLTk2Y2ItNDlmMi05ODQ1LWJkNWEzNzdjMjViOCIsImtpZCI6ImludGVyYWN0aW9uIiwic2NvcGUiOiIiLCJyZWRpcmVjdFVyaSI6Imh0dHA6Ly8xMjcuMC4wLjE6MzAwMS8iLCJpbml0QWN0aW9uIjoicmVnaXN0cmF0aW9uIiwiYXVkIjoibW9jayIsInJlc3BvbnNlVHlwZSI6ImNvZGUiLCJpYXQiOjE2NjM4NDIzNTR9.gfw3JFxzgBl1YA5_epWO-Jv8KBvPpotGdlw3_ihhPS4aLJCDv4sigWw0yZdNyZ9dtsgx5PqgIztC6lQaHuNUa3mNbfY8ptongcfdsAl1hOpliLwdaoucKrTzrojEuZbaUqfRlUAlIikZbG68qSOtQ9uvv_nj81KDfgFzCZCg5-itnEEvxjVCX43JfNBxRFkg5LiNEXmsfB5Sj4jkB284ZbnHga2E85L_YKYZtUttuHI5yPWP4l_aRxymiakiw1PchpWdcRf5V8oGz1rkxa5J3WvQ6BYvOUWMv547jmQI6BByiu8vVAm5wj96acIWsD6U6E6UiBqAPW6qRZGvuYZbdg'
-H 'Content-type: application/json'
-d '
{
"fingerprint": {
"ip": "127.0.0.1",
"os": "MAC OS",
"platform": "Apple",
"browser": "Chrome"
}
}
'
Email Confirmation Resend Response
200 Success
Email Confirmation Check Request
curl /auth/api/interaction/v1/email-confirmation/check -X GET
-H 'Authorization: Bearer <JWT_TOKEN>'
Email Confirmation Check Response
200 OK
json { "isEmailConfirmed": false }
Initial Data
GET /auth/api/interaction/v1/email-confirmation/initial-data
request
curl /auth/api/interaction/v1/email-confirmation/initial-data -X GET
-H 'Authorization: Bearer <JWT_TOKEN>
response
{
"email": "[email protected]"
}
Login
Http Request
GET /auth/api/interaction/v1/login
Login Request
curl /auth/api/interaction/v1/login -X POST
-H 'Authorization: Bearer <JWT_TOKEN>
-d '
{
"credentials": {
"token": "[email protected]",
"password": "0c748b9c43aaab6224efa08e19ec7a06ad94c20a46ab0e6462d27489f7b928ee",
"captcha": {
"response": "qweqweqweqwe",
"system": "mobile-invisible",
"version": "v2"
}
}
}
'
Login Response
{
"code": "jsdhfjhsdf943w4j",
"exp": 1662068165
}
Initial Data
GET /auth/api/interaction/v1/login/initial-data
Login Initial Data Request
curl /auth/api/interaction/v1/login/initial-data -X GET
-H 'Authorization: Bearer <JWT_TOKEN>
Login Initial Data Response
{
"passwordSalt": "werwereytrhfgbbrgbgfegbsbb",
"captcha": {
"general": {
"v2": "6LfwbvAUAAAAAHZw9KtmbkBZ4IBNVF6WUVAYyPpO",
"v3": "6LfwbvAUAARuyHZw9KyrKkBZ4IBNVF6WUVAYyPpO"
},
"mobile-invisible": {
"v2": "6LfwbvAUAAAAAHZw9KtmbkBZ4IBNVF6WUVAYyPpO"
}
}
}
Social Login
Social Authorization Request
curl /auth/api/interaction/v1/social -X POST
-H 'Authorization: Bearer <JWT_TOKEN>
-d '
{
"credentials": {
"code": "sdopwe233232lkldkl",
"redirectUri": "https://profile.cex.io/google/oauth<this url must be in social config>",
"type": "google",
"captcha": {
"response": "qweqweqweqwe",
"system": "mobile-invisible",
"version": "v2"
}
}
}
'
Social Authorization Response
Code 201
{
"credentials": {
"code": "sdopwe233232lkldkl",
"redirectUri": "https://profile.cex.io/google/oauth<this url must be in social config>",
"type": "google",
"captcha": {
"response": "qweqweqweqwe",
"system": "mobile-invisible",
"version": "v2"
}
}
}
Social Registration Request
curl /auth/api/interaction/v1/social/registration -X POST
-H 'Authorization: Bearer <JWT_TOKEN>
-d '
{
"credentials": {
"country": "US",
"region": "AL <Only for US country>",
"marketingEmailsAccepted": true,
"accountType": "<individual or business>",
"company": "<Only for business account type>",
"referralId": "",
"captcha": {
"response": "qweqweqweqwe",
"system": "mobile-invisible",
"version": "v2"
}
}
}
'
Social Registration Response
{
"credentials": {
"code": "sdopwe233232lkldkl",
"redirectUri": "https://profile.cex.io/google/oauth<this url must be in social config>",
"type": "google",
"captcha": {
"response": "qweqweqweqwe",
"system": "mobile-invisible",
"version": "v2"
}
}
}
Initial Data
GET /auth/api/interaction/v1/social/initial-data
Login Initial Data Request
curl /auth/api/interaction/v1/social/initial-data -X GET
-H 'Authorization: Bearer <JWT_TOKEN>
Login Initial Data Response
{
"passwordSalt": "werwereytrhfgbbrgbgfegbsbb",
"captcha": {
"general": {
"v2": "6LfwbvAUAAAAAHZw9KtmbkBZ4IBNVF6WUVAYyPpO",
"v3": "6LfwbvAUAARuyHZw9KyrKkBZ4IBNVF6WUVAYyPpO"
},
"mobile-invisible": {
"v2": "6LfwbvAUAAAAAHZw9KtmbkBZ4IBNVF6WUVAYyPpO"
}
}
}
Two Fa check
- TOTP
- SMS
Two Fa SMS Create Request
curl /auth/api/interaction/v1/two-fa/sms/create -X POST
-H 'Authorization: Bearer <JWT_TOKEN>
Two Fa SMS Create Response
{
"requestId": "f266ec6d-d2b3-4b7d-ad52-fac11bdfbda8",
"exp": "1667930843"
}
Two Fa Verify Request
curl /auth/api/interaction/v1/verify -X POST
-H 'Authorization: Bearer <JWT_TOKEN>'
-H 'Content-type: application/json'
-d '
{
"method":"sms",
"requestId":"123456",
"code":"f266ec6d-d2b3-4b7d-ad52-fac11bdfbda8"
}
'
Two Fa Verify Response
{
"code": "jsdhfjhsdf943w4j",
"exp": 1662068165
}
Initial Data
GET /auth/api/interaction/v1/two-fa/initial-data
Two Fa Initial Data Request
curl /auth/api/interaction/v1/two-fa/initial-data -X GET
-H 'Authorization: Bearer <JWT_TOKEN>
Two Fa Initial Data Response
{
"availableMethods": [
"sms",
"totp"
],
"maskedPhone": "+380*****7890"
}
Reset Password
Reset Password Send Email Request
curl /auth/api/interaction/v1/reset-password/send-request
-X POST
-H 'Authorization: Bearer <JWT_TOKEN>'
-H 'Content-type: application/json'
-d '
{
"email":"[email protected]",
"fingerprint": {
"ip": "127.0.0.1",
"os": "MAC OS",
"platform": "Apple",
"browser": "Chrome"
}
}
'
Reset Password Send Email Response
{
"requestId": "99b690b1-0f38-4d31-bb65-47558dcbbe9b"
}
Reset Password Verify Email Request
curl /auth/api/interaction/v1/reset-password/verify
-X POST
-H 'Authorization: Bearer <JWT_TOKEN>'
-H 'Content-type: application/json'
-d '
{
"code":"452321",
"requestId":"99b690b1-0f38-4d31-bb65-47558dcbbe9b",
"fingerprint": {
"ip": "127.0.0.1",
"os": "MAC OS",
"platform": "Apple",
"browser": "Chrome"
}
}
'
Reset Password Verify Email Response
Code 201 Created
{
"path": "API POST /v1/*",
"timestamp": "2022-12-20T15:32:03.028Z",
"rid": "bd699726-ac0f-489d-8001-c47a621ed5ce",
"reason": {
"key": "TWO_FA_REQUIRED",
"value": "TWO FA step required."
},
"details": {
"errors": [
{
"reason": "TWO FA step required."
}
]
}
}
Reset Password Submit new password Request
curl /auth/api/interaction/v1/reset-password/submit
-X POST
-H 'Authorization: Bearer <JWT_TOKEN>'
-H 'Content-type: application/json'
-d '
{
"password":"FekhbHVBUIYGUYiupnjpknIOUnhuiuopOIU67tYUIGHGH56bV",
"confirmPassword":"FekhbHVBUIYGUYiupnjpknIOUnhuiuopOIU67tYUIGHGH56bV",
"fingerprint": {
"ip": "127.0.0.1",
"os": "MAC OS",
"platform": "Apple",
"browser": "Chrome"
}
}
'
Reset Password Submit new password Response
200 OK
Initial Data
GET /auth/api/interaction/v1/registration/initial-data
Request
curl /auth/api/interaction/v1/reset-password/initial-data -X GET
-H 'Authorization: Bearer <JWT_TOKEN>
Response
{
"passwordSalt": "browserSalt"
}
Discard Interaction
Discard current interaction session by interaction token
curl /auth/api/interaction/v1/discard
-X POST
-H 'Authorization: Bearer <JWT_TOKEN>'
Responses
End-point Responses
Terminated response - finish of interaction:
200 - OK
{
"code": "jsdhfjhsdf943w4j",
"exp": 1662068165
}
Next Step Required:
201 - Interaction is not finished, next action is required.
{
"path": "API POST /v1/*",
"timestamp": "2022-12-20T15:32:03.028Z",
"rid": "bd699726-ac0f-489d-8001-c47a621ed5ce",
"reason": {
"key": "TWO_FA_REQUIRED",
"value": "TWO FA step required."
},
"details": {
"errors": [
{
"reason": "TWO FA step required."
}
]
}
}
All errors could have next fields:
reason
- general summary error object
key - could be used for mapping custom error
value - User friendly error message, use it as Default Error message for user
details.errors
- could contain list of errors per field or other unique reason of errors
On example above:
field="token" - what means "token" was not provided in request. reason - User friendly message
Could be used for validation field on UI during any validation errors
403 - Invalid Token
{
"details": {
"errors": [
{
"field": "token",
"reason": "signature verification failed"
}
]
},
"reason": {
"key": "INVALID_TOKEN",
"value": "Invalid token."
},
"uid": "XA51IydtDrNGGVBxOQsly",
"rid": "df03cf6e-28f8-4243-98a0-3e11aff5c7d1"
}
422 - Validation Error
{
"path": "API POST /v1/*",
"timestamp": "2022-12-20T15:32:03.028Z",
"rid": "bd699726-ac0f-489d-8001-c47a621ed5ce",
"reason": {
"key": "VALIDATION_ERROR",
"value": "Validation error."
},
"details": {
"errors": [
{
"field": "token",
"reason": "Token should be provided"
},
{
"field": "password",
"reason": "Password should be provided"
}
]
}
}
429 - Rate Limit Error
{
"path": "API {GET|POST} { PATH HERE }",
"timestamp": "2023-01-05T13:34:35.736Z",
"details": {
"errors": [
{
"reason": "You've already made too many attempts. Please, try again later."
}
]
},
"reason": {
"key": "RATE_LIMIT",
"value": "You've already made too many attempts. Please, try again later."
},
"uid": "7lYtn7LH7qC8nQx_hMkNE",
"rid": "1a73030c-c2f1-4df3-9c39-e2512c77cee4"
}
500 - Default error.
{
"path": "API POST /v1/*",
"timestamp": "2022-12-20T15:32:03.028Z",
"rid": "bd699726-ac0f-489d-8001-c47a621ed5ce",
"reason": {
"key": "SERVER_ERROR",
"value": "Service is currently unavailable. Please refresh the page or try again later."
},
"details": {
"errors": [
{
"reason": "Service is currently unavailable. Please refresh the page or try again later."
}
]
}
}
User Profile
This section contains all the endpoint resources for accessing information about the user.
Authorization
JWT_TOKEN - AccessToken which you got during authorization
User Resources
User Profile
Retrieve comprehensive user profile information, depending on the scope defined in your AccessToken.
/profile
Request GET /api/resources/users/{userIds}/profile
curl /api/resources/users/ud123456789/profile
-X GET
-H 'Authorization: Bearer <JWT_TOKEN>'
Response
Code: 200
[
{
"userId": "ud203447428",
"sub": "ud203447428",
"address": {
"city": "asdgfsdfg",
"region": "BR",
"street": "sdfgfdsg",
"country": "AL",
"zip_code": "324324"
},
"email": "[email protected]",
"isEmailConfirmed": true,
"isPhoneConfirmed": true,
"authyPhoneNumber": "380661232323",
"authyPhoneCountryCode": "380",
"firstName": "Qwe",
"lastName": "Rty",
"middleName": "",
"name": "",
"displayName": "Qwe Rty",
"dateOfBirth": "1960-03-04",
"accountType": "individual",
"company": "",
"country": "AL",
"state": "BR",
"userHash": "fc07a604a425f5105c457bd7a31407a37451e177ee8ab35fc710a507204a989e",
"encodedUserId": "NGFiN2Q5MTcxODhiMWE3NmI2MWY3ZWI4",
"gender": "male",
"referralId": "",
"mid": "bvi",
"deletionRequest": "",
"lastLogin": "1697121753",
"status": "active",
"signupTime": "1609432765048",
"passwordLastUpdate": "",
"techUser": false,
"registrationSource": "",
"registeredSystem": "email",
"countries": {
"details": {
"address": {
"city": "asdgfsdfg",
"region": "BR",
"street": "sdfgfdsg",
"country": "AL",
"zip_code": "324324"
},
"issuing": {
"country": "AL"
},
"declared": {
"region": "BR",
"country": "AL"
},
"corporate": {},
"taxResident": {}
},
"primary": {
"country": "AL",
"region": "BR",
"verified": true
}
},
"verification": {
"primary": "address",
"stages": [
"address",
"identity",
"intro_basic"
],
"details": {
"address": "accepted",
"enhanced": "draft",
"identity": "accepted",
"intro_basic": "accepted"
}
},
"nationality": "AL",
"identityDocument": {
"type": "internationalPassport",
"serialNumber": "SDGSDFG",
"hasExpireDate": false,
"issuingCountry": "AL"
},
"office": "BVI",
"polls": {
"sof": {
"answers": [
{
"id": "0",
"name": "identityadditionalstepsquestions_0",
"answers": [
{
"id": "1",
"answer": "Exchange crypto and withdraw to my other wallet(s)/platform(s)"
}
],
"question": "How will you be using the CEX.io platform?"
},
{
"id": "1",
"name": "identityadditionalstepsquestions_1",
"answers": [
{
"id": "4",
"answer": "10 000 - 20 000"
}
],
"question": "What is your expected monthly turnover on CEX.io in USD, EUR or GBP?"
},
{
"id": "2",
"name": "identityadditionalstepsquestions_2",
"answers": [
{
"id": "1",
"answer": "Inheritance"
}
],
"question": "What is the source of the funds you will be using on the platform?"
}
],
"createdAt": 1700570577678,
"updatedAt": 1700570920428
}
}
}
]
User Countries
/countries
Request GET /api/resources/users/{userIds}/countries
curl /api/resources/users/ud123456789/countries?limitIpLocation=5
-X GET
-H 'Authorization: Bearer <JWT_TOKEN>'
Response
Code: 200
{
"countries": {
"details": {
"address": {},
"issuing": {
"country": "JM"
},
"corporate": {},
"residence": {},
"taxResident": {},
"fullResidence": {
"city": "Malwood",
"region": "MAR",
"street": "Johnson 2",
"country": "JM",
"zip_code": "39102"
},
"declared": {
"country": "GB",
"region": ""
}
},
"primary": {
"country": "JM",
"region": "MAR",
"verified": false
},
"ip_location": [{
"ip_country": "UA",
"ip_city": "KV"
}]
}
}
User Limits
/user-limits
Request GET /api/resources/users/{userId}/user-limits
curl /api/resources/users/ud123456789/user-limits
-X GET
-H 'Authorization: Bearer <JWT_TOKEN>'
Response
Code: 200
{
"userLimits": {}
}
User Deletion Request ---> move to user settings?
POST /deletion-request
Request POST /api/resources/users/{userId}/deletion-request
curl /api/resources/users/ud123456789/deletion-request
-X POST
-H 'Authorization: Bearer <JWT_TOKEN>'
Response
Code: 200 - deletion request created Code: 422 - User is not active
DELETE /deletion-request
Request DELETE /api/resources/users/{userId}/deletion-request
curl /api/resources/users/ud123456789/deletion-request
-X DELETE
-H 'Authorization: Bearer <JWT_TOKEN>'
Response
Code: 200 - deletion request removed Code: 422 - User is not active
User Session Manager
Get all user sessions
Request GET /api/resources/users/{userId}/sessions
curl /api/resources/users/ud123456789/sessions
-X GET
-H 'Authorization: Bearer <JWT_TOKEN>'
Response
Code: 200
{
"sessions": [
{
"session_id": "nN6qN0aSt9b8d7pll2_al",
"clients": [
"profile",
"nex-plus"
],
"iat": 1700586,
"exp": 1700759,
"metadata": {
"ip": "10.77.2.15",
"user_agent": {
"os": "OS X",
"platform": "Apple Mac",
"browser": "Chrome"
},
"device": null,
"last_active_time": 1700586709
}
},
{
"session_id": "FBCcVX-v4XLHeV76nzhuv",
"clients": [
"profile"
],
"iat": 1700586,
"exp": 1700759,
"metadata": {
"ip": "10.77.2.15",
"user_agent": {
"os": "OS X",
"platform": "Apple Mac",
"browser": "Chrome"
},
"device": null,
"last_active_time": 1700586621
}
}
]
}
Delete user session
Request DELETE /api/resources/users/{userId}/sessions/{sessionId}
sessionId - list of session Ids, split: ;
curl /api/resources/users/ud123456789/sessions/sdvjio7867-sdf5dsfgr;sdvjktgkjvre6-safdreg
-X DELETE
-H 'Authorization: Bearer <JWT_TOKEN>'
Response
Code: 200 - Session removed
Delete all user sessions
Request DELETE /api/resources/users/{userId}/sessions
curl /api/resources/users/ud123456789/sessions
-X DELETE
-H 'Authorization: Bearer <JWT_TOKEN>'
Response
Code: 200 - Session removed
Common Data
Endpoints available for showing additional user details, such as country, phone number, currencies, and more.
Currencies List
Crypto coins and fiat with code and name.
Request GET /api/currencies
curl /api/currencies
-X GET'
Response
Code: 200
{
"crypto": [
{
"code": "GHS",
"name": "ghash"
},
{
"code": "BTC",
"name": "Bitcoin"
},
{
"code": "BCH",
"name": "Bitcoin Cash"
},
{
"code": "BTG",
"name": "Bitcoin Gold"
},
{
"code": "ETH",
"name": "Ethereum"
},
{
"code": "LTC",
"name": "Litecoin"
},
{
"code": "NMC",
"name": "Namecoin"
},
{
"code": "DOGE",
"name": "Dogecoin"
},
{
"code": "IXC",
"name": "ixcoin"
},
{
"code": "DRK",
"name": "darkcoin"
},
{
"code": "FTC",
"name": "feathercoin"
},
{
"code": "AUR",
"name": "auroracoin"
},
{
"code": "DGB",
"name": "digibytecoin"
},
{
"code": "USDE",
"name": "usdecoin"
},
{
"code": "POT",
"name": "potcoin"
},
{
"code": "ANC",
"name": "anoncoin"
},
{
"code": "MEC",
"name": "megacoin"
},
{
"code": "WDC",
"name": "worldcoin"
},
{
"code": "MYR",
"name": "myriadcoin"
},
{
"code": "DVC",
"name": "devcoin"
},
{
"code": "DASH",
"name": "dash"
},
{
"code": "ZEC",
"name": "zcash"
},
{
"code": "XRP",
"name": "Ripple"
},
{
"code": "XLM",
"name": "Stellar"
},
{
"code": "QASH",
"name": "Quash"
},
{
"code": "BSV",
"name": "bsv"
},
{
"code": "GUSD",
"name": "Gemini Dollar"
},
{
"code": "OMG",
"name": "miseGO"
},
{
"code": "MHC",
"name": "MetaHash"
},
{
"code": "TRX",
"name": "Tron"
},
{
"code": "BTT",
"name": "BitTorrent"
},
{
"code": "ONT",
"name": "Ontology"
},
{
"code": "ONG",
"name": "OntologyGas"
},
{
"code": "USDT",
"name": "Tether"
},
{
"code": "ADA",
"name": "Cardano"
},
{
"code": "USDC",
"name": "USD Coin"
},
{
"code": "NEO",
"name": "NEO"
},
{
"code": "GAS",
"name": "GAS"
},
{
"code": "BAT",
"name": "Basic Attention Token"
},
{
"code": "ATOM",
"name": "Atom"
},
{
"code": "XTZ",
"name": "Tezos"
},
{
"code": "WABI",
"name": "Tael"
},
{
"code": "MATIC",
"name": "Matic"
},
{
"code": "LINK",
"name": "Link"
},
{
"code": "MKR",
"name": "Maker"
},
{
"code": "ZRX",
"name": "ZRX"
},
{
"code": "LAMB",
"name": "Lambda"
},
{
"code": "HOT",
"name": "Holo"
},
{
"code": "DOT",
"name": "Polkadot"
},
{
"code": "COMP",
"name": "Compound"
},
{
"code": "ZIL",
"name": "Zilliqa"
},
{
"code": "UNI",
"name": "Uniswap"
},
{
"code": "DAI",
"name": "Multi-collateral DAI"
},
{
"code": "UMA",
"name": "Uma"
},
{
"code": "YFI",
"name": "yearn.finance"
},
{
"code": "SNX",
"name": "Synthetix Network Token"
},
{
"code": "KNC",
"name": "Kyber Network"
},
{
"code": "BAL",
"name": "Balancer"
},
{
"code": "CRV",
"name": "Curve DAO Token"
},
{
"code": "WBTC",
"name": "Wrapped Bitcoin"
},
{
"code": "TUSD",
"name": "TrueUSD"
},
{
"code": "MTA",
"name": "Meta"
},
{
"code": "MUSD",
"name": "mStable USD"
},
{
"code": "SUSHI",
"name": "SushiSwap"
},
{
"code": "CREAM",
"name": "Cream Finance"
},
{
"code": "YFII",
"name": "DFI.Money"
},
{
"code": "BUSD",
"name": "Binance USD"
},
{
"code": "REN",
"name": "Ren"
},
{
"code": "BAND",
"name": "Band Protocol"
},
{
"code": "AKRO",
"name": "Akropolis"
},
{
"code": "BNT",
"name": "Bancor"
},
{
"code": "ZAP",
"name": "Zap"
},
{
"code": "SRM",
"name": "Serum"
},
{
"code": "ANT",
"name": "Aragon"
},
{
"code": "PAXG",
"name": "PAX Gold"
},
{
"code": "OCEAN",
"name": "Ocean Protocol"
},
{
"code": "STORJ",
"name": "Storj"
},
{
"code": "KAVA",
"name": "Kava.io"
},
{
"code": "KSM",
"name": "Kusama"
},
{
"code": "AAVE",
"name": "Aave"
},
{
"code": "REPV2",
"name": "Augur v2"
},
{
"code": "GZIL",
"name": "Governance ZIL"
},
{
"code": "BCHA",
"name": "Bitcoincash ABC"
},
{
"code": "GLM",
"name": "Golem Network Token"
},
{
"code": "TON",
"name": "TON Crystal"
},
{
"code": "AWG",
"name": "AurusGOLD"
},
{
"code": "FUN",
"name": "FunFair"
},
{
"code": "UTK",
"name": "Utrust"
},
{
"code": "1INCH",
"name": "1inch"
},
{
"code": "RENBTC",
"name": "renBTC"
},
{
"code": "RSR",
"name": "Reserve Rights"
},
{
"code": "MANA",
"name": "Decentraland"
},
{
"code": "LRC",
"name": "Loopring"
},
{
"code": "DNT",
"name": "district0x"
},
{
"code": "CVC",
"name": "Civic"
},
{
"code": "XSGD",
"name": "Xfers"
},
{
"code": "ZWAP",
"name": "Zilswap"
},
{
"code": "BNB",
"name": "Binance Coin"
},
{
"code": "HAPI",
"name": "HAPI"
},
{
"code": "AWX",
"name": "AurusDefi"
},
{
"code": "COTI",
"name": "COTI"
},
{
"code": "AWS",
"name": "AurusSILVER"
}
],
"fiat": [
{
"code": "USD",
"name": "United States dollar"
},
{
"code": "EUR",
"name": "euro"
},
{
"code": "GBP",
"name": "British pound sterling"
}
]
}
Location
Countries
Complete List of Countries Eligible for Registration.
Request GET /api/location/countries
curl /api/location/countries
-X GET'
Response
Code: 200
{
"countries": [
{
"name": "Andorra",
"id": "AD"
},
{
"name": "United Arab Emirates",
"id": "AE"
},
{
"name": "Afghanistan",
"id": "AF"
},
{
"name": "Antigua and Barbuda",
"id": "AG"
},
{
"name": "Anguilla",
"id": "AI"
},
...
]
}
USA State
Complete List of USA States Eligible for Registration.
Request GET /api/location/us-states
curl /api/location/us-states
-X GET'
Response
Code: 200
{
"usStates": [
{
"id": "AL",
"name": "Alabama"
},
{
"id": "AK",
"name": "Alaska"
},
{
"id": "AS",
"name": "American Samoa"
},
{
"id": "AZ",
"name": "Arizona"
},
{
"id": "AR",
"name": "Arkansas"
},
{
"id": "AF",
"name": "Armed Forces Africa"
},
...
]
}
Phone Codes
Complete List of Phone Codes Eligible for Registration.
Request GET /api/location/phone-codes
curl /api/location/phone-codes
-X GET'
Response
Code: 200
{
"countriesPhoneCodes": [
{
"id": "US",
"code": "1"
},
{
"id": "AF",
"code": "93"
},
{
"id": "AL",
"code": "355"
},
{
"id": "DZ",
"code": "213"
},
{
"id": "AS",
"code": "1684"
},
{
"id": "AD",
"code": "376"
},
...
]
}
User Settings
Account Security Documentation
This API, built with a state machine known as the Interaction Engine, offers a structured approach to managing account security within the User Settings module.
- Change Email
- Endpoint:
/api/settings/change-email
- Purpose: Update the email associated with a user account.
- Endpoint:
- Change Password
- Endpoint:
/api/settings/change-password
- Purpose: Allow users to change their account password.
- Endpoint:
- Two-Factor Authentication (2FA)
- Setup
- Endpoint:
/api/settings/twofa/setup
- Purpose: Enable Two-Factor Authentication for enhanced account security.
- Disable
- Endpoint:
/api/settings/twofa/disable
- Purpose: Disable Two-Factor Authentication when no longer required.
Security Tips
- Any Flow has restrict time to live, like session time TBD
- ONLY ONE flow could be active for unique AccessToken, mean:
- if user started 2fa setup and not finished
- switched to another flow: started change email
- previous state of 2fa setup flow will be erased and user should start flow from begin
- Developers are encouraged to utilize the Interaction Engine's state machine to streamline and secure user interactions.
- Implement 2FA as a dynamic state within the Interaction Engine for adaptive security measures.
- Ensure thorough testing and validation of state transitions for robust account security management.
Authorizations
- For get access to any user settings action you need AccessToken, which you can receive during Authorization flow.
Init Data
To retrieve and display user data relevant to specified actions, such as two-factor authentication, password, and email, this endpoint will provide all essential information required for its utilization at the beginning of any process.
/settings/data
Request GET /api/settings/data
curl /api/settings/data
-X GET
-H 'Authorization: Bearer <JWT_TOKEN>'
Response for No two-fa enabled
Code: 200
{
"2fa": {
"availableMethods": [
"sms",
"totp"
]
},
"verification": {},
"password": {
"lastTimeChange": 123456789
},
"email": {
"current": "[email protected]",
"lastTimeChange": 123456789
}
}
Two-Factor Authentication (2FA)
2FA Flows Overview
SMS Setup Overview
When configuring SMS-based Two-Factor Authentication (2FA), there are two distinct flows to consider:
Flow 1: Setting Up SMS 2FA Without Existing 2FA:
- Initiate the setup process by sending a request. Email confirmation is required during this step.
- An email will be sent to the user for confirming the setup action.
- The user must provide the verification code received via email.
- After successful verification, the user is prompted to provide their phone number.
- Upon submitting the phone number, a verification SMS will be sent to the provided number.
- Once the SMS verification is successful, the phone number is saved as the 2FA method for the user's account.
Flow 2: Setting Up SMS 2FA With Existing TOTP 2FA:
- Initiate the setup process by sending a request. Email and TOTP confirmation is required during this step.
- An email will be sent to the user for confirming the setup action.
- The user must provide the verification code received via email and TOTP code generated based on previous install.
- After successful verification, the user is prompted to provide their phone number.
- Upon submitting the phone number, a verification SMS will be sent to the provided number.
- Once the SMS verification is successful, the phone number is saved as the 2FA method for the user's account.
TOTP Method Setup
Flow 1: Setting Up TOTP 2FA Without Existing 2FA:
- Initiate the setup process by sending a request. Email confirmation is required during this step.
- An email will be sent to the user for confirming the setup action.
- The user must provide the verification code received via email.
- After successful verification, QR and secret code will be sent to user in response
- Based on secret code, needs to provide verification of TOTP code
- Once the TOTP code verification is successful, the TOTP is saved as the 2FA method for the user's account.
Flow 2: Setting Up TOTP 2FA With Existing SMS 2FA:
- Initiate the setup process by sending a request. Email and SMS confirmation is required during this step.
- An email will be sent to the user for confirming the setup action.
- The user must provide the verification code received via email.
- After successful verification, QR and secret code will be sent to user in response
- Based on secret code, needs to provide verification of TOTP code
- Once the TOTP code verification is successful, the TOTP is saved as the 2FA method for the user's account.
2FA Disable Overview
SMS Disable
- Initiate disable process by sending a request.
- Sms with confirmation code(OTP) will be sent to user phoneNumber.
- User submit otp code, if verification passed SMS will be removed as 2FA method.
TOTP Disable
- Initiate disable process by sending a request.
- User submit TOTP code, if verification passed TOTP will be removed as 2FA method.
2FA REST API
In the user settings flow, there are two key components:
Initialization (Init) Endpoint: This serves as the starting point for the ANY process. For instance, initiating an email check triggers the flow, and an email containing a verification code is sent to the user.
Next Endpoint: This endpoint is responsible for managing the subsequent steps in the flow. It handles actions like confirming codes, providing personal data such as a phone number or new/old email, and advancing the 2FA setup or change process.
/twofa/setup/sms
Flow:
- Setup request (email sent) | /setup
- email check (with totp, if enabled) | /next
- phone number providing (sms sent) | /next
- sms check | /next
Request GET /api/settings/twofa/setup/sms
curl /api/settings/twofa/setup/sms
-X GET
-H 'Authorization: Bearer <JWT_TOKEN>'
Response for No two-fa enabled
Code: 201
{
"rid": "80c9d04d-4717-4286-89bc-eabef8bd1a76",
"reason": {
"key": "SETUP_SMS__NO_TWOFA__VERIFY_EMAIL",
"value": "SETUP_SMS__NO_TWOFA__VERIFY_EMAIL step required."
},
"details": {
"errors": [
{
"reason": "SETUP_SMS__NO_TWOFA__VERIFY_EMAIL step required."
}
],
"data": {
"email": "s***[email protected]",
"exp": {
"email": {
"expTTL": 1699730283,
"resendTTL": 1699644003,
"exp": 1699644003
}
}
}
}
}
Response with Enabled TOTP
Code: 201
{
"rid": "efde255c-bc3d-404a-aef4-0c85c8770604",
"reason": {
"key": "SETUP_SMS__TOTP_ENABLED__VERIFY_EMAIL_TOTP",
"value": "SETUP_SMS__TOTP_ENABLED__VERIFY_EMAIL_TOTP step required."
},
"details": {
"errors": [
{
"reason": "SETUP_SMS__TOTP_ENABLED__VERIFY_EMAIL_TOTP step required."
}
],
"data": {
"maskedEmail": "s***[email protected]",
"exp": {
"email": {
"expTTL": 1699965024,
"resendTTL": 1699878744,
"exp": 1699878744
},
"totp": {}
}
}
}
}
/twofa/setup/totp
Flow:
- setup request (email sent) | /setup
- email check (with sms, if enabled) | /next
- QR + secret code in response | /next
- totp check | /next
Request GET /api/settings/twofa/setup/totp
curl /api/settings/twofa/setup/totp
-X GET
-H 'Authorization: Bearer <JWT_TOKEN>'
Response No two-fa enabled
Code: 201
{
"rid": "a61f3029-91ad-4585-a1b1-7e996502f9d2",
"reason": {
"key": "SETUP_TOTP__NO_TWOFA__VERIFY_EMAIL",
"value": "SETUP_TOTP__NO_TWOFA__VERIFY_EMAIL step required."
},
"details": {
"errors": [
{
"reason": "SETUP_TOTP__NO_TWOFA__VERIFY_EMAIL step required."
}
],
"data": {
"email": "s***[email protected]",
"exp": {
"email": {
"expTTL": 1699731264,
"resendTTL": 1699644984,
"exp": 1699644984
}
}
}
}
}
/twofa/disable/sms
Flow:
- init disable flow | /setup
- phoneNumber check | /next
Request GET /api/settings/twofa/disable/sms
curl /api/settings/twofa/disable/sms
-X GET
-H 'Authorization: Bearer <JWT_TOKEN>'
Response
Code: 201
{
"rid": "9dcf4fbb-7371-4991-bca1-7c58ef3f5078",
"reason": {
"key": "DISABLE_SMS__VERIFY_SMS",
"value": "DISABLE_SMS__VERIFY_SMS step required."
},
"details": {
"errors": [
{
"reason": "DISABLE_SMS__VERIFY_SMS step required."
}
],
"data": {
"externalId": "4828b327-6e06-402b-8d0e-611ce4c2142a",
"maskedPhone": "+44 ********90",
"exp": {
"sms": {
"expTTL": 1699893994,
"resendTTL": 1699893814,
"exp": 1699893814
}
}
}
}
}
/twofa/disable/totp
Flow:
- init disable flow | /setup
- totp check | /next
Request GET /api/settings/twofa/disable/totp
curl /api/settings/twofa/disable/totp
-X GET
-H 'Authorization: Bearer <JWT_TOKEN>'
Response:
Code: 201
{
"rid": "9b4093e7-736b-4494-9167-6f2b24763be4",
"reason": {
"key": "DISABLE_TOTP__VERIFY_TOTP",
"value": "DISABLE_TOTP__VERIFY_TOTP step required."
},
"details": {
"errors": [
{
"reason": "DISABLE_TOTP__VERIFY_TOTP step required."
}
]
}
}
/twofa/next
- End-point:
/next
- Description:
- Manages the sequence of actions in 2FA (Two-Factor Authentication) processes.
- Allows for the completion of the current process.
- The flow structure can vary, including either 2 or 4 steps of actions.
- Example for ANY code submission, any combination of methods:
- Only Email:
{ "email": { "code": "000000" } }
- Only SMS:
{ "sms": { "code": "000000" } }
- Only TOTP:
{ "totp": { "code": "000000" } }
- Combination:
{ "email": { "code": "123456" }, "totp": { "code": "654321" } }
- Only Email:
- Example of phoneNumber providing:
{ "phoneNumber": "+37654332345" }
Email Submit:
Request GET /api/settings/twofa/next
curl /api/settings/twofa/next
-X POST
-H 'Authorization: Bearer <JWT_TOKEN>'
-H 'Content-type: application/json'
-d '{
"email": {
"code": "000000"
}
}'
SMS code Submit:
Request GET /api/settings/twofa/next
curl /api/settings/twofa/next
-X POST
-H 'Authorization: Bearer <JWT_TOKEN>'
-H 'Content-type: application/json'
-d '{
"sms": {
"code": "000000"
}
}'
TOTP Submit:
Request GET /api/settings/twofa/next
curl /api/settings/twofa/next
-X POST
-H 'Authorization: Bearer <JWT_TOKEN>'
-H 'Content-type: application/json'
-d '{
"totp": {
"code": "000000"
}
}'
Email+SMS Submit:
Request GET /api/settings/twofa/next
curl /api/settings/twofa/next
-X POST
-H 'Authorization: Bearer <JWT_TOKEN>'
-H 'Content-type: application.json'
-d '{
"email": {
"code": "000000"
},
"sms": {
"code": "000000"
}
}'
Email+TOTP Submit:
Request GET /api/settings/twofa/next
curl /api/settings/twofa/next
-X POST
-H 'Authorization: Bearer <JWT_TOKEN>'
-H 'Content-type: application/json'
-d '{
"email": {
"code": "000000"
},
"totp": {
"code": "000000"
}
}'
Phone Number Submit:
Request GET /api/settings/twofa/next
curl /api/settings/twofa/next
-X POST
-H 'Authorization: Bearer <JWT_TOKEN>'
-H 'Content-type: application/json'
-d '{
"phoneNumber": "+38023123234"
}'
2FA Responses
Final Success Response:
Http code: 200
{
"status": "finished",
"details": {
"userId": "ud204345292"
}
}
For SMS success:
{
"status": "finished",
"details": {
"userId": "ud204345292",
"rId": "890fda63-b738-4568-be8e-7e42ff9913ef",
"phoneNumber": "+380 *******79"
}
}
Reasons List:
INVALID_OPERATION
- Description:
- Requested method already Installed
- http code: 403
{
"rid": "47aaaddc-70a1-4ea9-9249-106952378774",
"reason": {
"key": "INVALID_OPERATION",
"value": "User already enabled totp two fa"
},
"details": {
"data": {
"availableMethods": [
"totp",
"sms"
]
}
}
}
DISABLE_TOTP__VERIFY_TOTP
- Description: Verify exist TOTP
- http code: 201
{
"rid": "c220a66a-ce18-476f-bb19-3a5bf5478e10",
"reason": {
"key": "DISABLE_TOTP__VERIFY_TOTP",
"value": "DISABLE_TOTP__VERIFY_TOTP step required."
},
"details": {
"errors": [
{
"reason": "DISABLE_TOTP__VERIFY_TOTP step required."
}
]
}
}
BAD_REQUEST_ERROR
- Description: No value provided, errors contain data where or what invalid.
- http code: 400
{
"path": "API POST /api/settings/twofa/next",
"timestamp": "2023-11-15T13:50:36.048Z",
"rid": "ea3ea19b-4233-463b-b3db-b77543550d63",
"reason": {
"key": "BAD_REQUEST_ERROR",
"value": "Bad Request Exception"
},
"errors": [
{
"field": "totp.code",
"value": "Request must contains correct totp code"
}
]
}
INVALID_2FA_CODE
- Description: Provided 2fa code INVALID
- http code: 429
{
"rid": "d0a44ade-b5cf-45b2-9e7e-a08646ddf27b",
"reason": {
"key": "INVALID_2FA_CODE",
"value": "Entered code was invalid. Please try again."
},
"details": {
"errors": {}
}
}
SETUP_TOTP_SMS_ENABLED_VERIFY_EMAIL_SMS
- Description: Verify email and verify SMS if installed
- http code: 201
{
"rid": "091ac2d8-c4ab-4eea-94f6-6b132f6bbda7",
"reason": {
"key": "SETUP_TOTP__SMS_ENABLED__VERIFY_EMAIL_SMS",
"value": "SETUP_TOTP__SMS_ENABLED__VERIFY_EMAIL_SMS step required."
},
"details": {
"errors": [
{
"reason": "SETUP_TOTP__SMS_ENABLED__VERIFY_EMAIL_SMS step required."
}
],
"data": {
"email": "s***[email protected]",
"exp": {
"email": {
"expTTL": 1699644463,
"resendTTL": 1699558183,
"exp": 1699558183
},
"sms": {
"expTTL": 1699558362,
"resendTTL": 1699558182,
"exp": 1699558182
}
}
}
}
}
SETUP_TOTP_SMS_ENABLED_VERIFY_TOTP
- Description: Expecting TOTP code verification, based on provided QR or secret code
- http code: 201
{
"rid": "8b2fa63b-61a9-4531-a9d6-c4526156dec8",
"reason": {
"key": "SETUP_TOTP__SMS_ENABLED__VERIFY_TOTP",
"value": "SETUP_TOTP__SMS_ENABLED__VERIFY_TOTP step required."
},
"details": {
"errors": [
{
"reason": "SETUP_TOTP__SMS_ENABLED__VERIFY_TOTP step required."
}
],
"data": {
"qrCodeData": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALQAAAC0CAYAAAA9zQYyAAAAAklEQVR4AewaftIAAAdzSURBVO3BQW4Ex7IgQfdE3//KPlrG5hdQaJJPygkz+wdrXeKw1kUOa13ksNZFDmtd5LDWRQ5rXeSw1kUOa13ksNZFDmtd5LDWRQ5rXeSw1kUOa13ksNZFPnxJ5S9VTCpPKp6oPKmYVKaK36TyRsWkMlW8ofKXKr5xWOsih7UucljrIh9+WMVPUnmj4jdVTCpvVDxReVLxRsUTlaniScVPUvlJh7UucljrIoe1LvLhl6m8UfFGxaTypOJJxaTypOINlaliqniiMlVMKn9J5Y2K33RY6yKHtS5yWOsiH/7jVKaKJypTxTdU3qh4Q2WqWP+3w1oXOax1kcNaF/nwH1cxqUwVU8UTlScVk8pU8YbKT6qYVP5/cljrIoe1LnJY6yIfflnF/5LKk4qp4onKVDGpfKPiGypPKn5Sxb/JYa2LHNa6yGGti3z4YSp/SWWqmFSmikllqphUpopJZaqYVKaKSeWJylQxqUwVk8oTlaniicq/2WGtixzWushhrYt8+FLFf4nKVDGpTBWTyhsV36iYVKaKSeWJyhsV/yWHtS5yWOsih7Uu8uFLKlPFpPKkYlJ5o2JSmSomlUllqnij4onKk4onKk9UpoonKlPFE5Wp4onKVDGpPKn4xmGtixzWushhrYt8+GMVk8pU8Y2KSWWq+F+qmFR+k8obKn+p4icd1rrIYa2LHNa6iP2DfxGVNyomlaliUpkqvqHypGJSeaPiicpU8YbKVDGpTBWTylQxqUwVv+mw1kUOa13ksNZF7B98QWWqmFSmikllqnii8o2KSWWqmFSmikllqphUpopJZar4hspUMalMFZPKk4onKlPFXzqsdZHDWhc5rHWRD1+qmFS+ofKkYlJ5UvGk4knFpPINlaniicpUMalMFd+omFSeqEwVT1SeVHzjsNZFDmtd5LDWRT78j1W8oTJVPFGZKiaVqeKNiknlDZWpYqqYVKaKSWWqeEPlL1X8pMNaFzmsdZHDWhf58CWVqWJSmVSmiknlJ1VMKlPFE5U3Kp6oPFGZKqaKb1RMKlPFpDKpvKHylw5rXeSw1kUOa13E/sEPUnlS8URlqphUpoonKn+p4g2VNyqeqLxR8Q2VqeINlaniG4e1LnJY6yKHtS7y4YdVTCpvVEwqb6hMFd9QmSqeqEwVk8pUMalMFZPKNyqeqLxR8UTlLx3WushhrYsc1rrIhz+mMlU8qXiiMlU8UZkqJpWp4hsqb1S8UTGpvKEyVUwqT1SeVEwqv+mw1kUOa13ksNZFPnxJZap4Q+UbFd9QmSq+UTGpTBWTyjdUpoonKlPFpDJVTCpPKiaVv3RY6yKHtS5yWOsiH75U8aRiUnlS8YbKVDGpTBWTyqTyjYqp4o2KSWWqmFSeqLxRMak8qZhUpoonKj/psNZFDmtd5LDWRT78MJWp4hsqU8UbFb+p4g2VJypTxaQyVTypeENlqniiMlU8UflNh7UucljrIoe1LmL/4AsqTyp+kspU8Q2VJxWTyk+qmFSmijdUpoonKk8q3lCZKv7SYa2LHNa6yGGti3z4UsUTlZ9UMak8qZhUnlS8UfFEZaqYVKaKSeVJxVQxqUwVU8UTlaliUnlDZar4SYe1LnJY6yKHtS7y4UsqU8U3Kt6oeKPiGxWTypOKSeWJyr9JxaTyhspfOqx1kcNaFzmsdZEPv6xiUnmi8qTiN6lMFW9UPKn4TSpTxaTyRsUbFZPKE5Wp4huHtS5yWOsih7Uu8uFLFZPKNyqeqHyj4g2VqWKqmFSmim+oPKmYKr5RMan8lxzWushhrYsc1rrIh19WMalMFZPKk4pJ5UnFE5WpYlJ5o+IbKk8qJpU3KiaVSWWqmFR+UsVPOqx1kcNaFzmsdZEPX1KZKiaVJypPKiaVJxVvVDypmFSmikllqphU/lLFGxWTypOKb6hMFd84rHWRw1oXOax1EfsH/2IqTyq+ofJGxRsqTyomlScVk8pU8UTlN1VMKk8qftJhrYsc1rrIYa2LfPiXq3ii8o2KJyqTypOKqeKJylTxv1Txhsqk8qTiNx3WushhrYsc1rrIhy+p/KWKNyomlScqU8Wk8obKVPGGylTxRGWqmComlScqU8WTiv+lw1oXOax1kcNaF/nwwyp+ksobFd+oeFIxqUwqb1RMKj9J5RsVb6hMFX/psNZFDmtd5LDWRT78MpU3Kt6oeKIyVbyh8kbFE5WpYqqYVN6oeENlUvlLKlPFNw5rXeSw1kUOa13kw3+cym+qmFSeqEwVU8UTlaliUnmi8qTiGxWTylTxROU3Hda6yGGtixzWusiHy1VMKm9UPKl4ojJVTCpvVHxD5RsqT1TeqPhJh7UucljrIoe1LvLhl1X8popJZVKZKiaVJyrfqJhUpoonKk8qJpWp4jdVTCpPKn7TYa2LHNa6yGGti3z4YSp/SeVJxaQyVUwqU8UbKlPFVPGNiicVk8pfqnii8qTiG4e1LnJY6yKHtS5i/2CtSxzWushhrYsc1rrIYa2LHNa6yGGtixzWushhrYsc1rrIYa2LHNa6yGGtixzWushhrYsc1rrI/wNez913Jvu8hwAAAABJRU5ErkJggg==",
"secretCode": "NM4G2XRRENGCYQSSGFITAJSJINUGMOLT"
}
}
}
DISABLE_SMS__VERIFY_SMS
- Description: Expecting SMS code verification and disable
- http code: 201
{
"rid": "74f0372e-12ca-476a-bdfd-09b65400e908",
"reason": {
"key": "DISABLE_SMS__VERIFY_SMS",
"value": "DISABLE_SMS__VERIFY_SMS step required."
},
"details": {
"errors": [
{
"reason": "DISABLE_SMS__VERIFY_SMS step required."
}
],
"data": {
"externalId": "a0807e91-649b-4f5f-ba77-a1b086bdb3f5",
"maskedPhone": "+380 *******79",
"exp": {
"sms": {
"expTTL": 1699564018,
"resendTTL": 1699563838,
"exp": 1699563838
}
}
}
}
}
SETUP_SMS_TOTP_ENABLED_VERIFY_EMAIL_TOTP
- Description: Expecting TOTP code and Email verification
- http code: 201
{
"rid": "80dfdb41-cd33-44b8-a3fd-86d755cbd159",
"reason": {
"key": "SETUP_SMS__TOTP_ENABLED__VERIFY_EMAIL_TOTP",
"value": "SETUP_SMS__TOTP_ENABLED__VERIFY_EMAIL_TOTP step required."
},
"details": {
"errors": [
{
"reason": "SETUP_SMS__TOTP_ENABLED__VERIFY_EMAIL_TOTP step required."
}
],
"data": {
"email": "s***[email protected]",
"exp": {
"email": {
"expTTL": 1699650225,
"resendTTL": 1699563945,
"exp": 1699563945
},
"totp": {}
}
}
}
}
SETUP_SMS_TOTP_ENABLED_SEND_CHECK_SMS
- Description: Expecting phone Number which will be verified and setup as Two-Fa phon number
- http code: 201
{
"rid": "10513efb-7ff0-4091-b02f-aea9587ac4ce",
"reason": {
"key": "SETUP_SMS__TOTP_ENABLED__SEND_CHECK_SMS",
"value": "SETUP_SMS__TOTP_ENABLED__SEND_CHECK_SMS step required."
},
"details": {
"errors": [
{
"reason": "SETUP_SMS__TOTP_ENABLED__SEND_CHECK_SMS step required."
}
]
}
}
SETUP_SMS_TOTP_ENABLED_VERIFY_SMS
- Description: Expecting SMS code for phone verification
- http code: 201
{
"rid": "96d32a69-51d5-44d6-b142-1a486293a624",
"reason": {
"key": "SETUP_SMS__TOTP_ENABLED__VERIFY_SMS",
"value": "SETUP_SMS__TOTP_ENABLED__VERIFY_SMS step required."
},
"details": {
"errors": [
{
"reason": "SETUP_SMS__TOTP_ENABLED__VERIFY_SMS step required."
}
],
"data": {
"externalId": "4eeb8469-e4ed-47f4-a4bf-bd2858b67a56",
"maskedPhone": "+380 *******79",
"exp": {
"sms": {
"expTTL": 1699970907,
"resendTTL": 1699970727,
"exp": 1699970727
}
}
}
}
}
TWO_FA_VERIFY_ERROR
- Description: Invalid verification code
- http code: 201
{
"rid": "38a74b30-727a-45df-bbb6-0758735dad4f",
"reason": {
"key": "TWO_FA_VERIFY_ERROR"
},
"details": {
"errors": {
"email": {
"reason": {
"key": "INVALID_2FA_CODE",
"value": "Entered code was invalid. Please try again."
},
"errorDetail": {}
}
}
}
}
SETUP_TOTP_NO_TWOFA_VERIFY_TOTP
- Description: Verify totp
- http code: 201
{
"rid": "2efe526e-2274-42d9-a0bb-9a2b00ef78e9",
"reason": {
"key": "SETUP_TOTP__NO_TWOFA__VERIFY_TOTP",
"value": "SETUP_TOTP__NO_TWOFA__VERIFY_TOTP step required."
},
"details": {
"errors": [
{
"reason": "SETUP_TOTP__NO_TWOFA__VERIFY_TOTP step required."
}
],
"data": {
"qrCodeData": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALQAAAC0CAYAAAA9zQYyAAAAAklEQVR4AewaftIAAAd8SURBVO3BQY4kR5IAQdVA/f/Lun20k2MDmdXkOE3E/mCtSzysdZGHtS7ysNZFHta6yMNaF3lY6yIPa13kYa2LPKx1kYe1LvKw1kUe1rrIw1oXeVjrIg9rXeSHD6n8TRW/SeWNik+onFRMKicVJyonFZPK31TxiYe1LvKw1kUe1rrID19W8U0qn1B5o2JSmSomlaniExUnFW+onFS8UfFNKt/0sNZFHta6yMNaF/nhl6m8UfEJlaniRGVSOVGZKiaVqeKk4hMqU8UbKlPFGypvVPymh7Uu8rDWRR7WusgPl6mYVKaKqWJSmSq+SWWqOFFZ/38Pa13kYa2LPKx1kR/+41SmijdUTlROVL5J5b/sYa2LPKx1kYe1LvLDL6v4TSpvqJyovFExqbxRMamcVJyoTBWTyjdV/Js8rHWRh7Uu8rDWRX74MpV/UsWkMlVMKlPFpDJVTCpTxaQyVUwqU8WkcqIyVUwqU8Wk8obKv9nDWhd5WOsiD2tdxP7gP0zljYpJZar4hMobFZPKVPFf8rDWRR7WusjDWhf54UMqU8WJylQxqZxUTConFZPKScWJylQxqUwVb1RMKlPFJ1SmikllqphUpop/k4e1LvKw1kUe1rrID1+mclJxUnGiclIxqXxC5Y2KE5W/SeUTKlPFicpJxaQyVXziYa2LPKx1kYe1LvLDX6ZyUjGpnFS8UfGJikllqjipmFROKiaVqeKk4kTlpOJE5Q2V3/Sw1kUe1rrIw1oXsT/4IpWTiknlpOJEZaqYVE4qJpU3KiaVqeINlZOKE5WTiknlmyr+SQ9rXeRhrYs8rHWRHz6kclIxqUwVk8qkMlWcqJxUTCpTxaQyVZxUTCqfqDhRmSomlTcqJpWp4kRlqphUTio+8bDWRR7WusjDWhf54R+mclIxqZxUnKicqHxC5Y2KSWVSOamYVD6h8k0qU8VveljrIg9rXeRhrYv88A+rmFQmlZOKSeWk4kTlROUTFZPKScWkMqlMFZ+omFROVKaKSeVEZar4xMNaF3lY6yIPa13E/uAfpHJSMal8ouJE5Y2KSeWfVDGpnFRMKp+o+Cc9rHWRh7Uu8rDWRX74ZSpTxRsqU8UbKpPKScWkMlWcVEwqU8WJylTxTRVvVEwqb6hMFb/pYa2LPKx1kYe1LmJ/8BepTBWTylQxqZxUTCpTxaRyUjGpnFRMKr+pYlKZKiaVqeITKicVk8pJxSce1rrIw1oXeVjrIvYHX6TyN1VMKlPFpHJSMal8ouKbVE4qJpWpYlI5qZhUTipOVE4qPvGw1kUe1rrIw1oX+eFfrmJSOan4hMpU8YbKJ1SmiqliUjmpeKNiUpkqTlROKiaVb3pY6yIPa13kYa2L/PAhlaliUpkqJpUTlaniDZWTiknlRGWqmCreUPkmlaliUpkq3lD5popveljrIg9rXeRhrYvYH/wilU9UnKi8UfGGylTxhspUcaIyVUwqJxVvqEwVk8pJxaQyVUwqJxWfeFjrIg9rXeRhrYvYH/wilW+qOFGZKiaVqeINlaliUpkqJpWTikllqphU3qg4Ufmmikllqvimh7Uu8rDWRR7WusgPX6YyVZyoTBUnKlPFVPFNKicqn6g4qZhUpoo3VL6p4o2KSWWq+MTDWhd5WOsiD2td5Id/WMWJylQxqbxRcaJyUvGJiknljYoTlZOK36QyVZxUfNPDWhd5WOsiD2tdxP7gi1TeqHhD5Zsq3lB5o+JE5aRiUpkqTlROKiaVqeITKm9UfOJhrYs8rHWRh7Uu8sOHVKaKSWWqmFTeqHhD5URlqphUpooTlROVqWJSmVS+qWJSmSomlTcqTiomlW96WOsiD2td5GGti9gffJHKScWkMlW8oTJVnKicVEwqJxUnKlPFpPKJim9SmSomlani3+RhrYs8rHWRh7UuYn/wAZWTikllqphUTipOVD5R8QmVk4oTlTcqJpWp4kTlb6qYVKaKTzysdZGHtS7ysNZFfvhQxRsVJxVvqEwVk8pJxaQyVUwqJxW/qWJSmSomlanipOINlaniROU3Pax1kYe1LvKw1kV++JDK31QxVbxR8YbKJ1Smijcq3lA5UXlDZao4UTmp+E0Pa13kYa2LPKx1kR++rOKbVE5UpoqpYlI5qfiEyhsqU8U3VZyonFS8UTGpTConFZ94WOsiD2td5GGti/zwy1TeqHijYlKZKqaKSeVEZaqYVD5RcaJyUjGpfELlEypTxYnKNz2sdZGHtS7ysNZFfvgfp/KGylTxhsonVKaKSWWqeKNiUpkqTipOVL6p4pse1rrIw1oXeVjrIj/8j6uYVD6h8kbFGyqTyhsqb1RMKp+omFSmikllqphUpopPPKx1kYe1LvKw1kV++GUVf1PFpHKiMlW8oTJVTCq/qWJSmVSmik+ovFFxUvFND2td5GGtizysdZEfvkzlb1KZKk4q3lA5qXijYlJ5o+Kk4kTljYpvUjmp+MTDWhd5WOsiD2tdxP5grUs8rHWRh7Uu8rDWRR7WusjDWhd5WOsiD2td5GGtizysdZGHtS7ysNZFHta6yMNaF3lY6yIPa13k/wCGOMqlGJDKKQAAAABJRU5ErkJggg==",
"secretCode": "HFQXUZCHOJ2XGRTIJR3SQ6ZRNBJCYJD2"
}
}
}
SMS_CODE_EXPIRED
- Description: Sms with code expired, new sms will be sent
- http code: 201
{
"rid": "3bc29fd2-3a04-4777-8fd1-143b8d4f13e8",
"reason": {
"key": "SMS_CODE_EXPIRED",
"value": "Sms code was expired. New code sent."
},
"details": {
"errors": [],
"data": {
"exp": {
"sms": {}
}
}
}
}
RATE_FAIL
- Description: Any Rate Limits, like: sms or email submit, verify any otp
- http code: 429
{
"rid": "bba5fa81-7816-4fba-a541-2139cc8f8a80",
"reason": {
"key": "RATE_FAIL",
"value": "You've already made too many attempts. Please try again later."
},
"details": {
"errors": {},
"data": {
"exp": {
"sms": {}
}
}
}
}
Changing Email
This feature permits users to switch their existing email to a new one. Users must be able to access both their old and new email addresses. The process is outlined as follows:
- Start the Email Update Process: Initiate the process to change your email. A confirmation email will be sent to your existing email address.
- If 2FA via SMS is enabled, you will receive a verification SMS as well.
- Complete the confirmation: Through the email and undergo 2FA verification if enabled (either via SMS or TOTP).
- Enter New Email Address: Provide the new email address you wish to use.
- Verify New Email Address: Authenticate the new email with the verification code sent to it.
- Finalize the Update: After successful verification, the new email will be ready for use for login and notifications.
REST API Change Email
Init change email
Request GET /api/settings/change-email
curl /api/settings/change-email
-X GET
-H 'Authorization: Bearer <JWT_TOKEN>'
Response:
Code: 201
{
"rid": "718d0bb6-22f1-4026-9750-eaea78003fdb",
"reason": {
"key": "CHANGE_EMAIL_VERIFY",
"value": "CHANGE_EMAIL_VERIFY step required."
},
"details": {
"errors": [
{
"reason": "CHANGE_EMAIL_VERIFY step required."
}
],
"data": {
"email": "s***[email protected]",
"externalId": "2d00f9dd-2ed5-4a43-b001-74a94dd3d3a4",
"exp": {
"email": {
"expTTL": 1699731264,
"resendTTL": 1699644984,
"exp": 1699644984
},
"sms": {
"expTTL": 1699564425,
"resendTTL": 1699564245,
"exp": 1699564245
}
}
}
}
}
/next change email
Step 1. Confirm current email step + 2FA(SMS or TOTP), if enabled
Request GET /api/settings/change-email/next
curl /api/settings/change-email/next
-X POST
-H 'Authorization: Bearer <JWT_TOKEN>'
-H 'Content-type: application/json'
-d '{
"email": {
"code": "150920"
},
"totp": {
"code": "215595"
}
}'
Response:
Code: 201
{
"rid": "e8a5a6d7-6a62-4757-9554-b444513c635e",
"reason": {
"key": "NEW_EMAIL_SEND_VERIFICATION",
"value": "NEW_EMAIL_SEND_VERIFICATION step required."
},
"details": {
"errors": [
{
"reason": "NEW_EMAIL_SEND_VERIFICATION step required."
}
]
}
}
Step 2: Provide new email
Request GET /api/settings/change-email/next
curl /api/settings/change-email/next
-X POST
-H 'Authorization: Bearer <JWT_TOKEN>'
-H 'Content-type: application/json'
-d '{
"newEmail": "[email protected]"
}'
Response:
Code: 201
{
"rid": "ab0db80b-b776-4bfe-8a3e-906da1306226",
"reason": {
"key": "NEW_EMAIL_VERIFY",
"value": "NEW_EMAIL_VERIFY step required."
},
"details": {
"errors": [
{
"reason": "NEW_EMAIL_VERIFY step required."
}
],
"data": {
"email": "s***[email protected]",
"externalId": "2d00f9dd-2ed5-4a43-b001-74a94dd3d3a4",
"exp": {
"email": {
"expTTL": 1699731264,
"resendTTL": 1699644984,
"exp": 1699644984
}
}
}
}
}
Step 3: Confirm new email
Request GET /api/settings/change-email/next
curl /api/settings/change-email/next
-X POST
-H 'Authorization: Bearer <JWT_TOKEN>'
-H 'Content-type: application/json'
-d '{
"email": {
"code": "429823"
}
}'
Response:
Code: 201
{
"status": "finished",
"details": {
"userId": "ud204352727",
"rId": "d919d761-df1a-41bd-a6f2-962f33cd26b8",
"newEmail": "[email protected]"
}
}
Changing Password
REST API Change Password
To update the password, you only need to provide the current (old) password and the new password.
/api/settings/change-password
Request POST /api/settings/change-password
curl /api/settings/change-password
-X POST
-H 'Authorization: Bearer <JWT_TOKEN>'
-d '{
"currentPassword": "encoded currentPassword",
"newPassword": "encoded new Password"
}'
Response:
Code: 200
{
"status": "finished",
"details": {
"userId": "ud204352727",
"rId": "d919d761-df1a-41bd-a6f2-962f33cd26b8"
}
}
Compliance
Verification
Below verification stages are available for submit:
- Intro
- Identity
- Address
- Enhanced
- Corporate
Use method POST/verification/required-blocks in order to get list of the blocks required to submit a certain verification stage.
Submit intro
The Intro verification stage consists of 2 blocks: - personalData - residence
Methods
In order to submit intro - use method POST/verification/intro.
Validation rules
Fields providerRequestId and provider are required in order to extract the rest of user's data from Prove. In case if these fields are submitted - blocks
personalData
andresidence
are not mandatory for submission.
Field | Mandatory | Length | Format |
---|---|---|---|
providerRequestId | no | - | No validation rules |
provider | no | - | No validation rules |
personalData
Field | Mandatory | Length | Format |
---|---|---|---|
firstName | no | 0 - 64 | alphanumeric (latin only) & special symbols: ` ‘ ’ ' - " space |
lastName | no | 0 - 64 | alphanumeric (latin only) & special symbols: ` ‘ ’ ' - " space |
dateOfBirth | no | - | YYYY-MM-DD; min date > current date - 100 years ; max date < current date - 18 years |
introResidence
Field | Mandatory | Length | Format |
---|---|---|---|
country | yes | - | id value from dict CountryDict_cex |
zipCode | no | custom | alphanumeric (numbers and latin) & special symbols: " - / \ \ . " space |
region | no | - | id value from dict CountryDict_cex |
subregion | no | - | id value from dict CountryDict_cex |
SSN | no | 9 | numeric |
street | no | 5 - 128 | alphanumeric (numbers and latin) & special symbols:- / # ( ) . , ] [ * $ ? space |
city | no | 3 - 64 | alphanumeric (numbers and latin) & special symbols: , / - . ` ‘ ’ ' space |
aptSuite | no | 1 - 128 | alphanumeric (numbers and latin) & special symbols: \ / - . ` ' ' ' , space |
Submit Identity
The Identity verification stage consists of 7 blocks:
- fullResidence
- SSN
- phone
- livenessCheckRegula
- livenessCheck
- selfieImage
- identityDocument
- jurisdictionCode
- personalCode
- occupation
- sof
- questionnairePage
Methods
Submit Identity
In order to submit Identity stage - use method POST/verification/identity.
Get required blocks
In order to get the list of blocks, which are required for the user to submit identity verification - use method POST/compliance/verification/required-blocks.
In response you would receive only the blocks which are required for user. If block is absent in response - it should not be submitted. An options
block contains information, whether frontend should use some additional methods, e.g. Regula Scan Document or simple image upload.
An example below shows that we are expecting for blocks: livenessCheckRegula
, identityDocument
with scanDocRegula, sof
.
"requiredBlocks": {
"livenessCheckRegula": [],
"identityDocument": [
{
"options": {
"scanDocRegula": true,
"uploadDoc": false
}
}
],
"sof": []
}
Get blocks details
Some blocks contains some specific fields, or fields which depends a certain dicts. In order to get the list of this conditions - user method GET/compliance/common/getMerchantParams.
Validation rules
fullResidence
Field | Mandatory | Length | Format |
---|---|---|---|
country | yes | - | id value from dict CountryDict_cex |
zipCode | yes | see 'Format' | validation per country |
region | yes | - | id value from dict CountryDict_cex |
subregion | yes | - | id value from dict CountryDict_cex |
street | yes | 5 - 128 | alphanumeric (numbers and latin) & special symbols: - / # ( ) . , ] [ * $ ? space |
city | yes | 3 - 64 | alphanumeric (numbers and latin) & special symbols: " ` ' - / , . space |
aptSuite | no | 1 - 128 | alphanumeric (numbers and latin) & special symbols: ' - / \ \ , . " ` space |
SSN
Field | Mandatory | Length | Format |
---|---|---|---|
SSN | yes | 9 | numeric |
phone
Field | Mandatory | Length | Format |
---|---|---|---|
country | yes | - | id value from dict CountryDict_cex |
code | yes | - | id value from dict CountryDict_cex |
number | yes | 5 - 15 | numeric |
livenessCheckRegula
For the livenessCheckRegula
massive please put below objects.
You can send from 1 to 10 of such blocks.
Field | mandatory | validation |
---|---|---|
passed | yes | boolean |
guid | yes | no validation rules |
verified | no | boolean |
results | no | no validation rules |
failReason | no | no validation rules |
Field | Mandatory | Length | Format |
---|---|---|---|
livenessCheckRegula | yes | - | - |
livenessCheck
Native liveness check implemented for mobile clients. Below is represented an example wich is received after livenessCheck block submission, which is expected on backend.
"livenessCheck": [
{
"actions": [
{
"time": 922,
"passed": false,
"failReason": "wrongAction",
"type": "turnLeft"
},
{
"passed": true,
"type": "smile",
"time": 2717
},
{
"passed": true,
"type": "turnRight",
"time": 1210
}
],
"time": 23948
}
]
selfieImage
The current block contains onyly the selfieImage
field for image data.
In order to submit image - use method use method POST/s3/upload Allowed file formats: PDF or PNG or JPG
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image fields while submitting the current block.
Field | Mandatory | Length | Format |
---|---|---|---|
selfieImage | yes | - | - |
identityDocument
The current block contains the images
field for image data.
In order to submit image - use method use method POST/s3/upload Allowed file formats: PDF or PNG or JPG
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image fields while submitting the current block.
Field | Mandatory | Length | Format |
---|---|---|---|
type | yes | 8 | only identity value allowed |
subtype | yes | - | id value from dict DocumentIdentitySubtypeDict |
issuingCountry | IF subtype <> International Passport THEN field is mandatory |
- | id value from dict CountryDict_cex |
hasExpireDate | yes | - | boolean |
expireDate | IF hasExpireDate = true THEN field is mandatory |
10 | YYYY-MM-DD; min date > 1 month from current date |
serialNumber | yes | 1 - 128 | alphanumeric (latin & cyryllic only) |
images | yes | - | See description above the table |
firstName | yes | 1 - 64 | alphanumeric (latin only) & special symbols: ` ‘ ’ ' - " space |
lastName | yes | 1 - 64 | alphanumeric (latin only) & special symbols: ` ‘ ’ ' - " space |
middleName | no | 1 - 64 | alphanumeric (latin only) & special symbols: ` ‘ ’ ' - " space |
dateOfBirth | yes | 10 | YYYY-MM-DD; min date > current date - 100 years ; max date < current date - 18 years |
placeOfBirth | no | 0 - 128 | alphanumeric (latin only) & special symbols: / . , ` ‘ ’ ' - " space |
gender | yes | - | only male or female values allowed |
nationality | yes | - | id value from dict CountryDict_cex |
jurisdictionCode
Field | Mandatory | Length | Format |
---|---|---|---|
jurisdictionCode | yes | 2 | alphanumeric (latin only) |
personalCode
Field | Mandatory | Length | Format |
---|---|---|---|
personalCode | yes | 11 | numeric |
occupation
Field | Mandatory | Length | Format |
---|---|---|---|
accountCreateReason | yes | - | id value from dict AccountCreateReasonDict |
accountCreateReasonOther | IF accountCreateReason = Other THEN field is mandatory |
3 - 512 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
status | yes | - | id value from dict EmploymentStatusDict |
industry | yes | - | id value from dict IndustryDict |
industryDetailed | IF industry = Other THEN field is mandatory |
3 - 128 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
position | yes | - | id value from dict EmploymentPositionDict |
positionDetailed | IF position = Other THEN field is mandatory |
3 - 128 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
type | IF status = Self-employed THEN field is mandatory |
- | id value from dict SelfEmploymentTypeDict |
typeDetailed | IF type = Other THEN field is mandatory |
3 - 128 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
sof
The current block contains the images
field for image data.
In order to submit image - use method use method POST/s3/upload
Allowed file formats: JPG, PNG, PDF Min 1 file, max 10 files Max file size is 30 MB.
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image fields while submitting the current block.
Field | Mandatory | Length | Format |
---|---|---|---|
accountCreateReason | yes | - | id value from dict AccountCreateReasonDict |
accountCreateReasonOther | IF accountCreateReason = Other THEN field is mandatory |
1 - 128 | alphanumeric (latin only) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
monthlyTurnover | yes | - | id value from dict MonthlyTurnoverIdentityDict |
sourceOfFunds | yes | - | id value from dict SourceOfFundsIdentityDict |
sourceOfFundsOther | IF sourceOfFunds = Other THEN field is mandatory |
1 - 128 | alphanumeric (latin only) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
annualFundsAmount | yes | - | id value from dict annualSalaryDict |
status | IF sourceOfFunds = Employment income OR Savings from Employment THEN field is mandatory |
- | id value from dict employmentStatusIdentityDict |
employmentPosition | IF sourceOfFunds = Employment income OR Savings from Employment THEN field is mandatory |
- | value from EmploymentPositionIdentityDict |
whenReceiveProfitFrom | IF sourceOfFunds = Savings from Employment OR Savings from Investments THEN field is mandatory |
10 | YYYY-MM-DD |
whenReceiveFunds | IF sourceOfFunds is not in list (Employment income , Savings from Employment , Savings from Investments ) THEN field is mandatory |
10 | YYYY-MM-DD |
monthlyIncome | no | - | id value from dict MonthlyIncomeDict |
images | no | - | JPG, PNG, PDF; Min 1 file, max 10 files; Max file size is 30 MB. |
questionnairePage
Field | Mandatory | Length | Format |
---|---|---|---|
accountCreateReason | yes | - | id value from dict AccountCreateReasonDict |
accountCreateReasonOther | IF accountCreateReason = Other THEN field is mandatory |
1 - 128 | alphanumeric (latin only) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
howFindOurExchange | yes | - | id value from dict HowFindOurExchangeDict |
howFindOurExchangeOther | IF howFindOurExchange = Other THEN field is mandatory |
3 - 128 | alphanumeric (latin only) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
passVerificationBySelf | yes | - | boolean |
cryptoFundsWithdraw | yes | - | boolean |
cryptoFundsWithdrawDestination | yes | - | id value from dict CryptoFundsWithdrawDestinationDict |
cryptoFundsWithdrawDestinationOther | IF cryptoFundsWithdrawDestination = Other THEN field is mandatory |
3 - 128 | alphanumeric (latin only) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
workWithTraders | yes | - | boolean |
Submit Address
The Address verification stage consists of 3 blocks:
- address
- addressDocument
- socialNetworkProfiles
Methods
In order to submit Address stage - use method POST/verification/address.
Validation rules
address
Field | Mandatory | Length | Format |
---|---|---|---|
type | yes | - | only residential value allowed |
country | yes | - | id value from dict CountryDict_cex |
zipCode | yes | see 'Format' | validation per country |
region | yes | - | id value from dict CountryDict_cex |
subregion | IF country = US THEN field mandatory |
- | id value from dict CountryDict_cex |
street | yes | 5 - 128 | alphanumeric (numbers and latin) & special symbols: - / # ( ) . , ] [ * $ ? space |
city | yes | 3 - 64 | alphanumeric (numbers and latin) & special symbols: " ` ' - / , . space |
aptSuite | no | 1 - 128 | alphanumeric (numbers and latin) & special symbols: ' - / \ \ , . " ` space |
addressDocument
The current block contains the images
field for image data.
In order to submit image - use method use method POST/s3/upload
Allowed file formats: JPG, PNG, PDF Min 1 file, max 10 files Max file size is 30 MB.
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image fields while submitting the current block.
Field | Mandatory | Length | Format |
---|---|---|---|
type | yes | 7 | only address value allowed |
subType | yes | - | id value from dict DocumentAddressSubtypeDict |
subTypeDetailed | IF subType = Other THEN field is mandatory |
1 - 128 | alphanumeric (latin only) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
images | yes | - | JPG, PNG, PDF; Min 1 file, max 10 files; Max file size is 30 MB. |
SocialNetworkProfiles
Field | Mandatory | Length | Format |
---|---|---|---|
url | no | 3 - 256 | default url format |
networkName | no | - | id value from dict SocialNetworkDict |
Submit Enhanced
The Enhanced verification stage consists of 8 blocks:
- purposeQuestionnaire
- employment
- employedDetails
- selfEmployedDetails
- sourceOfFiatFunds
- sourceOfCryptoFunds
- withdrawalDestination
- questionnaire
Methods
In order to submit Enhanced stage - use method POST/verification/enhanced.
Validation rules
purposeQuestionnaire
Field | Mandatory | Length | Format |
---|---|---|---|
depositReason | IF increaseTradingVolumeReason and otherDetailed are empty THEN field is mandatory | - | boolean |
increaseTradingVolumeReason | IF depositReason and otherDetailed are empty THEN field is mandatory | - | boolean |
otherDetailed | IF increaseTradingVolumeReason and depositReason are empty THEN field is mandatory | 3 - 256 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
employment
Field | Mandatory | Length | Format |
---|---|---|---|
status | yes | - | only employed , selfemployed , unemployed values allowed |
taxResidence | yes | - | id value from dict CountryDict_cex |
TIN | IF taxResidence <> US THEN field is mandatory |
2 - 9 | alphanumeric (numbers and latin) & special symbols: . - / \ ; IF country is found in the list BG, DE, EE, FR, HR, HU, LT, LU, NL, PL, PT, RO, SI, UA, RU, TR, CA THEN only numeric symbols allowed ELSE alphanumeric symbols allowed |
industry | IF status = Employed THEN field is mandatory |
- | id value from dict IndustryDict |
industryDetailed | IF industry = Other THEN field is mandatory |
3 - 128 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
position | IF status = Employed THEN field is mandatory |
- | id value from dict EmploymentPositionDict |
positionDetailed | IF position = Other THEN field is mandatory |
3 - 128 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
employmentPeriod | IF status = Employed THEN field is mandatory |
- | id value from dict EmploymentPeriodDict |
companyName | IF status = Employed THEN field is mandatory |
3 - 128 | alphanumeric (numbers and latin) & special symbols: " - . ` ‘ ’ ' & " space |
companyCountry | IF status = Employed THEN field is mandatory |
- | id value from dict CountryDict_cex |
selfEmploymentType | IF status = Self-Employed THEN field is mandatory |
- | id value from dict SelfEmploymentTypeDict |
selfEmploymentTypeDetailed | IF selfEmploymentType = Other THEN field is mandatory |
3 - 128 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
selfEmploymentIndustry | IF status = Self-Employed THEN field is mandatory |
- | id value from dict IndustryDict |
selfEmploymentIndustryDetailed | IF selfEmploymentIndustry = Other THEN field is mandatory |
3 - 128 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
selfEmploymentCompanyName | IF status = Self-Employed THEN field is mandatory |
3 - 128 | alphanumeric (numbers and latin) & special symbols: " - . ` ‘ ’ ' & " space |
sourceOfFiatFunds
The current block contains the images
field for image data.
In order to submit image - use method use method POST/s3/upload
Allowed file formats: JPG, PNG, PDF Min 1 file, max 10 files Max file size is 30 MB.
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image fields while submitting the current block.
Field | Mandatory | Length | Format |
---|---|---|---|
monthlyIncome | yes | - | id value from dict MonthlyIncomeDict |
sources | yes | - | id value from dict SourceOfFiatFundsDict |
detailed | IF sources = Other THEN field is mandatory |
3 - 128 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
images | yes | - | JPG, PNG, PDF; Min 1 file, max 10 files; Max file size is 30 MB. |
sourceOfCryptoFunds
Field | Mandatory | Length | Format |
---|---|---|---|
cryptoFundsDeposit | no | - | boolean |
sources | IF cryptoFundsDeposit = true THEN field is mandatory |
- | id value from dict SourceOfCryptoFundsDict |
detailed | IF sources = Mining OR Purchased OR Other THEN field is mandatory |
3 - 512 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
withdrawalDestination
Field | Mandatory | Length | Format |
---|---|---|---|
cryptoFundsWithdraw | no | - | boolean |
destination | IF cryptoFundsWithdraw = true THEN field is mandatory |
- | id value from dict WithdrawalDestinationDict |
detailed | IF destination = Other THEN field is mandatory |
3 - 512 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
questionnaire
Field | Mandatory | Length | Format |
---|---|---|---|
bankJurisdiction | yes | - | id value from dict CountryDict_cex |
primaryPurpose | yes | - | id value from dict PurposeDict |
primaryPurposeDetailed | IF primaryPurpose = Other Purpose THEN field is mandatory |
3 - 512 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
plannedTurnover | yes | - | id value from dict TurnoverDict |
isPep | yes | - | boolean |
pepPosition | IF isPep = true THEN field is mandatory |
3 - 512 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
hasPepRelatives | yes | - | boolean |
pepRelativesDetailed | IF hasPepRelatives = true THEN field is mandatory |
3 - 512 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
pepCloseAssociate | yes | - | boolean |
pepCloseAssociateDetailed | IF pepCloseAssociate = true THEN field is mandatory |
3 - 512 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
usCitizen | yes | - | boolean |
usResidentAlien | yes | - | boolean |
usTaxpayer | yes | - | boolean |
Requests
General info
Methods
Use method GET/requests/list in order to get list of all NC requests related to a certain user, in spit of request status.
Use method GET/requests/pending-list in order to get list of all NC requests related to a certain user, where status =
Required
.
Request types
Below NC requests types are available for submit:
- Selfie with card (selfieWithCard)
- Liveness check (liveness)
- Second ID (documents)
- Address (addressProof)
- Source of funds: Questionnaire (sof)
- Source of funds: Documents (sofDocuments)
- Red Crypto (redCrypto)
- Anti-scum (antiScum)
- Periodic review (periodicUpdate)
- ID Expiry (idExpiry)
- UK Questionnaire (uk_questionnaire)
Request content
Example:
"id": 17642,
"ncRequestId": "000017642",
"submitionQnt": 0,
"userId": "ud204376015",
"type": "uk_questionnaire",
"status": "approved",
"decisionCode": null,
"requestedBy": "[email protected]",
"techInfo": null,
"info": {
"externalComment": "Auto created uk_questionnaire request by ivs",
"ncReason": "string",
"requiredDocumentTypes": [
"0"
],
"coolingOffUntil": "2024-08-14T11:59:25.039Z"
},
"createdAt": "2024-09-17T10:05:07.730Z",
"updatedAt": "2024-09-17T10:21:52.166Z"
Field | Format | Description |
---|---|---|
id | - | nc request id |
ncRequestId | - | nc request id |
submitionQnt | - | Qty of submits for the current request |
userId | - | related user id |
type | - | nc request name |
status | - | The current nc request status |
decisionCode | - | not in use |
requestedBy | - | VA user email address or ivs (if auto-request) |
techInfo | - | not in use |
info | object | contains 2 fields:externalComment - comment made by VA user while manual nc request creationcoolingOffUntil - field is in use for uk_questionnaire onlyncReason - reason why NC request is created (see details below)requiredDocumentTypes - required ID document type (relevant for documents nc request only) |
createdAt | - | nc request creation date |
updatedAt | - | nc request update date |
Request statuses
In the table below you can find all possible NC requests statuses:
Status | Submit available | Description |
---|---|---|
New | Yes | Initial NC request status. |
Required | Yes | - |
To study | No | Submitted data is in Compliance department review. |
Approved | No | Request is approved. No actions required. |
Refused | No | Request is refused. It could be moved to New or Required or Cancelled status manually by Compliance. |
Cancelled | No | Request is cancelled by Compliance. No actions/transitions are available. |
Request reasons
ncReason
field is intended to provide frontend with a treigger - which information should be displayed to user regarding why CEX is asking a certain information.
ncReason | type |
---|---|
default | any |
unusual_activity | liveness |
new_device | liveness |
another_ip | liveness |
card_order | liveness |
Submit selfie-with-card
The Selfie with card request type consists of 2 blocks:
- selfieWithCardDocuments
- binInfo
Methods
In order to submit slefie-with-card request - use method POST/requests/selfie-with-card
Validation rules
selfieWithCardDocuments
In order to submit image - use method use method POST/s3/upload
Allowed file formats: PDF or PNG or JPG
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image block while submitting the current block.
binInfo
Field | Mandatory | Length | Format |
---|---|---|---|
countryISO | no | - | No validation rules |
bank | no | - | No validation rules |
provider | no | - | No validation rules |
Submit liveness
The Liveness check request type consists of 2 blocks:
- livenessCheckRegula
- selfieImage
Methods
In order to submit liveness request - use method POST/requests/liveness
Validation rules
For the livenessCheckRegula
massive please put below objects.
You can send from 1 to 10 of such blocks.
Field | mandatory | validation |
---|---|---|
passed | yes | boolean |
guid | yes | no validation rules |
verified | no | boolean |
results | no | no validation rules |
failReason | no | no validation rules |
The current block contains selfieImage
field for image data.
In order to submit image - use method use method POST/s3/upload Allowed file formats: PDF or PNG or JPG
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image fields while submitting the current block.
Submit documents
The Second ID request type consists of 2 blocks:
- additionalIdentityDocument
- personalData
Methods
In order to submit documents request - use method POST/requests/documents.
Validation rules
additionalIdentityDocument
The current block contains the images
field for image data.
In order to submit image - use method use method POST/s3/upload
Allowed file formats: PDF or PNG or JPG
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image block while submitting the current block.
Field | Mandatory | Length | Format |
---|---|---|---|
subtype | yes | - | id value from dict DocumentIdentitySubtypeDict |
issuingCountry | IF subtype <> International Passport THEN field is mandatory |
- | id value from dict CountryDict_cex |
hasExpireDate | yes | - | boolean |
expireDate | IF hasExpireDate = true THEN field is mandatory |
10 | YYYY-MM-DD; min date > 1 month from current date |
serialNumber | yes | 1 - 128 | alphanumeric (latin & cyryllic only) & special symbols: " * / - . \ \ " , space |
jurisdictionCode | IF issuingCountry = CA THEN field is mandatory |
2 | alphanumeric (latin only) |
personalCode | IF issuingCountry = LT THEN field is mandatory |
11 | numeric |
images | yes | - | PDF or PNG or JPG |
personalData
Field | Mandatory | Length | Format |
---|---|---|---|
firstName | yes | 1 - 64 | alphanumeric (latin only) & special symbols: ` ‘ ’ ' - " space |
lastName | yes | 1 - 64 | alphanumeric (latin only) & special symbols: ` ‘ ’ ' - " space |
middleName | no | 1 - 64 | alphanumeric (latin only) & special symbols: ` ‘ ’ ' - " space |
dateOfBirth | yes | 10 | YYYY-MM-DD; min date > current date - 100 years ; max date < current date - 18 years |
gender | yes | - | only male or female values allowed |
nationality | yes | - | id value from dict CountryDict_cex |
Submit addressProof
The Address request type has no separate block, only set of fields to submit.
Methods
In order to submit address-proof - use method POST/requests/address-proof
Validation rules
The current block contains the images
field for image data.
In order to submit image - use method use method POST/s3/upload
Allowed file formats: PDF or PNG or JPG. Min 1 file, max 10 files. Max file size is 30 MB.
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image block while submitting the current block.
Field | Mandatory | Length | Format |
---|---|---|---|
type | yes | - | only residential value allowed |
country | yes | - | id value from dict CountryDict_cex |
zipCode | yes | see 'Format' | validation per country |
region | yes | - | id value from dict CountryDict_cex |
subregion | IF country = US THEN field mandatory |
- | id value from dict CountryDict_cex |
street | yes | 5 - 128 | alphanumeric (numbers and latin) & special symbols: - / # ( ) . , ] [ * $ ? space |
city | yes | 3 - 64 | alphanumeric (numbers and latin) & special symbols: " ` ' - / , . space |
aptSuite | no | 1 - 128 | alphanumeric (numbers and latin) & special symbols: ' - / \ \ , . " ` space |
subType | yes | - | id value from dict DocumentAddressSubtypeDict |
subTypeDetailed | IF subType = Other THEN field is mandatory |
1 - 128 | alphanumeric (latin only) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
images | yes | - | JPG, PNG, PDF; Min 1 file, max 10 files; Max file size is 30 MB. |
Submit redCrypto
The Red Crypto request type has no separate blocks, only set of fields to submit.
Methods
In order to submit request - use method POST/requests/redCrypto.
Validation rules
The current block contains the images
field for image data.
In order to submit image - use method use method POST/s3/upload
Allowed file formats: PDF or PNG or JPG. Min 1 file, max 10 files. Max file size 30 MB.
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image block while submitting the current block.
Field | Mandatory | Length | Format |
---|---|---|---|
platformName | yes | 1 - 128 | alphanumeric (numbers and latin) & special symbols: \ / - . ` ' ' ' , space |
transactionPurpose | yes | 1 - 128 | alphanumeric (numbers and latin) & special symbols: \ / - . ` ' ' ' , space |
images | yes | - | From 1 to 10 files; PDF or PNG or JPG |
Submit employmentCA
The Employment request type has no separate blocks, only set of fields to submit.
Methods
In order to submit request - use method POST/requests/employmentCA.
Validation rules
Field | Mandatory | Length | Format |
---|---|---|---|
accountCreateReason | yes | - | id value from dict AccountCreateReasonDict |
status | yes | - | id value from dict EmploymentStatusDict |
industry | yes | - | id value from dict IndustryDict |
industryDetailed | IF industry = Other THEN field is mandatory |
3 - 128 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
position | yes | - | id value from dict EmploymentPositionDict |
positionDetailed | IF position = Other THEN field is mandatory |
3 - 128 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
typeOfBusiness | IF status = Self-employed THEN field is mandatory | - | id value from dict SelfEmploymentTypeDict |
typeOfBusinessDetailed | IF typeOfBusinessDetailed = Other THEN field is mandatory |
3 - 128 | alphanumeric (numbers and latin) & special symbols: \ / - . ` ' ' ' , space |
Submit antiScum
The Anti-scum request type has no separate blocks, only set of fields to submit.
Methods
In order to submit request - use method POST/requests/antiScum.
Validation rules
Field | Mandatory | Length | Format |
---|---|---|---|
accountCreateReason | yes | - | id value from dict AccountCreateReasonDict |
accountCreateReasonOther | IF accountCreateReason = Other THEN field is mandatory |
1 - 128 | alphanumeric (latin only) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
howFindOurExchange | yes | - | id value from dict HowFindOurExchangeDict |
howFindOurExchangeOther | IF howFindOurExchange = Other THEN field is mandatory |
3 - 128 | alphanumeric (latin only) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
passVerificationBySelf | yes | - | boolean |
cryptoFundsWithdraw | yes | - | boolean |
cryptoFundsWithdrawDestination | yes | - | id value from dict CryptoFundsWithdrawDestinationDict |
cryptoFundsWithdrawDestinationOther | IF cryptoFundsWithdrawDestination = Other THEN field is mandatory |
3 - 128 | alphanumeric (latin only) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
workWithTraders | yes | - | boolean |
Submit periodicUpdate
The Periodic review request consists of 3 blocks:
- fullResidence
- identityDocument
- personalData
Methods
In order to submit periodicUpdate- use method POST/requests/periodicUpdate.
Validation rules
fullResidence
Field | Mandatory | Length | Format |
---|---|---|---|
country | yes | - | id value from dict CountryDict_cex |
zipCode | yes | see 'Format' | validation per country |
region | yes | - | id value from dict CountryDict_cex |
subregion | yes | - | id value from dict CountryDict_cex |
SSN | IF country = US THEN field is mandatory |
9 | numeric |
street | yes | 5 - 128 | alphanumeric (numbers and latin) & special symbols: - / # ( ) . , ] [ * $ ? space |
city | yes | 3 - 64 | alphanumeric (numbers and latin) & special symbols: " ` ' - / , . space |
aptSuite | no | 1 - 128 | alphanumeric (numbers and latin) & special symbols: ' - / \ \ , . " ` space |
identityDocument
The current block contains 2 fields for image data: images
and selfieImage
.
In order to submit image - use method use method POST/s3/upload Allowed file formats: PDF or PNG or JPG
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image fields while submitting the current block.
Field | Mandatory | Length | Format |
---|---|---|---|
type | yes | 8 | only identity value allowed |
subtype | yes | - | id value from dict DocumentIdentitySubtypeDict |
issuingCountry | IF subtype <> International Passport THEN field is mandatory |
- | id value from dict CountryDict_cex |
hasExpireDate | yes | - | boolean |
expireDate | IF hasExpireDate = true THEN field is mandatory |
10 | YYYY-MM-DD; min date > 1 month from current date |
serialNumber | yes | 1 - 128 | alphanumeric (latin & cyryllic only) & special symbols: " * / - . \ \ " , space |
jurisdictionCode | IF issuingCountry = CA THEN field is mandatory |
2 | alphanumeric (latin only) |
personalCode | IF issuingCountry = LT THEN field is mandatory |
11 | numeric |
images | yes | - | See description above the table |
selfieImage | yes | - | See description above the table |
personalData
Field | Mandatory | Length | Format |
---|---|---|---|
firstName | yes | 1 - 64 | alphanumeric (latin only) & special symbols: ` ‘ ’ ' - " space |
lastName | yes | 1 - 64 | alphanumeric (latin only) & special symbols: ` ‘ ’ ' - " space |
middleName | no | 1 - 64 | alphanumeric (latin only) & special symbols: ` ‘ ’ ' - " space |
dateOfBirth | yes | 10 | YYYY-MM-DD; min date > current date - 100 years ; max date < current date - 18 years |
placeOfBirth | no | 0 - 128 | alphanumeric (latin only) & special symbols: / . , ` ‘ ’ ' - " space |
gender | yes | - | only male or female values allowed |
nationality | yes | - | id value from dict CountryDict_cex |
Submit id expiry
The ID Expiry request consists of 2 blocks:
- identityDocument
- personalData
Methods
In order to submit ID Expiry - use method POST/requests/periodicUpdate.
Validation rules
identityDocument
The current block contains the images
field for image data.
In order to submit image - use method use method POST/s3/upload Allowed file formats: PDF or PNG or JPG
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image fields while submitting the current block.
Field | Mandatory | Length | Format |
---|---|---|---|
subtype | yes | - | id value from dict DocumentIdentitySubtypeDict |
issuingCountry | IF subtype <> International Passport THEN field is mandatory |
- | id value from dict CountryDict_cex |
hasExpireDate | yes | - | boolean |
expireDate | IF hasExpireDate = true THEN field is mandatory |
10 | YYYY-MM-DD; min date > 1 month from current date |
serialNumber | yes | 1 - 128 | alphanumeric (latin & cyryllic only) & special symbols: " * / - . \ \ " , space |
jurisdictionCode | IF issuingCountry = CA THEN field is mandatory |
2 | alphanumeric (latin only) |
personalCode | IF issuingCountry = LT THEN field is mandatory |
11 | numeric |
images | yes | - | See description above the table |
selfieImage | yes | - | See description above the table |
personalData
Field | Mandatory | Length | Format |
---|---|---|---|
firstName | yes | 1 - 64 | alphanumeric (latin only) & special symbols: ` ‘ ’ ' - " space |
lastName | yes | 1 - 64 | alphanumeric (latin only) & special symbols: ` ‘ ’ ' - " space |
middleName | no | 1 - 64 | alphanumeric (latin only) & special symbols: ` ‘ ’ ' - " space |
dateOfBirth | yes | 10 | YYYY-MM-DD; min date > current date - 100 years ; max date < current date - 18 years |
placeOfBirth | no | 0 - 128 | alphanumeric (latin only) & special symbols: / . , ` ‘ ’ ' - " space |
gender | yes | - | only male or female values allowed |
nationality | yes | - | id value from dict CountryDict_cex |
Submit sof
The Source of funds: Questionnaire request has no separate blocks.
Methods
In order to submit request - use method POST/compliance/requests/sof.
Validation rules
The current request contains the images
field for image data.
In order to submit image - use method use method POST/s3/upload
Allowed file formats: JPG, PNG, PDF Min 1 file, max 10 files Max file size is 30 MB.
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image fields while submitting the current block.
Field | Mandatory | Length | Format |
---|---|---|---|
accountCreateReason | yes | - | id value from dict AccountCreateReasonDict |
accountCreateReasonOther | IF accountCreateReason = Other THEN field is mandatory |
1 - 128 | alphanumeric (latin only) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
monthlyTurnover | yes | - | id value from dict MonthlyTurnoverIdentityDict |
sourceOfFunds | yes | - | id value from dict SourceOfFundsIdentityDict |
sourceOfFundsOther | IF sourceOfFunds = Other THEN field is mandatory |
1 - 128 | alphanumeric (latin only) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
annualFundsAmount | IF sourceOfFunds <> empty THEN field is mandatory | - | id value from dict annualSalaryDict |
status | IF sourceOfFunds = Employment income OR Savings from Investments THEN field is mandatory |
- | id value from dict employmentStatusIdentityDict |
employmentPosition | IF sourceOfFunds = Employment income OR Savings from Investments THEN field is mandatory |
- | value from dict |
whenReceiveProfitFrom | IF sourceOfFunds = Savings from Investments THEN field is mandatory |
10 | YYYY-MM-DD |
whenReceiveProfitTo | IF sourceOfFunds = Savings from Investments THEN field is mandatory |
10 | YYYY-MM-DD |
whenReceiveFunds | IF sourceOfFunds <> Employment income OR Savings from Investments THEN field is mandatory |
10 | YYYY-MM-DD |
images | no | - | JPG, PNG, PDF; Min 1 file, max 10 files; Max file size is 30 MB. |
Submit sofDocuments
The Source of Funds: Documents request type has only sofDocument block to submit.
Methods
In order to submit request - use method POST/requests/sofDocuments.
Validation rules
The current block contains the images
field for image data.
In order to submit image - use method use method POST/s3/upload
Allowed file formats: PDF or PNG or JPG. Min 1 file, max 10 files. Max file size 30 MB.
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image block while submitting the current block.
Field | Mandatory | Length | Format |
---|---|---|---|
source | yes | 1 - 128 | id value from dict sofDocumentsDict |
sourceOther | yes | 1 - 128 | alphanumeric (numbers and latin) & special symbols: \ / - . ` ' ' ' , space |
images | yes | - | From 1 to 10 files; PDF or PNG or JPG |
Submit uk_qestionnaire
The UK Questionnaire request has no separate blocks.
The current request differs from the rest by the submit methodology (see 'Methods').
Methods
In order to initialize UK questionnaire - use method GET/requests/uk_questionnaire_question. In response you will receive first/next field for submit.
In order to get next field for submit - use method PUT/requests/uk_questionnaire_question. The current method is to be used for each field submit 1 by 1. In response you will receive next field for submit OR info that submit is not possible.
Validation rules
The corrrect answers of questionnaire are marked in bold. There are several question types with different submit format: initial, standard, multiple & declaration.
The initial and standard questions to be submitted in below format:
"questionId": "block_0_question_0",
"answerId": "block_0_question_0_answer_0"
The multiple question to be submitted in below format:
"questionId": "block_0_question_10_multiple",
"answerId": [
"10",
"10"
]
The declaration question to be submitted in below format:
"questionId": "declaration",
"answerId": "declaration_answer_0",
"declarationVersion": "v0"
Block 1 (block_0)
Field | Mandatory | Length | Answers |
---|---|---|---|
block_0_initial_question_0 | yes | - | block_0_initial_question_0_answer_1 |
block_0_standard_question_0 | yes | - | block_0_standard_question_0_answer_0 block_0_standard_question_0_answer_1 block_0_standard_question_0_answer_2 |
block_0_standard_question_1 | yes | - | block_0_standard_question_1_answer_0 block_0_standard_question_1_answer_1 block_0_standard_question_1_answer_2 |
block_0_standard_question_2 | yes | - | block_0_standard_question_2_answer_0 block_0_standard_question_2_answer_1 block_0_standard_question_2_answer_2 |
block_0_standard_question_3 | yes | - | block_0_standard_question_3_answer_0 block_0_standard_question_3_answer_1 block_0_standard_question_3_answer_2 |
block_0_standard_question_4 | yes | - | block_0_standard_question_4_answer_0 block_0_standard_question_4_answer_1 block_0_standard_question_4_answer_2 |
block_0_standard_question_5 | yes | - | block_0_standard_question_5_answer_0 block_0_standard_question_5_answer_1 block_0_standard_question_5_answer_2 |
block_0_standard_question_6 | yes | - | block_0_standard_question_6_answer_0 block_0_standard_question_6_answer_1 block_0_standard_question_6_answer_2 |
block_0_standard_question_7 | yes | - | block_0_standard_question_7_answer_0 block_0_standard_question_7_answer_1 block_0_standard_question_7_answer_2 |
block_0_standard_question_8 | yes | - | block_0_standard_question_8_answer_0 block_0_standard_question_8_answer_1 block_0_standard_question_8_answer_2 |
block_0_standard_question_9 | yes | - | block_0_standard_question_9_answer_0 block_0_standard_question_9_answer_1 block_0_standard_question_9_answer_2 |
block_0_question_10_multiple | yes | - | |
declaration | yes | - | declaration_answer_0 |
congratulations | yes | - | congratulations_answer_0 |
Block 2 (block_1)
Field | Mandatory | Length | Expected answer |
---|---|---|---|
block_1_initial_question_0 | yes | - | block_1_initial_question_0_answer_1 |
block_1_standard_question_0 | yes | - | block_1_standard_question_0_answer_0 block_1_standard_question_0_answer_1 block_1_standard_question_0_answer_2 |
block_1_standard_question_1 | yes | - | block_1_standard_question_1_answer_0 block_1_standard_question_1_answer_1 block_1_standard_question_1_answer_2 |
block_1_standard_question_2 | yes | - | block_1_standard_question_2_answer_0 block_1_standard_question_2_answer_1 block_1_standard_question_2_answer_2 |
block_1_standard_question_3 | yes | - | block_1_standard_question_3_answer_0 block_1_standard_question_3_answer_1 block_1_standard_question_3_answer_2 |
block_1_standard_question_4 | yes | - | block_1_standard_question_4_answer_0 block_1_standard_question_4_answer_1 block_1_standard_question_4_answer_2 |
block_1_standard_question_5 | yes | - | block_1_standard_question_5_answer_0 block_1_standard_question_5_answer_1 block_1_standard_question_5_answer_2 |
block_1_standard_question_6 | yes | - | block_1_standard_question_6_answer_0 block_1_standard_question_6_answer_1 block_1_standard_question_6_answer_2 |
block_1_standard_question_7 | yes | - | block_1_standard_question_7_answer_0 block_1_standard_question_7_answer_1 block_1_standard_question_7_answer_2 |
block_1_standard_question_8 | yes | - | block_1_standard_question_8_answer_0 block_1_standard_question_8_answer_1 block_1_standard_question_8_answer_2 |
block_1_standard_question_9 | yes | - | block_1_standard_question_9_answer_0 block_1_standard_question_9_answer_1 block_1_standard_question_9_answer_2 |
block_1_question_10_multiple | yes | - | |
declaration | yes | - | declaration_answer_0 |
congratulations | yes | - | congratulations_answer_0 |
Block 3 (block_2)
Field | Mandatory | Length | Expected answer |
---|---|---|---|
block_2_initial_question_0 | yes | - | block_2_initial_question_0_answer_1 |
block_2_standard_question_0 | yes | - | block_2_standard_question_0_answer_0 block_2_standard_question_0_answer_1 block_2_standard_question_0_answer_2 |
block_2_standard_question_1 | yes | - | block_2_standard_question_1_answer_0 block_2_standard_question_1_answer_1 block_2_standard_question_1_answer_2 |
block_2_standard_question_2 | yes | - | block_2_standard_question_2_answer_0 block_2_standard_question_2_answer_1 block_2_standard_question_2_answer_2 |
block_2_standard_question_3 | yes | - | block_2_standard_question_3_answer_0 block_2_standard_question_3_answer_1 block_2_standard_question_3_answer_2 |
block_2_standard_question_4 | yes | - | block_2_standard_question_4_answer_0 block_2_standard_question_4_answer_1 block_2_standard_question_4_answer_2 |
block_2_standard_question_5 | yes | - | block_2_standard_question_5_answer_0 block_2_standard_question_5_answer_1 block_2_standard_question_5_answer_2 |
block_2_standard_question_6 | yes | - | block_2_standard_question_6_answer_0 block_2_standard_question_6_answer_1 block_2_standard_question_6_answer_2 |
block_2_standard_question_7 | yes | - | block_2_standard_question_7_answer_0 block_2_standard_question_7_answer_1 block_2_standard_question_7_answer_2 |
block_2_standard_question_8 | yes | - | block_2_standard_question_8_answer_0 block_2_standard_question_8_answer_1 block_2_standard_question_8_answer_2 |
block_2_standard_question_9 | yes | - | block_2_standard_question_9_answer_0 block_2_standard_question_9_answer_1 block_2_standard_question_9_answer_2 |
block_2_question_10_multiple | yes | - | |
declaration | yes | - | declaration_answer_0 |
congratulations | yes | - | congratulations_answer_0 |
Block 4 (block_3)
Field | Mandatory | Length | Expected answer |
---|---|---|---|
block_3_initial_question_0 | yes | - | block_3_initial_question_0_answer_1 |
block_3_standard_question_0 | yes | - | block_3_standard_question_0_answer_0 block_3_standard_question_0_answer_1 block_3_standard_question_0_answer_2 |
block_3_standard_question_1 | yes | - | block_3_standard_question_1_answer_0 block_3_standard_question_1_answer_1 block_3_standard_question_1_answer_2 |
block_3_standard_question_2 | yes | - | block_3_standard_question_2_answer_0 block_3_standard_question_2_answer_1 block_3_standard_question_2_answer_2 |
block_3_standard_question_3 | yes | - | block_3_standard_question_3_answer_0 block_3_standard_question_3_answer_1 block_3_standard_question_3_answer_2 |
block_3_standard_question_4 | yes | - | block_3_standard_question_4_answer_0 block_3_standard_question_4_answer_1 block_3_standard_question_4_answer_2 |
block_3_standard_question_5 | yes | - | block_3_standard_question_5_answer_0 block_3_standard_question_5_answer_1 block_3_standard_question_5_answer_2 |
block_3_standard_question_6 | yes | - | block_3_standard_question_6_answer_0 block_3_standard_question_6_answer_1 block_3_standard_question_6_answer_2 |
block_3_standard_question_7 | yes | - | block_3_standard_question_7_answer_0 block_3_standard_question_7_answer_1 block_3_standard_question_7_answer_2 |
block_3_standard_question_8 | yes | - | block_3_standard_question_8_answer_0 block_3_standard_question_8_answer_1 block_3_standard_question_8_answer_2 |
block_3_standard_question_9 | yes | - | block_3_standard_question_9_answer_0 block_3_standard_question_9_answer_1 block_3_standard_question_9_answer_2 |
block_3_question_10_multiple | yes | - | |
declaration | yes | - | declaration_answer_0 |
congratulations | yes | - | congratulations_answer_0 |
Errors
Code | Name | Description |
---|---|---|
UK_SUBMIT_FORBIDDEN_LIVENESS | Submit forbidden, liveness required | User has active (new, required, to study, refused) Liveness request |
UK_QUESTIONNAIRE_FORBIDDEN | Submit forbidden | The current nc request does not exist or already approved. |
UK_QUESTIONNAIRE_TRY_TOMORROW | Submit forbidden, please try tomorrow | User has reached daily submittion limit for the current request. |
- | Submit forbidden, already approved | The related nc request dossier is approved, but nc request status not changed. Should not occur. |
- | No questions found | User has submitted all questions, but nc request dossier status not changed. Should not occur. |
UK_SUBMIT_FORBIDDEN_COOLINGOFF | Cooling off period | Cooling of fir the current user has not ended yet. |
UK_QUESTIONNAIRE_QUESTION_SUBMIT_MISMATH | Expected question mismatch | User tries to submit the question from different block (e.g. backend expects block 0, while user submits block 3) |
UNEXPECTED_ES_RESPONSE | Unexpected es response | Unknown ES response received. Should not occur. |
Corporate
The Corporate verification stage consists of 13 blocks:
- generalInformation
- registeredAddress
- premisesAddress
- socialNetworkProfiles
- businessActivity
- corporateSourceOfFiatFunds
- corporateSourceOfCryptoFunds
- accountActivity
- licenses
- paymentDetails (contains sub-blocks: cryptoInfo, fiatInfo, correspondentBank)
- personalInfo (contains sub-blocks: sourceofFiatFunds, identityDocument, residentalAddress, socialNetworkProfiles, pepStatus)
- companyDocuments
- eSignature
Methods
In order to submit stage - use method POST/verification/corporate.
Validation rules
generalInformation
Field | Mandatory | Length | Format |
---|---|---|---|
fullLegalName | yes | 2 - 128 | alphanumeric (numbers and latin) & special symbols: ` " - . ‘ ’ ' & " space |
tradeName | yes | 2 - 128 | alphanumeric (numbers and latin) & special symbols: ` " - . ‘ ’ ' & " space |
typeOfCompany | yes | - | id value from dict company_type |
companyRegistrationNumber | yes | 3 - 128 | alphanumeric (numbers and latin) & special symbols: /-.\ |
industry | yes | - | id value from dict company_industry |
otherIndustry | IF industry = Other THEN field is mandatory |
3 - 512 | alphanumeric (numbers and latin) & special symbols: \ / - . ` ' ' ' , space |
regionOfBusiness | yes | 3 - 400 | alphanumeric (numbers and latin) & special symbols: `‘’'-/\,. space |
TIN | IF country <> US THEN field is mandatory |
3 - 64 | alphanumeric (numbers and latin) & special symbols: . - / \ IF country is found in the list BG, DE, EE, FR, HR, HU, LT, LU, NL, PL, PT, RO, SI, UA, RU, TR, CA THEN only numeric symbols allowed ELSE alphanumeric symbols allowed |
employerIdentificationNumber | IF country = US THEN field is mandatory |
9 | alphanumeric (numbers and latin) special symbols: . - / \ |
VAT | yes | 3 - 128 | alphanumeric (numbers and latin) & special symbols: \ / - . |
dateOfIncorporation | yes | - | YYYY-MM-DD |
phone | yes | 5 - 15 | numeric |
premisesAddressSameAsRegistered | yes | - | boolean |
premisesAddress | IF premisesAddressSameAsRegistered = false THEN massive is mandatory |
- | massive: see table below |
registeredAddress | IF premisesAddressSameAsRegistered = false THEN massive is mandatory |
- | massive: see table below |
registeredAddress
Field | Mandatory | Length | Format |
---|---|---|---|
country | yes | - | id value from dict CountryDict_cex |
zipCode | yes | see 'Format' | validation per country |
region | yes | - | id value from dict CountryDict_cex |
SSN | IF country = US THEN field mandatory |
9 | numeric |
subregion | IF country = US AND region = any THEN field mandatory |
- | id value from dict CountryDict_cex |
street | yes | 5 - 128 | alphanumeric (numbers and latin) & special symbols: - / # ( ) . , ] [ * $ ? space |
city | yes | 3 - 64 | alphanumeric (numbers and latin) & special symbols: " ` ' - / , . space |
aptSuite | no | 1 - 128 | alphanumeric (numbers and latin) & special symbols: ' - / \ \ , . " ` space |
premisesAddress
Field | Mandatory | Length | Format |
---|---|---|---|
country | yes | - | id value from dict CountryDict_cex |
address | yes | 5 - 400 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
socialNetworkProfiles
Field | Mandatory | Length | Format |
---|---|---|---|
url | no | 3 - 256 | default url format |
networkName | no | - | id value from dict SocialNetworkDict |
businessActivity
The current block contains the bussinessModelFiles
field for image data.
In order to submit image - use method use method POST/s3/upload
Allowed file formats: JPG, PNG, PDF
Min 1 file, max 10 files
Max file size is 30 MB.
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image fields while submitting the current block.
Field | Mandatory | Length | Format |
---|---|---|---|
annualNetProfitLastYear | yes | - | id value from dict company_annual_net_profit |
bussinessModel | IF bussinessModelFiles is empty THEN field is mandatory | 100 - 1024 | alphanumeric (numbers and latin) & special symbols: \ / - . ` ‘ ’ ' , space |
bussinessModelFiles | IF bussinessModel is empty THEN field is mandatory | - | PDF, PNG, JPG; Min - 1 file; Max - 10 files; Max file size - 30MB |
corporateSourceOfFiatFunds | yes | - | massive: see below tab |
planToDepositCryptoFunds | yes | - | boolean |
corporateSourceOfCryptoFunds | IF planToDepositCryptoFunds = true THEN block is mandatory |
- | massive: see below tab |
corporateSourceOfFiatFunds
The current block contains the images
field for image data.
In order to submit image - use method use method POST/s3/upload
Allowed file formats: JPG, PNG, PDF Min 1 file, max 10 files Max file size is 30 MB.
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image fields while submitting the current block.
Field | Mandatory | Length | Format |
---|---|---|---|
source | yes | - | id value from dict company_source_of_fiat_funds |
detailed | IF source = Other THEN field is mandatory |
3 - 128 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
images | yes | - | JPG, PNG, PDF; Min 1 file, max 10 files; Max file size is 30 MB. |
corporateSourceOfCryptoFunds
Field | Mandatory | Length | Format |
---|---|---|---|
sources | IF cryptoFundsDeposit = true THEN field is mandatory |
- | id value from dict SourceOfCryptoFundsDict |
detailed | IF sources = Other THEN field is mandatory |
3 - 512 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
purchaseDetails | IF sources = Purchased THEN field is mandatory |
3 - 512 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
accountActivity
Field | Mandatory | Length | Format |
---|---|---|---|
primaryPurpose | yes | - | id value from dict company_puprose |
primaryPurposeDetailed | IF primaryPurpose = Other Purpose THEN field is mandatory |
3 - 512 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
plannedMonthlyDepositVolume | yes | - | id value from dict planned_monthly_deposit_volume |
expectedMonthlyDepositOperations | yes | - | id value from dict number_of_deposit_operations |
plannedMonthlyWithdrawalVolume | yes | - | id value from dict planned_monthly_withdrawal_volume |
Licenses
The current block contains several fields for image data: proofOfLicensing
, proofOfPermissionsAndAuthorizations
, proofOfAmlProgram
, proofOfSharesTradedOnStockExchange
, proofOfAuditedEntity
.
In order to submit image - use method use method POST/s3/upload
Allowed file formats: JPG, PNG, PDF
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image fields while submitting the current block.
Field | Mandatory | Length | Format |
---|---|---|---|
licensing | yes | - | id value from dict company_licensing |
licenseLinks | IF licensing = true AND proofOfLicensing is empty THEN field is mandatory |
3 - 256 | default url format |
proofOfLicensing | IF licensing = true AND licenseLinks is empty THEN field is mandatory |
- | JPG, PNG, PDF; Min 1 file, max 10 files; Max file size is 30 MB. |
permissionsAndAuthorizations | yes | - | id value from dict company_has_permissions |
permissionsAndAuthorizationsLinks | IF permissionsAndAuthorizations = true AND proofOfPermissionsAndAuthorizations is empty THEN field is mandatory |
3 - 256 | default url format |
proofOfPermissionsAndAuthorizations | IF permissionsAndAuthorizations = true AND permissionsAndAuthorizationsLinks is empty THEN field is mandatory |
- | JPG, PNG, PDF; Min 1 file, max 10 files; Max file size is 30 MB. |
amlReportingEntity | yes | - | id value from dict company_aml_reporting |
amlProgram | yes | - | id value from dict company_aml_program |
amlProgramLinks | IF amlProgram = true AND proofOfAmlProgram is empty THEN field is mandatory |
3 - 256 | default url format |
proofOfAmlProgram | IF amlProgram = true AND amlProgramLinks is empty THEN field is mandatory |
- | JPG, PNG, PDF; Min 1 file, max 10 files; Max file size is 30 MB. |
sharesTradedOnStockExchange | yes | - | id value from dict company_trade_on_stock |
stockExchangeLinks | IF sharesTradedOnStockExchange = true AND proofOfSharesTradedOnStockExchange is empty THEN field is mandatory |
3 - 256 | default url format |
proofOfSharesTradedOnStockExchange | IF sharesTradedOnStockExchange = true AND stockExchangeLinks is empty THEN field is mandatory |
- | JPG, PNG, PDF; Min 1 file, max 10 files; Max file size is 30 MB. |
auditedEntity | yes | - | id value from dict company_audited_entity |
auditorLinks | IF auditedEntity = true AND proofOfAuditedEntity is empty THEN field is mandatory |
3 - 256 | default url format |
proofOfAuditedEntity | IF auditedEntity = true AND auditorLinks is empty THEN field is mandatory |
- | JPG, PNG, PDF; Min 1 file, max 10 files; Max file size is 30 MB. |
paymentDetails
Any of listed blocks are not mandatory for submission. Each block can be submitted up to 10 times.
Field | Mandatory | Length | Format |
---|---|---|---|
cryptoInfo | no | - | massive: see table below |
planToDepositOrWithdrawFiatFunds | no | - | boolean |
fiatinfo | IF planToDepositOrWithdrawFiatFunds = true THEN block is mandatory |
- | massive: see table below |
cryptoInfo
You are able to submit up to 5 such blocks.
Field | Mandatory | Length | Format |
---|---|---|---|
cryptoCurrency | yes | - | id value from dict crypto_currency |
cryptoWalletAddress | yes | - | to finalize |
fiatInfo
You are able to submit up to 5 such blocks.
The current block contains the images
field for image data.
In order to submit image - use method use method POST/s3/upload
Allowed file formats: JPG, PNG, PDF Min 1 file, max 10 files Max file size is 30 MB.
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image fields while submitting the current block.
Field | Mandatory | Length | Format |
---|---|---|---|
entryID | yes | 0-64 | no validation rules |
currency | yes | - | id value from dict payment_currency |
paymentMethod | yes | - | id value from dict payment_method |
bankCountry | yes | - | id value from dict CountryDict_cex |
bankName | yes | 3 - 512 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
sortCode | IF paymentMethod = Domestic bank transfer AND currency= GBP THEN field is mandatory ELSE field is forbidden |
2 - 6 | no validation rules |
bankAddress | IF (paymentMethod = Domestic Bank Transfer AND currency is in list USD, GPB, RUB, EUR ) OR (paymentMethod = International Bank Transfer AND currency is in list USD, EUR ) THEN field is mandatory ELSE field is forbidden |
3 - 512 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
ABARouting | IF paymentMethod = Domestic Bank Transfer AND currency = USD THEN field is mandatory ELSE field is forbidden |
9 | no validation rules |
bankAccountNumber | IF*paymentMethod* = Domestic Bank Transfer AND currency is in list USD, GBP THEN field is mandatory ELSE field is forbidden |
14 | numeric |
images | yes | - | JPG, PNG, PDF; Min 1 file, max 10 files; Max file size is 30 MB. |
IBAN | IF (paymentMethod = International Bank Transfer AND currency is in list USD, GPB, RUB, EUR ) OR (paymentMethod = Domestic Bank Transfer AND currency = EUR ) THEN field is mandatory ELSE field is forbidden |
- | to finalize |
swiftBicCode | IF (paymentMethod = International Bank Transfer AND currency is in list USD, GPB, RUB, EUR ) OR (paymentMethod = Domestic Bank Transfer AND currency = EUR ) THEN field is mandatory ELSE field is forbidden |
6 - 10 | alphanumeric (latin and numbers only) |
correspondentBank | no | - | massive: see below tab |
correspondentBank
Block is optional
Field | Mandatory | Length | Format |
---|---|---|---|
name | yes | 3 - 512 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
country | yes | - | id value from dict CountryDict_cex |
address | yes | 3 - 512 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
swiftBicCode | yes | 6 - 10 | alphanumeric (latin and numbers only) |
IBAN | yes | - | to finalize |
personalInfo
You are able to submit from 1 to 11 of such blocks. All 3 roles (userRole) should be submitted at least 1 time. All 3 roles could be submitted within 1 massive (1 user with 3 roles).
Field | Mandatory | Length | Format |
---|---|---|---|
roles | yes | - | massive: see below table |
roles
The current block contains several fields for image data: proofOfPosition
& proofOfInterestShares
.
In order to submit image - use method use method POST/s3/upload
Allowed file formats: JPG, PNG, PDF Min 1 file, max 10 files Max file size is 30 MB.
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image fields while submitting the current block.
Field | Mandatory | Length | Format |
---|---|---|---|
entryID | yes | 0-64 | no validation rules |
userRole | yes | - | id value from dict company_user_role |
phone | IF userRole = Authorized person THEN block is mandatory |
- | massive: see table below |
TIN | IF taxResidence <> US THEN field is mandatory |
2 - 9 | alphanumeric (numbers and latin) & special symbols: . - / \ ; IF country is found in the list BG, DE, EE, FR, HR, HU, LT, LU, NL, PL, PT, RO, SI, UA, RU, TR, CA THEN only numeric symbols allowed ELSE alphanumeric symbols allowed |
SSN | IF country = US THEN field is mandatory |
9 | numeric |
identityDocument | no | - | massive: see table below |
addressDocument | no | - | massive: see table below |
pepStatus | no | - | massive: see table below |
socialNetworkProfiles | no | - | massive: see table below |
position | IF userRole is in list Authorised Person, Director/Officer THEN field is mandatory ELSE field is forbidden |
- | id value from dict company_officer_position |
otherDetailed | IF position = Other THEN field is mandatory |
3 - 512 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
proofOfPosition | IF userRole is in list Authorised Person, Director/Officer THEN field is mandatory ELSE field is forbidden |
- | JPG, PNG, PDF; Min 1 file, max 10 files; Max file size is 30 MB. |
interestShares | IF userRole = Ultimate beneficial owners (UBOs) THEN field is mandatory ELSE field is forbidden |
- | numeric; values from 0 to 100 (decimals allowed) |
proofOfInterestShares | IF userRole = Ultimate beneficial owners (UBOs) THEN field is mandatory ELSE field is forbidden |
- | JPG, PNG, PDF; Min 1 file, max 10 files; Max file size is 30 MB. |
sourceOfFiatFunds | IF userRole = Ultimate beneficial owners (UBOs) THEN field is mandatory ELSE field is forbidden |
- | massive: see table below |
phone
Block is mandatory IF userRole =
Authorized person
Field | Mandatory | Length | Format |
---|---|---|---|
country | yes | - | id value from dict CountryDict_cex |
code | yes | - | id value from dict CountryDict_cex |
number | yes | 5 - 15 | numeric |
identityDocument
Block is not mandatory for submission.
The current block contains the images
field for image data.
In order to submit image - use method use method POST/s3/upload Allowed file formats: PDF or PNG or JPG
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image fields while submitting the current block.
For the livenessCheckRegula
massive please put below objects.
You can send from 1 to 5 of such blocks.
Field | mandatory | validation |
---|---|---|
passed | yes | boolean |
guid | yes | no validation rules |
verified | no | boolean |
results | no | no validation rules |
failReason | no | no validation rules |
Field | Mandatory | Length | Format |
---|---|---|---|
type | yes | 8 | only identity value allowed |
subtype | yes | - | id value from dict DocumentIdentitySubtypeDict |
issuingCountry | IF subtype <> International Passport THEN field is mandatory |
- | id value from dict CountryDict_cex |
hasExpireDate | yes | - | boolean |
expireDate | IF hasExpireDate = true THEN field is mandatory |
10 | YYYY-MM-DD; min date > 1 month from current date |
serialNumber | yes | 1 - 128 | alphanumeric (latin & cyryllic only) & special symbols: " * / - . \ \ " , space |
images | yes | - | See description above the table |
livenessCheckRegula | yes | - | See description above the table |
addressDocument
Block is not mandatory for submission.
The current block contains the images
field for image data.
In order to submit image - use method use method POST/s3/upload
Allowed file formats: JPG, PNG, PDF Min 1 file, max 10 files Max file size is 30 MB.
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image fields while submitting the current block.
Field | Mandatory | Length | Format |
---|---|---|---|
country | yes | - | id value from dict CountryDict_cex |
zipCode | yes | see 'Format' | validation per country |
region | yes | - | id value from dict CountryDict_cex |
subregion | IF country = US AND region = any THEN field mandatory |
- | id value from dict CountryDict_cex |
street | yes | 5 - 128 | alphanumeric (numbers and latin) & special symbols: - / # ( ) . , ] [ * $ ? space |
city | yes | 3 - 64 | alphanumeric (numbers and latin) & special symbols: " ` ' - / , . space |
aptSuite | no | 1 - 128 | alphanumeric (numbers and latin) & special symbols: ' - / \ \ , . " ` space |
images | yes | - | JPG, PNG, PDF; Min 1 file, max 10 files; Max file size is 30 MB. |
pepStatus
Block is not mandatory for submission
Field | Mandatory | Length | Format |
---|---|---|---|
isPep | yes | - | boolean |
pepPosition | IF isPep = true THEN field is mandatory |
3 - 512 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
hasPepRelatives | yes | - | boolean |
pepRelativesDetailed | IF hasPepRelatives = true THEN field is mandatory |
3 - 512 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
pepCloseAssociate | yes | - | boolean |
pepCloseAssociateDetailed | IF pepCloseAssociate = true THEN field is mandatory |
3 - 512 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
usCitizen | yes | - | boolean |
usResidentAlien | yes | - | boolean |
usTaxpayer | yes | - | boolean |
socialNetworkProfiles
Block is not mandatory for submission
Field | Mandatory | Length | Format |
---|---|---|---|
url | no | 3 - 256 | default url format |
networkName | no | - | id value from dict SocialNetworkDict |
sourceOfFiatFunds
Block is mandatory IF userRole =
Ultimate beneficial owners (UBOs)
The current block contains the images
field for image data.
In order to submit image - use method use method POST/s3/upload
Allowed file formats: JPG, PNG, PDF Min 1 file, max 10 files Max file size is 30 MB.
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image fields while submitting the current block.
Field | Mandatory | Length | Format |
---|---|---|---|
monthlyIncome | yes | - | id value from dict MonthlyIncomeDict |
source | yes | - | id value from dict SourceOfFiatFundsDict |
detailed | IF source = Other THEN field is mandatory |
3 - 512 | alphanumeric (numbers and latin) & special symbols: " ` ‘ ’ ' - / \ \ , . " space |
images | yes | - | JPG, PNG, PDF; Min 1 file, max 10 files; Max file size is 30 MB. |
companyDocuments
Block could be submitted empty
All fields of the current block are intended for image data. In order to submit image - use method use method POST/s3/upload
Allowed file formats: JPG, PNG, PDF
In response you will receive block in below format:
"id": "DEV:2B79B:97FF96C44F08BFE5ACBF484B6F73D782FB58BAFB",
"fileMime": "image/jpeg",
"fileLength": 178075,
"fileMeta": "Cannot extract exif data from JPEG file",
"date": 1679515272692
Please put all fields from response to the image fields while submitting the current block.
Field | Mandatory | Length | Format |
---|---|---|---|
certificateOfRegistration | no | - | PDF, PNG, JPG; 1 file. |
statutoryDocuments | no | - | PDF, PNG, JPG; Min 1, max 5 files. |
extractFromRegister | no | - | PDF, PNG, JPG; 1 file. |
corporateFundsConfirmation | no | - | PDF, PNG, JPG; Min 1, max 5 files. |
signedResolution | no | - | PDF, PNG, JPG; 1 file. |
otherDocuments | no | - | PDF, PNG, JPG; Min 1, max 5 files. |
allDocuments | no | - | PDF, PNG, JPG; Min 1, max 10 files. |
esignature
Block is not mandatory for submission. However, IF block is submitted - the q-ty of submitted signerEmails should correspond to the q-ty of personalInfo.
Block contains massive signerEmails:
Field | Mandatory | Length | Format |
---|---|---|---|
entryId | yes | 1 - 64 | No validation rules |
name | yes | - | No validation rules |
yes | - | to finalize |
CEX Services Availability
The services availavility logic is intended to get list of CEX Services available for a certain user. The main logic calculates service availability by combination of user's residence country and jurisdiction (subject). Additional logic could check whether any submitted NC request is required (see 'Requests' paragraph above).
By using the current logic you will receive in response the list of all CEX services which are mentioned in rules and its statuses.
In case service is not available (status = disabled) and there is no options block in the response - it means that user's combination of country and subject does not match any of existing availability rules.
Othervise options block will provide you with details (see 'Option' parapraph below).
Methods
Use method GET/compliance/cex-services/service-list in order to get list of services and its statuses.
No parameters to send. We are using user's authorisation token.
Services list
You can get response for services below:
- Convert (convert)
- Spot Trading (nex)
- Сex (exchange)
- Staking (staking)
- Savings (savings)
- Storage (wallet)
- Card Issuing (issuedcard)
- Margin Trading (nexmt)
- Prime (prime)
- Affiliate (affiliate)
Service statuses list
The listed services could be in the below statuses:
Status | Description |
---|---|
enabled | Service is enabled. |
limited | Serivce is enabled, but a certain actions would be limited. Customized within service/product internally. |
disabled | Service is forbidden for user. |
Options list
The tag options in the response is an object that contains a details why a certain service status is disabled or limited.
E.g. Response below means that service 'convert' is disabled due to:
- cooling of period for the current user is not finished yet (date in value)
- user has low verification level
- some internal profile tag is assigned to the user
- there is an open compliance request in required status
{
"services": {
"convert": {
"status": "limited",
"options": {
"coolingOffUntil": "2025-04-04T12:43:00.125Z",
"allowedVerificationLevel": "address",
"tagRules": true,
"ncRequestRules": {
"additionalInfo": [
{
"status": "required",
"ncRequestId": "0000045678",
}
]
}
}
}
}
}
Wallet
CEX IO Wallet is a digital wallet solution designed to provide users with a secure and efficient way to manage their cryptocurrencies and digital assets. As a product of the CEX.IO ecosystem, it integrates seamlessly with other services offered by the platform, ensuring a cohesive user experience.
Accounts
In In the context of the CEX IO Wallet, an account refers to a distinct category within the wallet structure that serves specific purposes and functionalities, allowing users to manage their digital and fiat assets effectively.
Personal Wallets: Used for securely storing cryptocurrencies such as Bitcoin, Ethereum, etc. Managed through blockchain-related accounts.
- Endpoint: POST /wallet/v1/accounts/blockchains - Add a new blockchain-based account for securely storing and handling cryptocurrencies.
Trading Accounts: Designated for executing buy and sell operations on the exchange platform.
Fiat Accounts: Allow users to hold traditional currencies (e.g., USD, EUR) to streamline transactions with cryptocurrencies. Managed through bank, card, and PSP accounts.
- Endpoint: POST /wallet/v1/accounts/cards - Add a new account associated with a card to facilitate fiat transactions.
- Endpoint: POST /wallet/v1/accounts/banks - Add a new account associated with a bank for fiat transactions.
- Endpoint: POST /wallet/v1/accounts/psp - Add a new account associated with a payment service provider such as Skrill, Neteller, ePay, PayPal, and MoneyGram.
Savings Accounts: Enable users to earn interest on their crypto holdings.
Staking Accounts: Provide options for users to engage in crypto lending or staking activities.
These account types enable comprehensive management of digital assets and facilitate various interactions with the platform through the API.
Operations
The flow of operations in the CEX IO Wallet API begins with the initiation of a new operation. This is done by sending a POST
request to the endpoint /wallet/v1/operations
, which allows the user to request an operation and provides them with the necessary information and an operation identifier. For further details, refer to the documentation.
Operation Workflow
Initiation
- Endpoint: POST /wallet/v1/operations
- Description: Sends a request to initiate a new operation and returns an operation identifier.
Confirmation
- Endpoint: POST /wallet/v1/operations/confirm
- Description: Confirms the requested operation, triggering the processing phase with the payment provider or related services. More information can be found in the documentation.
Processing Phase
- Operations are handled according to the selected payment method, which may involve different methods like Google Pay, Apple Pay, etc.
- Google Pay Payment Request
- Endpoint: GET /wallet/v1/operations/psp/googlepay/payment-request
- Description: To request payment information using Google Pay. More details are available in the documentation.
- For ECommPay and other payment methods, users should refer to the documentation.
Checking Status
- Endpoint: GET /wallet/v1/operations/{operationId}
- Description: Retrieves the current status and details of the operation using its identifier. The detailed status, whether intermediate or final, along with additional information, is provided through a WebSocket connection.
For further in-depth details about each step and method, please consult the respective sections in the documentation.
Deposits
A deposit in the context of CEX IO Wallet refers to the process of transferring cryptocurrencies or fiat money into the user's wallet account. During a deposit:
- Source: The account or address from which the funds originate. This could be an external source such as a bank account, credit card, or cryptocurrency wallet. It is a key value for the deposit operation.
- Destination: The user's CEX IO Wallet account, where the funds are transferred and stored. It is a key value for the deposit operation.
Deposits can be made through various methods, including:
- Cryptocurrency transfers from external wallets.
- Bank transfers or credit card payments for fiat currencies.
- Utilization of supported payment services such as Google Pay and Apple Pay.
The deposited funds are securely stored and become available for use in the user's wallet balance once the transaction is confirmed.
Withdrawals
A withdrawal involves moving cryptocurrencies or fiat money out of the user's CEX IO Wallet to an external wallet or bank account. During a withdrawal:
- Source: The user's CEX IO Wallet account, from which the funds are deducted. It is a key value for the withdrawal operation.
- Destination: The external account or address where the funds are sent, such as a bank account or a cryptocurrency wallet outside the CEX.IO ecosystem. It is a key value for the withdrawal operation.
Withdrawals can be initiated through the wallet interface and may include the following methods:
- Sending cryptocurrency to external digital wallet addresses.
- Transferring fiat currencies to linked bank accounts.
- Using supported payment services for fund transfers.
Withdrawals require appropriate confirmations, and users must ensure that the recipient details are correct to prevent any loss of funds.
Buy
A buy operation on a crypto platform involves purchasing cryptocurrency directly using fiat money, such as dollars or euros. The user selects the desired cryptocurrency and specifies the amount in fiat currency or the quantity of cryptocurrency. They then choose a payment method, such as a credit/debit card or bank transfer. After reviewing exchange rates, fees, and the total cost, the user confirms the transaction.
Buy workflow
Initiation
- Endpoint: POST /wallet/v1/operations
- Description: Initiates a request to start a new buy operation and returns an operation identifier.
Retrieve Currency Rates
- Endpoint: GET /wallet/v1/system/rates
- Description: Requests the current indicative rate for currency conversion, essential for assessing the buy operation's cost.
Confirmation
- Endpoint: POST /wallet/v1/operations/confirm
- Description: Confirms the buy operation, initiating the processing phase with the payment provider or relevant services. Further details are in the documentation.
Deposit Initiation
- Description: Initiates a call to the payment provider to complete the deposit process necessary for the buy operation. Further details can be found in the deposit section of the documentation.
Successful Deposit Notification
- Description: This notification indicates that the payment provider has successfully sent the funds, confirming the deposit completion.
Asset Exchange
- Method: POST - walletExchange
- Description: Facilitates the exchange of assets as part of the sell process, convert assets into specified currencies at available rates.
Update User's Crypto Balance
- Description: After the buy operation and related exchanges, updates the user's cryptocurrency balance to reflect the new holdings, ensuring real-time account accuracy.
For detailed steps and more information, please consult the related sections in the API documentation.
Sell
A sell operation on a crypto platform involves exchanging cryptocurrency for fiat money. The user selects the cryptocurrency they want to sell and specifies the amount. They choose how they wish to receive the fiat money, such as a bank transfer or credit to a payment card. The platform provides details on exchange rates, fees, and the total amount the user will receive. After reviewing this information, the user confirms the transaction. Once completed, the fiat currency is transferred to the user's designated account. This process allows users to convert digital assets into cash, though it may involve transaction and processing fees.
Initiation
- Endpoint: POST /wallet/v1/operations
- Description: Sends a request to initiate a new sell operation and returns an operation identifier.
Retrieve Currency Rates
- Endpoint: GET /wallet/v1/system/rates
- Description: Requests the current indicative rate for currency conversion, providing essential information for the sell operation.
Confirmation
- Endpoint: POST /wallet/v1/operations/confirm
- Description: Confirms the sell operation, initiating the processing phase with the payment provider or relevant services.
Asset Exchange
- Method: POST - walletExchange
- Description: Facilitates the exchange of assets as part of the sell process, convert assets into specified currencies at available rates.
Withdrawal to External Account
- Description: Sends the converted assets to the user's external account, completing the withdrawal process. This step ensures that the user receives the proceeds from their sell operation in their chosen external account.
For detailed steps and more information, please consult the related sections in the API documentation.
WebSocket
A WebSocket is a simple event-notification system that allows the CEX Wallet to send real-time updates to clients. When an event occurs within the CEX Wallet, a payload of JSON data containing information about the event is transmitted via a WebSocket connection.
Each event provides information regarding the state of a transaction, which may vary in format depending on the event's type.
Common Event Types
Confirm/Decline Events
Currently, all WebSocket events for transaction confirmations and declines include the following common attributes:
Common Attributes
deposit3DsFlow verification depositDecline withdrawalDecline depositConfirm withdrawalConfirm exchangePlaceOrderConfirm exchangePlaceOrderDecline transferFunds reversalSell operationSubmitted cardPayReversal cardPayClear cardPayAccounting cardPayConfirm cardPayReject
Example of a Confirm/Decline Event
buyAuth
Auth Capture Flow for InstantBuy Cryptocurrency We use Auth Capture Flow in the InstantBuy process to make sure everything goes smoothly and reduce risks. Here’s how it works:
- Authorization (Auth) - First, we check and block the funds needed for the purchase before KYC. This guarantees the user has enough money for the transaction.
- KYC Verification - Next, the user completes the KYC verification to confirm their identity.
- Capture - Finally, if the KYC is successful, the blocked funds are captured, and the cryptocurrency is delivered. If the KYC fails, the funds are automatically unblocked.
This process makes the system safer, more reliable, and user-friendly.
InstantBuy Flow
This section outlines the step-by-step process for the InstantBuy flow.
1. Commissions
Retrieve the necessary commissions for InstantBuy to display them to the user during the purchase process.
Request:
GET /wallet/v1/system/status
Description:
This endpoint provides the applicable commissions for transactions.
2. Auth Request
After the user confirms their payment on the CLIENT side, two API calls to the WALLET API must be made:
Request:
Description: This step ensures that the funds are reserved on the user’s card but not yet captured.
Initiation
- Endpoint: POST /wallet/v1/operations/buy-auth
- Description: Sends a request to initiate a new operation (in scope of Auth) and returns an operation identifier.
Confirmation
- Endpoint: POST /wallet/v1/operations/confirm
- Description: Confirms the requested operation, triggering the processing phase with the payment provider or related services. More information can be found in the documentation.
3. 3DS Verification
The 3DS process is identical to a deposit operation on the platform and depends on the provider's settings. If 3DS is required, the user will need to complete the challenge.
Failure Handling: If there are any issues with completing the 3DS process, the auth will be canceled on the provider's side, and the reserved funds will be unblocked.
4. buyAuth Notification
If the previous step (3DS verification) is successful, a notification will be sent to indicate the success of the buyAuth process.
- Action: Upon receiving the notification, the user will be directed to complete KYC on the CLIENT side.
- Webhook:
json { "event": "operationSubmitted", "data": { "id": "39fab577-5109-4e10-86ff-fa24b1951711", "type": "buyAuth", "createdAt": "2024-12-20T12:55:11.247Z", "updatedAt": "2024-12-20T12:55:17.759Z", "status": "approved" } }
5. KYC Verification
The user must complete the KYC process to confirm their identity and proceed with the transaction.
Failure Handling: If the user fails the KYC process, the WALLET service will unblock the reserved funds on the provider's side.
6. Capture Request
After successful KYC completion, the wallet service will be notified by IVS, triggering the capture of the reserved transaction. Description: This step finalizes the transaction by capturing the reserved funds.
7. Operation Completed
Once the capture process is successful, the Client will receive a notification about the successful completion of the operation.
8. Transactions Status Method for buyAuth Flow
- Endpoint: GET /wallet/v1/operations/buy-auth-flow/exists
- Description: This method returns the status of a transactions within the buyAuth flow.
Request:
The body of the request is empty. The request retrieves information based on the user's token and returns a list of operations along with their statuses.
Response Example:
json
[
{
"id": "e81b3e98-7fa2-421a-a536-6c31b5c9247b",
"auth": "success",
"kys": "success",
"capture": "success"
}
]
Attributes:
- id: The unique identifier for the operation.
- auth, kys, capture: These indicate the statuses of the operation, where the possible values are "success" or "failed". If an attribute is absent in the array, it means the operation is still in progress for that particular step.
Response Example:
json
[
{
"id": "e81b3e98-7fa2-421a-a536-6c31b5c9247b",
"auth": "success"
}
]
This indicates that the operation is currently in the process of user KYC verification.
Errors
This error section includes common errors that users may encounter when interacting with the CEX WALLET API. These are public errors used to provide specific reasons for particular issues. Each error code below is accompanied by a brief description of its meaning. This section will be updated further based on implementation feedback and improvements.
Common Error Codes
Error Code | Meaning |
---|---|
400 | Bad Request – Your request is invalid. This typically occurs due to malformed syntax or invalid request parameters. Please check the request format and parameters to ensure they are correct. |
401 | Unauthorized – Your API key is wrong. This error indicates that the API key provided is either incorrect or missing. Please verify that you are using a valid API key in your request. |
403 | Forbidden – The CEX WALLET requested is hidden for administrators only. Access to this resource is restricted, and you do not have permission to access it. Please ensure you have the necessary permissions. |
404 | Not Found – Specified method could not be found. This error indicates that the requested endpoint or resource does not exist. Please verify the URL and the method you are trying to access. |
405 | Method Not Allowed – You tried to access a CEX WALLET with an invalid HTTP method. This indicates that the endpoint you are trying to reach does not support the method you used (e.g., using POST instead of GET). |
406 | Not Acceptable – You requested a format that isn't JSON. This error occurs when the server cannot produce a response matching the list of acceptable values defined in the request's headers. Ensure that your request accepts JSON format. |
500 | Internal Server Error – We had a problem with our server. This is a generic error message indicating that something went wrong on the server side. Please try again later and report the issue if it persists. |
503 | Service Unavailable – We're temporarily offline for maintenance. This error suggests that the server is currently unable to handle the request due to maintenance or temporary overload. Please try again later. |
Conclusion
When interacting with the CEX WALLET API, understanding and correctly interpreting these error codes will help you troubleshoot issues more effectively. If you encounter an error not listed here, please refer to the API documentation or contact support for further assistance. This section will continue to evolve as the API implementation grows.
Earn
Staking
Savings
Errors
The Kittn API uses the following error codes:
Error Code | Meaning |
---|---|
400 | Bad Request -- Your request is invalid. |
401 | Unauthorized -- Your API key is wrong. |
403 | Forbidden -- The kitten requested is hidden for administrators only. |
404 | Not Found -- The specified kitten could not be found. |
405 | Method Not Allowed -- You tried to access a kitten with an invalid method. |
406 | Not Acceptable -- You requested a format that isn't json. |
410 | Gone -- The kitten requested has been removed from our servers. |
418 | I'm a teapot. |
429 | Too Many Requests -- You're requesting too many kittens! Slow down! |
500 | Internal Server Error -- We had a problem with our server. Try again later. |
503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |