Errors and Rate Limits
Error response
A request that fails returns an HTTP status of 400 or higher and a JSON body with an error field:
{
"error": "InvalidFieldError: inputCurrency-inputPaymentMethod is invalid"
}
Some errors add extraInfo with a hint about how to fix the request. Branch on the HTTP status and on the type at the start of error; show the rest of the message in logs, not to your end user.
Type at the start of error | Status | Meaning | Fix it by |
|---|---|---|---|
InvalidFieldError: <field> is invalid | 400 | A field is missing, malformed or not allowed in this combination. | Correcting that field. A pair like inputCurrency-inputPaymentMethod means the combination isn't supported — see Supported Assets. |
InvalidBodyError: could not parse body data | 400 | The body isn't valid JSON for this route. | Fixing the body. |
AlreadyExistsError, DoesNotExistError, UnsupportedError | 400 | The resource already exists, doesn't exist, or the operation isn't supported. | Changing the request. |
UnauthorizedError | 401 | Authentication failed. | See Fixing a 401. |
ForbiddenError | 403 | The access is authenticated but not allowed to do this. extraInfo says why, for example PayOut permission is required to create tickets with external payment methods. | Using an access with the right permissions — see Accesses Management. |
NotFoundError: <thing> not found | 404 | The resource doesn't exist for this account. A sub-account's ticket read without subAccountId also returns 404. | Checking the ID and the subAccountId. |
| — | 429 | Too many requests. | Waiting and retrying — see Rate limits. |
InternalError: please contact us | 500 | Something failed on Avenia's side. | Retrying later; if it persists, contacting support with the request time and IDs. On POST /v2/account/tickets/, a ticket may still have been created: look it up by externalId before creating again — see Idempotency and Retries. |
Other 400 errors carry a plain message that explains itself, for example cannot reuse quote token (see Idempotency and Retries) or COP deposits can only buy USDC….
A few routes return their own error codes, listed on their page — for example Notification Contacts.
Errors that happen after a ticket was created don't come back as HTTP errors: the ticket ends FAILED or PARTIAL-FAILED with a failureReason. See Ticket Lifecycle and Failures.
Common field errors
error | Cause |
|---|---|
InvalidFieldError: InputThirdParty is invalid | inputThirdParty / outputThirdParty missing from the quote. Both are required. |
InvalidFieldError: inputAmount/outputAmount is invalid | Both amounts were sent, or neither. Send exactly one. |
InvalidFieldError: InputAmount is invalid | The amount isn't a valid number — for example 10,5. Use a dot as the decimal separator: 10.5. |
InvalidFieldError: outputCurrency-outputPaymentMethod is invalid | That token isn't supported on that network or method — see Supported Networks and Tokens. Send the method alone (BANK-TRANSFER, POLYGON), never prefixed with the currency. |
InvalidFieldError: quoteToken is invalid | The quote expired (15 seconds) or the quote and the ticket name different accounts. |
InvalidFieldError: ticketBlockchainOutput.beneficiaryWalletId is invalid | The ID isn't one of your registered wallets or accounts — see beneficiaryWalletId by operation. |
Rate limits
Avenia doesn't publish the exact limits, and they can change. When you send too many requests, the API answers 429 with {"error":"too many requests, please try again later"}. The response has no Retry-After header: wait and retry with exponential backoff (for example 1 s, 2 s, 4 s…).
- Login and password routes (
/v2/auth/login,/v2/auth/validate-login, password reset) are limited per IP address. Servers should authenticate with an API key instead of logging in repeatedly. - PIX key lookups (
GET /v2/account/bank-accounts/brl/pix-info) use a token budget that refills over time; invalid lookups cost more than valid ones. When it runs out the API returns429withDICT token limit reached. See DICT Lookup Limits. - Poll ticket status at a modest interval (every few seconds), or better, use webhooks.