Errors and rate limits
Failures with a Personal Access Token come from two different places, and they look different. Knowing which one you are looking at is most of the debugging.
Two error shapes​
The gateway rejects the token before your request reaches any Paysera service. Its errors carry
error and message:
{
"error": "invalid_token",
"message": "PAT is not valid"
}
The service rejects the request after the token was accepted — a missing scope, an invalid
parameter, a transfer in the wrong state. Those use the standard Paysera format with error and
error_description, documented in the
Error codes reference:
{
"error": "invalid_parameters",
"error_description": "Parameter 'amount' is required"
}
If you see message, the problem is with the token. If you see error_description, the token was
fine and the problem is with the request.
Token errors​
| Status | error | Meaning | Fix |
|---|---|---|---|
| 401 | missing_token | No Authorization header, or it does not use the Bearer scheme | Send Authorization: Bearer <token> |
| 401 | invalid_token | The token is not recognised, or validation refused it for another reason | Check the token in your token list; issue a new one if it was revoked |
| 401 | token_expired | The token is not active — it expired, or it was suspended or revoked | Check the token's status before assuming the expiry passed: a suspended token can be reactivated |
| 401 | validation_error | The token could not be validated at all | Transient — retry; if it persists, contact support |
| 403 | forbidden | The request came from an IP outside the token's allowed list | Add the egress address, or clear the restriction |
missing_token with a token presentThe cause is always the shape of the header, not the token: Authorization: <token> without the
scheme, or a capitalisation the gateway does not accept. A damaged token produces a different error —
see below.
The gateway only inspects a token it can decode and whose typ claim is PAT. Two kinds of
bearer token therefore skip its checks entirely and are handed to the service unchecked: a token
that lost a segment — the usual result of copying it out of a terminal and losing the tail — and a
perfectly valid bearer token of some other kind, sent here by mistake. You then get an error_description body for what is really a
broken credential, so the rule above ("error_description means the token was fine") does not hold
in this one case. A token that kept its three segments but lost part of the signature is decoded and
rejected properly, with invalid_token.
Spending-limit errors​
| Status | error | Meaning | Fix |
|---|---|---|---|
| 409 | token_spending_limit_exists | The token already has a spending-limit record | There is no update and no delete. Revoke the token and create a new one with the amounts you want — see Changing or removing the limits. |
| 403 | (service error) | The GET found no limit record for this token | Not an IP problem. The token simply has no record — write one with the POST while the slot is open |
| 400 | (service error) | The POST body carried neither limit | Send per_transaction_limit, daily_aggregate_limit, or both |
403 answersA 403 from the allowed-IP check and a 403 for a missing limit record look alike in the status
line. The body separates them: the gateway's IP refusal carries error and message, the missing
record carries error and error_description.
Scope errors​
A token that is valid but lacks the scope for an operation is rejected by the service, not by the
gateway, so it comes back in the error_description shape. Check the scope column in
Available endpoints against the scopes on your
token.
Scopes cannot be added to an existing token. If a token is missing one, create a new token with the right set and retire the old one.
Rate limits​
Requests to the Personal Access Token endpoints are rate limited at the gateway:
| Limit | Value |
|---|---|
| Requests | 50 per 60 seconds |
| Counted per | Client IP address |
| Response when exceeded | 429 Too Many Requests |
Two details worth knowing:
- The counter is keyed on the IP address, not on the token. Several tokens used from the same host draw on the same budget, and so do several processes on that host.
- Every endpoint has its own budget. The 50 requests are counted per gateway route, so each row in the tables of this guide gets its own allowance. Do not measure the remaining budget on one endpoint and assume it applies to another.
- Each response carries
X-RateLimit-Limit,X-RateLimit-RemainingandX-RateLimit-Reset. Read them rather than discovering the limit by hitting it.
On 429, wait for the number of seconds in X-RateLimit-Reset and then retry. Fall back to an
exponential back-off only if the header is missing. Polling a transfer's status in a tight loop is
the usual way to run into this; poll every few seconds instead, or wait for the callback.
Transfers that fail after they were accepted​
A transfer can be accepted by the API and still not happen: the spending limits on the token are
enforced during processing. Look for the transfer failure codes
token_transaction_limit_exceeded and token_daily_limit_exceeded, and see
Token controls for how the limits are applied.
Troubleshooting checklist​
- Is the host right? The token described in this guide is accepted only on
api.paysera.com— see Base URL. - Is the path right? The PAT paths carry a
/publicprefix —/public/transfer/rest/v1/..., not/transfer/rest/v1/.... - Is the header right?
Authorization: Bearer <token>, with the full token. - Is the token active? Check its status in your token list —
ACTIVE, notSUSPENDEDorEXPIRED. - Does the token carry the scope the endpoint requires?
- Is the account allowed? If the token is pinned to specific accounts, other accounts are refused.
- Is the egress IP allowed? Check what address your requests actually leave from.
- Are you inside the rate limit? Look at
X-RateLimit-Remaining, and atX-RateLimit-Resetfor the seconds until the window opens again.
The access log in your token list answers most of these directly: it shows each request the token made, with the method, path and response status.
Support​
Still stuck? Contact: tech_support@paysera.com