Skip to main content

Troubleshooting Your API Requests

REST error response​

Every error response of the Payments API has the same format and contains exactly one error:

{
"code": 7004,
"error_message": "TRANSFER_INSUFFICIENT_FUNDS",
"description": "Insufficient funds on the source account. Check the balance, then fund the source account or reduce the amount."
}
FieldTypeUse
codeintegerStable numeric business code. Use it in your error handling.
error_messagestringStable public name of the error. Use it in your error handling and logs.
descriptionstringShort human-readable hint. The text may change without notice; do not parse it.

The HTTP status describes the transport and API layer. code and error_message identify the exact problem.

HTTP status guide​

HTTPMeaningCodes
400The request structure is invalid3000
401Authentication failed1000, 1001
403The operation is not permitted1002, 7002
404The account or transfer was not found2000, 7010
409Conflict with the idempotency key or the account state3016, 7004
422Request parameters or transfer rules validation failed3001, 7000, 7001, 7003, 7005, 7006, 7007, 7009
429Rate limit exceeded3015
500Internal error, or the transfer outcome is unknown3, 7008
503Service temporarily unavailable2

Payments API error codes​

The Retry column describes automatic retries. No means that repeating the request without fixing the cause will not help; it does not prevent you from sending a corrected request. After fixing authentication or permissions, resend the same transfer request with the same idempotency key. After a rate-limit error, wait and reduce the request rate before resending.

For transfer creation, the client actions apply while no request sent with the idempotency key has had an unknown outcome. After an unknown outcome, an error on a retry leaves the outcome unknown: do not change the request or the key to get past the error. Follow Recovery and idempotency to decide whether to resend, fix the cause, or close the record and check Transaction History.

Operations: Create — POST /v1/transfers; Balance — GET /v1/accounts/{account_id}/balance; Status — GET /v1/transfers/{transfer_id}.

HTTPcodeerror_messageReturned byRetryClient action
4003000REQUEST_INVALIDAllNoThe body is not valid JSON. Fix the request structure.
4011000AUTH_INVALID_API_KEYAllNoThe API key is invalid or inactive. Check the key.
4011001AUTH_INVALID_SIGNATUREAllNoSignature verification failed. Check the signing steps; see the checklist below.
4031002AUTH_PERMISSION_DENIEDAllNoThe operation is outside the scopes of the key, or your source IP is not allowed for the key. Check the scopes and the allowed IPs of the key.
4037002TRANSFER_SOURCE_NOT_ALLOWEDCreateNoThe source account is not your Partner Reward Wallet. Use your Reward Wallet for transfers to another client.
4042000ACCOUNT_NOT_FOUNDCreate, BalanceNoThe account does not exist, is not available to your key, or does not match destination_type. Check the account number.
4047010TRANSFER_NOT_FOUNDStatusNoThe transfer does not exist, you are neither its sender nor its recipient, or its type is not covered by the scopes of your key. Check the identifier.
4093016REQUEST_IDEMPOTENCY_KEY_REUSEDCreateNoThe key was already used with a different request. On a retry, resend the original request unchanged with the same key. For a new transfer, generate a new key.
4097004TRANSFER_INSUFFICIENT_FUNDSCreateNoNot enough funds on the source account. Fund the account or reduce the amount.
4223001REQUEST_INVALID_PARAMETERSAllNoParameters did not pass validation: a required field is missing, or a value has a wrong type or format. Check the request against the field rules.
4227000TRANSFER_NOT_SUPPORTEDCreateNoThe account combination is not supported. Choose different accounts.
4227001TRANSFER_DESTINATION_NOT_SUPPORTEDCreateNoTransfers to this destination are not supported. Choose another destination account.
4227003OPERATION_NOT_ALLOWEDCreateNoThe operation is not allowed for your account. Check account eligibility or contact support.
4227005TRANSFER_AMOUNT_TOO_SMALLCreateNoIncrease the amount.
4227006TRANSFER_AMOUNT_TOO_LARGECreateNoReduce the amount.
4227007TRANSFER_LIMIT_REACHEDCreateLaterTry again later. Changing the amount does not help.
4227009TRANSFER_MT_ACCOUNT_NOT_SUPPORTEDCreateNoMT4 and MT5 accounts are not supported. Choose an account on the Exness platform.
4293015REQUEST_RATE_LIMITAllAfter a waitWait before sending another request and reduce the request rate; see API Configuration and Limits.
5003SYSTEM_INTERNAL_ERRORAllYes, with exponential backoffFor transfer creation, reuse the same idempotency key and the same request: the outcome is unknown. Contact support if it repeats.
5007008TRANSFER_OUTCOME_UNKNOWNCreateSame key onlyResend the exact same request with the same idempotency key. See Recovery and idempotency.
5032SYSTEM_TEMPORARY_UNAVAILABLEAllYes, with exponential backoffFor transfer creation, reuse the same idempotency key and the same request: the outcome is unknown.

Best practices for handling errors​

  • Branch on the code

    Use code or error_message, never description or the HTTP status alone.

  • Check before retrying

    Use automatic retries only where the table allows them. Otherwise, fix the cause first and follow the recovery rules for transfer creation.

  • Reuse the key on retries

    For every retry of a creation request, reuse the same idempotency key and the exact same request.

  • New key only for a new transfer

    Use a new idempotency key only for a new transfer, after the outcome of the previous attempt is confirmed. If you stop sending a transfer without a 201, retire its key first.

  • Record before sending

    Save the idempotency key, request, state, and attempt time before sending. Keep this record across restarts; do not send the request if saving fails.

  • Log for reconciliation

    Log code, error_message, the idempotency key, and the transfer_id if you have one, so that you can reconcile every attempt.

Common scenarios and solutions​

ScenarioLikely causeSolution
ACCOUNT_NOT_FOUND for an account that existsdestination_type does not match the destination account, or the account is not available to your keyUse own_account for your own accounts and another_client for other clients' accounts. Check that the account is available to the key. An account that is not available to your key is always reported as ACCOUNT_NOT_FOUND, not as AUTH_PERMISSION_DENIED.
TRANSFER_SOURCE_NOT_ALLOWED on a transfer to another clientThe source account is not your Reward WalletSend transfers to other clients from your Reward Wallet, listed in the Partner Personal Area under Wallet accounts.
TRANSFER_MT_ACCOUNT_NOT_SUPPORTEDThe source or destination is an MT4 or MT5 accountUse accounts on the Exness platform.
REQUEST_INVALID_PARAMETERS on transfer creationThe idempotency key is missing or not a UUID, the source and destination are the same account, or a field has a wrong type or formatSend a random UUID in EXN-IDEMPOTENCY-KEY, use two different accounts, and check the field formats.
REQUEST_IDEMPOTENCY_KEY_REUSED on a retryThe retry differs from the original requestResend the original request unchanged, with the same key.
REQUEST_IDEMPOTENCY_KEY_REUSED on a new transferThe key was already used for another transferGenerate a new key for every new transfer.
The transfer stays processingProcessing takes longer than usual, or the transfer needs a manual checkCheck the status again later. Transfers usually complete within a few seconds, but the processing time is not guaranteed. If it stays processing beyond your own time budget, contact Customer Support with the transfer_id.
The transfer is rejectedThe transfer was not completedThe API does not return the reason. See Transaction History in the Payments & wallet section of your Personal Area.
A transfer was sent to a wrong accountWrong destination accountA transfer cannot be cancelled or reversed through the API. Contact Customer Support.
TRANSFER_NOT_FOUND for a transfer_id you receivedThe key belongs to a user who is neither the sender nor the recipient of the transfer, or its scopes do not cover this transfer typeUse a key of the sender or the recipient whose scopes cover the transfer type.

Authentication and permission checklist​

For AUTH_INVALID_API_KEY and AUTH_INVALID_SIGNATURE, follow the checks in Request signing. Checks specific to the Payments API:

  • For GET requests, EXN-IDEMPOTENCY-KEY is present with an empty value, and the signed idempotency_key is an empty string.
  • For POST /v1/transfers, the signed idempotency_key is the same UUID as in EXN-IDEMPOTENCY-KEY.
  • The signed path contains account_id or transfer_id exactly as sent in the request path.

For AUTH_PERMISSION_DENIED, check:

  • The key has the scope for the operation: Internal transfers for transfers between your own accounts, Partner transfers for transfers to another client. See Payments scopes.
  • The request comes from a source IP that is allowed for the key.

The complete signing rules are described in Request signing.

Idempotency and recovery​

Unknown outcome

After a timeout, no response, a non-API response (an HTML page, or a JSON body from a proxy or load balancer), TRANSFER_OUTCOME_UNKNOWN, SYSTEM_INTERNAL_ERROR, or SYSTEM_TEMPORARY_UNAVAILABLE, the outcome is unknown: resend the exact same request with the same idempotency key. Before every creation request, record durably that it is being sent, and send the requests of one transfer from one sender at a time.

Errors on a retry

An error on a retry after an unknown outcome does not show whether a transfer exists. Do not change the request or the key to get past it.

If you stop resending without a 201, retire the key first, so that no restart or pending resend sends it again. Then check Transaction History, and use a new key only after Customer Support confirms that no transfer was created.

The complete procedure is described in Recovery and idempotency.

Core Concepts · Code Examples · API Reference