A trader is an entity that can perform trades.
You can create a trader entity with the trader signup endpoint.
Mandatory trader information
We distinguish between two types of trader accounts, individual
and corporate
.
In order for the trader to be able to complete their trades they must provide some mandatory information first.
Please find the mandatory API endpoints for each trader account type below.
Individual trader mandatory endpoints:
Important:
The Individual trader endpoints have to be called in the specific order they are presented below.
- Provide address
- Provide source of funds
- Politically Exposted Person status
- Complete trader identification (KYC)
Corporate trader mandatory endopoints:
- Provide corporate details
- Provide address
- Provide source of funds
- Shareholder relations status
- Politically Exposed Person status
Once the corporate trader provides the above listed information, they will receive a KYB email to provide necessary documents.
Get trader information
Example response for
GET /traders/me
{
"id": 754035,
"email": "[email protected]",
"personalInformation": {
"name": "Jens Jensen"
},
"corporateDetails": null,
"isEmailVerified": true,
"identificationState": "approved",
"corporateDetailsState": "N/A",
"addressState": "approved",
"sourceOfFundsState": "approved",
"kybState": "N/A",
"shareholderRelationState": "N/A",
"proofOfSourceOfFundsState": "pending",
"enhancedProofOfSourceOfFundsState": "pending",
"pepState": "pep",
"tradeSubscriptionsAllowed": false,
"consentAdditionalMails": true,
"accountType": "individual"
}
GET https://app-api.coinify.com/traders/me
This endpoint returns a trader object for your trader, provided you are authorized as a trader.
addressState
,sourceOfFundsState
,PEP status
, andidentificationState
all have to be provided/approved for trader to be able to complete their trades. See sections below on how to get them approved.
Trader Object
Key | Type | Description |
---|---|---|
id | Integer | ID of the trader |
email | String | Email address of the trader |
personalInformation | Object | object containing personal information (null until name of trader is set) |
→name | string | Name of trader |
corporateDetails | Object | Object containing corporate details (will be null until corporate details is provided) |
→name | string | name of corporation |
isEmailVerified | Boolean | Is email verified |
identificationState | String | State of traders identity verification. Possible states are approved , N/A and pending |
corporateDetailsState | String | State of traders corporate details. Possible state are approved , N/A and pending |
addressState | String | State of trader address. Possibles states are approved , pending |
sourceOfFundsState | String | State of traders source of funds. Possible states are approved , N/A and pending |
kybState | String | State of kyb process. Possible states are approved , documents_requested , N/A and pending |
enhancedDueDiligenceState | String | State of trader's Enhanced Due Diligence (EDD). If the trader is marked as high-risk, Coinify will do the EDD and a questionnaire will be sent to the trader's email address. Possible states are pending , questionnaire_sent , approved , or rejected |
shareholderRelationState | String | State of shareholderRelation, Possible states are pending , related , not_related , N/A |
proofOfSourceOfFundsState | String | State of traders proof of source of funds. If the trader traded for more than 10000 EUR we will sent him an email with proof of source of funds questionaire and he won't be allowed to trade until it is approved. Possible states are approved , rejected , questionaire_sent and pending |
enhancedProofOfSourceOfFundsState | String | State of traders enhanced proof of source of funds. Possible states are pending , questionaire_sent , approved and rejected . |
pepState | String | State of traders PEP. Possible states are pep , non_pep , pep_relative , N/A and pending |
consentAdditionalMails | Boolean | Determines whether the user consents to receive additional email from Coinify. This is to comply with GDPR |
accountType | String | Determines the trader account type, possible account types are individual and corporate |
Response
HTTP Response code | JSON data |
---|---|
200 OK | Success, response as shown to the right. |
404 Not found | Error, trader not found. |
Address
Important:
Individual trader must provide address details before initiating the KYC process!
Provide Address
Example request for
POST /traders/me/address
{
"street": "Best street 1",
"city": "City",
"postalCode": "1000"
}
POST https://app-api.coinify.com/traders/me/address
Endpoint to provide address
Request object
The parameters in the request object are as follows:
Parameter | Type | Default | Description |
---|---|---|---|
street | String | Required | Residential street |
city | String | Required | Residential city |
postalCode | String | null | Residential postal code≤ |
Response
HTTP Response code | JSON data |
---|---|
201 Created | Success, empty object {} |
400 Bad request | Error, already provided |
401 Unauthorized | Error, access token missing. |
403 Forbidden | Error, invalid access token. |
Get Address
Example response for
GET /traders/me/address
{
"street": "Best street 1",
"city": "City",
"postalCode": "1000",
"country": "US",
"state": "NY"
}
GET https://app-api.coinify.com/traders/me/address
Endpoint to get address
Response
HTTP Response code | JSON data |
---|---|
200 OK | Success |
401 Unauthorized | Error, access token missing. |
403 Forbidden | Error, invalid access token. |
Trader Identification
In order to comply with financial regulations, all traders must undergo a KYC (Know-Your-Customer) review before they can start trading. A KYC review typically revolves around verifying the identity of the trader.
This section deals with the mechanisms for doing so.
Individual trader must provide address details before initiating the KYC process!Identification attempt object
Example of an identification attempt:
{
"id": "0cf12488-0dcf-4f99-96c4-e1ec879c906d",
"state": "approved",
"createTime": "2019-11-26T07:45:44.852Z",
"approveTime": "2019-11-26T07:49:19.126Z",
"expireTime": "2028-03-04T00:00:00.000Z",
"redirectUrl": "https://www.example.com/redirect-client-to-this-url",
"sdkToken": null,
"returnUrl": null
}
An identification attempt is represented as an object as seen to the right. The table below describes each of the properties in the object.
Key | Type | Description |
---|---|---|
id | String | Identifier (UUID) for the identification attempt |
state | Identification attempt state | State of the identification attempt |
createTime | ISO 8601 time | Timestamp for when this identification attempt was first initiated. |
approveTime | ISO 8601 time or null | Timestamp for when this identification attempt was approved |
expireTime | ISO 8601 time or null | Timestamp for when this identification attempt will expire |
redirectUrl | URL (String) | URL to redirect the user to in order to perform the identification |
sdkToken | JWT (String) | Deprecated The parameter is till returned in the response but will always be null |
returnUrl | URL (String) or null | URL to return to when identification attempt is submitted or failed. Returning after identification flow below for more information. |
rejectReason | Identification attempt rejection reason or null | Machine-readable reason for rejecting this identification attempt, if state is 'rejected' . |
Identification attempt state
An identification attempt can be in a number of well-defined states throughout its lifetime.
State | Description |
---|---|
pending | (Starting state) Identification attempt has been initiated, but is waiting for action from the end-user. |
processing | (Intermediate state) Identification attempt is currently being processed. |
approved | (Final state) Identification attempt was successfully approved. (This state is also used if the identification attempt was manual and accepted) |
expired | (Final state) Identification attempt expired because the documents used to identify with has expired |
rejected | (Final state) Identification attempt was rejected |
Identification attempt rejection reasons
If an identification attempt state is rejected
, the identification attempt contains a rejectReason
providing a reason
for the rejection. The below table lists all currently possible reasons:
Rejection reason | Description |
---|---|
DENIED | Denied without any further reason |
DENIED_UNSUPPORTED_ID_TYPE | The used identification was not supported |
DENIED_UNSUPPORTED_ID_COUNTRY | The used identification was issued in a country not supported by Coinify |
DENIED_MISSING_DATE_OF_BIRTH | The used identification didn't contain a date of birth |
DENIED_YOUNGER_THAN_18_YEARS | The identified person must be 18 years or older |
DENIED_EXPIRED_IDENTIFICATION | The used identification has expired |
DENIED_FAILED_IDENTITY_VERIFICATION | We were unable to ensure that the person submitting the identification was the same person in the ID photo |
ERROR_NOT_READABLE_ID.PHOTOCOPY_BLACK_WHITE | |
ERROR_NOT_READABLE_ID.PHOTOCOPY_COLOR | |
ERROR_NOT_READABLE_ID.DIGITAL_COPY | |
ERROR_NOT_READABLE_ID.NOT_READABLE_DOCUMENT .BLURRED | |
ERROR_NOT_READABLE_ID.NOT_READABLE_DOCUMENT .BAD_QUALITY | |
ERROR_NOT_READABLE_ID.NOT_READABLE_DOCUMENT .MISSING_PART_DOCUMENT | |
ERROR_NOT_READABLE_ID.NOT_READABLE_DOCUMENT .HIDDEN_PART_DOCUMENT | |
ERROR_NOT_READABLE_ID.NOT_READABLE_DOCUMENT .DAMAGED_DOCUMENT | |
ERROR_NOT_READABLE_ID.NO_DOCUMENT | |
ERROR_NOT_READABLE_ID.SAMPLE_DOCUMENT | |
ERROR_NOT_READABLE_ID.MISSING_BACK | |
ERROR_NOT_READABLE_ID.WRONG_DOCUMENT_PAGE | |
ERROR_NOT_READABLE_ID.MISSING_SIGNATURE | |
ERROR_NOT_READABLE_ID.CAMERA_BLACK_WHITE | |
ERROR_NOT_READABLE_ID.DIFFERENT_PERSONS_SHOWN | |
ERROR_NOT_READABLE_ID.MANUAL_REJECTION | |
MANUAL_REVIEW | The identification attempt is under manual review by Coinify compliance. This process can last betwen 1-3 days. Coinify will communicate the final result with the trader via email and a callback will be sent to your webhook accordingly. As an API integrated Partner you should inform the user about this accordingly. |
NO_ID_UPLOADED | No identification was successfully submitted. |
Initiate identification attempt
Example request to
POST /kyc/identification-attempts
{
"returnUrl": "https://mypage.com/ida_complete"
}
Example response from
POST /kyc/identification-attempts
{
"id": "0cf12488-0dcf-4f99-96c4-e1ec879c906d",
"state": "pending",
"createTime": "2019-11-26T07:45:44.852Z",
"approveTime": null,
"expireTime": null,
"redirectUrl": "https://www.example.com/redirect-client-to-this-url",
"returnUrl": "https://mypage.com/ida_complete",
"sdkToken": null
}
POST https://app-api.coinify.com/kyc/identification-attempts
Initiates an identification attempt. The user must be redirected to the URL specified in the redirectUrl
parameter of the response in order to actually identify themselves.
Request object
The parameters in the request object are as follows:
Parameter | Type | Default | Description |
---|---|---|---|
returnUrl | URL (String) | No value | URL to return to after the process is done when using the redirectUrl . See Returning after identification flow below for more information. |
deviceType | String | No value | Type of device on which the user will perform identification. Used to provide the best possible user experience. Possible values are android (Android phone/tablet), ios (iPhone/iPad), desktop (Non-mobile device). If left blank, auto-detection will be attempted from the User-Agent HTTP header of the request. |
Response
HTTP Response code | JSON data |
---|---|
201 Created | Success, Identification attempt object as shown to the right. |
400 Bad request | Error interpreting the request. |
401 Unauthorized | Error, access token missing. |
403 Forbidden | Error, invalid access token. |
Returning after identification flow
If a returnUrl
is specified during the initiate identification attempt API call, then the user will be redirected to that URL once they have submitted (or failed to submit) their identification.
The returnUrl
is augmented with a result
query parameter containing either a 'submitted'
or 'failed'
value. Examples:
returnUrl | Result of flow | Actual URL that user is redirected to |
---|---|---|
https://mypage.com/ida_return | Documents submitted | https://mypage.com/ida_return?result=submitted |
https://mypage.com/ida_return | Failed | https://mypage.com/ida_return?result=failed |
https://mypage.com/ida_return?other_query_parameter=1234 | Documents submitted | https://mypage.com/ida_return?other_query_parameter=1234&result=submitted |
https://mypage.com/ida_return?other_query_parameter=1234 | Failed | https://mypage.com/ida_return?other_query_parameter=1234&result=failed |
Get identification attempt
Example request for
GET /kyc/identification-attempts/0cf12488-0dcf-4f99-96c4-e1ec879c906d
{
"id": "0cf12488-0dcf-4f99-96c4-e1ec879c906d",
"state": "approved",
"createTime": "2019-11-26T07:45:44.852Z",
"approveTime": "2019-11-26T07:49:19.126Z",
"expireTime": "2028-03-04T00:00:00.000Z",
"redirectUrl": "https://www.example.com/redirect-client-to-this-url",
"sdkToken": null,
"returnUrl": null
}
GET https://app-api.coinify.com/kyc/identification-attempts/<id>
This endpoint allows you to query a specific identification attempt by ID.
Response
HTTP Response code | JSON data |
---|---|
200 OK | Success, Identification attempt object as shown to the right. |
401 Unauthorized | Error, access token missing. |
403 Forbidden | Error, invalid access token. |
404 Not Found | Error retrieving identification attempt with the specified ID. |
List identification attempts
Example request for
GET /kyc/identification-attempts
[
{
"id": "0cf12488-0dcf-4f99-96c4-e1ec879c906d",
"state": "approved",
"createTime": "2019-11-26T07:45:44.852Z",
"approveTime": "2019-11-26T07:49:19.126Z",
"expireTime": "2028-03-04T00:00:00.000Z",
"redirectUrl": "https://www.example.com/redirect-client-to-this-url",
"sdkToken": null,
"returnUrl": null
},
{
// next attempt...
}
]
GET https://app-api.coinify.com/kyc/identification-attempts
This endpoint allows you to get all identification attempts for the trader.
The identification attempts are ordered by createTime
(newest first).
Response
HTTP Response code | JSON data |
---|---|
200 OK | Success, A list of identification attempt objects as shown to the right. |
401 Unauthorized | Error, access token missing. |
403 Forbidden | Error, invalid access token. |
Skip identification process (KYC) - Sandbox environment only
For testing purposes, you can skip the identification process in Sandbox environment.
See how to skip KYC process in sandbox by following this link .
Corporate Details
Provide Corporate Details
Example request for
POST /traders/me/corporate-details
{
"name": "Some corporation name",
"industry": "wholesale_and_retail_trade",
"website": "www.somecorporation.com",
"description": "some corporation description"
}
POST https://app-api.coinify.com/traders/me/corporate-details
Endpoint to provide corporate details
Request object
The parameters in the request object are as follows:
Parameter | Type | Default | Description |
---|---|---|---|
name | String | Required | Name of the corporation |
industry | String | Required | Can be one of these values 'wholesale_and_retail_trade', 'accommodation_and_food_service', 'information_and_communication', 'professional_or_scientific_and_technical_activities', 'administrative_and_support_service_activities', 'education', 'financial_and_insurance_activities', 'human_health', 'real_estate_activities', 'arts_or_entertainment_or_recreation', 'non_profit_and_public_sectors', 'other' |
otherIndustry | String | null | Alternative industry, needs to be supplied if 'other' is chosen as industry |
website | String | null | Corporate website |
description | String | Required | Description of the corporation |
Response
HTTP Response code | JSON data |
---|---|
201 Created | Success, empty object {} |
400 Bad request | Error, already provided |
401 Unauthorized | Error, access token missing. |
403 Forbidden | Error, invalid access token. |
Source of funds
Get annual trade volume buckets
Example response for
GET /traders/me/source-of-funds/annual-trade-volume-buckets
[
{
"id": 1,
"lt": 10000,
"currency": "EUR"
},
{
"id": 2,
"lt": 50000,
"gte": 10000,
"currency": "EUR"
},
{
"id": 3,
"gte": 50000,
"currency": "EUR"
}
]
GET https://app-api.coinify.com/traders/me/source-of-funds/annual-trade-volume-buckets
Endpoint to get annual trade volume buckets. ID of the response will be used for next request
Provide source of funds
Example request for
POST /traders/me/source-of-funds
{
"originOfFunds": "crypto-mining",
"annualTradeVolumeBucketId": 1,
"areFundsFromLegalActivities": true
}
POST https://app-api.coinify.com/traders/me/source-of-funds
Endpoint to provide source of funds.
Request object
The parameters in the request object are as follows:
Parameter | Type | Default | Description |
---|---|---|---|
originOfFunds | String | Required | Must be one of the following values for an individual trader: 'occupation','inheritance','investment-proceeds','crypto-mining','savings', 'loan', 'crypto-purchased-elsewhere', 'sale-of-property', 'sale-of-precious-goods' . Options for a corporate trader: 'investment-proceeds', 'crypto-mining', 'business-income' . |
annualTradeVolumeBucketId | Integer | Required | Id of bucket see get annual trade volume buckets endpoint to get ID. |
areFundsFromLegalActivities | Boolean | Required | Must be set to true for a valid request |
Response
HTTP Response code | JSON data |
---|---|
201 Created | Success, empty object {} |
400 Bad request | Error, already provided |
401 Unauthorized | Error, access token missing. |
403 Forbidden | Error, invalid access token. |
Shareholder Relations
Provide Shareholder Relation
Example request for
POST /traders/me/shareholder-relation
{
"shareholderRelationState": "not_related"
}
POST https://app-api.coinify.com/traders/me/shareholder-relation
Endpoint to provide shareholder relation state. Its only applicable for corporate traders.
Used for providing whether shareholders in the corporations are related in some way
Request object
The parameters in the request object are as follows:
Parameter | Type | Default | Description |
---|---|---|---|
shareholderRelationState | String | Required | Shareholder Relation state can be one of the following: related , not_related |
Response
HTTP Response code | JSON data |
---|---|
200 OK | Success |
400 Bad request | Error, invalid request |
401 Unauthorized | Error, access token missing. |
403 Forbidden | Error, invalid access token. |
Politically Exposed Person
Provide PEP (Politically Exposed Person)
Example request for
POST /traders/me/pep
{
"pepState": "pep"
}
POST https://app-api.coinify.com/traders/me/pep
Endpoint to provide PEP state.
Request object
The parameters in the request object are as follows:
Parameter | Type | Default | Description |
---|---|---|---|
pepState | String | Required | PEP can be one of these values for individual traders 'pep','non_pep','pep_relative' and these values for corporate traders 'pep','non_pep' |
Response
HTTP Response code | JSON data |
---|---|
200 OK | Success |
400 Bad request | Error, invalid request |
401 Unauthorized | Error, access token missing. |
403 Forbidden | Error, invalid access token. |
Resend emails
The following endpoints allow you to resend specific emails that are usually sent to the traders by our system, in case for some reason the trader does not receive the emails in the first place or does not provide the necessary information in time.
Resend Proof of Source of Funds (PSOF) Email
POST https://app-api.coinify.com/traders/me/resend-proof-of-source-of-funds-email
This endpoint enables you to resend a PSOF email to the trader. A PSOF email is usually sent when a trader reaches a significant volume of trades.
If the trader does not complete the PSOF before it expires, you can resend it with a request to this endpoint.
You must be authenticated as the specific trader to use this endpoint and for the email to be delivered to the correct address.
HTTP Response code | JSON data |
---|---|
200 OK | Success |
400 Bad request | Error, invalid request |
401 Unauthorized | Error, access token missing. |
403 Forbidden | Error, invalid access token. |
Resend Enhanced Due Diligence (EDD) Email
POST https://app-api.coinify.com/traders/me/resend-enhanced-due-diligence-email
This endpoint enables you to resend an EDD email to the trader. An EDD email is usually sent when the customer is marked as a high-risk trader.
If the trader does not complete the EDD before it expires, you can resend it with a request to this endpoint.
You must be authenticated as the specific trader to use this endpoint and for the email to be delivered to the correct address.
HTTP Response code | JSON data |
---|---|
200 OK | Success |
400 Bad request | Error, invalid request |
401 Unauthorized | Error, access token missing. |
403 Forbidden | Error, invalid access token. |
Resend KYB upload email (Corporate traders only)
POST https://app-api.coinify.com/traders/me/resend-kyb-upload-email
This endpoint enables you to resend the KYB document upload email to a corporate trader.
The KYB email is automatically sent when a new corporate trader creates an account and provides the basic mandatory information required from all corporate traders. See mandatory info that a corporate trader needs to provide here.
Trader authentication is required to use this endpoint and for the email to be delivered to the correct address.
HTTP Response code | JSON data |
---|---|
200 OK | Success |
400 Bad request | Error, invalid request |
401 Unauthorized | Error, access token missing. |
403 Forbidden | Error, invalid access token. |