Create OTC Quote
Request a conversion quote priced off Esca's OTC rate (the same basis as the
/v1/otc-rates streaming feed), with a locked-in
exchange rate. Like POST /v1/quotes, the returned
quoteId can be used when executing a conversion to guarantee the quoted rate.
POST /v1/otc-rates
Available on request. OTC pricing is opt-in — the same allowlist as the
/v1/otc-ratesWebSocket feed. Until your account is enabled, this endpoint returns403. Contact your account manager to have it enabled. The indicativePOST /v1/quotesendpoint is unaffected.
Headers
| Header | Required | Description |
|---|---|---|
X-Api-Key |
Yes | Your API key |
Content-Type |
Yes | application/json |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
amount |
number | Yes | Amount in source currency to convert (see minimum amounts below) |
sourceCurrency |
string | Yes | One of source/target must be NGN, the other a base currency |
targetCurrency |
string | Yes | One of source/target must be NGN, the other a base currency |
Supported pairs
An OTC conversion is between NGN and a base currency, in either direction —
one of sourceCurrency/targetCurrency must be NGN and the other one of USD,
EUR, GBP, USDT, USDC, BTC (e.g. NGN → USD or USD → NGN). Any other
combination (base → base, or a non-NGN local leg — including any GHS pair) is
rejected with 400.
Note:
sourceCurrencyandtargetCurrencymust be different.
Minimum Amounts
The OTC minimum is on the base currency of the pair — a flat 25,000 units
of that currency (0.4 for BTC), per the OTC desk:
| Currency | Minimum |
|---|---|
USD, EUR, GBP, USDT, USDC |
25,000 |
BTC |
0.4 |
source currency → NGN: the source amount must be at least the minimum above.-
NGN → target currency: the converted (target) amount must be at least the minimum — e.g.NGN → USDmust convert to ≥ 25,000 USD. NGN itself has no fixed floor; a request that converts below the minimum is rejected with400.
Example Request
curl -X POST "https://api.esca.finance/v1/otc-rates" \
-H "X-Api-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"amount": 50000000,
"sourceCurrency": "NGN",
"targetCurrency": "USD"
}'
Example Response
{
"status": true,
"message": "OTC quote created successfully.",
"data": {
"quoteId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"sourceCurrency": "NGN",
"targetCurrency": "USD",
"sourceAmount": 50000000,
"targetAmount": 29761.90,
"appliedRate": 1680,
"status": "PENDING",
"expiresAt": "2026-02-15T12:00:30.000Z",
"basis": "OTC"
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
quoteId |
string | UUID of the quote. Use this when executing a conversion. |
sourceCurrency |
string | Source currency |
targetCurrency |
string | Target currency |
sourceAmount |
number | Amount in source currency |
targetAmount |
number | Amount you will receive in target currency |
appliedRate |
number | Locked-in OTC exchange rate |
status |
string | Quote status: PENDING, EXECUTED, EXPIRED, CANCELLED |
expiresAt |
string | When the quote expires (ISO 8601) |
basis |
string | Always OTC for this endpoint |
Errors
| Status | When |
|---|---|
400 |
Validation failed, same source/target, a pair that isn't NGN ↔ base currency, or an amount below the OTC minimum |
401 |
Missing/invalid API key |
403 |
OTC rates not enabled for this account |
503 |
OTC rate source temporarily unavailable |
Retrieve a quote
GET /v1/otc-rates/:id
Returns the quote by its quoteId, identical in shape to the create response.
Quote Status Flow
PENDING -> EXECUTED (used in a conversion)
-> EXPIRED (time elapsed)
-> CANCELLED