Errors
An error is an HTTP status with an RFC 9457 problem body (application/problem+json):
{
"type": "https://developer.jeton.com/errors/#scope_missing",
"title": "Missing scope",
"status": 400,
"detail": "This API key is not granted the 'payouts:write' scope.",
"code": "scope_missing",
"traceId": "4bf92f3577b34da6a3ce929d0e0e4736"
}
| Field | What it is |
|---|---|
code |
The stable, machine-readable reason. Branch on this. |
status |
The HTTP status, repeated. |
title |
A short label for the code. |
detail |
Text written for a person, about this occurrence. It can change at any time and can be absent: show it or log it, never parse it. |
type |
A link to the code's section on this page. |
traceId |
Quote it when you contact Jeton support. |
errors |
Only on validation_failed: one entry per field. |
Handling an error
The status says what kind of answer it is, the code says which one:
| Status | Meaning | What to do |
|---|---|---|
400 |
The request was refused: it is not valid, or a business rule did not allow it. No money moved. | Fix the request, or the situation the code names, and send it again under a new Idempotency-Key: the same key replays the same refusal. request_in_progress is the exception. |
401 |
Authentication failed. | Check your signing, as Signing requests shows. |
404 |
There is no such resource for you. | Check the id. |
429 |
Too many requests. Nothing was carried out. | Wait, then send it again, as the code's section says. |
500 |
Something failed on our side, or the outcome is not known yet. It is never a refusal. | Retry. A request that moves money is retried with the same Idempotency-Key: you get what the first attempt made, never a second movement. |
The codes on this page are the ones the API documents. Like the enums it returns, the set is open: a code that is not
listed here can appear with any status. Handle a code you do not know by its status, as the table above says, and log
its code and traceId.
400: refused
validation_failed
The request does not meet the schema or a field's rules. errors lists every field at fault:
"errors": [
{ "field": "merchantReference", "code": "not_empty", "message": "…" }
]
field is where the field sits in your request, and code is the field's own reason: for example not_empty,
minimum_length, maximum_length or regular_expression. An enum value you send that the API does not know is
validation_failed too. Fix the fields and send the request again.
idempotency_key_required
A request that moves money (POST /payments, /payouts, /transfers or /fx/exchanges) came without an
Idempotency-Key header. Send one: a UUID is recommended.
idempotency_key_invalid
The Idempotency-Key is too long or has characters it may not have. It must be 1–255 printable ASCII characters,
without spaces.
idempotency_key_reused
The key was used before for a different request: another method, path or body. A key keeps answering for the first request it was sent with, however long ago. Send a different request under a new key.
request_in_progress
The first request sent with this key has not finished yet. Wait for Retry-After (one second), then retry with the
same key and the same request.
request_not_executed
A payout or transfer request was left unanswered and not retried for 15 minutes, and the platform settled it as never
carried out. Nothing moved, and its merchantReference is free again. Every retry under that key gets this answer, so
send the request again under a new key.
duplicate_merchant_reference
The merchantReference is already taken, and the request came under a new Idempotency-Key. A payment or an exchange
takes its reference for good. A payout or a transfer takes it while the movement holds it: a refused one frees it.
If you are retrying an earlier request, retry it with its original Idempotency-Key. To see what holds the
reference, list with ?merchantReference= (GET /payments, GET /payouts, GET /transfers).
insufficient_funds
The account to debit does not have enough balance for this movement. Add funds, then send the request again. A refused
payout or transfer frees its merchantReference; a refused exchange stays failed and keeps it, so the new attempt
needs a new reference as well as a new key.
limit_exceeded
The movement would go over a limit. detail describes which. Send it again once the limit's period has passed, or
send a smaller amount.
declined
The platform declined the operation. The answer does not say why, and sending the same request again will not change
it. If you think it is wrong, contact Jeton support with the traceId.
no_account_for_currency
You hold no account in the currency the request needs: for a payment, an account in its currency to credit; for a
payout, transfer or exchange that does not name its source account, an account in the currency to debit.
GET /accounts lists your accounts.
merchant_not_active
Your merchant account is not in a state that allows it to take payments or move money. Contact Jeton support.
unsupported_currency
The currency is not supported for this operation.
payment_method_not_enabled
The payment's method is not enabled for you. GET /payment-methods lists the methods you can use.
scope_missing
The API key is not granted the scope the endpoint requires. detail names the scope, and GET /me lists the scopes
the key has. Use a key that has the scope.
payout_rail_unavailable
No payout rail can reach this bank beneficiary for you in this currency, or the instant route does not serve it.
POST /payouts/requirements tells you before you pay.
payout_recipient_not_found
The individual named in a jeton_account payout did not resolve: no such user, no active account in the payout
currency, or not an individual. These are one answer on purpose. A business on Jeton is paid with a transfer
(POST /transfers).
payout_network_unavailable
The network of a crypto_wallet payout is not an active network of the asset. GET /accounts/{accountId} lists the
networks of a crypto account.
payout_network_required
The asset of a crypto_wallet payout is active on more than one network, and the payout does not name one. Name the
network: some networks share an address format, and money sent on the wrong one is lost.
payout_invalid_wallet_address
The address of a crypto_wallet payout is not valid on its network. Nothing was priced or sent.
fx_quote_expired
The quote has expired, has already been used, or is not known. Get a new one with POST /fx/quotes.
fx_same_currency_not_allowed
The sell and buy currencies are the same.
fx_target_account_not_found
You hold no account in the buy currency. GET /accounts lists your accounts.
fx_account_currency_mismatch
A named account (sellAccountId or buyAccountId) is in another currency than the side it is named for.
currency_mismatch
The destination account of an own_account transfer is in another currency than the source account; or, for a
sandbox deposit, amount.currency is not the account's currency.
destination_not_found
The business named in a business transfer did not resolve: no such business, it cannot receive, it has no account in
the currency, or the owner e-mail is shared by several businesses. These are one answer on purpose. An individual on
Jeton is paid with a payout (POST /payouts).
destination_is_self
The business destination is your own business. Move money between your own accounts with an own_account
destination.
destination_is_source
The own_account destination is the account the transfer is debited from.
transfer_failed
The transfer was refused for a reason that has no code of its own. Like any refusal, it does not use up the
merchantReference. If it happens again, contact Jeton support with the traceId.
401: not authenticated
unauthorized
Every authentication failure gives this one answer: an unknown key, a bad signature, a timestamp more than 300 seconds off, a reused nonce, or an IP allowlist rejection. They look the same by design. Check the usual causes.
404: not found
not_found
There is no such resource for you. An id that does not exist and one that belongs to another merchant give the same
answer, by design. A named account that is not yours is not_found too.
429: too many requests
rate_limit_exceeded
The API key went over its rate limit. Limits apply per key over a fixed one-minute window; GET /me reports yours,
and every authenticated response carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset. Wait for Retry-After
seconds. Nothing was carried out and no Idempotency-Key was used up, so a request that moves money is retried with
the same key.
payout_recipient_lookup_limited
Too many of this API key's payout recipients have failed to resolve lately. Payouts to jeton_account recipients are
refused for the rest of the window, even to recipients that exist. Check the recipients you send, and send the payout
again later under a new Idempotency-Key: the same key replays this answer.
destination_lookup_limited
Too many of this API key's business transfer destinations have failed to resolve lately. Transfers to businesses are
refused for the rest of the window, even to businesses that exist. Check the destinations you send, and send the
transfer again later under a new Idempotency-Key: the same key replays this answer.
500: our side
internal_error
Something failed unexpectedly, or the platform could not reach the store that guarantees a safe retry, and refused the
request rather than run it without that guarantee. Retry; a request that moves money is retried with the same
Idempotency-Key. For a payout or a transfer, ?merchantReference= on its list also finds it, if it was made.
merchant_payout_temporarily_unavailable
A payout route or the exchange service could not be reached, or the outcome of a movement is not known yet. Retry; a
request that moves money is retried with the same Idempotency-Key.