API conventions
Ids, amounts, versioning, idempotency and errors on the platform API.
These rules apply to the platform API: /consumer, /document-types, /events,
/sessions/*, /parties/*, /destinations, /quotes, /payments, /limits,
/rates, /withdrawals, /deposits, webhook payloads, and every new
endpoint TuCOP adds. The P2P (/p2p/*) endpoints keep the
shapes they have today; their differences are listed in Errors.
Ids
Every object has a public id: a type prefix, an underscore and 26 characters.
con_0bdy554f0x9szsmatwdnz8z6gb
| Prefix | Object |
|---|---|
org_ | Organization |
con_ | Consumer (your app) |
key_ | API key |
pty_ | Party (a person or business you serve) |
dst_ | Destination (a bank account or Bre-B key) |
op_ | Operation (a payment) |
qte_ | Quote |
wdr_ | Withdrawal address |
dep_ | Deposit account |
onr_ | Wallet on-ramp order |
evt_ | Event |
whep_ | Webhook endpoint |
- Treat ids as opaque strings. Store them as text of up to 32 characters.
- TuCOP sends ids in lowercase. It accepts the part after the prefix in any case; the prefix itself must be lowercase.
- An id sent where another type is expected (a
key_id in place of acon_id) is rejected. - Ids of new objects sort in creation order.
Amounts
Amounts are objects with a decimal string and an asset, never JSON numbers:
{ "amount": "1250000.00", "asset": "COP" }
| Asset | Decimals | Notes |
|---|---|---|
COP | 2 | Colombian pesos. Bank payouts settle in whole pesos. |
USDC | 6 | USDC on Celo (eip155:42220). |
COPm | 18 | Mento COP on Celo (eip155:42220). |
- The string always has exactly as many decimals as the asset:
"1250000.00", not"1250000". - Parse it with a decimal library or as an integer number of base units. A JavaScript
numbercannot hold COPm amounts exactly. - Send amounts in the same form. A value with more decimals than the asset has is rejected, not rounded.
The P2P endpoints use plain numbers for whole COP amounts (gross_amount_cop: 500000). They keep
doing so.
Versioning
TuCOP runs one version of the API, so paths carry no version and there is no version header to send.
curl https://sandbox.api.ramp.tucop.xyz/consumer \
--header "X-TuCOPRamp-Key: $TUCOPRAMP_API_KEY"
- Paths used to start with
/v1. Those paths still work for now and are answered exactly the same, with aDeprecation: trueresponse header. They will be removed: move to the paths in these docs. - The
TuCOPRamp-Versionheader is no longer needed. Stop sending it. - Adding a field, an endpoint, an event type or an error code is not a breaking change. Ignore fields you do not know.
Idempotency
Every platform POST and PATCH needs an Idempotency-Key header, except the party session endpoints
(/sessions/*): they exchange a one-time code or signature for a session token, and a stored
response would keep that token. See Parties. Generate a new random value, such as a
UUID, for each operation, and reuse it only when you retry that same operation.
curl https://sandbox.api.ramp.tucop.xyz/<resource> \
--request POST \
--header "X-TuCOPRamp-Key: $TUCOPRAMP_API_KEY" \
--header "Idempotency-Key: 7b8f2f4e-0a7c-4d55-9a8e-3c1f9e0d2b61" \
--header "Content-Type: application/json" \
--data '{ ... }'
| Situation | Answer |
|---|---|
| Header missing | 400 idempotency_key_required |
| Key longer than 255 characters, or with spaces or non-ASCII characters | 400 idempotency_key_invalid |
| Same key, same request, first one finished | The first response again, with Idempotent-Replayed: true |
| Same key while the first request is still running | 409 idempotency_in_progress with Retry-After. Retry later with the same key. |
| Same key with a different body, method or path | 422 idempotency_key_reuse |
First request failed with a 5xx | Nothing is stored. A retry with the same key runs again. |
- Keys belong to your consumer and environment. Another consumer's key never collides with yours.
- On endpoints that take a party session, the key is also tied to the session: the same key sent
with another session, or without one, gets
422 idempotency_key_reuse. - Keys are kept 24 hours. After that the same key starts a new operation.
4xxanswers are stored and replayed like successes. Fix the request and use a new key.- The body is compared as JSON: the order of fields does not matter.
Request ids
Every response, success or error, carries an X-Request-Id header. Error bodies repeat it as
request_id.
- To choose it yourself, send
X-Request-Idwith a UUID. TuCOP uses yours and returns it. A value that is not a UUID is ignored and TuCOP creates one. - Use a new value for each request, and log it next to the call in your own system. Otherwise store the one TuCOP returns.
- When you ask TuCOP about a request, give its request id. It is how TuCOP finds that exact request.
curl https://sandbox.api.ramp.tucop.xyz/consumer \
--header "X-TuCOPRamp-Key: $TUCOPRAMP_API_KEY" \
--header "X-Request-Id: 2c4e6a8b-0d1f-4a3b-9c5d-7e9f1a2b3c4d"
Errors
Errors are application/problem+json (RFC 7807) with a code to branch on. See
Errors.