Sell to Account API Integration
Welcome to the Simplex API documentation.
The Simplex API enables you to initiate SellCrypto transactions
The API documentation begins by describing the flow of a SellCrypto transaction, introducing the stages involved. Key concepts in the API are introduced next. The technical part then follows: types, detailed reference for each API, and the protocols involved.
p/REST and MsgQueue
Certain use-cases require that Simplex “reach out” to you in order to notify you of events that have occurred, request that you perform certain actions, or get some information.
This is achieved by either you exposing API endpoints for Simplex to invoke or by you periodically polling Simplex, asking for any new “messages”. Exposing API’s for Simplex to invoke is called “p/REST” (“Partner REST”), while polling Simplex for messages is called “MsgQueue”.
The specifics on p/REST and MsgQueue are documented in a dedicated section.
API’s where Simplex reaches out to you are marked as such, and you can choose for each what method to use.
Regardless of the method chosen, the API’s remain the same: they accept the same parameters, return the same responses, and the same errors may arise under the same circumstances.
Authentication
All API’s must be authenticated. To authenticate, supply your API key as the Authorization
HTTP header with the apikey
authorization scheme.
Parameters
For API’s that use POST, set the request’s Content-Type
header to "application/json"
and supply an appropriate JSON object in the request body.
For API’s that use GET, specify each request parameter as a properly-escaped query parameter.
Response
All responses have their Content-Type
set to "application/json"
, and contain the response JSON object in the response body.
When an API has no response an empty HTTP response is returned.
Sandbox vs. Production
Simplex provides a sandbox environment, which you use while developing and testing your integration. When you are ready to go live, you simply switch to the production environment.
Environments are accessed with different URLs and require different API keys.
IP limitations are not enforced in Sandbox, in contrary to Production. Test net wallet addresses are supported for Sandbox. Please make sure to use it in order to test an end to end flow.
The API key for Sandbox will be provided to you when you start the integration. The production API key will be provided when all testing are complete and the integration part is done.
Integer
A plain old integer: a whole number (no fraction), positive, zero or negative.
Float
A plain old floating-point number. A number
in JSON parlance
Timestamp
A floating-point number representing the number of seconds since the Epoch (Jan 1, 1970 at 0:00am). Millisecond resolution.
E.g. 1537078623.305
represents Sep 16, 2018 at 06:17:03.305 UTC.
Fiat Currency
A 3-letter upper-case string. For example: USD
, EUR
Crypto Currency
A 3 or 4-letter upper-case string. For example: BTC
, ETH
Money Amount
An integer representing amounts of money of a certain currency, be it crypto or fiat.
The integer counts millionths of a whole currency unit.
An amount of 100.0 (a hundred “somethings”) is represented as the integer 100,000,000 (one hundred million), while the integer 30,000 (thirty thousand) represents the amount 0.03 of “something”.
Crypto Address
A string representing a crypto address.
Address
An address in the real world.
1st line of the address, city and country (ISO 3166-1 ALPHA-2) are required.
2nd line of the address, zip code and state are optional.
Date
A date on the Gregorian calendar.
Day (1-31), month (1-12) and year (full year) are all required
Payment Method
A PaymentMethod that used on the transaction.
Currently, must be set to simplex_account
Convert between crypto and fiat money.
In order for you to provide the “Quote” experience described in the “Flow” section, where users make the decision of how much cryptocurrency they wish to sell, you need to be able to convert back and forth between crypto and fiat money. This is what the get-quote
API is for.
Direction: You → Simplex
Sandbox URL: https://api.sandbox.test-simplexcc.com/v3/get-quote
Production URL: https://api.simplexcc.com/v3/get-quote
Request parameters
The currency to convert from: this is the currency the end-user wishes to sell.
The amount of base_currency
units, in millionths of a unit, the end-user wishes to sell.
If this is present then quote_amount
is missing, and the end-user is asking how many quote_currency
units they will receive for selling base_amount
units of base_currency
.
If this is missing then quote_amount
is present, and the end-user is asking how many base_currency
units they need to sell in order to receive quote_amount
units of quote_currency
.
The currency to convert to: this is the currency the end-user wishes to receive.
If base_currency
represents a fiat currency then quote_currency
will represent a crypto currency, and vise versa.
The amount of quote_currency
units, in millionths of a unit, the end-user wishes to receive.
If this is present then base_amount
is missing, and the end-user is asking how many quote_currency
units they need to sell in order to receive quote_amount
units of quote_currency
.
If this is missing then base_amount
is present, and the end-user is asking many quote_currency
units they will receive for selling base_amount
units of base_currency
.
The payment method that used in the transaction
The identifier you use for the end-user’s account
Responses
Body
An identifier for this quote. Keep this identifier and pass it back to Simplex when creating a transaction based on this quote.
The exchange rate: how many units of quote_currency
equal one unit of base_currency
.
Timestamp at which this quote expires.
The exchange rate in USD
the end-user wishes to sell 0.5 BTC and wishes to know how many EUR they will get in exchange:
GET /v3/get-quote?base_amount=500000&base_currency=BTC"e_currency=EUR&pp_payment_method=simplex_account&account_id=39cb996a-6cc8-43b9-ad37-1102a958ff38 HTTP/1.1
Host: api.sandbox.test-simplexcc.com
Authorization: ApiKey XXXXXXXX
After the user asked in crypto
{
"quote_id": "d9437375-dd8e-4ce5-8cd0-c45ef11265c6",
"rate": 8012.978974353465,
"expiry_ts": 1590503.085,
"quote_rate_in_usd": 8795
}
the end-user is asking how many BTC’s they need to sell in order to receive 1,000 EUR:
GET /v3/get-quote?base_currency=BTC"e_amount=1000000000"e_currency=EUR&pp_payment_method=simplex_account&account_id=39cb996a-6cc8-43b9-ad37-1102a958ff38 HTTP/1.1
Host: api.sandbox.test-simplexcc.com
Authorization: ApiKey XXXXXXXX
After the user asked in fiat
{
"quote_id": "12c8ba26-674f-444e-aa7c-7a0a00b80151",
"rate": 7989.890049684924,
"expiry_ts": 1590503.822,
"quote_rate_in_usd": 8769
}
Create a SellCrypto transaction, and have the end-user start the checkout flow.
A SellCrypto transaction is initiated by the entity representing the end-user, such as a wallet app, an exchange, etc.
Each transaction has an identifier, which you use when referring to the transaction. This identifier is created by Simplex and returned in the response.
Parameters in account_details
are optional but allow Simplex’s risk algorithms to approve a broader range of end-users. The more information you supply in account_details
the more accurate Simplex’s risk decisions will be, and as a result the happier your users become.
The response includes a transaction URL to which you send your end-user in order to start the checkout flow.
Direction: You → Simplex
Sandbox URL: https://api.sandbox.test-simplexcc.com/v3/initiate-sell
Production URL: https://api.simplexcc.com/v3/initiate-sell
Request body
required
The value of the Referer HTTP header with which the end-user first landed at your site. In other words - where did the end-user arrive at your site from?
A URL to redirect the end-user to when the transaction is finalized
A deep-link to the transaction page in the wallet will be send via email once user could send his crypto. If not provide, generic email will sent instead
required
The quote_id
returned by get-quote
.
If this is missing then Simplex will provide the “Quote” user experience as the first stage in the checkout flow
The source crypto address(es) from which, when transaction is approved, the cryptocurrency will be sent on the blockchain.
Simplex uses these to run preliminary risk, policy and compliance checks.
required
The crypto address to which sent cryptocurrency will be returned in case of a refund.
required
The identifier you use for the end-user’s account.
Simplex uses account_id
to identify returning users, and to afford them the smoothest possible experience. They won’t need to fill-in nor verify their email or billing information, for example.
Instead of the actual account identifier you may send its hash, or anything else for which the following holds: If I send the same account_id then it’s the same account.
A list of sessions/logins in the account, each with at least an IP and a timestamp.
If the account has more than 200 login events, include the first 100 and the last 100. In particular make sure to include the session in which the account was created.
Simplex uses these for policy and risk purposes, allowing your legitimate users to enjoy the credibility of their online identity.
required
IPv4 of end-user’s device
required
Timestamp of session start
The User-Agent
HTTP header sent by the end-user’s browser
The value of a per-device tracking cookie that is managed by you. That is to say: equal uaid
‘s mean “same end-user device”.
The Accept-Language
HTTP header sent by the end-user’s browser
The first name on the account.
The last name on the account.
A list of account email addresses, starting with the account’s primary email address.
Simplex will never send anything to any of these email addresses, and will never divulge them to a third party.
Specify the primary email address first, followed by any other email addresses associated with the account, such as a secondary recovery email, past email addresses on the account, etc.
Simplex uses these for policy and risk purposes, allowing your legitimate users to enjoy the credibility of their online identity.
A list of account phone numbers, starting with the account’s primary phone number.
Simplex will never call any of these numbers, and will never divulge them to a third party.
Specify the primary phone number first, followed by any other phone numbers associated with the account, such as a recovery phone number, past phone numbers on the account, etc.
Simplex uses these for policy and risk purposes, allowing your legitimate users to enjoy the credibility of their identity.
A list of account mailing addresses, starting with the account’s primary address.
Simplex will never mail anything to any of these mailing addresses, and will never divulge them to a third party.
Specify the primary mailing address first, followed by any other mailing addresses associated with the account.
Simplex uses these for policy and risk purposes, allowing your legitimate users to enjoy the credibility of their identity.
Responses
Body
The identifier for the newly-created transaction. Simplex will use this identifier when referencing the transaction in subsequent API’s.
The URL where the checkout flow will take place. You should direct the end-user’s browser there, in either a new tab, an iframe, or a webview in your app.
In case of an error txn_url
will not be returned.
initiate-sell example, that has all possible fields
POST /v3/initiate-sell HTTP/1.1
Host: api.sandbox.test-simplexcc.com
Authorization: ApiKey XXXXXXXXXX
Content-Type: application/json
{
"referer_url": "https://www.legit-site.com/pay-with-btc",
"return_url": "https://www.legit-site.com/thank-you",
"deep_link": "https://www.legit-site.com/sells/af492cb2-5b07-4318-8ece-be34f479e23b",
"txn_details": {
"quote_id": "bf81cd71-c1a1-4e2e-934b-5e13e1cdf10b",
"source_crypto_addresses": [ "1EmXYy57z71H8J5jrxXsdjuJXZnPZgHnjh" ],
"refund_crypto_address": "1EmXYy57z71H8J5jrxXsdjuJXZnPZgHnjh"
},
"account_details": {
"account_id": "39cb996a-6cc8-43b9-ad37-1102a958ff38",
"web_sessions": [{
"ip": "74.115.209.58",
"timestamp": 1529055882.223,
"user_agent": "Mozilla/5.0 (Acme Laptop) AcmeWebKit/128 (KHTML, like Gecko) Chrome/65.0.1024.100",
"uaid": "VHJhY2tpbmdDb29raWU",
"http_accept_language": "en-US,en;q=0.9"
}, {
"ip": "74.115.209.61",
"timestamp": 1536831495.900,
"user_agent": "Mozilla/5.0 (Acme Laptop) AcmeWebKit/128 (KHTML, like Gecko) Chrome/65.0.1024.100",
"uaid": "VHJhY2tpbmdDb29raWU",
"http_accept_language": "en-US,en;q=0.9"
}],
"personal_details": {
"first_name": "Wile",
"last_name": "Coyote",
"emails": [ "wile.e@rr.com" ],
"phones": [ "+16085559103" ],
"addresses": [{
"line1": "42 Desert Road",
"line2": "Apt. 314",
"city": "San Diego",
"zip": "22434",
"country": "US",
"state": "CA"
}]
}
}
}
initiate-sell example, with mandatory fields only
POST /v3/initiate-sell HTTP/1.1
Host: api.sandbox.test-simplexcc.com
Authorization: ApiKey XXXXXXXXXX
Content-Type: application/json
{
"referer_url": "https://www.legit-site.com/pay-with-btc",
"txn_details": {
"quote_id": "2bb6cc44-cc4f-454c-8f48-7d11e0a7f930",
"refund_crypto_address": "1EmXYy57z71H8J5jrxXsdjuJXZnPZgHnjh"
},
"account_details": {
"account_id": "39cb996a-6cc8-43b9-ad37-1102a958ff38"
}
}
{
"txn_id": "6fa39351-db01-43a9-abb6-9b661720b883",
"txn_url": "https://checkout.sandbox.test-simplexcc.com/sell?t=6fa39351-db01-43a9-abb6-9b661720b883"
}
A request from Simplex for you to send cryptocurrency to a specified destination crypto address.
If you are the entity providing liquidity for a Simplex transaction, then after Simplex approves the transaction you will be asked to create a blockchain transaction that will result in the transfer of a specified amount of cryptocurrency to a specified destination crypto address.
In case of a refund, if you are the entity that received the cryptocurrency you will be asked to send it back (albeit to a possibly different crypto address from which it was sent).
This request from Simplex results in you creating an “execution order” process, which on your end is responsible for generating the blockchain transaction.
Your response includes an identifier for this execution order, which Simplex can use to query you about its status.
The status of an execution order may be:
"pending"
: you haven’t yet created the blockchain transaction, but are in the process of doing so."completed"
: you fulfilled the execution order by creating a blockchain transaction."failed"
: there was an error creating the blockchain transaction."reject"
: the request to send crypto was rejected. e.g. The user refused to send crypto
Direction: Simplex → You
p/REST
If you supply a p/REST endpoint for this API, Simplex will use
POST https://${YOUR_API_URL}/send-crypto
MsgQueue
Alternatively, you may receive this request as a message of type "send-crypto"
in
Sandbox URL: GET https://api.sandbox.test-simplexcc.com/v3/msg
Production URL: GET https://api.simplexcc.com/v3/msg
You respond by
POST https://api.simplexcc.com/v3/msg/:msg-id/response
You will need to also acknowledge receipt of the message, by
POST https://api.simplexcc.com/v3/msg/:msg-id/ack
Request body
required
The reason you are sending cryptocurrency.
One of { "delivery"
, "refund"
}.
"delivery"
: you are selling cryptocurrency: you are either the Liquidity Provider (in a BuyCrypto transaction) or the App (in a SellCrypto transaction)"refund"
: the reverse of “delivery” – we need to return, to the original sender, cryptocurrency that you previously received.
required
The identifier of the Simplex transaction involved
required
A unique identifier, created by Simplex, for the end-user performing the transaction.
Same user_id
as a previous message means same end-user.
required
A list of unique identifiers, on top of user_id
, by which the user is also known.
For wallets/exchanges: the end-user’s account id on your system. This is what you sent Simplex in initiate-sell
required
The identifier of the quote on which this transaction is based
required
The crypto currency (the currency, not the amount) to send.
required
How much cryptocurrency of type crypto_currency
to send
required
The destination crypto address to which to send the cryptocurrency.
Responses
Your response is an ExecutionOrder. If its status is "pending"
you will need to later notify Simplex when the status changes. You do this using the execution-order-notify-status
message.
Alternatively, Simplex may poll you for the status, via either p/REST or MsgQueue, using execution-order-get-status
.
Body
required
An opaque string generated by you and stored by Simplex.
You may use this identifier to notify Simplex of the status of the execution order once it changes, and Simplex may use this identifier to query you about the status of the execution order
required
One of { "pending"
, "completed"
, "failed"
}.
required (if status == "completed"
)
The actual amount sent. Must match crypto_amount
from the request unless reason == "refund"
, in which case you may, under previous agreement with Simplex, subtract a reasonable amount for the blockchain transaction fee.
required (if status == "completed"
)
The blockchain transaction hash of the transaction created by you in order to fulfill the execution order.
Examples
{
"execution_order": {
"id": "xo:7791528",
"status": "completed",
"crypto_amount_sent": 125000, // 0.125 BTC
"blockchain_txn_hash": "f1eddb27fced47de0684f913714b43e589f23fbb9ef17ceaa9f75e290f1541af"
}
}
when Simplex sends you a delivery request
{
"reason": "delivery",
"txn_id": "af492cb2-5b07-4318-8ece-be34f479e23b",
"user_id": "595b88bea687c5dd444f99e0004a45d3",
"user_aka_ids": ["1504241c7d83476aa3adcd54e2272d25", "38b583c7ccd246ffaed4ab0232b71647"],
"account_id": "39cb996a-6cc8-43b9-ad37-1102a958ff38",
"quote_id": "bb4fbdef-9abc-41c1-94d9-a670413c4d02",
"crypto_currency": "BTC",
"crypto_amount": 125000, // 0.125 BTC
"destination_crypto_address": "1GzW2M6L54DGMUUv2DTrdPTt8PX6ck5SYp"
}
when you get the message from the message queue
{
"msg_id": "aa31ee25-d768-4b4f-ab69-00ae6795ccc9",
"msg_type": "send-crypto",
"msg": {
"reason": "delivery",
"txn_id": "177997fb-2bed-4936-aab2-c088b8fdf566",
"user_id": "11a447c3280ce22e4dadeaf72da779e6afc8bc7fb0438c5aff80a090f9c60b9f",
"quote_id": "b06e486d-5c07-402e-8a5e-530e8fd29f45",
"account_id": "11ab996a-6cc8-43b9-ad37-1102a958ff38",
"user_aka_ids": [
"aaa00b065da79e2e543c1be41dde374ed8d0f45b67f447967846dcdff40a1b1d",
"11124f2ce2a40092d2f0e190c0e44e5ca88edff08e7347a1297013c6d83987f4"
],
"crypto_amount": 10000,
"crypto_currency": "BTC",
"destination_crypto_address": "1GzW2M6L54DGMUUv2DTrdPTt8PX6ck5SYp"
}
}
A notification, from you to Simplex, that the status of an execution order has changed.
Direction: You → Simplex
Sandbox URL: https://api.sandbox.test-simplexcc.com/v3/execution-order-notify-status
Production URL: https://api.simplexcc.com/v3/execution-order-notify-status
Request body
required
An opaque string generated by you and stored by Simplex.
You may use this identifier to notify Simplex of the status of the execution order once it changes, and Simplex may use this identifier to query you about the status of the execution order
required
One of { "pending"
, "completed"
, "failed"
}.
required (if status == "completed"
)
The actual amount sent. Must match crypto_amount
from the request unless reason == "refund"
, in which case you may, under previous agreement with Simplex, subtract a reasonable amount for the blockchain transaction fee.
required (if status == "completed"
)
The blockchain transaction hash of the transaction created by you in order to fulfill the execution order.
you notifying Simplex of an execution order status change:
{
"execution_order": {
"id": "xo:7791528",
"status": "completed",
"crypto_amount_sent": 125000, // 0.125 BTC
"blockchain_txn_hash": "f1eddb27fced47de0684f913714b43e589f23fbb9ef17ceaa9f75e290f1541af"
}
}
Notifications about major transaction life cycle events.
You can receive notifications when certain events occur during the life cycle of transactions. You might use these notifications for analytics, for example, or for prompting end-users to perform certain actions.
Direction: Simplex → You
p/REST
If you supply a p/REST endpoint for this API, Simplex will use
POST https://${YOUR_API_URL}/txn-event-notify
MsgQueue
Alternatively, you may receive this request as a message of type "txn-event-notify"
in
Sandbox URL: GET https://api.sandbox.test-simplexcc.com/v3/msg
Production URL: GET https://api.simplexcc.com/v3/msg
You need to acknowledge receipt of the message, by
POST https://api.simplexcc.com/v3/msg/:msg-id/ack
You do not need to respond.
Request body
required
Timestamp of when the event occurred.
required
Identifier of the Simplex transaction.
required
The type of event that occurred in the transaction.
One of { "txn-payout"
, "txn-declined"
, "txn-refunded"
}.
"txn-payout"
: The transaction was approved and the payment method was credited (in SellCrypto).
"txn-declined"
: The transaction was declined, for policy or risk reasons. Simplex does not divulge exact reasons to end-users. No fiat has been charged, and any holds on the end-user’s card have been released (some users’ banks may take time to reflect that).
"txn-refunded"
: The transaction has been refunded: fiat money (in a BuyCrypto transaction) or cryptocurrency (in a SellCrypto transaction) has been returned to the end-user.
{
"timestamp": 1537540352.012,
"txn_id": "af492cb2-5b07-4318-8ece-be34f479e23b",
"event": "txn-payout"
}
Successful requests return 200 OK
HTTP status.
On error, the following HTTP status codes may be returned:
Status Code | Description |
---|---|
400 Bad Request |
Invalid request (e.g. invalid parameters) |
401 Unauthorized |
Missing or invalid API key |
404 Not Found |
Invalid URL |
On error, responses will include an _error
top-level field with a short error message. That error message is for debugging purposes only and is not meant to be displayed to end-users.
Successful requests do not return an _error
field.
Base URL
The base URL for REST endpoints you provide for Simplex to invoke is configured in your Simplex account, and is referred to in this document as ${YOUR_API_URL}
.
Simplex will only ever make HTTPS requests, never HTTP.
Authentication
You provide Simplex with a p/REST API key of your own, which Simplex will include as the Authorization
HTTP header with the apikey
authorization scheme in all p/REST API calls it makes.
Parameters
The same semantics hold here as when you invoke Simplex REST API’s.
Simplex will pass parameters to p/REST API’s using a Content-Type
of "application/json"
and using a JSON object in the request body in POST requests, and will use query parameters in GET requests.
Response
The same semantics hold here as when you invoke Simplex REST API’s.
HTTP responses are expected to have a Content-Type
set to "application/json"
and contain a JSON object in the response body.
Errors
The same semantics hold here as when you invoke Simplex REST API’s.
Successful p/REST API calls are expected to return a 200 OK
HTTP status code, while errors are to be signalled with an appropriate HTTP status code and the presence of an _error
top-level field in the JSON response body.
An alternative to p/REST is MsgQueue, which has message queue semantics: you poll Simplex for messages waiting for you, take action on the message if required, respond to the message if required, and then acknowledge your handling of the message so you don’t receive it again.
The base URL for Simplex MsgQueue API’s is:
- sandbox:
https://api.sandbox.test-simplexcc.com/v3/msg
- production:
https://api.simplexcc.com/v3/msg
Polling
You poll for messages by periodically issuing:
GET https://api.simplexcc.com/v3/msg
The response is JSON object with a single "messages"
field containing a list of messages.
Each message has the following fields:
Name | Type | Description |
---|---|---|
msg_id | String (required) | A unique identifier for this message |
msg_type | String (required) | The message type (e.g. "send-crypto" ) |
msg | Object (required) | The message payload itself, as described in the relevant API section |
Responding
If a message requires a response, you respond with
POST https://api.simplexcc.com/v3/msg/:msg-id/response
:msg-id
is the message identifier returned from /msg
, and the POST body contains the response.
Acknowledging
To avoid loss of messages, an explicit acknowledgement from you is required to each message. Until you acknowledge a message you will keep receiving it from /msg
.
To acknowledge that you have handled a particular message and are done with it:
POST https://api.simplexcc.com/v3/msg/:msg-id/ack
:msg-id
is the identifier of the message you are acknowledging. There are no other parameters, so no body is expected in the POST.
Only acknowledge messages after you have completely finished handling them.