API reference
TuCOPRamp API 1.0.0. Generated from the public OpenAPI file. For the request flow, start with the Quickstart.
TuCOPRamp is the TuCOP service that partner apps call to move between COPm (Mento COP on Celo) and Colombian pesos (COP).
Consumer and platform endpoints require a consumer API key in the X-TuCOPRamp-Key header (or as Authorization: Bearer). All keys of one integrator share a budget of 1,000 requests per minute; GET /rates also allows 120 per minute. A read-only key may only send GET requests.
Errors use the Error schema (RFC 7807, application/problem+json). Match on code.
Endpoints that act for a person (/parties, /destinations, /quotes, /payments, /limits, /withdrawals, /deposits) require a party session in the X-TuCOPRamp-Party-Session header, opened with /sessions. When TuCOP has linked your integrator's own payments provider account, /destinations, /quotes, /payments, /limits, /withdrawals and /deposits also accept the API key alone, without a party session, and act for the party that holds that account. POST /parties always needs a party session. GET /rates needs only the consumer key.
Platform endpoints (/consumer, /document-types, /events, /sessions, /parties, /destinations, /quotes, /payments, /limits, /rates, /withdrawals, /deposits) also follow the API contract: public ids such as con_..., amounts as decimal strings with an asset and, on POST, a required Idempotency-Key (except /sessions).
Paths carry no version. The older /v1/... form of every path still works for now, answered the same way with a Deprecation: true header; move to the paths shown here.
Servers
https://sandbox.api.ramp.tucop.xyz- sandbox (test keys, payments provider sandbox)
Endpoints
Consumer
The consumer and API key making the request.
Get the consumer for the calling API key
GET/consumer
Return the consumer the API key belongs to, the products and scopes it has, and which key and environment were used. Use it to check that a key works. Consumer key only.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Responses
200The calling consumer
application/jsonConsumerWhoAmIResponseName Type Description consumerrequiredobject api_keyrequiredobject | null The key used for this request. Null for tcr_<64 hex>keys.400api_key_conflict (X-TuCOPRamp-Key and Authorization carry different keys) or invalid_api_version (unknown TuCOPRamp-Version)
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing, invalid, expired or revoked consumer key
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403api_key_ip_not_allowed (the key is limited to other IP ranges) or api_key_origin_not_allowed (an older pk key limited to other origins)
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response example
{
"consumer": {
"id": "con_01j9z3k8q2m4n6p8r0s2t4v6w8",
"name": "acme-wallet",
"products": [
"pay",
"withdraw"
],
"services": {
"on_off_ramp": [
"pay",
"withdraw"
],
"p2p": []
},
"scopes": [
"wallet.read",
"wallet.write"
]
},
"api_key": {
"id": "key_01j9z3k8q2m4n6p8r0s2t4v6w8",
"public_id": "AbCdEfGhIjKlMnOp"
}
}Put together from the field examples in the spec. Fields without an example are left out.
List the identity documents accepted for a country
GET/document-types
Colombia answers TuCOP types with their own rules. Other countries answer the list the payments provider publishes for that country plus the types it accepts for any non-US country, checked for shape only. Consumer key only. Static data, cacheable for an hour.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
countryrequired | query | string | ISO 3166-1 alpha-3 code. |
party_type | query | string: individual, business | Defaults to individual. |
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Responses
200Accepted document types
application/jsonDocumentTypesResponseName Type Description countryrequiredstring ISO 3166-1 alpha-3 code. country_namerequiredstring party_typerequiredstring: individual, business document_typesrequiredarray of object 400invalid_country (not an ISO 3166-1 alpha-3 code), invalid_party_type, api_key_conflict or invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing, invalid, expired or revoked consumer key
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response example
{
"country": "COL",
"country_name": "Colombia",
"document_types": [
{
"code": "CC",
"name": "Cedula de ciudadania",
"hint": "1 a 10 digitos"
}
]
}Put together from the field examples in the spec. Fields without an example are left out.
Events
Your event feed: the events webhooks deliver, by sequence number.
List your events
GET/events
Your events, oldest first, after a sequence number. The same events webhooks deliver, so you can catch up after downtime or poll instead of receiving webhooks. Store next_after and ask again with it: an event that committed late gets a higher seq than anything already returned, so nothing is skipped. Consumer key only.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
after | query | integer | null | Return events with a higher seq. Default 0. |
limit | query | integer | Page size, 1 to 200. Default 50. |
category | query | string: on_off_ramp, p2p, platform | Only the events of one service category. |
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Responses
200A page of events
application/jsonEventsPageName Type Description datarequiredarray of Event next_afterrequiredinteger Pass as afterto get the next page. Equal toafterwhendatais empty.has_morerequiredboolean 400invalid_query, or invalid_api_version (unknown TuCOPRamp-Version)
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing, invalid, expired or revoked consumer key
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403api_key_ip_not_allowed (the key is limited to other IP ranges) or api_key_origin_not_allowed (an older pk key limited to other origins)
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response example
{
"data": [
{
"id": "evt_01j9z3k8q2m4n6p8r0s2t4v6w8",
"seq": 1842,
"type": "ping",
"category": "platform",
"api_version": "2026-10-08"
}
]
}Put together from the field examples in the spec. Fields without an example are left out.
Sessions
Party sessions: the person using your app proves an email (code) or a wallet (signature).
Send a sign-in code to an email
POST/sessions/email-otp
Emails a 6-digit code, valid 10 minutes, to the person using your app. The answer is the same whether or not the email is known. Limited to 3 codes per email per 15 minutes. No Idempotency-Key: this is a credential exchange, see the Parties guide. Consumer key only.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Request bodyrequired
| Name | Type | Description |
|---|---|---|
emailrequired | string (email) |
Responses
202Code sent
application/jsonobjectName Type Description expires_atrequiredstring (date-time) 400invalid_body or invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing, invalid, expired or revoked consumer key
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403product_not_enabled (the key has no On/Off Ramp service: withdraw, pay, collect or deposit;
categoryon_off_ramp), api_key_ip_not_allowed (the key is limited to other IP ranges), api_key_origin_not_allowed (an older pk key limited to other origins) or api_key_scope_missing (a read-only key on a request that changes something)application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429rate_limited_email or rate_limited_consumer. See Retry-After.
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.502email_not_sent
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Request example
{
"email": "ana@example.com"
}Put together from the field examples in the spec. Fields without an example are left out.
Exchange an email code for a party session
POST/sessions/email-otp/verify
Checks the newest code sent to this email through your consumer. A code sent through another consumer is not accepted. Five wrong tries spend a code. Consumer key only.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Request bodyrequired
| Name | Type | Description |
|---|---|---|
emailrequired | string (email) | |
coderequired | string |
Responses
201Session opened
application/jsonPartySessionName Type Description tokenrequiredstring Send it in the X-TuCOPRamp-Party-Session header. Shown once; TuCOP keeps only its hash. methodrequiredstring: email_otp, wallet, google expires_atrequiredstring (date-time) One hour after it was issued. party_idrequiredPartyPublicId & string | null 400invalid_body or invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401invalid_code (wrong, used or expired), or an invalid consumer key
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403product_not_enabled (the key has no On/Off Ramp service: withdraw, pay, collect or deposit;
categoryon_off_ramp), api_key_ip_not_allowed (the key is limited to other IP ranges), api_key_origin_not_allowed (an older pk key limited to other origins) or api_key_scope_missing (a read-only key on a request that changes something)application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429rate_limited_email or rate_limited_consumer. See Retry-After.
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Request example
{
"email": "ana@example.com",
"code": "493027"
}Put together from the field examples in the spec. Fields without an example are left out.
Response example
{
"token": "tps_q1Xn0d3S2m6v9bK8aP4tZr7wYc5eH1jL0uG2fN3sD8o"
}Put together from the field examples in the spec. Fields without an example are left out.
Get a message for a wallet to sign
POST/sessions/wallet/nonce
Returns a nonce and the exact message the wallet signs with EIP-191 (personal_sign). The message names your consumer, the wallet, the chain, the nonce and its expiry (5 minutes). Sign message as returned, without changing it. Consumer key only.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Request bodyrequired
| Name | Type | Description |
|---|---|---|
addressrequired | string | |
chain_id | integer | Only 42220 (Celo) is accepted. Default 42220. |
Responses
201Nonce issued
application/jsonobjectName Type Description noncerequiredstring messagerequiredstring chain_idrequiredinteger expires_atrequiredstring (date-time) 400invalid_body or invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing, invalid, expired or revoked consumer key
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403product_not_enabled (the key has no On/Off Ramp service: withdraw, pay, collect or deposit;
categoryon_off_ramp), api_key_ip_not_allowed (the key is limited to other IP ranges), api_key_origin_not_allowed (an older pk key limited to other origins) or api_key_scope_missing (a read-only key on a request that changes something)application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.422chain_not_supported
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429rate_limited_wallet or rate_limited_consumer. See Retry-After.
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Request example
{
"chain_id": 42220
}Put together from the field examples in the spec. Fields without an example are left out.
Response example
{
"nonce": "9f2c4b1e0a7d4c3b8e6f5a4d3c2b1a09",
"message": "TuCOPRamp party session\nConsumer: con_01j9z3k8q2m4n6p8r0s2t4v6w8\nWallet: 0x8f51dc0791cdddce08052fff939eb7cf0c17856\nChain ID: 42220\nNonce: 9f2c4b1e0a7d4c3b8e6f5a4d3c2b1a09\nExpires: 2026-10-08T15:05:00.000Z"
}Put together from the field examples in the spec. Fields without an example are left out.
Exchange a wallet signature for a party session
POST/sessions/wallet
Verifies the EIP-191 signature of the message from POST /sessions/wallet/nonce. A nonce is used once and only by the consumer it was issued to. EOA signatures only. Consumer key only.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Request bodyrequired
| Name | Type | Description |
|---|---|---|
addressrequired | string | |
noncerequired | string | |
signaturerequired | string |
Responses
201Session opened
application/jsonPartySessionName Type Description tokenrequiredstring Send it in the X-TuCOPRamp-Party-Session header. Shown once; TuCOP keeps only its hash. methodrequiredstring: email_otp, wallet, google expires_atrequiredstring (date-time) One hour after it was issued. party_idrequiredPartyPublicId & string | null 400invalid_body or invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401nonce_invalid (unknown, used, expired or issued to another consumer), signature_invalid, or an invalid consumer key
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403product_not_enabled (the key has no On/Off Ramp service: withdraw, pay, collect or deposit;
categoryon_off_ramp), api_key_ip_not_allowed (the key is limited to other IP ranges), api_key_origin_not_allowed (an older pk key limited to other origins) or api_key_scope_missing (a read-only key on a request that changes something)application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429rate_limited_consumer. See Retry-After.
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response example
{
"token": "tps_q1Xn0d3S2m6v9bK8aP4tZr7wYc5eH1jL0uG2fN3sD8o"
}Put together from the field examples in the spec. Fields without an example are left out.
Get a nonce for Google sign-in (TuCOP sites)
POST/sessions/google/nonce
For TuCOP's own sites. Returns a nonce and the Google OAuth client id to sign in with. Put the nonce in the Google sign-in request; the ID token Google returns carries it. Google only runs this client on pages TuCOP registered, so integrators open sessions with the email code or the wallet signature. Valid 10 minutes. Consumer key only.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Request body
Responses
201Nonce issued
application/jsonobjectName Type Description noncerequiredstring client_idrequiredstring expires_atrequiredstring (date-time) 400invalid_body or invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing, invalid, expired or revoked consumer key
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403product_not_enabled (the key has no On/Off Ramp service: withdraw, pay, collect or deposit;
categoryon_off_ramp), api_key_ip_not_allowed (the key is limited to other IP ranges), api_key_origin_not_allowed (an older pk key limited to other origins) or api_key_scope_missing (a read-only key on a request that changes something)application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429rate_limited_consumer. See Retry-After.
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.503google_sign_in_unavailable
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response example
{
"nonce": "9f2c4b1e0a7d4c3b8e6f5a4d3c2b1a09"
}Put together from the field examples in the spec. Fields without an example are left out.
Exchange a Google ID token for a party session (TuCOP sites)
POST/sessions/google
Verifies the Google ID token (signature, issuer, expiry, audience) and the nonce from POST /sessions/google/nonce, used once and only by the consumer it was issued to. Google must have verified the email. The session proves that email, like an email code. Consumer key only.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Request bodyrequired
| Name | Type | Description |
|---|---|---|
id_tokenrequired | string |
Responses
201Session opened
application/jsonPartySessionName Type Description tokenrequiredstring Send it in the X-TuCOPRamp-Party-Session header. Shown once; TuCOP keeps only its hash. methodrequiredstring: email_otp, wallet, google expires_atrequiredstring (date-time) One hour after it was issued. party_idrequiredPartyPublicId & string | null 400invalid_body or invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401id_token_invalid, nonce_invalid (unknown, used, expired or issued to another consumer), email_not_verified, or an invalid consumer key
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403product_not_enabled (the key has no On/Off Ramp service: withdraw, pay, collect or deposit;
categoryon_off_ramp), api_key_ip_not_allowed (the key is limited to other IP ranges), api_key_origin_not_allowed (an older pk key limited to other origins) or api_key_scope_missing (a read-only key on a request that changes something)application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429rate_limited_consumer. See Retry-After.
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.503google_sign_in_unavailable
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response example
{
"token": "tps_q1Xn0d3S2m6v9bK8aP4tZr7wYc5eH1jL0uG2fN3sD8o"
}Put together from the field examples in the spec. Fields without an example are left out.
Sign out: revoke the party session
DELETE/sessions/current
Revokes the session sent in X-TuCOPRamp-Party-Session at once; later calls with it get 401 party_session_invalid. Only the consumer that opened the session can revoke it. Answers 204 whether or not there was a live session to revoke, so it can be called on every sign-out.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Responses
204Signed out
401party_session_required (header missing) or an invalid consumer key
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403product_not_enabled (the key has no On/Off Ramp service: withdraw, pay, collect or deposit;
categoryon_off_ramp), api_key_ip_not_allowed (the key is limited to other IP ranges), api_key_origin_not_allowed (an older pk key limited to other origins) or api_key_scope_missing (a read-only key on a request that changes something)application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429rate_limited_consumer. See Retry-After.
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Parties
The person behind a party session: identity verification status and the instruments you may see.
Create or link the session's party
POST/parties
Creates the party for the person in the party session and starts identity verification (201), or links the party that already holds the document to your consumer (200). An existing party is linked only when the session's email or wallet is already attached to it; otherwise the answer is 409 party_identity_not_proven, which TuCOP reviews. Consumer key, party session and Idempotency-Key.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Idempotency-Keyrequired | header | IdempotencyKey | Unique key for this operation, for example a UUID. Retrying with the same key and body returns the first response; a different body gets 422 idempotency_key_reuse; a retry while the first is running gets 409 idempotency_in_progress. Kept 24 hours. |
Request bodyrequired
| Name | Type | Description |
|---|---|---|
typerequired | string: individual, business | individual (verified with hosted KYC) or business (verified with hosted KYB). |
country | string | ISO 3166-1 alpha-3 code of the country that issued the document. Defaults to COL. |
legal_name | string | A business: its registered name (required). An individual: the full legal name, at least two words, when first_names and last_names are not sent. |
first_names | string | Individuals: given names as on the document. Sent together with last_names; preferred over legal_name. |
last_names | string | Individuals: surnames as on the document. Sent together with first_names. |
nationality | string | ISO 3166-1 alpha-3. Can differ from country, which is the document issuer: a foreigner with a Colombian cedula de extranjeria has nationality VEN and country COL. Unknown code: 400 invalid_nationality. |
document_typerequired | string | One of the codes GET /document-types lists for country and type. Colombia: CC, CE, NUIP, PAS (individual) or NIT (business). TI is not accepted. Other countries: the payments provider's code, for example cpf for Brazil. |
document_numberrequired | string | Dots, spaces and dashes are ignored. A Colombian NIT may carry its check digit after a dash (900123456-8); when it does, the digit must be right. |
consentrequired | object | |
email | string (email) | Contact email for identity verification. Only used when the session was opened with a wallet and the party has no verified email. Not attached to the party. |
redirect_url | string (uri) | Where the person returns after identity verification. Must be one of the return URLs TuCOP has on file for your consumer. |
Responses
200The existing party, now linked to your consumer
application/jsonPartyResponseName Type Description partyrequiredParty A person or a business served through your consumer. 201Party created
application/jsonPartyResponseName Type Description partyrequiredParty A person or a business served through your consumer. 400invalid_body, invalid_country, invalid_document, invalid_name, invalid_consent, invalid_api_version, idempotency_key_required or idempotency_key_invalid
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401party_session_required (also with the API key alone: creating or linking a party always needs a party session), party_session_invalid, or an invalid consumer key
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403product_not_enabled (the key has no On/Off Ramp service: withdraw, pay, collect or deposit;
categoryon_off_ramp), api_key_ip_not_allowed (the key is limited to other IP ranges), api_key_origin_not_allowed (an older pk key limited to other origins) or api_key_scope_missing (a read-only key on a request that changes something)application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.409party_identity_not_proven or idempotency_in_progress
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.422email_required, redirect_url_not_allowed or idempotency_key_reuse
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429rate_limited_party_session. See Retry-After.
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.502provider_unavailable. Retry with the same Idempotency-Key.
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Request example
{
"country": "COL",
"legal_name": "Empresa Ejemplo SAS",
"first_names": "Ana Maria",
"last_names": "Perez Gomez",
"nationality": "COL",
"document_type": "CC",
"document_number": "1017123456",
"consent": {
"version": "2026-10-08"
}
}Put together from the field examples in the spec. Fields without an example are left out.
Response examples
{
"party": {
"id": "pty_01j9z3k8q2m4n6p8r0s2t4v6w8",
"country": "COL"
}
}Put together from the field examples in the spec. Fields without an example are left out.
{
"party": {
"id": "pty_01j9z3k8q2m4n6p8r0s2t4v6w8",
"country": "COL"
}
}Put together from the field examples in the spec. Fields without an example are left out.
Get the session's party
GET/parties/me
Status, endorsements and the instruments your consumer may see. While verification is moving, the status is re-read from the provider (at most every 10 seconds). Consumer key and party session.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Responses
200The party
application/jsonPartyMeName Type Description partyrequiredParty A person or a business served through your consumer. instrumentsrequiredobject Instruments your consumer may see: destinations it created and the party's own (first-party) destinations. Empty while the party is restricted. 400invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401party_session_required, party_session_invalid, or an invalid consumer key
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403party_required (the session has no party linked to your consumer yet), product_not_enabled (no On/Off Ramp service;
categoryon_off_ramp), api_key_ip_not_allowed or api_key_origin_not_allowedapplication/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response example
{
"party": {
"id": "pty_01j9z3k8q2m4n6p8r0s2t4v6w8",
"country": "COL"
},
"instruments": {
"destinations": [
{
"id": "dst_01j9z3k8q2m4n6p8r0s2t4v6w8",
"key_masked": "****4567",
"bank": "Bancolombia"
}
]
}
}Put together from the field examples in the spec. Fields without an example are left out.
Destinations
Bre-B keys a party pays to (third party) or is paid at (first party), verified against the Bre-B directory.
List destinations
GET/destinations
The party's destinations your consumer can see: those it created and the party's first-party ones. Newest first, a page at a time: limit (1 to 100, default 100) and starting_after (the last id of the previous page); has_more says whether there is another page. Deleted destinations are left out unless include_disabled=true; they then come with active: false and disabled_at.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
include_disabled | query | string: true, false | true also returns deleted destinations (active: false). Default false. |
limit | query | integer | Page size, 1 to 100. Default 100. |
starting_after | query | string | A destination id: return the destinations after it (the last id of the previous page). |
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Responses
200Destinations
application/jsonDestinationListName Type Description datarequiredarray of Destination has_morerequiredboolean 400invalid_query or invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing or invalid consumer key, party_session_required (no session, and TuCOP has not linked a payments provider account to your integrator) or party_session_invalid
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403party_required (the session has no party linked to your consumer yet), party_not_linked, party_restricted, product_not_enabled, integrator_customer_mismatch (your integrator pays from its own payments provider account and the session is for another party), or an API key restriction
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.409integrator_not_linked (no session sent, and the payments provider account TuCOP set for your integrator is not linked to it yet)
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response example
{
"data": [
{
"id": "dst_01j9z3k8q2m4n6p8r0s2t4v6w8",
"key_masked": "****4567",
"owner_name": "Carlos Ruiz"
}
]
}Put together from the field examples in the spec. Fields without an example are left out.
Register a Bre-B key
POST/destinations
Registers a Bre-B key for the session's party. When the party already has it (first_party: same key; third_party: same key added by your consumer) the existing destination is returned with 200; that includes a deleted first-party destination that had a withdrawal address, which comes back active. Otherwise TuCOP creates the account with the payments provider and answers 202 with status pending; the Bre-B directory answers in about a minute and the result arrives as destination.verified or destination.rejected, or by polling GET /destinations/{id}. first_party passes only when the directory matches, the holder is the party's KYC'd name and the holder document is the party's. third_party with owner_name passes when the directory matches. third_party without owner_name is a key lookup: it passes when the directory resolves the key to a holder, and is rejected with directory_no_match when it finds none. Either way, confirm a third-party destination (POST /destinations/{id}/confirm) after showing holder to the payer; payments need it. Rejected accounts are deleted at the payments provider. There is no limit on how many destinations a party has.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Idempotency-Keyrequired | header | IdempotencyKey | Unique key for this operation, for example a UUID. Retrying with the same key and body returns the first response; a different body gets 422 idempotency_key_reuse; a retry while the first is running gets 409 idempotency_in_progress. Kept 24 hours. |
Request bodyrequired
| Name | Type | Description |
|---|---|---|
ownershiprequired | string: first_party, third_party | third_party: someone the party pays (needs the pay product). first_party: the party's own account (needs the withdraw product). |
bre_b_keyrequired | string | The Bre-B key, in the format of its type: mobile number (10 digits starting with 3, no +57), document number (up to 18 letters or digits), email, alphanumeric key (@ and 5 to 20 letters or digits) or merchant code (10 digits starting with 00). Taken in lower case, and a mobile number without +57; anything else gets invalid_bre_b_key. Never stored; only a hash and the masked key are kept. |
owner_name | string | Holder name, at least two words. Optional for third_party: leave it out to look the key up, and the directory's holder (name, bank, document last 4) is returned in holder once verified. When sent, the directory also checks it loosely, as before. Ignored for first_party. |
Responses
200The destination already existed
application/jsonDestinationName Type Description idrequiredDestinationPublicId Public id of a destination: dst_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.ownershiprequiredstring: first_party, third_party railrequiredstring: bre_b statusrequiredstring: pending, verified, rejected pendinguntil the Bre-B directory answers (about a minute), thenverifiedorrejected. Each change is also sent asdestination.verifiedordestination.rejected.key_maskedrequiredstring | null owner_namerequiredstring | null Holder name sent to the payments provider: the payer's input for third_party, the KYC'd name for first_party. nullfor a key lookup (third_party created withoutowner_name): the holder comes from the Bre-B directory inholder.holderrequiredobject | null What the Bre-B directory returned. Only on verified. Show it to the payer before they confirm a third-party destination. For a key lookup this is how the payer learns who holds the key.rejection_reasonrequiredstring | null: directory_no_match, holder_name_mismatch, holder_document_mismatch, verification_timeout, directory_unavailable verified_atrequiredstring | null (date-time) confirmed_atrequiredstring | null (date-time) When the payer confirmed the holder. Payments need it on third_party. activerequiredboolean falseonce the destination was deleted (DELETE /destinations/{id}). A deleted destination is only returned by GET /destinations/{id} and by GET /destinations?include_disabled=true, and cannot be paid or withdrawn to.statusstays the verification status.disabled_atrequiredstring | null (date-time) When the destination was deleted. Null while active. created_atrequiredstring (date-time) updated_atrequiredstring (date-time) 202Created; verification in progress
application/jsonDestinationName Type Description idrequiredDestinationPublicId Public id of a destination: dst_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.ownershiprequiredstring: first_party, third_party railrequiredstring: bre_b statusrequiredstring: pending, verified, rejected pendinguntil the Bre-B directory answers (about a minute), thenverifiedorrejected. Each change is also sent asdestination.verifiedordestination.rejected.key_maskedrequiredstring | null owner_namerequiredstring | null Holder name sent to the payments provider: the payer's input for third_party, the KYC'd name for first_party. nullfor a key lookup (third_party created withoutowner_name): the holder comes from the Bre-B directory inholder.holderrequiredobject | null What the Bre-B directory returned. Only on verified. Show it to the payer before they confirm a third-party destination. For a key lookup this is how the payer learns who holds the key.rejection_reasonrequiredstring | null: directory_no_match, holder_name_mismatch, holder_document_mismatch, verification_timeout, directory_unavailable verified_atrequiredstring | null (date-time) confirmed_atrequiredstring | null (date-time) When the payer confirmed the holder. Payments need it on third_party. activerequiredboolean falseonce the destination was deleted (DELETE /destinations/{id}). A deleted destination is only returned by GET /destinations/{id} and by GET /destinations?include_disabled=true, and cannot be paid or withdrawn to.statusstays the verification status.disabled_atrequiredstring | null (date-time) When the destination was deleted. Null while active. created_atrequiredstring (date-time) updated_atrequiredstring (date-time) 400invalid_body, invalid_bre_b_key, invalid_owner_name, idempotency_key_required, idempotency_key_invalid or invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing or invalid consumer key, party_session_required (no session, and TuCOP has not linked a payments provider account to your integrator) or party_session_invalid
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403party_required (the session has no party linked to your consumer yet), party_not_linked, party_restricted, product_not_enabled, integrator_customer_mismatch (your integrator pays from its own payments provider account and the session is for another party), or an API key restriction
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.409party_not_verified, kyc_name_missing (first_party, KYC name not available yet), first_party_not_available (first_party for a party that stands for a payments provider account linked by TuCOP: it has no identity document to match; use pay for third-party keys), destination_conflict (the same key is being registered by another request; retry), holder_name_mismatch (third_party: the key was already looked up and its holder does not match owner_name; includes destination_id), destination_already_registered (the key is already registered on this payments provider account and could not be matched to one; list destinations or contact TuCOP), destination_limit_reached (first_party: the person already has as many active first-party keys registered by this integrator as allowed: the lower of the limit the integrator sets in its console and a maximum TuCOP may set for the integrator; none by default. The detail says which applies; delete one first), integrator_not_linked or idempotency_in_progress
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.422destination_invalid (the payments provider refused the key) or idempotency_key_reuse
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Request example
{
"bre_b_key": "3001234567",
"owner_name": "Carlos Ruiz"
}Put together from the field examples in the spec. Fields without an example are left out.
Response examples
{
"id": "dst_01j9z3k8q2m4n6p8r0s2t4v6w8",
"key_masked": "****4567",
"owner_name": "Carlos Ruiz"
}Put together from the field examples in the spec. Fields without an example are left out.
{
"id": "dst_01j9z3k8q2m4n6p8r0s2t4v6w8",
"key_masked": "****4567",
"owner_name": "Carlos Ruiz"
}Put together from the field examples in the spec. Fields without an example are left out.
Get a destination
GET/destinations/{id}
Returns the destination, also after it was deleted (active: false), so you can still show it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | DestinationPublicId | Public id of a destination: dst_ followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively. |
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Responses
200The destination
application/jsonDestinationName Type Description idrequiredDestinationPublicId Public id of a destination: dst_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.ownershiprequiredstring: first_party, third_party railrequiredstring: bre_b statusrequiredstring: pending, verified, rejected pendinguntil the Bre-B directory answers (about a minute), thenverifiedorrejected. Each change is also sent asdestination.verifiedordestination.rejected.key_maskedrequiredstring | null owner_namerequiredstring | null Holder name sent to the payments provider: the payer's input for third_party, the KYC'd name for first_party. nullfor a key lookup (third_party created withoutowner_name): the holder comes from the Bre-B directory inholder.holderrequiredobject | null What the Bre-B directory returned. Only on verified. Show it to the payer before they confirm a third-party destination. For a key lookup this is how the payer learns who holds the key.rejection_reasonrequiredstring | null: directory_no_match, holder_name_mismatch, holder_document_mismatch, verification_timeout, directory_unavailable verified_atrequiredstring | null (date-time) confirmed_atrequiredstring | null (date-time) When the payer confirmed the holder. Payments need it on third_party. activerequiredboolean falseonce the destination was deleted (DELETE /destinations/{id}). A deleted destination is only returned by GET /destinations/{id} and by GET /destinations?include_disabled=true, and cannot be paid or withdrawn to.statusstays the verification status.disabled_atrequiredstring | null (date-time) When the destination was deleted. Null while active. created_atrequiredstring (date-time) updated_atrequiredstring (date-time) 400invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing or invalid consumer key, party_session_required (no session, and TuCOP has not linked a payments provider account to your integrator) or party_session_invalid
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403party_required (the session has no party linked to your consumer yet), party_not_linked, party_restricted, product_not_enabled, integrator_customer_mismatch (your integrator pays from its own payments provider account and the session is for another party), or an API key restriction
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.404destination_not_found
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.409integrator_not_linked (no session sent, and the payments provider account TuCOP set for your integrator is not linked to it yet)
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response example
{
"id": "dst_01j9z3k8q2m4n6p8r0s2t4v6w8",
"key_masked": "****4567",
"owner_name": "Carlos Ruiz"
}Put together from the field examples in the spec. Fields without an example are left out.
Delete a destination
DELETE/destinations/{id}
Deletes a destination your consumer created, or a first-party destination of the party. It is kept with active: false and can no longer be paid or withdrawn to. Deleting it again answers 204 and changes nothing. The account is also deleted at the payments provider, except while a withdrawal address (even a disabled one) pays to it: the provider keeps paying out what reaches a disabled address to its key, so that key must stay. A destination with an active withdrawal address cannot be deleted: disable the withdrawal first (DELETE /withdrawals/{id}). To use the key again, register it again with POST /destinations: a key that had a withdrawal address comes back as the same destination (200, same id, still verified) and its address can be re-enabled; any other key gets a new destination.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | DestinationPublicId | Public id of a destination: dst_ followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively. |
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Responses
204Deleted
400invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing or invalid consumer key, party_session_required (no session, and TuCOP has not linked a payments provider account to your integrator) or party_session_invalid
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403party_required (the session has no party linked to your consumer yet), party_not_linked, party_restricted, product_not_enabled, integrator_customer_mismatch (your integrator pays from its own payments provider account and the session is for another party), or an API key restriction
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.404destination_not_found
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.409destination_in_use (a payment in progress or an active withdrawal address uses it; disable the withdrawal first) or integrator_not_linked
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Confirm a verified destination
POST/destinations/{id}/confirm
Records that the payer saw the holder name, bank and document last 4 and confirmed this is the account they mean to pay. Payments to a third-party destination need it. Confirming again returns the destination unchanged.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | DestinationPublicId | Public id of a destination: dst_ followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively. |
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Idempotency-Keyrequired | header | IdempotencyKey | Unique key for this operation, for example a UUID. Retrying with the same key and body returns the first response; a different body gets 422 idempotency_key_reuse; a retry while the first is running gets 409 idempotency_in_progress. Kept 24 hours. |
Request body
Responses
200The confirmed destination
application/jsonDestinationName Type Description idrequiredDestinationPublicId Public id of a destination: dst_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.ownershiprequiredstring: first_party, third_party railrequiredstring: bre_b statusrequiredstring: pending, verified, rejected pendinguntil the Bre-B directory answers (about a minute), thenverifiedorrejected. Each change is also sent asdestination.verifiedordestination.rejected.key_maskedrequiredstring | null owner_namerequiredstring | null Holder name sent to the payments provider: the payer's input for third_party, the KYC'd name for first_party. nullfor a key lookup (third_party created withoutowner_name): the holder comes from the Bre-B directory inholder.holderrequiredobject | null What the Bre-B directory returned. Only on verified. Show it to the payer before they confirm a third-party destination. For a key lookup this is how the payer learns who holds the key.rejection_reasonrequiredstring | null: directory_no_match, holder_name_mismatch, holder_document_mismatch, verification_timeout, directory_unavailable verified_atrequiredstring | null (date-time) confirmed_atrequiredstring | null (date-time) When the payer confirmed the holder. Payments need it on third_party. activerequiredboolean falseonce the destination was deleted (DELETE /destinations/{id}). A deleted destination is only returned by GET /destinations/{id} and by GET /destinations?include_disabled=true, and cannot be paid or withdrawn to.statusstays the verification status.disabled_atrequiredstring | null (date-time) When the destination was deleted. Null while active. created_atrequiredstring (date-time) updated_atrequiredstring (date-time) 400invalid_body, idempotency_key_required or invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing or invalid consumer key, party_session_required (no session, and TuCOP has not linked a payments provider account to your integrator) or party_session_invalid
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403party_required (the session has no party linked to your consumer yet), party_not_linked, party_restricted, product_not_enabled, integrator_customer_mismatch (your integrator pays from its own payments provider account and the session is for another party), or an API key restriction
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.404destination_not_found
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.409destination_not_verified, integrator_not_linked or idempotency_in_progress
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.422idempotency_key_reuse
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response example
{
"id": "dst_01j9z3k8q2m4n6p8r0s2t4v6w8",
"key_masked": "****4567",
"owner_name": "Carlos Ruiz"
}Put together from the field examples in the spec. Fields without an example are left out.
Payments
The pay product: estimate (GET /rates), quote and pay a third-party Bre-B key from USDC on Celo, and read the limits that apply.
Quote a payment or a withdrawal
POST/quotes
pay: prices a payment of amount_cop to a verified third-party destination at the payments provider's current rate. The quote lasts 2 minutes and is used by one payment. withdraw: the USDC to send to the party's liquidation address (POST /withdrawals) so that at least amount_cop reaches its own Bre-B key. Nothing takes a withdraw quote.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Idempotency-Keyrequired | header | IdempotencyKey | Unique key for this operation, for example a UUID. Retrying with the same key and body returns the first response; a different body gets 422 idempotency_key_reuse; a retry while the first is running gets 409 idempotency_in_progress. Kept 24 hours. |
Request bodyrequired
| Name | Type | Description |
|---|---|---|
productrequired | string: pay, withdraw | pay: a verified third-party destination. withdraw: one of the party's own verified (first-party) destinations. |
destination_idrequired | DestinationPublicId | Public id of a destination: dst_ followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively. |
amount_coprequired | Money & any |
Responses
201The quote
application/jsonQuoteName Type Description idrequiredQuotePublicId Public id of a quote: qte_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.productrequiredstring: pay, withdraw destination_idrequiredDestinationPublicId Public id of a destination: dst_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.destination_amountrequiredMoney An amount of one asset. source_amountrequiredMoney & any feesrequiredobject total_amountrequiredMoney & any consumer_fee_walletrequiredstring | null raterequiredobject rounding_moderequiredstring: floor, ceil, down, up, half_up, half_even How every division was rounded. ceil: the payer never sends too little.settlement_timerequiredSettlementTime How long the payout usually takes: after the USDC land on-chain, the pesos usually reach the Bre-B key between min_minutes and max_minutes later. Meanwhile the payment reads awaiting_fundswhile the provider detects the deposit, thenprocessing(a withdrawal payout is in progress); neither is a failure. The status and theoperation.updatedwebhook say when it completed. An expectation, not a guarantee.expires_atrequiredstring (date-time) created_atrequiredstring (date-time) 400invalid_body, invalid_amount, amount_not_settleable (not whole pesos), idempotency_key_required or invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing or invalid consumer key, party_session_required (no session, and TuCOP has not linked a payments provider account to your integrator) or party_session_invalid
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403party_required (the session has no party linked to your consumer yet), party_not_linked, party_restricted, product_not_enabled, integrator_customer_mismatch (your integrator pays from its own payments provider account and the session is for another party), or an API key restriction
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.404destination_not_found
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.409destination_not_verified, party_not_verified, first_party_not_available (withdraw, for a party that stands for a payments provider account linked by TuCOP; use pay for third-party keys), integrator_not_linked or idempotency_in_progress
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.422amount_below_minimum (pay: with
minimum), pay_limit_exceeded (pay: withcheck, one ofper_operation,integrator_day,integrator_month), destination_not_third_party (pay), destination_not_first_party (withdraw) or idempotency_key_reuseapplication/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.502rate_unavailable
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Request example
{
"destination_id": "dst_01j9z3k8q2m4n6p8r0s2t4v6w8",
"amount_cop": {
"amount": "200000.00",
"asset": "COP"
}
}Put together from the field examples in the spec. Fields without an example are left out.
Response example
{
"id": "qte_01j9z3k8q2m4n6p8r0s2t4v6w8",
"destination_id": "dst_01j9z3k8q2m4n6p8r0s2t4v6w8",
"destination_amount": {
"amount": "1250000.00",
"asset": "COP"
},
"source_amount": {
"amount": "1250000.00",
"asset": "COP"
},
"fees": {
"tucop": {
"amount": "1250000.00",
"asset": "COP"
},
"consumer": {
"amount": "1250000.00",
"asset": "COP"
},
"fx_buffer": {
"amount": "1250000.00",
"asset": "COP"
}
},
"total_amount": {
"amount": "1250000.00",
"asset": "COP"
},
"rate": {
"value": "4012.55",
"source": "provider"
},
"settlement_time": {
"min_minutes": 15,
"max_minutes": 30
}
}Put together from the field examples in the spec. Fields without an example are left out.
Create a payment
POST/payments
Takes a quote and creates the payments provider transfer to its destination, which must be a verified third-party destination the payer confirmed. Answers with the deposit instructions: send exactly deposit.amount of USDC on Celo to deposit.address. Status changes arrive as operation.updated.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Idempotency-Keyrequired | header | IdempotencyKey | Unique key for this operation, for example a UUID. Retrying with the same key and body returns the first response; a different body gets 422 idempotency_key_reuse; a retry while the first is running gets 409 idempotency_in_progress. Kept 24 hours. |
Request bodyrequired
| Name | Type | Description |
|---|---|---|
quote_idrequired | QuotePublicId | Public id of a quote: qte_ followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively. |
return_address | string | Wallet the USDC is sent from and returned to on failure. Defaults to the session's wallet. Required when there is no wallet session, for example when you call with the API key alone. The integrator sends it and answers for it. |
Responses
201The payment
application/jsonPaymentName Type Description idrequiredOperationPublicId Public id of an operation: op_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.productrequiredstring: pay statusrequiredstring: creating, awaiting_funds, processing, completed, failed, refunded, canceled awaiting_fundsuntil the payments provider detects the deposit (about 15 minutes after it lands on-chain), thenprocessing, thencompleted. From the deposit landing tocompletedusually takes 15 to 30 minutes (seesettlement_time); it is not a failure.completedmeans the payments provider sent the pesos through Bre-B; Bre-B is instant, so in practice they arrived (the receiving bank's own confirmation is not visible to TuCOP).failed(seeerror_code),refunded(the USDC went back toreturn_address) andcanceled(by you with POST /payments/{id}/cancel, or by TuCOP when no deposit arrived in time; seeerror_code) are final too.creatingonly after a request that failed with 5xx; retry it with the same Idempotency-Key.quote_idrequiredQuotePublicId & string | null destination_idrequiredDestinationPublicId & string | null destination_amountrequiredMoney & object | null source_amountrequiredMoney & object | null feesrequiredobject | null total_amountrequiredMoney & object | null consumer_fee_walletrequiredstring | null depositrequiredobject | null return_addressrequiredstring | null Where the payments provider returns the USDC if the payment fails. error_coderequiredstring | null Why the payment ended without paying. failed:provider_<reason>.canceled:canceled_by_integrator(POST /payments/{id}/cancel),expired_unfunded(no deposit arrived within 30 minutes, so TuCOP canceled it) orprovider_canceled. Null otherwise.settlement_timerequiredSettlementTime How long the payout usually takes: after the USDC land on-chain, the pesos usually reach the Bre-B key between min_minutes and max_minutes later. Meanwhile the payment reads awaiting_fundswhile the provider detects the deposit, thenprocessing(a withdrawal payout is in progress); neither is a failure. The status and theoperation.updatedwebhook say when it completed. An expectation, not a guarantee.created_atrequiredstring (date-time) updated_atrequiredstring (date-time) 400invalid_body, invalid_return_address, idempotency_key_required or invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing or invalid consumer key, party_session_required (no session, and TuCOP has not linked a payments provider account to your integrator) or party_session_invalid
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403party_required (the session has no party linked to your consumer yet), party_not_linked, party_restricted, product_not_enabled, integrator_customer_mismatch (your integrator pays from its own payments provider account and the session is for another party), or an API key restriction
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.404quote_not_found or destination_not_found
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.409quote_expired (also when the rate moved and the quote no longer pays the destination), quote_already_used, destination_not_confirmed, destination_not_verified, party_not_verified, integrator_not_linked or idempotency_in_progress
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.422payment_rejected (the payments provider refused it), return_address_required, amount_below_minimum, pay_limit_exceeded (with
check), destination_not_third_party or idempotency_key_reuseapplication/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.502provider_error
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Request example
{
"quote_id": "qte_01j9z3k8q2m4n6p8r0s2t4v6w8"
}Put together from the field examples in the spec. Fields without an example are left out.
Response example
{
"id": "op_01j9z3k8q2m4n6p8r0s2t4v6w8",
"destination_amount": {
"amount": "1250000.00",
"asset": "COP"
},
"source_amount": {
"amount": "1250000.00",
"asset": "COP"
},
"fees": {
"tucop": {
"amount": "1250000.00",
"asset": "COP"
},
"consumer": {
"amount": "1250000.00",
"asset": "COP"
}
},
"total_amount": {
"amount": "1250000.00",
"asset": "COP"
},
"deposit": {
"address": "0x5b1d7c0a4f2e8b9d6c3a1e0f7b2d4c6a8e9f0b1c",
"chain": "eip155:42220",
"amount": {
"amount": "1250000.00",
"asset": "COP"
}
},
"settlement_time": {
"min_minutes": 15,
"max_minutes": 30
}
}Put together from the field examples in the spec. Fields without an example are left out.
Cancel a payment
POST/payments/{id}/cancel
Cancels a payment that is still creating or awaiting_funds: the payer backed out, or the deposit transaction failed. The payment ends canceled with error_code canceled_by_integrator and operation.updated is sent. Canceling a canceled payment answers it again. Do not send the deposit after canceling: it would not be credited. TuCOP also cancels on its own any payment that got no deposit within 30 minutes (expired_unfunded), unless a deposit of exactly deposit.amount from return_address is already on-chain.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | OperationPublicId | Public id of an operation: op_ followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively. |
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Idempotency-Keyrequired | header | IdempotencyKey | Unique key for this operation, for example a UUID. Retrying with the same key and body returns the first response; a different body gets 422 idempotency_key_reuse; a retry while the first is running gets 409 idempotency_in_progress. Kept 24 hours. |
Responses
200The canceled payment
application/jsonPaymentName Type Description idrequiredOperationPublicId Public id of an operation: op_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.productrequiredstring: pay statusrequiredstring: creating, awaiting_funds, processing, completed, failed, refunded, canceled awaiting_fundsuntil the payments provider detects the deposit (about 15 minutes after it lands on-chain), thenprocessing, thencompleted. From the deposit landing tocompletedusually takes 15 to 30 minutes (seesettlement_time); it is not a failure.completedmeans the payments provider sent the pesos through Bre-B; Bre-B is instant, so in practice they arrived (the receiving bank's own confirmation is not visible to TuCOP).failed(seeerror_code),refunded(the USDC went back toreturn_address) andcanceled(by you with POST /payments/{id}/cancel, or by TuCOP when no deposit arrived in time; seeerror_code) are final too.creatingonly after a request that failed with 5xx; retry it with the same Idempotency-Key.quote_idrequiredQuotePublicId & string | null destination_idrequiredDestinationPublicId & string | null destination_amountrequiredMoney & object | null source_amountrequiredMoney & object | null feesrequiredobject | null total_amountrequiredMoney & object | null consumer_fee_walletrequiredstring | null depositrequiredobject | null return_addressrequiredstring | null Where the payments provider returns the USDC if the payment fails. error_coderequiredstring | null Why the payment ended without paying. failed:provider_<reason>.canceled:canceled_by_integrator(POST /payments/{id}/cancel),expired_unfunded(no deposit arrived within 30 minutes, so TuCOP canceled it) orprovider_canceled. Null otherwise.settlement_timerequiredSettlementTime How long the payout usually takes: after the USDC land on-chain, the pesos usually reach the Bre-B key between min_minutes and max_minutes later. Meanwhile the payment reads awaiting_fundswhile the provider detects the deposit, thenprocessing(a withdrawal payout is in progress); neither is a failure. The status and theoperation.updatedwebhook say when it completed. An expectation, not a guarantee.created_atrequiredstring (date-time) updated_atrequiredstring (date-time) 202The payments provider accepted the cancel and has not confirmed it yet: the payment still reads
awaiting_funds. It endscanceledwithcanceled_by_integratorshortly;operation.updatedsays when. Do not send the deposit.application/jsonPaymentName Type Description idrequiredOperationPublicId Public id of an operation: op_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.productrequiredstring: pay statusrequiredstring: creating, awaiting_funds, processing, completed, failed, refunded, canceled awaiting_fundsuntil the payments provider detects the deposit (about 15 minutes after it lands on-chain), thenprocessing, thencompleted. From the deposit landing tocompletedusually takes 15 to 30 minutes (seesettlement_time); it is not a failure.completedmeans the payments provider sent the pesos through Bre-B; Bre-B is instant, so in practice they arrived (the receiving bank's own confirmation is not visible to TuCOP).failed(seeerror_code),refunded(the USDC went back toreturn_address) andcanceled(by you with POST /payments/{id}/cancel, or by TuCOP when no deposit arrived in time; seeerror_code) are final too.creatingonly after a request that failed with 5xx; retry it with the same Idempotency-Key.quote_idrequiredQuotePublicId & string | null destination_idrequiredDestinationPublicId & string | null destination_amountrequiredMoney & object | null source_amountrequiredMoney & object | null feesrequiredobject | null total_amountrequiredMoney & object | null consumer_fee_walletrequiredstring | null depositrequiredobject | null return_addressrequiredstring | null Where the payments provider returns the USDC if the payment fails. error_coderequiredstring | null Why the payment ended without paying. failed:provider_<reason>.canceled:canceled_by_integrator(POST /payments/{id}/cancel),expired_unfunded(no deposit arrived within 30 minutes, so TuCOP canceled it) orprovider_canceled. Null otherwise.settlement_timerequiredSettlementTime How long the payout usually takes: after the USDC land on-chain, the pesos usually reach the Bre-B key between min_minutes and max_minutes later. Meanwhile the payment reads awaiting_fundswhile the provider detects the deposit, thenprocessing(a withdrawal payout is in progress); neither is a failure. The status and theoperation.updatedwebhook say when it completed. An expectation, not a guarantee.created_atrequiredstring (date-time) updated_atrequiredstring (date-time) 400idempotency_key_required or invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing or invalid consumer key, party_session_required (no session, and TuCOP has not linked a payments provider account to your integrator) or party_session_invalid
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403party_required (the session has no party linked to your consumer yet), party_not_linked, party_restricted, product_not_enabled, integrator_customer_mismatch (your integrator pays from its own payments provider account and the session is for another party), or an API key restriction
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.404payment_not_found
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.409payment_not_cancelable (the deposit arrived or the payment already ended; the error includes
payment), deposit_in_flight (a deposit of exactlydeposit.amountfromreturn_addressis on-chain and the payments provider has not detected it yet; follow the payment) or idempotency_in_progressapplication/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.502provider_unavailable
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response examples
{
"id": "op_01j9z3k8q2m4n6p8r0s2t4v6w8",
"destination_amount": {
"amount": "1250000.00",
"asset": "COP"
},
"source_amount": {
"amount": "1250000.00",
"asset": "COP"
},
"fees": {
"tucop": {
"amount": "1250000.00",
"asset": "COP"
},
"consumer": {
"amount": "1250000.00",
"asset": "COP"
}
},
"total_amount": {
"amount": "1250000.00",
"asset": "COP"
},
"deposit": {
"address": "0x5b1d7c0a4f2e8b9d6c3a1e0f7b2d4c6a8e9f0b1c",
"chain": "eip155:42220",
"amount": {
"amount": "1250000.00",
"asset": "COP"
}
},
"settlement_time": {
"min_minutes": 15,
"max_minutes": 30
}
}Put together from the field examples in the spec. Fields without an example are left out.
{
"id": "op_01j9z3k8q2m4n6p8r0s2t4v6w8",
"destination_amount": {
"amount": "1250000.00",
"asset": "COP"
},
"source_amount": {
"amount": "1250000.00",
"asset": "COP"
},
"fees": {
"tucop": {
"amount": "1250000.00",
"asset": "COP"
},
"consumer": {
"amount": "1250000.00",
"asset": "COP"
}
},
"total_amount": {
"amount": "1250000.00",
"asset": "COP"
},
"deposit": {
"address": "0x5b1d7c0a4f2e8b9d6c3a1e0f7b2d4c6a8e9f0b1c",
"chain": "eip155:42220",
"amount": {
"amount": "1250000.00",
"asset": "COP"
}
},
"settlement_time": {
"min_minutes": 15,
"max_minutes": 30
}
}Put together from the field examples in the spec. Fields without an example are left out.
Get a payment
GET/payments/{id}
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | OperationPublicId | Public id of an operation: op_ followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively. |
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Responses
200The payment
application/jsonPaymentName Type Description idrequiredOperationPublicId Public id of an operation: op_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.productrequiredstring: pay statusrequiredstring: creating, awaiting_funds, processing, completed, failed, refunded, canceled awaiting_fundsuntil the payments provider detects the deposit (about 15 minutes after it lands on-chain), thenprocessing, thencompleted. From the deposit landing tocompletedusually takes 15 to 30 minutes (seesettlement_time); it is not a failure.completedmeans the payments provider sent the pesos through Bre-B; Bre-B is instant, so in practice they arrived (the receiving bank's own confirmation is not visible to TuCOP).failed(seeerror_code),refunded(the USDC went back toreturn_address) andcanceled(by you with POST /payments/{id}/cancel, or by TuCOP when no deposit arrived in time; seeerror_code) are final too.creatingonly after a request that failed with 5xx; retry it with the same Idempotency-Key.quote_idrequiredQuotePublicId & string | null destination_idrequiredDestinationPublicId & string | null destination_amountrequiredMoney & object | null source_amountrequiredMoney & object | null feesrequiredobject | null total_amountrequiredMoney & object | null consumer_fee_walletrequiredstring | null depositrequiredobject | null return_addressrequiredstring | null Where the payments provider returns the USDC if the payment fails. error_coderequiredstring | null Why the payment ended without paying. failed:provider_<reason>.canceled:canceled_by_integrator(POST /payments/{id}/cancel),expired_unfunded(no deposit arrived within 30 minutes, so TuCOP canceled it) orprovider_canceled. Null otherwise.settlement_timerequiredSettlementTime How long the payout usually takes: after the USDC land on-chain, the pesos usually reach the Bre-B key between min_minutes and max_minutes later. Meanwhile the payment reads awaiting_fundswhile the provider detects the deposit, thenprocessing(a withdrawal payout is in progress); neither is a failure. The status and theoperation.updatedwebhook say when it completed. An expectation, not a guarantee.created_atrequiredstring (date-time) updated_atrequiredstring (date-time) 400invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing or invalid consumer key, party_session_required (no session, and TuCOP has not linked a payments provider account to your integrator) or party_session_invalid
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403party_required (the session has no party linked to your consumer yet), party_not_linked, party_restricted, product_not_enabled, integrator_customer_mismatch (your integrator pays from its own payments provider account and the session is for another party), or an API key restriction
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.404payment_not_found
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.409integrator_not_linked (no session sent, and the payments provider account TuCOP set for your integrator is not linked to it yet)
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response example
{
"id": "op_01j9z3k8q2m4n6p8r0s2t4v6w8",
"destination_amount": {
"amount": "1250000.00",
"asset": "COP"
},
"source_amount": {
"amount": "1250000.00",
"asset": "COP"
},
"fees": {
"tucop": {
"amount": "1250000.00",
"asset": "COP"
},
"consumer": {
"amount": "1250000.00",
"asset": "COP"
}
},
"total_amount": {
"amount": "1250000.00",
"asset": "COP"
},
"deposit": {
"address": "0x5b1d7c0a4f2e8b9d6c3a1e0f7b2d4c6a8e9f0b1c",
"chain": "eip155:42220",
"amount": {
"amount": "1250000.00",
"asset": "COP"
}
},
"settlement_time": {
"min_minutes": 15,
"max_minutes": 30
}
}Put together from the field examples in the spec. Fields without an example are left out.
Get effective pay limits
GET/limits
Caps for pay for this integrator, and how much of its calendar month in America/Bogota is already used. TuCOP sets the floor and the monthly ceiling per integrator. The same checks run again when a quote or a payment is created.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Responses
200Effective limits
application/jsonPayLimitsName Type Description payrequiredobject 400invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing or invalid consumer key, party_session_required (no session, and TuCOP has not linked a payments provider account to your integrator) or party_session_invalid
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403party_required (the session has no party linked to your consumer yet), party_not_linked, party_restricted, product_not_enabled, integrator_customer_mismatch (your integrator pays from its own payments provider account and the session is for another party), or an API key restriction
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.409integrator_not_linked (no session sent, and the payments provider account TuCOP set for your integrator is not linked to it yet)
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response example
{
"pay": {
"minimum_per_operation": {
"amount": "1250000.00",
"asset": "COP"
},
"maximum_per_operation": {
"amount": "1250000.00",
"asset": "COP"
},
"integrator_day": {
"limit": {
"amount": "1250000.00",
"asset": "COP"
},
"used": {
"amount": "1250000.00",
"asset": "COP"
},
"remaining": {
"amount": "1250000.00",
"asset": "COP"
}
},
"integrator_month": {
"limit": {
"amount": "1250000.00",
"asset": "COP"
},
"used": {
"amount": "1250000.00",
"asset": "COP"
},
"remaining": {
"amount": "1250000.00",
"asset": "COP"
}
}
}
}Put together from the field examples in the spec. Fields without an example are left out.
Get the current rate and estimate a payment
GET/rates
The payments provider's current USDC/COP rate and, when the pay product is enabled, this integrator's pay fees. With amount_cop, also an estimate of how many USDC to send so that exactly that many pesos reach a Bre-B key, priced with the same math as a pay quote, and whether that amount is within this integrator's pay limits (reported, not refused). This is an ESTIMATE: nothing is stored or reserved and the rate moves. The binding amount comes from POST /quotes, which lasts 2 minutes. Consumer key only, no party session. The bare rate needs one of pay, withdraw or deposit enabled; an estimate needs pay. Each call reads the rate live: at most 120 requests per minute per consumer.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
amount_cop | query | string | Pesos that must reach the Bre-B key, whole pesos (150000 or 150000.00). |
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Responses
200The rate, and the estimate when amount_cop was given
application/jsonRatesName Type Description raterequiredobject The payments provider's current sell rate, the one a pay quote would use now. payrequiredobject | null Pricing of the pay product for this integrator. null when pay is not enabled. estimaterequiredobject | null Present when amount_cop was given; otherwise null. 400invalid_amount, amount_not_settleable (not whole pesos), api_key_conflict or invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing, invalid, expired or revoked consumer key
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403product_not_enabled (an estimate needs pay; the bare rate needs pay, withdraw or deposit), api_key_ip_not_allowed or api_key_origin_not_allowed
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429rate_limited_consumer. See Retry-After.
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.502rate_unavailable
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response example
{
"rate": {
"value": "4012.55",
"source": "provider"
},
"pay": {
"fees": {
"tucop_bps": 150,
"fx_buffer_bps": 100,
"consumer_bps": 50
},
"minimum_per_operation": {
"amount": "1250000.00",
"asset": "COP"
},
"quote_ttl_seconds": 120
},
"estimate": {
"destination_amount": {
"amount": "1250000.00",
"asset": "COP"
},
"source_amount": {
"amount": "1250000.00",
"asset": "COP"
},
"fees": {
"tucop": {
"amount": "1250000.00",
"asset": "COP"
},
"consumer": {
"amount": "1250000.00",
"asset": "COP"
},
"fx_buffer": {
"amount": "1250000.00",
"asset": "COP"
}
},
"total_amount": {
"amount": "1250000.00",
"asset": "COP"
},
"settlement_time": {
"min_minutes": 15,
"max_minutes": 30
}
}
}Put together from the field examples in the spec. Fields without an example are left out.
Withdrawals
The withdraw product: a reusable USDC address that pays out in COP to the party's own Bre-B key.
List withdrawal addresses
GET/withdrawals
The party's withdrawal addresses, active and disabled, newest first, at most 50, without payouts. Each has status and disabled_at. For payouts and their status read one address (GET /withdrawals/{id}) or listen to withdraw.drained.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Responses
200The party's withdrawals your integrator created, newest first
application/jsonobjectName Type Description datarequiredarray of Withdrawal 400invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing or invalid consumer key, party_session_required (no session, and TuCOP has not linked a payments provider account to your integrator) or party_session_invalid
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403party_required (the session has no party linked to your consumer yet), party_not_linked, party_restricted, product_not_enabled, integrator_customer_mismatch (your integrator pays from its own payments provider account and the session is for another party), or an API key restriction
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.409integrator_not_linked (no session sent, and the payments provider account TuCOP set for your integrator is not linked to it yet)
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response example
{
"data": [
{
"id": "wdr_01j9z3k8q2m4n6p8r0s2t4v6w8",
"destination_id": "dst_01j9z3k8q2m4n6p8r0s2t4v6w8",
"deposit": {
"address": "0x5b1d7c0a4f2e8b9d6c3a1e0f7b2d4c6a8e9f0b1c",
"chain": "eip155:42220",
"minimum_destination_amount": {
"amount": "1250000.00",
"asset": "COP"
}
},
"settlement_time": {
"min_minutes": 15,
"max_minutes": 30
},
"payouts": [
{
"amount": {
"amount": "1250000.00",
"asset": "COP"
},
"destination_amount": {
"amount": "1250000.00",
"asset": "COP"
}
}
]
}
]
}Put together from the field examples in the spec. Fields without an example are left out.
Create or get a withdrawal address
POST/withdrawals
Returns the party's liquidation address for a verified first-party destination, creating it the first time (201) and returning the same one afterwards (200). There is one address per destination and integrator (another integrator linked to the person never sees or reuses yours); a party with several keys gets one address per key, each paying only to its own key. When the address was disabled, this re-enables the same address (200, status: active); no new address is created. Send USDC on Celo to deposit.address; the payments provider pays it out in COP to the destination. Use POST /quotes with product: withdraw to know how much to send for a given COP amount.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Idempotency-Keyrequired | header | IdempotencyKey | Unique key for this operation, for example a UUID. Retrying with the same key and body returns the first response; a different body gets 422 idempotency_key_reuse; a retry while the first is running gets 409 idempotency_in_progress. Kept 24 hours. |
Request bodyrequired
| Name | Type | Description |
|---|---|---|
destination_idrequired | DestinationPublicId & any | |
return_address | string | Optional. Where the payments provider returns the USDC if a payout fails. Defaults to the session's wallet. Without either, the address has no return wallet: a failed payout goes to TuCOP, which returns it to the person. When sent, the integrator answers for it. A different value sent for an existing address (active, or disabled and being re-enabled) replaces the stored one, here and at the payments provider; it can be added later this way. |
Responses
200The existing withdrawal
application/jsonWithdrawalName Type Description idrequiredWithdrawalPublicId Public id of a withdrawal (liquidation address): wdr_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.productrequiredstring: withdraw statusrequiredstring: active, disabled disabledafter DELETE /withdrawals/{id}. The payments provider cannot turn an address off: USDC sent to a disabled address is still paid out in COP to the same Bre-B key. It is not held or returned. POST /withdrawals for the destination re-enables it.destination_idrequiredDestinationPublicId Public id of a destination: dst_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.depositrequiredobject fee_bpsrequiredinteger | null TuCOP's fee on this address, in basis points. TuCOP sets it for each integrator. return_addressrequiredstring | null Where the payments provider returns the USDC if a payout fails. Each address has its own; it can differ between the keys of one party. Null when none was given: a failed payout then goes to TuCOP, which returns it to the person. settlement_timerequiredSettlementTime How long the payout usually takes: after the USDC land on-chain, the pesos usually reach the Bre-B key between min_minutes and max_minutes later. Meanwhile the payment reads awaiting_fundswhile the provider detects the deposit, thenprocessing(a withdrawal payout is in progress); neither is a failure. The status and theoperation.updatedwebhook say when it completed. An expectation, not a guarantee.disabled_atrequiredstring | null (date-time) When the address was disabled. Null while active. payoutsarray of WithdrawalPayout Payouts from this address, most recent first. On GET /{id} only; the list leaves them out (use GET /{id} or the withdraw.drained webhook). created_atrequiredstring (date-time) 201The new withdrawal
application/jsonWithdrawalName Type Description idrequiredWithdrawalPublicId Public id of a withdrawal (liquidation address): wdr_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.productrequiredstring: withdraw statusrequiredstring: active, disabled disabledafter DELETE /withdrawals/{id}. The payments provider cannot turn an address off: USDC sent to a disabled address is still paid out in COP to the same Bre-B key. It is not held or returned. POST /withdrawals for the destination re-enables it.destination_idrequiredDestinationPublicId Public id of a destination: dst_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.depositrequiredobject fee_bpsrequiredinteger | null TuCOP's fee on this address, in basis points. TuCOP sets it for each integrator. return_addressrequiredstring | null Where the payments provider returns the USDC if a payout fails. Each address has its own; it can differ between the keys of one party. Null when none was given: a failed payout then goes to TuCOP, which returns it to the person. settlement_timerequiredSettlementTime How long the payout usually takes: after the USDC land on-chain, the pesos usually reach the Bre-B key between min_minutes and max_minutes later. Meanwhile the payment reads awaiting_fundswhile the provider detects the deposit, thenprocessing(a withdrawal payout is in progress); neither is a failure. The status and theoperation.updatedwebhook say when it completed. An expectation, not a guarantee.disabled_atrequiredstring | null (date-time) When the address was disabled. Null while active. payoutsarray of WithdrawalPayout Payouts from this address, most recent first. On GET /{id} only; the list leaves them out (use GET /{id} or the withdraw.drained webhook). created_atrequiredstring (date-time) 400invalid_body, invalid_return_address, idempotency_key_required or invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing or invalid consumer key, party_session_required (no session, and TuCOP has not linked a payments provider account to your integrator) or party_session_invalid
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403party_required (the session has no party linked to your consumer yet), party_not_linked, party_restricted, product_not_enabled, integrator_customer_mismatch (your integrator pays from its own payments provider account and the session is for another party), or an API key restriction
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.404destination_not_found
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.409destination_not_verified, party_not_verified, first_party_not_available (a party that stands for a payments provider account linked by TuCOP has no identity document to match a first-party key; use pay for third-party keys), integrator_not_linked or idempotency_in_progress
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.422destination_not_first_party, provider_rejected or idempotency_key_reuse
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.502provider_unavailable (also when a new return_address could not be set at the payments provider: the previous one stays, and a disabled address stays disabled)
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response examples
{
"id": "wdr_01j9z3k8q2m4n6p8r0s2t4v6w8",
"destination_id": "dst_01j9z3k8q2m4n6p8r0s2t4v6w8",
"deposit": {
"address": "0x5b1d7c0a4f2e8b9d6c3a1e0f7b2d4c6a8e9f0b1c",
"chain": "eip155:42220",
"minimum_destination_amount": {
"amount": "1250000.00",
"asset": "COP"
}
},
"settlement_time": {
"min_minutes": 15,
"max_minutes": 30
},
"payouts": [
{
"amount": {
"amount": "1250000.00",
"asset": "COP"
},
"destination_amount": {
"amount": "1250000.00",
"asset": "COP"
}
}
]
}Put together from the field examples in the spec. Fields without an example are left out.
{
"id": "wdr_01j9z3k8q2m4n6p8r0s2t4v6w8",
"destination_id": "dst_01j9z3k8q2m4n6p8r0s2t4v6w8",
"deposit": {
"address": "0x5b1d7c0a4f2e8b9d6c3a1e0f7b2d4c6a8e9f0b1c",
"chain": "eip155:42220",
"minimum_destination_amount": {
"amount": "1250000.00",
"asset": "COP"
}
},
"settlement_time": {
"min_minutes": 15,
"max_minutes": 30
},
"payouts": [
{
"amount": {
"amount": "1250000.00",
"asset": "COP"
},
"destination_amount": {
"amount": "1250000.00",
"asset": "COP"
}
}
]
}Put together from the field examples in the spec. Fields without an example are left out.
Get a withdrawal address and its payouts
GET/withdrawals/{id}
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | WithdrawalPublicId | Public id of a withdrawal (liquidation address): wdr_ followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively. |
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Responses
200The withdrawal with
payoutsapplication/jsonWithdrawalName Type Description idrequiredWithdrawalPublicId Public id of a withdrawal (liquidation address): wdr_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.productrequiredstring: withdraw statusrequiredstring: active, disabled disabledafter DELETE /withdrawals/{id}. The payments provider cannot turn an address off: USDC sent to a disabled address is still paid out in COP to the same Bre-B key. It is not held or returned. POST /withdrawals for the destination re-enables it.destination_idrequiredDestinationPublicId Public id of a destination: dst_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.depositrequiredobject fee_bpsrequiredinteger | null TuCOP's fee on this address, in basis points. TuCOP sets it for each integrator. return_addressrequiredstring | null Where the payments provider returns the USDC if a payout fails. Each address has its own; it can differ between the keys of one party. Null when none was given: a failed payout then goes to TuCOP, which returns it to the person. settlement_timerequiredSettlementTime How long the payout usually takes: after the USDC land on-chain, the pesos usually reach the Bre-B key between min_minutes and max_minutes later. Meanwhile the payment reads awaiting_fundswhile the provider detects the deposit, thenprocessing(a withdrawal payout is in progress); neither is a failure. The status and theoperation.updatedwebhook say when it completed. An expectation, not a guarantee.disabled_atrequiredstring | null (date-time) When the address was disabled. Null while active. payoutsarray of WithdrawalPayout Payouts from this address, most recent first. On GET /{id} only; the list leaves them out (use GET /{id} or the withdraw.drained webhook). created_atrequiredstring (date-time) 400invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing or invalid consumer key, party_session_required (no session, and TuCOP has not linked a payments provider account to your integrator) or party_session_invalid
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403party_required (the session has no party linked to your consumer yet), party_not_linked, party_restricted, product_not_enabled, integrator_customer_mismatch (your integrator pays from its own payments provider account and the session is for another party), or an API key restriction
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.404withdrawal_not_found
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.409integrator_not_linked (no session sent, and the payments provider account TuCOP set for your integrator is not linked to it yet)
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.502provider_unavailable
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response example
{
"id": "wdr_01j9z3k8q2m4n6p8r0s2t4v6w8",
"destination_id": "dst_01j9z3k8q2m4n6p8r0s2t4v6w8",
"deposit": {
"address": "0x5b1d7c0a4f2e8b9d6c3a1e0f7b2d4c6a8e9f0b1c",
"chain": "eip155:42220",
"minimum_destination_amount": {
"amount": "1250000.00",
"asset": "COP"
}
},
"settlement_time": {
"min_minutes": 15,
"max_minutes": 30
},
"payouts": [
{
"amount": {
"amount": "1250000.00",
"asset": "COP"
},
"destination_amount": {
"amount": "1250000.00",
"asset": "COP"
}
}
]
}Put together from the field examples in the spec. Fields without an example are left out.
Disable a withdrawal address
DELETE/withdrawals/{id}
Disables the address and answers 200 with it (status: disabled, disabled_at). Disabling it again answers 200 with the same resource. The payments provider cannot turn an address off: USDC sent to it afterwards is still paid out in COP to the same Bre-B key. It is not held or returned. Tell the person to stop using the address. TuCOP keeps reading a disabled address for 7 days, so payouts in that time still arrive as withdraw.drained. POST /withdrawals for the same destination re-enables the same address. Sends withdrawal.disabled when the status changes.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | WithdrawalPublicId | Public id of a withdrawal (liquidation address): wdr_ followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively. |
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Responses
200The disabled withdrawal
application/jsonWithdrawalName Type Description idrequiredWithdrawalPublicId Public id of a withdrawal (liquidation address): wdr_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.productrequiredstring: withdraw statusrequiredstring: active, disabled disabledafter DELETE /withdrawals/{id}. The payments provider cannot turn an address off: USDC sent to a disabled address is still paid out in COP to the same Bre-B key. It is not held or returned. POST /withdrawals for the destination re-enables it.destination_idrequiredDestinationPublicId Public id of a destination: dst_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.depositrequiredobject fee_bpsrequiredinteger | null TuCOP's fee on this address, in basis points. TuCOP sets it for each integrator. return_addressrequiredstring | null Where the payments provider returns the USDC if a payout fails. Each address has its own; it can differ between the keys of one party. Null when none was given: a failed payout then goes to TuCOP, which returns it to the person. settlement_timerequiredSettlementTime How long the payout usually takes: after the USDC land on-chain, the pesos usually reach the Bre-B key between min_minutes and max_minutes later. Meanwhile the payment reads awaiting_fundswhile the provider detects the deposit, thenprocessing(a withdrawal payout is in progress); neither is a failure. The status and theoperation.updatedwebhook say when it completed. An expectation, not a guarantee.disabled_atrequiredstring | null (date-time) When the address was disabled. Null while active. payoutsarray of WithdrawalPayout Payouts from this address, most recent first. On GET /{id} only; the list leaves them out (use GET /{id} or the withdraw.drained webhook). created_atrequiredstring (date-time) 400invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing or invalid consumer key, party_session_required (no session, and TuCOP has not linked a payments provider account to your integrator) or party_session_invalid
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403party_required (the session has no party linked to your consumer yet), party_not_linked, party_restricted, product_not_enabled, integrator_customer_mismatch (your integrator pays from its own payments provider account and the session is for another party), or an API key restriction
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.404withdrawal_not_found
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.409integrator_not_linked (no session sent, and the payments provider account TuCOP set for your integrator is not linked to it yet)
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response example
{
"id": "wdr_01j9z3k8q2m4n6p8r0s2t4v6w8",
"destination_id": "dst_01j9z3k8q2m4n6p8r0s2t4v6w8",
"deposit": {
"address": "0x5b1d7c0a4f2e8b9d6c3a1e0f7b2d4c6a8e9f0b1c",
"chain": "eip155:42220",
"minimum_destination_amount": {
"amount": "1250000.00",
"asset": "COP"
}
},
"settlement_time": {
"min_minutes": 15,
"max_minutes": 30
},
"payouts": [
{
"amount": {
"amount": "1250000.00",
"asset": "COP"
},
"destination_amount": {
"amount": "1250000.00",
"asset": "COP"
}
}
]
}Put together from the field examples in the spec. Fields without an example are left out.
Deposits
The deposit product: a reusable Bre-B key where the party pays COP and receives USDC on Celo.
List deposit accounts
GET/deposits
Parameters
| Name | In | Type | Description |
|---|---|---|---|
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Responses
200The party's deposit accounts, newest first
application/jsonobjectName Type Description datarequiredarray of Deposit 400invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing or invalid consumer key, party_session_required (no session, and TuCOP has not linked a payments provider account to your integrator) or party_session_invalid
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403party_required (the session has no party linked to your consumer yet), party_not_linked, party_restricted, product_not_enabled, integrator_customer_mismatch (your integrator pays from its own payments provider account and the session is for another party), or an API key restriction
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.409integrator_not_linked (no session sent, and the payments provider account TuCOP set for your integrator is not linked to it yet)
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response example
{
"data": [
{
"id": "dep_01j9z3k8q2m4n6p8r0s2t4v6w8",
"destination": {
"chain": "eip155:42220"
},
"events": [
{
"amount": {
"amount": "1250000.00",
"asset": "COP"
}
}
]
}
]
}Put together from the field examples in the spec. Fields without an example are left out.
Create or get a deposit account
POST/deposits
Returns the party's virtual account for a wallet, creating it the first time (201) and returning the same one afterwards (200). When the payments provider already has an active COP account for the party that sends USDC on Celo to that wallet (opened outside TuCOP) and no integrator holds it yet, TuCOP takes it over instead of opening another one and answers 200: same Bre-B key, and fee_bps is that account's own fee. Not available in the sandbox: the payments provider's sandbox does not create COP virtual accounts, so the request answers 422 provider_rejected there.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Idempotency-Keyrequired | header | IdempotencyKey | Unique key for this operation, for example a UUID. Retrying with the same key and body returns the first response; a different body gets 422 idempotency_key_reuse; a retry while the first is running gets 409 idempotency_in_progress. Kept 24 hours. |
Request bodyrequired
| Name | Type | Description |
|---|---|---|
wallet_address | string | Where the USDC goes. Defaults to the session's wallet. Required when there is no wallet session, for example when you call with the API key alone. The integrator sends it and answers for it. |
Responses
200The existing deposit account
application/jsonDepositName Type Description idrequiredDepositPublicId Public id of a deposit account (virtual account): dep_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.productrequiredstring: deposit statusrequiredstring: active, deactivated deposit_instructionsrequiredobject destinationrequiredobject fee_bpsrequiredinteger TuCOP's fee in basis points, fixed on the account. For an account the payments provider already had for the party and wallet (taken over by POST /deposits), it is that account's own fee, which can differ from your integrator's fee. eventsarray of object Activity on the account, as the payments provider reports it. On GET /{id} only. created_atrequiredstring (date-time) 201The new deposit account
application/jsonDepositName Type Description idrequiredDepositPublicId Public id of a deposit account (virtual account): dep_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.productrequiredstring: deposit statusrequiredstring: active, deactivated deposit_instructionsrequiredobject destinationrequiredobject fee_bpsrequiredinteger TuCOP's fee in basis points, fixed on the account. For an account the payments provider already had for the party and wallet (taken over by POST /deposits), it is that account's own fee, which can differ from your integrator's fee. eventsarray of object Activity on the account, as the payments provider reports it. On GET /{id} only. created_atrequiredstring (date-time) 400invalid_body, invalid_wallet_address, idempotency_key_required or invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing or invalid consumer key, party_session_required (no session, and TuCOP has not linked a payments provider account to your integrator) or party_session_invalid
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403party_required (the session has no party linked to your consumer yet), party_not_linked, party_restricted, product_not_enabled, integrator_customer_mismatch (your integrator pays from its own payments provider account and the session is for another party), or an API key restriction
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.409party_not_verified, integrator_not_linked or idempotency_in_progress
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.422wallet_address_required, provider_rejected or idempotency_key_reuse
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.502provider_unavailable
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response examples
{
"id": "dep_01j9z3k8q2m4n6p8r0s2t4v6w8",
"destination": {
"chain": "eip155:42220"
},
"events": [
{
"amount": {
"amount": "1250000.00",
"asset": "COP"
}
}
]
}Put together from the field examples in the spec. Fields without an example are left out.
{
"id": "dep_01j9z3k8q2m4n6p8r0s2t4v6w8",
"destination": {
"chain": "eip155:42220"
},
"events": [
{
"amount": {
"amount": "1250000.00",
"asset": "COP"
}
}
]
}Put together from the field examples in the spec. Fields without an example are left out.
Get a deposit account and its activity
GET/deposits/{id}
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | DepositPublicId | Public id of a deposit account (virtual account): dep_ followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively. |
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Responses
200The deposit account with
eventsapplication/jsonDepositName Type Description idrequiredDepositPublicId Public id of a deposit account (virtual account): dep_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.productrequiredstring: deposit statusrequiredstring: active, deactivated deposit_instructionsrequiredobject destinationrequiredobject fee_bpsrequiredinteger TuCOP's fee in basis points, fixed on the account. For an account the payments provider already had for the party and wallet (taken over by POST /deposits), it is that account's own fee, which can differ from your integrator's fee. eventsarray of object Activity on the account, as the payments provider reports it. On GET /{id} only. created_atrequiredstring (date-time) 400invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing or invalid consumer key, party_session_required (no session, and TuCOP has not linked a payments provider account to your integrator) or party_session_invalid
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403party_required (the session has no party linked to your consumer yet), party_not_linked, party_restricted, product_not_enabled, integrator_customer_mismatch (your integrator pays from its own payments provider account and the session is for another party), or an API key restriction
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.404deposit_not_found
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.409integrator_not_linked (no session sent, and the payments provider account TuCOP set for your integrator is not linked to it yet)
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.502provider_unavailable
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response example
{
"id": "dep_01j9z3k8q2m4n6p8r0s2t4v6w8",
"destination": {
"chain": "eip155:42220"
},
"events": [
{
"amount": {
"amount": "1250000.00",
"asset": "COP"
}
}
]
}Put together from the field examples in the spec. Fields without an example are left out.
Change the wallet of a deposit account
PATCH/deposits/{id}
Points the same Bre-B key at another wallet: pesos paid from now on arrive as USDC at wallet_address. Only for accounts your integrator opened or took over, and needs deposit. The same wallet answers 200 with the account unchanged. Refused with 409 deposit_in_flight while money may still be on its way to the current wallet: a deposit whose latest activity is funds_scheduled, funds_received, in_review or payment_submitted, or any money activity in the last 2 minutes. Retry once the deposit was delivered (payment_processed) or refunded. No webhook is sent for the change: this answer confirms it. The Idempotency-Key header is required.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | DepositPublicId | Public id of a deposit account (virtual account): dep_ followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively. |
TuCOPRamp-Version | header | TuCOPRampVersion | Deprecated: do not send it. The API has a single version and paths carry none. Still accepted for now; an unknown value gets 400 invalid_api_version. |
Idempotency-Keyrequired | header | IdempotencyKey | Unique key for this operation, for example a UUID. Retrying with the same key and body returns the first response; a different body gets 422 idempotency_key_reuse; a retry while the first is running gets 409 idempotency_in_progress. Kept 24 hours. |
Request bodyrequired
| Name | Type | Description |
|---|---|---|
wallet_addressrequired | string | The wallet the USDC goes to from now on. Checked like POST /deposits: TuCOP checks only that it is an address; your app answers for it. |
Responses
200The deposit account with its new (or unchanged) destination
application/jsonDepositName Type Description idrequiredDepositPublicId Public id of a deposit account (virtual account): dep_followed by 26 Crockford base32 characters. Treat it as an opaque string; compare it case-insensitively.productrequiredstring: deposit statusrequiredstring: active, deactivated deposit_instructionsrequiredobject destinationrequiredobject fee_bpsrequiredinteger TuCOP's fee in basis points, fixed on the account. For an account the payments provider already had for the party and wallet (taken over by POST /deposits), it is that account's own fee, which can differ from your integrator's fee. eventsarray of object Activity on the account, as the payments provider reports it. On GET /{id} only. created_atrequiredstring (date-time) 400invalid_body, invalid_wallet_address, idempotency_key_required or invalid_api_version
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.401Missing or invalid consumer key, party_session_required (no session, and TuCOP has not linked a payments provider account to your integrator) or party_session_invalid
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.403party_required (the session has no party linked to your consumer yet), party_not_linked, party_restricted, product_not_enabled, integrator_customer_mismatch (your integrator pays from its own payments provider account and the session is for another party), or an API key restriction
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.404deposit_not_found
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.409deposit_in_flight (the error includes
deposit), deposit_not_owned (an account from before accounts belonged to one integrator), deposit_deactivated, deposit_wallet_in_use (you already have an account for that wallet), party_not_verified, integrator_not_linked or idempotency_in_progressapplication/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.422provider_rejected or idempotency_key_reuse
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.429Rate limited
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.502provider_unavailable (also when the payments provider did not accept the change: the destination stays as it was)
application/problem+jsonErrorName Type Description typestring URI derived from code. An identifier, not a page.titlestring statusrequiredinteger coderequiredstring Machine-readable code in snake_case. Branch on this field only. detailrequiredstring A sentence for people. It can change at any time. request_idstring Same value as the X-Request-Id response header. issuesarray of object Fields that failed validation, when there are any. categorystring | null: on_off_ramp, p2p On product_not_enabled: the category of the services that would open the route.on_off_ramp(a payments provider moves the money) orp2p(TuCOP runs the exchange). Null when they belong to both.requiredarray of string On product_not_enabled: the services that would open the route. Any one is enough.
Response example
{
"id": "dep_01j9z3k8q2m4n6p8r0s2t4v6w8",
"destination": {
"chain": "eip155:42220"
},
"events": [
{
"amount": {
"amount": "1250000.00",
"asset": "COP"
}
}
]
}Put together from the field examples in the spec. Fields without an example are left out.
Console
The terms an integrator accepts when it registers in the console.
Terms an integrator accepts at registration
GET/console/terms
Responses
200Current terms
application/jsonobjectName Type Description versionrequiredstring textrequiredstring
Health
Liveness and readiness probes. No API key needed.
Liveness probe
GET/health/live
Liveness check. No API key needed.
Responses
200Alive
application/jsonHealthLiveResponseName Type Description statusrequiredstring: ok
Readiness probe
GET/health/ready
Readiness check (DB + upstreams). No API key needed.
Responses
200Ready
application/jsonHealthReadyResponseName Type Description statusrequiredstring: ok, degraded checksrequiredobject 503Degraded
application/jsonHealthReadyResponseName Type Description statusrequiredstring: ok, degraded checksrequiredobject
Webhook events
Requests TuCOP Ramp sends to your endpoints. See Webhooks for signatures and retries.
party.updated
POSTparty.updated
Sent to every consumer linked to a party when its verification status, endorsements or restriction change. Read the party with GET /parties/me for the full picture. Signed with Standard Webhooks. Any 2xx within 15 seconds counts as delivered. Otherwise it is retried after about 5 s, 5 min, 30 min, 2 h, 5 h, 10 h, 14 h, 20 h and 24 h (ten attempts over about 3 days, each delay varied by up to 10 percent). Redirects are not followed. A 410 disables the endpoint. Verify webhook-signature against the raw body before parsing it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
webhook-idrequired | header | string | Event id. Same value as id in the body, and the same on every retry. Use it to deduplicate. |
webhook-timestamprequired | header | string | Unix seconds when this attempt was signed. Each retry is signed again. |
webhook-signaturerequired | header | string | Space-separated list of v1,<base64> signatures: HMAC-SHA256 of <webhook-id>.<webhook-timestamp>.<raw body>, keyed with the base64-decoded part of the secret after whsec_. Two signatures are sent for a while after a secret rotation; accept the request if any one matches. |
Payload
| Name | Type | Description |
|---|---|---|
idrequired | EventPublicId | Event id. |
typerequired | string: party.updated | |
categoryrequired | string: on_off_ramp | Service category of the event: on_off_ramp or platform. p2p is reserved for TuCOP's own apps. |
timestamprequired | string (date-time) | When the event happened (not when this attempt was sent). |
api_versionrequired | string | API version of the payload, pinned per webhook endpoint. |
datarequired | WebhookPartyUpdatedData |
Expected responses
200Any 2xx marks the delivery as done.
410Disables the endpoint. No more events are sent to it.
Example payload
{
"id": "evt_3f3gn1wv2y9e59mn9z1xn1pb2a",
"type": "party.updated",
"category": "on_off_ramp",
"timestamp": "2026-10-08T15:20:41.090Z",
"api_version": "2026-10-08",
"data": {
"party_id": "pty_01j9z3k8q2m4n6p8r0s2t4v6w8",
"status": {
"kyc": "approved",
"tos": "accepted",
"endorsements": [
{
"name": "cop",
"status": "approved"
}
]
},
"restricted": false,
"updated_at": "2026-10-08T15:20:40.512Z"
}
}ping
POSTping
Sent when TuCOP tests one of your webhook endpoints. Signed with Standard Webhooks. Any 2xx within 15 seconds counts as delivered. Otherwise it is retried after about 5 s, 5 min, 30 min, 2 h, 5 h, 10 h, 14 h, 20 h and 24 h (ten attempts over about 3 days, each delay varied by up to 10 percent). Redirects are not followed. A 410 disables the endpoint. Verify webhook-signature against the raw body before parsing it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
webhook-idrequired | header | string | Event id. Same value as id in the body, and the same on every retry. Use it to deduplicate. |
webhook-timestamprequired | header | string | Unix seconds when this attempt was signed. Each retry is signed again. |
webhook-signaturerequired | header | string | Space-separated list of v1,<base64> signatures: HMAC-SHA256 of <webhook-id>.<webhook-timestamp>.<raw body>, keyed with the base64-decoded part of the secret after whsec_. Two signatures are sent for a while after a secret rotation; accept the request if any one matches. |
Payload
| Name | Type | Description |
|---|---|---|
idrequired | EventPublicId | Event id. |
typerequired | string: ping | |
categoryrequired | string: platform | Service category of the event: on_off_ramp or platform. p2p is reserved for TuCOP's own apps. |
timestamprequired | string (date-time) | When the event happened (not when this attempt was sent). |
api_versionrequired | string | API version of the payload, pinned per webhook endpoint. |
datarequired | WebhookPingData |
Expected responses
200Any 2xx marks the delivery as done.
410Disables the endpoint. No more events are sent to it.
Example payload
{
"id": "evt_3f3gn1wv2y9e59mn9z1xn1pb1x",
"type": "ping",
"category": "platform",
"timestamp": "2026-10-07T21:04:11.512Z",
"api_version": "2026-10-08",
"data": {
"consumer_id": "con_0bdy554f0x9szsmatwdnz8z6gb",
"endpoint_id": "whep_1x5gdgn7we9ny8ptjz9ryjr6ra"
}
}destination.verified
POSTdestination.verified
A destination your consumer created passed the Bre-B directory check. Read it with GET /destinations/{id} to show the holder to the payer. Signed with Standard Webhooks. Any 2xx within 15 seconds counts as delivered. Otherwise it is retried after about 5 s, 5 min, 30 min, 2 h, 5 h, 10 h, 14 h, 20 h and 24 h (ten attempts over about 3 days, each delay varied by up to 10 percent). Redirects are not followed. A 410 disables the endpoint. Verify webhook-signature against the raw body before parsing it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
webhook-idrequired | header | string | Event id. Same value as id in the body, and the same on every retry. Use it to deduplicate. |
webhook-timestamprequired | header | string | Unix seconds when this attempt was signed. Each retry is signed again. |
webhook-signaturerequired | header | string | Space-separated list of v1,<base64> signatures: HMAC-SHA256 of <webhook-id>.<webhook-timestamp>.<raw body>, keyed with the base64-decoded part of the secret after whsec_. Two signatures are sent for a while after a secret rotation; accept the request if any one matches. |
Payload
| Name | Type | Description |
|---|---|---|
idrequired | EventPublicId | Event id. |
typerequired | string: destination.verified | |
categoryrequired | string: on_off_ramp | Service category of the event: on_off_ramp or platform. p2p is reserved for TuCOP's own apps. |
timestamprequired | string (date-time) | When the event happened (not when this attempt was sent). |
api_versionrequired | string | API version of the payload, pinned per webhook endpoint. |
datarequired | WebhookDestinationData |
Expected responses
200Any 2xx marks the delivery as done.
410Disables the endpoint. No more events are sent to it.
Example payload
{
"id": "evt_3f3gn1wv2y9e59mn9z1xn1pb1x",
"type": "destination.verified",
"category": "on_off_ramp",
"timestamp": "2026-10-07T21:04:11.512Z",
"api_version": "2026-10-08",
"data": {
"destination_id": "dst_01j9z3k8q2m4n6p8r0s2t4v6w8",
"ownership": "third_party",
"status": "verified",
"rejection_reason": null,
"key_masked": "****4567",
"verified_at": "2026-10-08T15:02:51.120Z",
"confirmed_at": null,
"updated_at": "2026-10-08T15:02:51.120Z"
}
}destination.rejected
POSTdestination.rejected
A destination your consumer created failed the Bre-B directory check, or the directory did not answer in time. It was deleted at the payments provider. Signed with Standard Webhooks. Any 2xx within 15 seconds counts as delivered. Otherwise it is retried after about 5 s, 5 min, 30 min, 2 h, 5 h, 10 h, 14 h, 20 h and 24 h (ten attempts over about 3 days, each delay varied by up to 10 percent). Redirects are not followed. A 410 disables the endpoint. Verify webhook-signature against the raw body before parsing it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
webhook-idrequired | header | string | Event id. Same value as id in the body, and the same on every retry. Use it to deduplicate. |
webhook-timestamprequired | header | string | Unix seconds when this attempt was signed. Each retry is signed again. |
webhook-signaturerequired | header | string | Space-separated list of v1,<base64> signatures: HMAC-SHA256 of <webhook-id>.<webhook-timestamp>.<raw body>, keyed with the base64-decoded part of the secret after whsec_. Two signatures are sent for a while after a secret rotation; accept the request if any one matches. |
Payload
| Name | Type | Description |
|---|---|---|
idrequired | EventPublicId | Event id. |
typerequired | string: destination.rejected | |
categoryrequired | string: on_off_ramp | Service category of the event: on_off_ramp or platform. p2p is reserved for TuCOP's own apps. |
timestamprequired | string (date-time) | When the event happened (not when this attempt was sent). |
api_versionrequired | string | API version of the payload, pinned per webhook endpoint. |
datarequired | WebhookDestinationData |
Expected responses
200Any 2xx marks the delivery as done.
410Disables the endpoint. No more events are sent to it.
Example payload
{
"id": "evt_3f3gn1wv2y9e59mn9z1xn1pb1x",
"type": "destination.rejected",
"category": "on_off_ramp",
"timestamp": "2026-10-07T21:04:11.512Z",
"api_version": "2026-10-08",
"data": {
"destination_id": "dst_01j9z3k8q2m4n6p8r0s2t4v6w8",
"ownership": "third_party",
"status": "rejected",
"rejection_reason": "directory_no_match",
"key_masked": "****4567",
"verified_at": null,
"confirmed_at": null,
"updated_at": "2026-10-08T15:02:51.120Z"
}
}operation.updated
POSToperation.updated
A payment changed status, or its deposit_amount changed while awaiting_funds (then with the same status). Read deposit.amount from GET /payments/{id} right before sending. Signed with Standard Webhooks. Any 2xx within 15 seconds counts as delivered. Otherwise it is retried after about 5 s, 5 min, 30 min, 2 h, 5 h, 10 h, 14 h, 20 h and 24 h (ten attempts over about 3 days, each delay varied by up to 10 percent). Redirects are not followed. A 410 disables the endpoint. Verify webhook-signature against the raw body before parsing it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
webhook-idrequired | header | string | Event id. Same value as id in the body, and the same on every retry. Use it to deduplicate. |
webhook-timestamprequired | header | string | Unix seconds when this attempt was signed. Each retry is signed again. |
webhook-signaturerequired | header | string | Space-separated list of v1,<base64> signatures: HMAC-SHA256 of <webhook-id>.<webhook-timestamp>.<raw body>, keyed with the base64-decoded part of the secret after whsec_. Two signatures are sent for a while after a secret rotation; accept the request if any one matches. |
Payload
| Name | Type | Description |
|---|---|---|
idrequired | EventPublicId | Event id. |
typerequired | string: operation.updated | |
categoryrequired | string: on_off_ramp | Service category of the event: on_off_ramp or platform. p2p is reserved for TuCOP's own apps. |
timestamprequired | string (date-time) | When the event happened (not when this attempt was sent). |
api_versionrequired | string | API version of the payload, pinned per webhook endpoint. |
datarequired | WebhookOperationData |
Expected responses
200Any 2xx marks the delivery as done.
410Disables the endpoint. No more events are sent to it.
Example payload
{
"id": "evt_3f3gn1wv2y9e59mn9z1xn1pb1x",
"type": "operation.updated",
"category": "on_off_ramp",
"timestamp": "2026-10-07T21:04:11.512Z",
"api_version": "2026-10-08",
"data": {
"operation_id": "op_01j9z3k8q2m4n6p8r0s2t4v6w8",
"product": "pay",
"status": "processing",
"destination_id": "dst_01j9z3k8q2m4n6p8r0s2t4v6w8",
"destination_amount": {
"amount": "200000.00",
"asset": "COP"
},
"source_amount": {
"amount": "51.27",
"asset": "USDC"
},
"deposit_amount": {
"amount": "51.27",
"asset": "USDC"
},
"fees": {
"tucop": {
"amount": "0.770000",
"asset": "USDC"
},
"consumer": {
"amount": "0.256350",
"asset": "USDC"
}
},
"error_code": null,
"updated_at": "2026-10-08T15:04:10.003Z"
}
}withdraw.drained
POSTwithdraw.drained
A payout from one of your withdrawal addresses was created or changed status. Sent once per payout and status (processing, then completed, failed, refunded or canceled); read the address with GET /withdrawals/{id}. Signed with Standard Webhooks. Any 2xx within 15 seconds counts as delivered. Otherwise it is retried after about 5 s, 5 min, 30 min, 2 h, 5 h, 10 h, 14 h, 20 h and 24 h (ten attempts over about 3 days, each delay varied by up to 10 percent). Redirects are not followed. A 410 disables the endpoint. Verify webhook-signature against the raw body before parsing it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
webhook-idrequired | header | string | Event id. Same value as id in the body, and the same on every retry. Use it to deduplicate. |
webhook-timestamprequired | header | string | Unix seconds when this attempt was signed. Each retry is signed again. |
webhook-signaturerequired | header | string | Space-separated list of v1,<base64> signatures: HMAC-SHA256 of <webhook-id>.<webhook-timestamp>.<raw body>, keyed with the base64-decoded part of the secret after whsec_. Two signatures are sent for a while after a secret rotation; accept the request if any one matches. |
Payload
| Name | Type | Description |
|---|---|---|
idrequired | EventPublicId | Event id. |
typerequired | string: withdraw.drained | |
categoryrequired | string: on_off_ramp | Service category of the event: on_off_ramp or platform. p2p is reserved for TuCOP's own apps. |
timestamprequired | string (date-time) | When the event happened (not when this attempt was sent). |
api_versionrequired | string | API version of the payload, pinned per webhook endpoint. |
datarequired | WebhookWithdrawDrainedData |
Expected responses
200Any 2xx marks the delivery as done.
410Disables the endpoint. No more events are sent to it.
Example payload
{
"id": "evt_3f3gn1wv2y9e59mn9z1xn1pb1x",
"type": "withdraw.drained",
"category": "on_off_ramp",
"timestamp": "2026-10-07T21:04:11.512Z",
"api_version": "2026-10-08",
"data": {
"withdrawal_id": "wdr_01j9z3k8q2m4n6p8r0s2t4v6w8",
"destination_id": "dst_01j9z3k8q2m4n6p8r0s2t4v6w8",
"payout_id": "3f9c2a1e-5b7d-4c8e-9a0b-1d2e3f4a5b6c",
"status": "completed",
"amount": {
"amount": "25.123456",
"asset": "USDC"
},
"destination_amount": {
"amount": "98500.00",
"asset": "COP"
},
"error_code": null,
"created_at": "2026-10-11T15:04:10.003Z",
"updated_at": "2026-10-11T15:05:10.003Z",
"completed_at": "2026-10-11T15:05:10.003Z"
}
}withdrawal.disabled
POSTwithdrawal.disabled
One of your withdrawal addresses was disabled (DELETE /withdrawals/{id}). Sent once, when the status changes, to the consumer that created the address. The payments provider still pays out to the same key whatever reaches the address afterwards. Signed with Standard Webhooks. Any 2xx within 15 seconds counts as delivered. Otherwise it is retried after about 5 s, 5 min, 30 min, 2 h, 5 h, 10 h, 14 h, 20 h and 24 h (ten attempts over about 3 days, each delay varied by up to 10 percent). Redirects are not followed. A 410 disables the endpoint. Verify webhook-signature against the raw body before parsing it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
webhook-idrequired | header | string | Event id. Same value as id in the body, and the same on every retry. Use it to deduplicate. |
webhook-timestamprequired | header | string | Unix seconds when this attempt was signed. Each retry is signed again. |
webhook-signaturerequired | header | string | Space-separated list of v1,<base64> signatures: HMAC-SHA256 of <webhook-id>.<webhook-timestamp>.<raw body>, keyed with the base64-decoded part of the secret after whsec_. Two signatures are sent for a while after a secret rotation; accept the request if any one matches. |
Payload
| Name | Type | Description |
|---|---|---|
idrequired | EventPublicId | Event id. |
typerequired | string: withdrawal.disabled | |
categoryrequired | string: on_off_ramp | Service category of the event: on_off_ramp or platform. p2p is reserved for TuCOP's own apps. |
timestamprequired | string (date-time) | When the event happened (not when this attempt was sent). |
api_versionrequired | string | API version of the payload, pinned per webhook endpoint. |
datarequired | WebhookWithdrawalDisabledData |
Expected responses
200Any 2xx marks the delivery as done.
410Disables the endpoint. No more events are sent to it.
Example payload
{
"id": "evt_3f3gn1wv2y9e59mn9z1xn1pb1x",
"type": "withdrawal.disabled",
"category": "on_off_ramp",
"timestamp": "2026-10-07T21:04:11.512Z",
"api_version": "2026-10-08",
"data": {
"withdrawal_id": "wdr_01j9z3k8q2m4n6p8r0s2t4v6w8",
"destination_id": "dst_01j9z3k8q2m4n6p8r0s2t4v6w8",
"status": "disabled",
"disabled_at": "2026-10-14T15:04:10.003Z"
}
}deposit.received
POSTdeposit.received
Activity on one of your deposit accounts: COP arrived, or the USDC was sent to the wallet. Sent once per activity line, as soon as the payments provider reports it (TuCOP also reads the account about once a minute, so a missed notice still arrives); read the account with GET /deposits/{id}. Signed with Standard Webhooks. Any 2xx within 15 seconds counts as delivered. Otherwise it is retried after about 5 s, 5 min, 30 min, 2 h, 5 h, 10 h, 14 h, 20 h and 24 h (ten attempts over about 3 days, each delay varied by up to 10 percent). Redirects are not followed. A 410 disables the endpoint. Verify webhook-signature against the raw body before parsing it.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
webhook-idrequired | header | string | Event id. Same value as id in the body, and the same on every retry. Use it to deduplicate. |
webhook-timestamprequired | header | string | Unix seconds when this attempt was signed. Each retry is signed again. |
webhook-signaturerequired | header | string | Space-separated list of v1,<base64> signatures: HMAC-SHA256 of <webhook-id>.<webhook-timestamp>.<raw body>, keyed with the base64-decoded part of the secret after whsec_. Two signatures are sent for a while after a secret rotation; accept the request if any one matches. |
Payload
| Name | Type | Description |
|---|---|---|
idrequired | EventPublicId | Event id. |
typerequired | string: deposit.received | |
categoryrequired | string: on_off_ramp | Service category of the event: on_off_ramp or platform. p2p is reserved for TuCOP's own apps. |
timestamprequired | string (date-time) | When the event happened (not when this attempt was sent). |
api_versionrequired | string | API version of the payload, pinned per webhook endpoint. |
datarequired | WebhookDepositReceivedData |
Expected responses
200Any 2xx marks the delivery as done.
410Disables the endpoint. No more events are sent to it.
Example payload
{
"id": "evt_3f3gn1wv2y9e59mn9z1xn1pb1x",
"type": "deposit.received",
"category": "on_off_ramp",
"timestamp": "2026-10-07T21:04:11.512Z",
"api_version": "2026-10-08",
"data": {
"deposit_id": "dep_01j9z3k8q2m4n6p8r0s2t4v6w8",
"event_id": "event_example",
"type": "funds_received",
"amount": {
"amount": "100000.00",
"asset": "COP"
},
"created_at": "2026-10-11T15:04:10.003Z",
"destination_address": "0x1111111111111111111111111111111111111111"
}
}