Ramp Partner developer API errors

Fetch Off Ramp Transaction

Documentation: Fetch Off Ramp Transaction.

Endpoint: GET /api/v1/merchants/off_ramp_transaction/:reference.

reference identifies the merchant_reference supplied at initiation, rather than an internal transaction identifier. A successful response can contain a transaction failure reason in data.error_message; see Introduction.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
404Transaction not foundNo transaction matches the supplied merchant reference.

Fetch On Ramp Transaction

Documentation: Fetch On Ramp Transaction.

Endpoint: GET /api/v1/merchants/on_ramp_transaction/:reference.

reference identifies the merchant_reference supplied at initiation, rather than an internal transaction identifier. A successful response can contain a transaction failure reason in data.error_message; see Introduction.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
404Transaction not foundNo transaction matches the supplied merchant reference.

Payment Methods

Documentation: Payment Methods.

Endpoint: GET /api/v1/merchants/payment_methods.

Send currency and side as query parameters. No default currency or side is applied.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
400Invalid fiat currencyThe requested currency is unavailable; use its supported lowercase code.
400Inactive fiat currencyThe requested currency is currently inactive.
400Invalid sideside is missing or is not on_ramp/off_ramp; comparison is case-insensitive.

Purchase Limits (BUY)

Documentation: Purchase Limits (BUY).

Endpoint: GET /api/v1/merchants/purchase_limits/buy.

Send currency_symbol as a query parameter. Supported values are ngn and ghs. Supply the parameter explicitly; omission does not guarantee a fixed validation response.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
400Invalid fiat currencycurrency_symbol must be ngn or ghs.
400Invalid currency limitPurchase limits are unavailable for the requested currency.

Purchase Limit (SELL)

Documentation: Purchase Limit (SELL).

Endpoint: GET /api/v1/merchants/purchase_limits/sell.

Send token_symbol as a query parameter. This endpoint accepts usdt and usdc. The linked reference also lists xaut/usat, which are not accepted by this endpoint. Supply the parameter explicitly; omission does not guarantee a fixed validation response.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
400Invalid crypto currencyThe requested crypto currency is not supported; this endpoint accepts usdt and usdc.
400Invalid currency limitPurchase limits are unavailable for the requested currency.

Purchase Quotes (BUY)

Documentation: Purchase Quotes (BUY).

Endpoint: GET /api/v1/merchants/purchase_quotes/buy.

Use GET for this endpoint; the linked reference currently shows POST. Send currency, token, fiat_amount, and token_network as query parameters. A blockchain payout requires a network and blockchain fee. The amount is checked against your app’s applicable transaction limits.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
400Invalid networkA blockchain transaction requires a recognized token_network.
400Invalid amountThe amount is missing, negative, or outside the allowed range, or limits are unavailable. Use fiat_amount for BUY and token_amount for SELL.
400Invalid currencyA requested currency is unavailable or not enabled for your app, depending on the endpoint.
400Failed to fetch quotationThe quotation provider could not supply a quote.
400An unexpected error occurred: <exception_message>The quote request failed unexpectedly. The error details vary.
400Failed to apply stamp chargeThe transaction’s stamp charge could not be calculated or applied.
400Unable to fetch blockchain feeA blockchain fee is unavailable for the selected target currency and network.

Purchase Quotes (SELL)

Documentation: Purchase Quotes (SELL).

Endpoint: GET /api/v1/merchants/purchase_quotes/sell.

Send token, currency, token_amount, and token_network as query parameters. Blockchain transactions require a supported currency/network combination. The amount is checked against your app’s applicable transaction limits.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
400Invalid networkA blockchain transaction requires a recognized token_network.
400Invalid amountThe amount is missing, negative, or outside the allowed range, or limits are unavailable. Use fiat_amount for BUY and token_amount for SELL.
400Invalid currencyA requested currency is unavailable or not enabled for your app, depending on the endpoint.
400Failed to fetch quotationThe quotation provider could not supply a quote.
400An unexpected error occurred: <exception_message>The quote request failed unexpectedly. The error details vary.
400Failed to apply stamp chargeThe transaction’s stamp charge could not be calculated or applied.
400Invalid currency networkThe selected currency and network combination is unsupported.

Fetch On Ramp Transactions

Documentation: Fetch On Ramp Transactions.

Endpoint: GET /api/v1/merchants/on_ramp_transactions.

No matching transactions returns a successful empty list. Blank pagination parameters use defaults; per_page is capped at 50. Accepts completed, pending, failed, and supported transaction lifecycle statuses. Error responses include status even where the linked examples omit it.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
400status is invalidThe supplied status filter is not accepted for this endpoint.
400Invalid currencyThe supplied nonblank currency filter is not recognized.
400page must be a positive integerA supplied nonblank page is not a positive integer.
400per_page must be a positive integerA supplied nonblank per_page is not a positive integer. Values above 50 are capped at 50.
400start_date and end_date must both be presentExactly one of start_date and end_date was supplied.
400start_date and end_date must be valid datesOne or both supplied dates cannot be parsed.
400start_date must be less than or equal to end_datestart_date is later than end_date.
400An error occurred while fetching transactionsThe transaction list could not be retrieved.

Fetch Off Ramp Transactions

Documentation: Fetch Off Ramp Transactions.

Endpoint: GET /api/v1/merchants/off_ramp_transactions.

No matching transactions returns a successful empty list. Blank pagination parameters use defaults; per_page is capped at 50. Accepts completed, pending, failed, and supported transaction lifecycle statuses. Error responses include status even where the linked examples omit it.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
400status is invalidThe supplied status filter is not accepted for this endpoint.
400Invalid currencyThe supplied nonblank currency filter is not recognized.
400page must be a positive integerA supplied nonblank page is not a positive integer.
400per_page must be a positive integerA supplied nonblank per_page is not a positive integer. Values above 50 are capped at 50.
400start_date and end_date must both be presentExactly one of start_date and end_date was supplied.
400start_date and end_date must be valid datesOne or both supplied dates cannot be parsed.
400start_date must be less than or equal to end_datestart_date is later than end_date.
400An error occurred while fetching transactionsThe transaction list could not be retrieved.

CUSTODIAL

Introduction

Documentation: Introduction.

Errors usually return JSON like this: {"status":"bad_request","message":"Invalid amount","data":null}. The tables show the HTTP status, exact API message, and what caused it.

Validation messages can be text, such as customer first_name is missing, or an object, such as {"phone_number":["is missing"]}. Several field errors can appear together. Nested field names use spaces and keep underscores. Send all required fields with the correct types; whitespace-only values may still be rejected. Optional nullable fields accept null.

Placeholders such as <exception_message> or <remaining_amount> change with the request. The amount placeholders use decimal numbers; currency placeholders are uppercase. Some provider errors and unexpected failures have no fixed message or response format.

Rate limits, when active, allow 600 merchant requests per API key per minute and 1,000 API requests per IP per minute. A 429 response includes Retry-After: wait that many seconds before retrying. Five invalid keys within 5 minutes block the IP for 1 hour. These checks can run before authentication.

A successful request does not mean the transaction is complete. Check transaction status and webhooks. A transaction query may return HTTP 200 with data.error_message describing a failed, cancelled, or needs_attention transaction. Messages include We had an issue processing the swap. Please contact support., We couldn’t complete the payout. Please contact support., Depositor name doesn’t match the account name., and We couldn’t complete this right now. Please contact support.

For mobile-money payments, HTTP 400 with message: {"error":"UNKNOWN_AUTH_MODEL"} means the provider returned an unsupported payment step. Read the error from message.error.

Initiate On Ramp Transaction

Documentation: Initiate On Ramp Transaction.

Endpoint: POST /api/v1/merchants/custodial/on_ramp_transactions/initiate.

Send complete transaction and customer details. Missing fields may have no fixed error message. Blockchain payout needs a wallet address. This endpoint does not accept destination_tag.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
403You are not authorized to make this request.Your merchant account cannot use this endpoint.
400Currency swap not allowed: <from_currency> -> <to_currency>These currencies cannot be converted to each other.
400Wallet address is requiredBlockchain crypto payout is selected, but wallet_address is missing or blank.
400Onramp transaction disabledOn-ramp transactions are disabled for your app.
400Invalid currencyA requested currency is unavailable or not enabled for your app, depending on the endpoint.
400Invalid amountThe amount after payment-processing fees is negative or outside the applicable min/max, or limits are unavailable.
400Transaction with reference already existsThe merchant reference is already used for another transaction of this type.
400Failed to initiate swap transactionThe quotation request failed or could not be completed.
400Error in calculating markupThe transaction quote or merchant markup could not be calculated or applied.
400Error in calculating platform feeThe platform fee could not be calculated or applied.
400Network is requiredA blockchain payout requires a network.
400Total amount cannot be negativeThe quoted crypto amount is less than the blockchain fee.
400Failed to apply blockchain fees to transactionThe transaction amount could not be updated after blockchain fees.
400Failed to initiate on-ramp transactionThe buy transaction could not be created. Check the amount and transaction details.
400Customer creation failedCustomer details could not be saved. Check the email and name.
400Invalid customerThe customer is missing or cannot use this app.
400Daily on-ramp limit reachedThis buy would exceed the customer’s daily limit, including completed buys today.
400Customer account is restrictedThe customer account is suspended or banned.
400Invalid networkwallet_address.network is missing or unsupported for blockchain payout.
400Address is requiredwallet_address is present, but its address is blank.
400Invalid address formatThe destination address does not meet the selected network’s address format requirements.
400Invalid transactionThe transaction is no longer available when attaching the wallet address.
400Invalid currency networkThe selected currency and network combination is unsupported.
400Failed to add addressThe wallet address could not be attached, or the required blockchain fee is unavailable.
400<validation_messages>Some transaction details were rejected. The validation message varies.
400Unexpected error: <exception_message>The transaction failed unexpectedly. The error details vary.

Refresh On Ramp Transaction

Documentation: Refresh On Ramp Transaction.

Endpoint: PUT /api/v1/merchants/custodial/on_ramp_transactions/:transaction_ref/refresh.

Use the original merchant reference and currencies. Send from_currency, to_currency, and from_amount. A missing transaction returns 400. Amount limits apply; daily usage is not checked again.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
403You are not authorized to make this request.Your merchant account cannot use this endpoint.
400Transaction not foundNo transaction matches the supplied merchant reference.
400Transaction has already been completedThe transaction is already complete.
400Transaction currencies cannot be changedfrom_currency or to_currency differs from the currencies used to initiate the transaction.
400Invalid amountThe amount after payment-processing fees is negative or outside the applicable min/max, or limits are unavailable.
400Currency swap not allowed: <from_currency> -> <to_currency>These currencies cannot be converted to each other.
400Failed to refresh swap quotationThe quotation provider could not refresh the quote.
400Network is requiredA blockchain payout requires a network.
400Total amount cannot be negativeThe quoted crypto amount is less than the blockchain fee.
400Failed to apply blockchain fees to transactionThe transaction amount could not be updated after blockchain fees.
400Failed to refresh on-ramp transactionThe buy quote could not be updated. Check the amount and transaction details.

Initiate GHS Momo deposit

Documentation: Initiate GHS Momo deposit.

Endpoint: POST /api/v1/merchants/custodial/on_ramp_transactions/initiate_mobile_money.

Send merchant_reference, phone_number, and network_provider. Supported institution names include MTN, AIRTEL, and VODAFONE. An unknown institution returns Invalid bank code. The customer may then need to enter a PIN or OTP.

Validation fields: merchant_reference, phone_number, network_provider.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
403You are not authorized to make this request.Your merchant account cannot use this endpoint.
404Transaction does not existNo transaction matches the supplied merchant reference.
400Invalid customerThe customer is missing or cannot use this app.
400Daily on-ramp limit reachedThis buy would exceed the customer’s daily limit, including completed buys today.
400{ "<field>": ["is missing"] }A required field is missing.
400{ "<field>": ["must be filled"] }A required field is empty or null.
400{ "<field>": ["must be a string"] }The field must contain text, not another value type.
400Invalid phone numberThe account number or mobile-money phone number is blank.
400Invalid bank codeThe bank or mobile-money institution code is missing or unsupported.
400Invalid currencyA requested currency is unavailable or not enabled for your app, depending on the endpoint.
400Invalid Kyc ProfileA verified customer name is unavailable for account-name matching.
400Name does not matchThe resolved account name does not match the customer’s name.
400Invalid Currencycurrency_code does not identify a supported fiat currency. Capitalization is part of the returned message.
400Failed to resolve bank accountThe bank or mobile-money account could not be resolved. Provider details are replaced by this message.
400Failed to validate mobile money accountMobile-money account validation could not be completed.
400Mobile money deposit already existsThe transaction already has a successful mobile-money deposit.
400Mobile money network is not supportedThe mobile-money operator is unsupported for the selected payment flow.
400Provider not supportedThe configured payment provider does not support this payment flow.
400Mobile money deposit failedThe mobile-money charge could not be created or processed.
400{"error":"UNKNOWN_AUTH_MODEL"}The payment provider returned an unsupported payment step. This object appears inside message.

Verify Mobile Money Otp

Documentation: Verify Mobile Money Otp.

Endpoint: POST /api/v1/merchants/custodial/on_ramp_transactions/verify_mobile_money_otp.

Send merchant_reference and token. The linked reference uses otp, but sending only otp returns {"token":["is missing"]}. A missing transaction returns 404. This action does not check daily usage again.

Validation fields: merchant_reference, token.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
403You are not authorized to make this request.Your merchant account cannot use this endpoint.
404Transaction does not existNo transaction matches the supplied merchant reference.
400{ "<field>": ["is missing"] }A required field is missing.
400{ "<field>": ["must be filled"] }A required field is empty or null.
400{ "<field>": ["must be a string"] }The field must contain text, not another value type.
400Fiat deposit already existsA successful mobile-money deposit already exists for this transaction.
400Missing OTP tokenThe supplied token is blank, for example a whitespace-only value.
400Deposit not foundNo pending mobile-money deposit is available for OTP verification.
400Failed to verify the OTP for your mobile money deposit. Please try again.The OTP could not be verified, the provider does not support this flow, or payment processing failed.

Confirm On Ramp Transaction

Documentation: Confirm On Ramp Transaction.

Endpoint: POST /api/v1/merchants/custodial/on_ramp_transactions/:reference/confirm.

Use the original merchant_reference in the URL. If you also send merchant_reference in the request, keep it identical to the URL reference. This endpoint also returns the HTTP 400 failures below, although the linked reference lists only 403/404.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
403You are not authorized to make this request.Your merchant account cannot use this endpoint.
404Transaction does not existNo transaction matches the supplied merchant reference.
400Invalid customerThe customer is missing or cannot use this app.
400Daily on-ramp limit reachedThis buy would exceed the customer’s daily limit, including completed buys today.
403Virtual bank transfer is currently unavailable for GHS transactionsGHS virtual bank transfers are not enabled for your app.
400Transaction does not existsThe confirmation reference does not match a transaction. The spelling is part of the API response.
400Transaction is not pendingThe transaction must be pending or assigned_bank_account to be confirmed.
400Bank account has expiredThe transaction’s existing deposit bank account has expired.
400Bank account creation failedA deposit bank account could not be created or attached, or the transaction no longer allows one.

Initiate Off Ramp Transaction

Documentation: Initiate Off Ramp Transaction.

Endpoint: POST /api/v1/merchants/custodial/off_ramp_transactions/initiate.

Send currencies, amount, merchant reference, network, and customer details. Use a supported currency/network combination for the crypto deposit. A nonnumeric amount may return Unexpected error rather than Invalid amount.

Validation fields: from_currency, to_currency, from_amount, merchant_reference, customer email, customer first_name, customer last_name.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
403You are not authorized to make this request.Your merchant account cannot use this endpoint.
400<field> is missingA required field is missing.
400<field> must be filledA required field is empty or null.
400<field> must be a stringThe field must contain text, not another value type.
400<object> is missingA required nested object is missing: customer.
400<object> must be a hashA nested object must be a JSON object: customer.
400Offramp transaction disabledOff-ramp transactions are disabled for your app.
400Invalid currencyA requested currency is unavailable or not enabled for your app, depending on the endpoint.
400Invalid amountThe crypto amount is negative or outside the applicable min/max, or limits are unavailable.
400Invalid networkA blockchain-funded transaction requires a recognized network.
400Invalid currency networkThe selected currency and network combination is unsupported.
400Currency swap not allowed: <from_currency> -> <to_currency>These currencies cannot be converted to each other.
400Transaction with reference already existsThe merchant reference is already used for another transaction of this type.
400Failed to initiate swap transactionThe quotation request failed or could not be completed.
400Error in calculating markupThe transaction quote or merchant markup could not be calculated or applied.
400Error in calculating platform feeThe platform fee could not be calculated or applied.
400Failed to apply currency fees to transactionThe fiat amount could not be updated after payment-provider fees.
400Failed to apply stamp chargeThe transaction’s stamp charge could not be calculated or applied.
400Customer creation failedCustomer details could not be saved. Check the email and name.
400Invalid customerThe customer is missing or cannot use this app.
400Daily off-ramp limit reachedThis sell would exceed the customer’s daily limit, including completed stablecoin sells today.
400Customer account is restrictedThe customer account is suspended or banned.
400Unexpected error: <exception_message>The transaction failed unexpectedly. The error details vary.

Refresh Off Ramp Transaction

Documentation: Refresh Off Ramp Transaction.

Endpoint: PUT /api/v1/merchants/custodial/off_ramp_transactions/:transaction_ref/refresh.

Use PUT with the original merchant_reference in the URL. Keep both currencies unchanged and provide from_currency, to_currency, and from_amount. Validation occurs before transaction lookup; a missing transaction returns HTTP 400.

Validation fields: from_currency, to_currency, from_amount.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
403You are not authorized to make this request.Your merchant account cannot use this endpoint.
400<field> is missingA required field is missing.
400<field> must be filledA required field is empty or null.
400<field> must be a stringThe field must contain text, not another value type.
400Transaction not foundNo transaction matches the supplied merchant reference.
400Transaction has already been completedThe transaction is already complete.
400Transaction currencies cannot be changedfrom_currency or to_currency differs from the currencies used to initiate the transaction.
400Invalid amountThe crypto amount is negative or outside the applicable min/max, or limits are unavailable.
400Currency swap not allowed: <from_currency> -> <to_currency>These currencies cannot be converted to each other.
400Failed to refresh swap quotationThe quotation provider could not refresh the quote.
400Error in calculating markupThe transaction quote or merchant markup could not be calculated or applied.
400Error in calculating platform feeThe platform fee could not be calculated or applied.
400Failed to apply currency fees to transactionThe fiat amount could not be updated after payment-provider fees.
400Failed to apply stamp chargeThe transaction’s stamp charge could not be calculated or applied.
400Invalid customerThe customer is missing or cannot use this app.
400Daily off-ramp limit reachedThis sell would exceed the customer’s daily limit, including completed stablecoin sells today.
400Failed to refresh off-ramp transactionThe sell quote could not be updated. Check the amount and transaction details.

Confirm Off Ramp Transaction

Documentation: Confirm Off Ramp Transaction.

Endpoint: POST /api/v1/merchants/custodial/off_ramp_transactions/:transaction_ref/confirm.

Use the original merchant reference in the URL. Missing transactions return 400; invalid keys return 403. Confirmation generates or reuses a crypto deposit address for the selected currency and network.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
403You are not authorized to make this request.Your merchant account cannot use this endpoint.
400Transaction not foundNo transaction matches the supplied merchant reference.
400Transaction has already been completedThe transaction is already complete.
400Bank Account is required on off-ramp transactionAttach a payout bank account before confirming the sell.
400Currency network not supportedThe crypto currency and blockchain network combination is unsupported.
400Currency network not enabledThe selected crypto currency and blockchain network combination is disabled.
400No address availableA crypto deposit address is unavailable for the selected currency and network.
400Failed to assign off-ramp addressThe crypto deposit address could not be prepared.

Banks Off Ramp

Documentation: Banks Off Ramp.

Endpoint: GET /api/v1/merchants/custodial/banks.

country defaults to NG. An unsupported or blank country returns a successful empty list. Unexpected retrieval failures have no fixed message.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.

Add Bank Account Offramp

Documentation: Add Bank Account Offramp.

Endpoint: POST /api/v1/merchants/custodial/off_ramp_transactions/:transaction_ref/bank_account.

Use the original merchant_reference in the URL. Send account_number and bank_code; currency_code defaults to ngn. The resolved account name must match the customer’s name. The linked Failed to create account example is not a fixed error message for this endpoint.

Validation fields: account_number, bank_code, currency_code.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
400<field> must be filledA required field is empty or null.
400<field> must be a stringThe field must contain text, not another value type.
400Account number is requiredThe supplied account number is blank, for example whitespace-only.
400Bank code is requiredThe supplied bank code is blank, for example whitespace-only.
400Invalid Currencycurrency_code does not identify a supported fiat currency. Capitalization is part of the returned message.
400Failed to resolve bank accountThe bank or mobile-money account could not be resolved. Provider details are replaced by this message.
400Invalid account numberThe supplied account number is blank or unavailable.
400Invalid account nameAccount resolution did not return a usable account-holder name.
400Invalid bank codeThe bank or mobile-money institution code is missing or unsupported.
400Invalid ramp transaction idNo off-ramp transaction matches the supplied merchant reference.
400Invalid currencyA requested currency is unavailable or not enabled for your app, depending on the endpoint.
400Customer not foundThe transaction has no customer.
400Name does not matchThe resolved account name does not match the customer’s name.
400Currency mismatchcurrency_code differs from the transaction’s payout currency.
400Bank account can only be added to a pending or needs attention transactionYou can add a payout account only when status is pending or needs_attention.
400Invalid customerThe customer is missing or cannot use this app.
400Daily off-ramp limit reachedThis sell would exceed the customer’s daily limit, including completed stablecoin sells today.
400An error occurred while adding bank account detailsThe payout bank account could not be created or attached.
400Failed to add bank account to the offramp transaction.The bank account could not be attached to the sell.

Verify a bank account

Documentation: Verify a bank account.

Endpoint: POST /api/v1/merchants/refunds/:reference/verify_account.

Use the original buy transaction’s merchant_reference to verify the bank account details. currency_code defaults to ngn.

Validation fields: account_number, bank_code. Optional nullable strings: currency_code.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
404Transaction not foundNo transaction matches the supplied merchant reference.
400<field> is missingA required field is missing.
400<field> must be filledA required field is empty or null.
400<field> must be a stringThe field must contain text, not another value type.
400Bank not foundbank_code does not identify a supported bank.
400Account number is requiredThe supplied account number is blank, for example whitespace-only.
400Bank code is requiredThe supplied bank code is blank, for example whitespace-only.
400Invalid Currencycurrency_code does not identify a supported fiat currency. Capitalization is part of the returned message.
400Failed to resolve bank accountThe bank or mobile-money account could not be resolved. Provider details are replaced by this message.

Create an Auto Swap

Auto Swap returns a static bank account for a customer. Each eligible deposit into that account automatically starts a crypto purchase and sends the crypto to the configured wallet.

Documentation: Create an Auto Swap.

Endpoint: POST https://ramp-be.quidax.io/api/v1/merchants/custodial/auto_swap/initiate_onramp.

Send a JSON body containing customer, coin_deposit, and bank_account. merchant_reference is optional; if supplied, it must be a nonempty string unique to this setup within your app. Repeating the same customer, fiat currency, crypto destination, and direction returns the existing Auto Swap and static bank account. A reference can be attached to an existing setup that has none; an assigned reference cannot be replaced through this endpoint. This endpoint does not accept a destination tag or memo.

Validation fields: customer email, customer first_name, customer last_name, coin_deposit address, coin_deposit network, coin_deposit currency, bank_account bvn, bank_account bank_code, and bank_account currency. All are required strings. Validation errors are returned as a string in message; multiple errors can be joined with commas.

Success response: HTTP 200, status: "ok", and message: "Auto swap successfully created". data contains the complete Auto Swap object, including customer and static bank account details.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
403You are not authorized to make this request.Your merchant account cannot use this endpoint.
400<field> is missingA required field is missing.
400<field> must be filledA supplied field is empty or null, including an optional merchant reference that was provided empty.
400<field> must be a stringThe field must contain text, not another value type.
400<object> is missingA required customer, coin_deposit, or bank_account object is missing or was not supplied as an accepted JSON object.
400Feature disabledAuto swaps are disabled for your app.
400Invalid networkThe requested coin_deposit.network is not recognized.
400Invalid currencyThe fiat or crypto currency code is not recognized.
400Invalid BVNFor an NGN bank account, the trimmed BVN must contain exactly 11 digits.
400Invalid bank codeThe supplied bank code must contain digits only. Send a supported bank code as a string.
400Invalid currency networkThe selected currency and network combination is unsupported.
400Invalid wallet addressThe crypto destination address is invalid for the selected network.
400Customer creation failedCustomer details could not be saved. Check the email and name.
400Invalid customerThe customer is missing or cannot use this app.
400Merchant reference has already been usedAnother auto swap for your app uses this merchant reference.
400Auto swap already exists with a different merchant referenceThe same auto swap already exists with another merchant reference.
400Bank account creation failedA static bank account could not be created. Check the supplied details or contact support.
400Auto swap limit reachedThe customer has reached your app’s auto-swap limit, or the limit allows no auto swaps.
400An unexpected error occurredAn unexpected failure prevented the auto swap from being created.

HTTP 400 — multiple validation errors:

{
  "status": "bad_request",
  "message": "customer email is missing, customer first_name must be filled",
  "data": null
}

HTTP 400 — merchant reference conflict:

{
  "status": "bad_request",
  "message": "Auto swap already exists with a different merchant reference",
  "data": null
}

HTTP 429 — request rate exceeded:

Read the Retry-After response header and wait that many seconds before retrying. For example, Retry-After: 60 accompanies this body:

{
  "status": "too_many_requests",
  "message": "Too many requests. Try again later.",
  "data": null
}

List Auto Swaps

Return your app's Auto Swaps, including each customer's details and static bank account.

Documentation: List Auto Swaps.

Endpoint: GET https://ramp-be.quidax.io/api/v1/merchants/custodial/auto_swaps.

Optional query parameters: currency, start_date, end_date, page, and per_page. currency filters by the fiat deposit currency. Supply both dates together in YYYY-MM-DD format. page must be a positive integer no greater than 1,000,000. per_page defaults to 25 and is capped at 50.

Success response: HTTP 200, status: "ok", and message: "Auto swaps fetched successfully". data is an array of complete Auto Swap objects, with pagination in meta. No matches returns an empty array.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
403You are not authorized to make this request.Your merchant account cannot use this endpoint.
400Invalid currencyThe supplied nonblank currency filter is not recognized.
400page must be a positive integerThe supplied nonblank page is not a positive integer or exceeds 1,000,000.
400per_page must be a positive integerA supplied nonblank per_page is not a positive integer. Values above 50 are capped at 50.
400start_date and end_date must both be presentExactly one of start_date and end_date was supplied.
400start_date and end_date must be valid datesOne or both supplied dates cannot be parsed.
400start_date must be less than or equal to end_datestart_date is later than end_date.
400An error occurred while fetching auto swapsThe auto-swap list could not be retrieved.

HTTP 400 — invalid page:

{
  "status": "bad_request",
  "message": "page must be a positive integer",
  "data": null
}

Retrieve an Auto Swap

Return one Auto Swap using its merchant reference, including the customer's details and static bank account.

Documentation: Retrieve an Auto Swap.

Endpoint: GET https://ramp-be.quidax.io/api/v1/merchants/custodial/auto_swap/{merchant_reference}.

Use the setup's merchant_reference, URL-encoded in the path. The setup must belong to the app identified by your private key. An unknown reference or one belonging to another app returns HTTP 404. Unexpected server failures can have a variable response body.

Success response: HTTP 200, status: "ok", and message: "Auto swap found". data is the complete Auto Swap object.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
403You are not authorized to make this request.Your merchant account cannot use this endpoint.
404Auto swap not foundNo auto swap with this merchant reference belongs to your app.

HTTP 404 — setup not found:

{
  "status": "not_found",
  "message": "Auto swap not found",
  "data": null
}

List an Auto Swap's transactions

Return the crypto purchase transactions created from deposits into an Auto Swap's static bank account, including their status, converted amounts, and payout details.

Documentation: List an Auto Swap's transactions.

Endpoint: GET https://ramp-be.quidax.io/api/v1/merchants/custodial/auto_swap/{merchant_reference}/transactions.

Optional query parameters: status, from_currency, to_currency, start_date, end_date, page, and per_page. Use the setup's merchant reference in the URL; each buy transaction has a separately generated merchant reference. The setup is checked before filters. Supply both dates together, and use positive integers for pagination; per_page defaults to 25 and is capped at 50.

The grouped filters are completed, pending (includes pending, processing, failed_aml, needs_attention, swap_reversed, and assigned_bank_account), and failed (includes failed, abandoned, cancelled, and account_expired). Individual statuses such as processing and needs_attention are also accepted. Use lowercase values.

Success response: HTTP 200, status: "ok", and message: "Auto swap transactions fetched successfully". data contains complete transaction objects, including the nested Auto Swap, deposit details, and payout details when available. Pagination is in meta; no matches returns an empty array.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
403You are not authorized to make this request.Your merchant account cannot use this endpoint.
404Auto swap not foundNo auto swap with this merchant reference belongs to your app.
400status is invalidThe supplied status filter is not accepted for this endpoint.
400Invalid currencyThe supplied from_currency or to_currency code is not recognized. Use supported lowercase codes.
400page must be a positive integerA supplied nonblank page is not a positive integer.
400per_page must be a positive integerA supplied nonblank per_page is not a positive integer. Values above 50 are capped at 50.
400start_date and end_date must both be presentExactly one of start_date and end_date was supplied.
400start_date and end_date must be valid datesOne or both supplied dates cannot be parsed.
400start_date must be less than or equal to end_datestart_date is later than end_date.
400An error occurred while fetching transactionsThe transaction list could not be retrieved.

HTTP 400 — unsupported status:

{
  "status": "bad_request",
  "message": "status is invalid",
  "data": null
}

HTTP 404 — setup not found:

{
  "status": "not_found",
  "message": "Auto swap not found",
  "data": null
}

HTTP 200 can include a transaction whose status is needs_attention or failed. Inspect each record's status and error_message to determine the payment outcome.

List rejected Auto Swap deposits

Return deposits into your app's Auto Swap static bank accounts that could not proceed with a crypto purchase. Each record includes its amount, rejection reason, and resolution status.

Documentation: List rejected Auto Swap deposits.

Endpoint: GET https://ramp-be.quidax.io/api/v1/merchants/custodial/auto_swap/rejected_deposits.

Optional query parameters: status, currency, start_date, end_date, page, and per_page. status filters by the deposit’s resolution state; currency filters by the fiat deposit currency. Supply both dates together. page must be a positive integer no greater than 1,000,000; per_page defaults to 25 and is capped at 50.

Success response: HTTP 200, status: "ok", and message: "Rejected auto swap deposits fetched successfully". data is an array of complete rejected deposit objects, with pagination in meta. No matches returns an empty array.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
403You are not authorized to make this request.Your merchant account cannot use this endpoint.
400status is invalidThe supplied status filter is not accepted for this endpoint.
400Invalid currencyThe supplied nonblank currency filter is not recognized.
400page must be a positive integerThe supplied nonblank page is not a positive integer or exceeds 1,000,000.
400per_page must be a positive integerA supplied nonblank per_page is not a positive integer. Values above 50 are capped at 50.
400start_date and end_date must both be presentExactly one of start_date and end_date was supplied.
400start_date and end_date must be valid datesOne or both supplied dates cannot be parsed.
400start_date must be less than or equal to end_datestart_date is later than end_date.
400An error occurred while fetching rejected auto swap depositsThe rejected-deposit list could not be retrieved.

HTTP 400 — unsupported rejected deposit status:

{
  "status": "bad_request",
  "message": "status is invalid",
  "data": null
}

Rejected deposits are separate from buy transaction history. auto_swap.deposit.rejected reports a rejected deposit.

Retrieve a rejected Auto Swap deposit

Return one rejected Auto Swap deposit by its public ID, including the payment details, rejection reason, and resolution status.

Documentation: Retrieve a rejected Auto Swap deposit.

Endpoint: GET https://ramp-be.quidax.io/api/v1/merchants/custodial/auto_swap/rejected_deposits/{public_id}.

Use the rejected deposit's public_id, rather than the Auto Swap ID or a buy transaction ID. The record must belong to your app. Unexpected server failures can have a variable response body.

Success response: HTTP 200, status: "ok", and message: "Rejected auto swap deposit found". data includes public_id, status, reason, amount, currency, deposit_reference, auto_swap_public_id, customer_email, account_number, created_at, and updated_at. The amount is a decimal string.

HTTP statusExact error messageMeaning / trigger
403Private key is requiredAdd your private key to the X-Private-Key header.
403Invalid private keyYour private key is invalid, inactive, or revoked.
403IP address is not allowedYour IP address is not on your app’s allowed IP list.
429Too many requests. Try again later.You exceeded the request limit for your API key or IP. Wait the number of seconds in Retry-After before retrying.
429Too many invalid credentials. Try again later.Your IP is blocked for 1 hour after 5 invalid keys within 5 minutes. Missing keys do not count. Retry-After: 3600.
403You are not authorized to make this request.Your merchant account cannot use this endpoint.
404Rejected auto swap deposit not foundNo rejected deposit with this public_id belongs to your app.

HTTP 404 — rejected deposit not found:

{
  "status": "not_found",
  "message": "Rejected auto swap deposit not found",
  "data": null
}

Did this page help you?