International exchange (FX)
Perform international currency conversions between USD and COP.
All endpoints require authentication with Authorization: Bearer [TOKEN] and x-api-key.
Overview
What is Exchange?
The Exchange module in Colurs allows you to:
- Get FX quotes between currency pairs
- Execute cross-border movements with automatic payout to bank accounts
- Calculate exchange rates with user-specific fees
Behavior
- Synchronous: Quote creation and retrieval (immediate response)
- Asynchronous: Cross-border movement execution (confirmation as status changes)
Supported currencies
Available pairs
The system supports multiple currency pairs in source/destination format (e.g. usd/cop, cop/usd).
| Source currency | Destination currencies |
|---|---|
| USD | COP |
| COP | USD |
Restrictions
- Minimum amount: 50 USD or equivalent in source currency
- Schedule: By default, only during business hours (Monday-Friday). With
off_market: true, operation is available 24/7.
General flow
Get FX quote
Request a quote with POST /v2/exchange/quotes/. Valid for 3 minutes.
(Optional) Preview
Get details with GET /v2/exchange/quotes/{quote_uuid}/ or .../preview/.
Get bank account
Use GET /list_third_party_banks/?country=CO (or corresponding country) for destination account.
Start movement
Execute with POST /v2/exchange/initiate/ using quote and bank account.
Receive confirmation
The system notifies when movement is completed and automatic payout is performed.
Quotes
Request FX quote
Authorizations
Both
x-api-key and Authorization: Bearer <token> headers are required.Endpoint
POST/v2/exchange/quotes/Required Headers
Content-Type: application/jsonAccept: application/jsonx-api-key: [API_KEY]Authorization: Bearer [ACCESS_TOKEN]Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| currency_pair | string | Currency pair (e.g. usd/cop) | |
| source_amount | decimal | Amount in source currency (send one of source_amount or destination_amount) | |
| destination_amount | decimal | Amount in destination currency | |
| type | string | static_quote (default) or rolling_quote | |
| off_market | boolean | Allow 24/7 operation (default: false) |
Response
response.json
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"currency_pair": "usd/cop",
"source_currency": "usd",
"destination_currency": "cop",
"source_amount": 100.00,
"destination_amount": 407731.25,
"fx_rate": 4077.3125,
"status": "pending",
"is_valid": true,
"valid_until": "2026-02-03T10:03:00Z",
"created_at":
"2026-02-03T10:00:00Z"}Possible Errors
| Code | Error | Description |
|---|---|---|
| 400 | Bad Request | Minimum amount not met ($50 USD or equivalent) |
| 400 | Bad Request | Both source_amount and destination_amount were sent |
| 400 | Bad Request | Market closed (outside schedule and off_market=false) |
| 502 | Bad Gateway | Error processing quote |
⏱️
Quote expires in 3 minutes. Only the latest quote for the pair can be used to start a movement.
Get quote by UUID
Authorizations
Both
x-api-key and Authorization: Bearer <token> headers are required.Endpoint
GET/v2/exchange/quotes/{quote_uuid}/Required Headers
Content-Type: application/jsonAccept: application/jsonx-api-key: [API_KEY]Authorization: Bearer [ACCESS_TOKEN]Response
response.json
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"currency_pair": "usd/cop",
"source_amount": 100.00,
"destination_amount": 407731.25,
"status": "pending",
"is_valid": true,
"valid_until":
"2026-02-03T10:03:00Z"}Possible Errors
| Code | Error | Description |
|---|---|---|
| 404 | Not Found | Quote not found |
List quotes
Authorizations
Both
x-api-key and Authorization: Bearer <token> headers are required.Endpoint
GET/v2/exchange/quotes/list/Required Headers
Content-Type: application/jsonAccept: application/jsonx-api-key: [API_KEY]Authorization: Bearer [ACCESS_TOKEN]Response
response.json
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"currency_pair": "usd/cop",
"source_amount": 100.00,
"destination_amount": 407731.25,
"status":
"pending"}
]Latest valid quote
Authorizations
Both
x-api-key and Authorization: Bearer <token> headers are required.Endpoint
GET/v2/exchange/quotes/last/Required Headers
Content-Type: application/jsonAccept: application/jsonx-api-key: [API_KEY]Authorization: Bearer [ACCESS_TOKEN]Response
response.json
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"currency_pair": "usd/cop",
"source_amount": 100.00,
"destination_amount": 407731.25,
"is_valid": true
}Available currency pairs
Authorizations
Both
x-api-key and Authorization: Bearer <token> headers are required.Endpoint
GET/v2/exchange/currency-pairs/Required Headers
Content-Type: application/jsonAccept: application/jsonx-api-key: [API_KEY]Authorization: Bearer [ACCESS_TOKEN]Response
response.json
{
"currency_pairs": [
"usd/cop", "usd/mxn", "usd/pen", "usd/clp",
"cop/usd", "cop/mxn", "cop/pen", "cop/clp",
"mxn/cop", "mxn/usd", "mxn/pen", "mxn/clp",
"pen/usd", "pen/mxn", "pen/cop", "pen/clp",
"clp/usd", "clp/mxn", "clp/pen",
"clp/cop"]
}Cross-border movements
Start movement
Authorizations
Both
x-api-key and Authorization: Bearer <token> headers are required.Endpoint
POST/v2/exchange/initiate/Required Headers
Content-Type: application/jsonAccept: application/jsonx-api-key: [API_KEY]Authorization: Bearer [ACCESS_TOKEN]Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| quote_id | UUID | Valid quote UUID | |
| source_account_id | string | Source account ID | |
| destination_account_id | string | Destination account ID | |
| bank_account_id | int | User bank account ID (ThirdPartyBankAccount) | |
| destination_description | string | Movement description | |
| external_id | string | External tracking ID |
Response
response.json
{
"sale_crypto_id": "123",
"quote_id":
"456"}Possible Errors
| Code | Error | Description |
|---|---|---|
| 400 | Bad Request | Quote expired or already used |
| 404 | Not Found | Quote not found |
| 502 | Bad Gateway | Error processing movement |
Execute manual payout
Authorizations
Both
x-api-key and Authorization: Bearer <token> headers are required.Endpoint
POST/v2/exchange/execute/Required Headers
Content-Type: application/jsonAccept: application/jsonx-api-key: [API_KEY]Authorization: Bearer [ACCESS_TOKEN]🔧
Internal use or special cases. Standard flow performs automatic payout when movement is completed.
Movement statuses
| Status | Description |
|---|---|
initiated | Movement started |
processing | In progress |
completed | Completed -> automatic payout is created |
rejected | Rejected |
failed | Failed |
returned | Returned |
canceled | Canceled |