TuCOPRamp

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.

text
con_0bdy554f0x9szsmatwdnz8z6gb
PrefixObject
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 a con_ 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:

json
{ "amount": "1250000.00", "asset": "COP" }
AssetDecimalsNotes
COP2Colombian pesos. Bank payouts settle in whole pesos.
USDC6USDC on Celo (eip155:42220).
COPm18Mento 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 number cannot 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.

bash
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 a Deprecation: true response header. They will be removed: move to the paths in these docs.
  • The TuCOPRamp-Version header 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.

bash
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 '{ ... }'
SituationAnswer
Header missing400 idempotency_key_required
Key longer than 255 characters, or with spaces or non-ASCII characters400 idempotency_key_invalid
Same key, same request, first one finishedThe first response again, with Idempotent-Replayed: true
Same key while the first request is still running409 idempotency_in_progress with Retry-After. Retry later with the same key.
Same key with a different body, method or path422 idempotency_key_reuse
First request failed with a 5xxNothing 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.
  • 4xx answers 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-Id with 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.
bash
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.