Create order
Creates an OTC order. The order is created in waiting_approval and doesn't execute until a second user approves it.
A market order executes at the current rate once approved. A limit order waits until the rate reaches target_rate, then executes once approved.
Set destination_type to control where the converted funds settle: an internal account, a crypto wallet, or a saved settlement instruction (ssi).
The Idempotency-Key header is required; requests without it are rejected.
Headers
A unique key to prevent duplicate requests. Required on all FX write operations; requests without it are rejected with a 400.
Request Body
ID of the customer the order is created for.
A market order executes at the current rate once approved. A limit order waits until the rate reaches target_rate, then executes once approved.
Possible values: market, limit
Base currency code (ISO 4217 or crypto ticker).
Quote currency code (ISO 4217 or crypto ticker).
Amount of the base currency to exchange. Must be greater than zero.
Required for limit orders. The rate at which the order should execute.
Side of the order. Defaults to sell.
Possible values: buy, sell
Where the funds come from. Fiat base currencies are funded from an account; crypto base currencies from a wallet.
Possible values: account, wallet
ID of the source account or wallet.
Where the proceeds settle. Use ssi to settle to a saved settlement instruction.
Possible values: account, wallet, ssi
ID of the destination account, wallet, or settlement instruction.
Request Examples
{
"customer_id": "85034797-3ea1-4ad8-a952-becd67d74acc",
"order_type": "market",
"pair": {
"base": "USD",
"quote": "ZAR"
},
"amount": "1000",
"source_type": "account",
"source_id": "74653c7b-ae84-45ab-8085-2d2493f86d81",
"destination_type": "ssi",
"destination_id": "b23ffd0e-d0fc-432e-acc9-c396194121b3"
}
{
"customer_id": "85034797-3ea1-4ad8-a952-becd67d74acc",
"order_type": "limit",
"pair": {
"base": "USD",
"quote": "ZAR"
},
"amount": "1000",
"target_rate": "17.50",
"source_type": "account",
"source_id": "74653c7b-ae84-45ab-8085-2d2493f86d81",
"destination_type": "ssi",
"destination_id": "b23ffd0e-d0fc-432e-acc9-c396194121b3"
}
Responses
| Status | Description |
|---|---|
200 |
Order created and awaiting approval |
400 |
Invalid request |
401 |
Missing or invalid API key |
500 |
Internal server error |
200 response
Internal UUID of the order.
Human-readable order reference. Use this value as the order_id path parameter in the order endpoints.
Possible values: market, limit
Possible values: buy, sell
Base currency code (ISO 4217 or crypto ticker).
Quote currency code (ISO 4217 or crypto ticker).
Amount of the base currency to exchange.
Proceeds in the quote currency.
Rate applied to the order.
Target rate for limit orders. Returns null for market orders.
Fee charged for the order, if any.
Current order status: * waiting_approval: created and waiting for a second user to approve or reject * pending: approved; the funds are charged and the order is executing * rejected: a reviewer rejected the order * cancelled: cancelled before execution * expired: not approved before it expired
ID of the customer the order was created for.
ID of the tenant that owns the order.
Where the funds come from (account or wallet).
ID of the source account or wallet.
Where the proceeds settle (account, wallet, or ssi).
ID of the destination account, wallet, or settlement instruction.
ID of the user who created the order.
Role of the user who created the order.
ID of the user who approved the order. null until approved.
When the order was approved. null until approved.
ID of the user who rejected the order. null unless rejected.
When the order was rejected. null unless rejected.
Reason given when the order was rejected. null unless rejected.
When the order executed. null until executed.
When the proceeds settled. null until settled.
When the order expires if it isn't approved. null when the order doesn't expire.
When the order was last updated. null if never updated.
{
"data": {
"id": "4994339f-4a19-47ef-a86b-1005eff0a4d0",
"order_id": "OTC-0VA89I",
"order_type": "market",
"side": "sell",
"pair": {
"base": "USD",
"quote": "ZAR"
},
"amount": "1000.00000000",
"amount_currency": "USD",
"converted_amount": "16242.50000000",
"converted_currency": "ZAR",
"rate": "16.24250000",
"target_rate": null,
"fee": null,
"status": "waiting_approval",
"customer_id": "85034797-3ea1-4ad8-a952-becd67d74acc",
"tenant_id": "dfa96ede-fc13-43cf-8328-8b910d1cd1d2",
"source_type": "account",
"source_id": "74653c7b-ae84-45ab-8085-2d2493f86d81",
"destination_type": "ssi",
"destination_id": "b23ffd0e-d0fc-432e-acc9-c396194121b3",
"created_by_user_id": "804201c6-2760-4da1-9c5e-0ff09ebc3b5e",
"created_by_role": "developer",
"approved_by_user_id": null,
"approved_at": null,
"rejected_by_user_id": null,
"rejected_at": null,
"rejection_reason": null,
"executed_at": null,
"settled_at": null,
"expires_at": null,
"created_at": "2026-07-03T15:32:37.878676Z",
"updated_at": null
},
"error": null
}
400 response
Always null for error responses.
Human-readable error message.
{
"data": null,
"error": "missing idempotency key in request headers"
}
{
"data": null,
"error": "missing x-customer-id in metadata"
}
{
"data": null,
"error": "missing required field 'order_type', missing required field 'base', missing required field 'quote', missing required field 'amount'"
}
{
"data": null,
"error": "field 'order_type' must be one of: market limit"
}
{
"data": null,
"error": "field 'amount' failed validation on 'gt_zero_string'"
}
{
"data": null,
"error": "target_rate is required for limit orders"
}
{
"data": null,
"error": "currency pair USD/XXX is not supported"
}
{
"data": null,
"error": "source type for USD must be 'account', got 'vault'"
}
{
"data": null,
"error": "failed to create order"
}
401 response
Always null for error responses.
Human-readable error message.
{
"data": null,
"error": "Invalid or missing Api-Key header. Api-Key is required!"
}
{
"data": null,
"error": "Invalid token!"
}
500 response
Always null for error responses.
Human-readable error message.
{
"data": null,
"error": "Internal server error"
}
Authorization
- ApiKeyAuth