Skip to main content

Start Here

This page is the shortest path from zero to a working Avenia integration. Read it once, then follow Authentication and Your First Operation in the sandbox.

Environments​

Sandbox and production are separate environments. Each one has its own account, its own API keys and its own MFA setup: a key created in sandbox does not work in production.

EnvironmentAPI base URLDashboard
Sandboxhttps://api.sandbox.avenia.io:10952https://app.sandbox.avenia.io/
Productionhttps://api.avenia.io:8443https://app.avenia.io/

Every endpoint in this guide starts with /v2/, for example https://api.sandbox.avenia.io:10952/v2/account/account-info. Examples use the sandbox URL.

In sandbox no real money moves: PIX deposits up to R$1,000 are paid automatically by a simulated payer, and other rails have their own simulators (see Sandbox Usecases).

How an integration works​

  1. Authenticate. Sign each request with an API key (recommended for servers) or send a JWT from the login flow. See Authentication.
  2. Set up who operates. Your main account can operate for itself or on behalf of sub-accounts, one per end customer. Each account needs the KYC (individuals) or KYB (companies) level required by the currencies it uses.
  3. Quote. GET /v2/account/quote/fixed-rate prices the operation and returns a quoteToken.
  4. Create a ticket. POST /v2/account/tickets/ with that quoteToken executes the operation and returns what to pay (a BR Code, deposit instructions, an on-chain address) or starts the payout.
  5. Follow it to the end. Receive webhooks or read GET /v2/account/tickets/{id} until the ticket reaches a final status.

Rules that save you a support ticket​

  • A quote token lives 15 seconds and creates at most one ticket. Create the ticket right after the quote. Within those 15 seconds, re-sending the same token returns 400 cannot reuse quote token, which means the first request did create a ticket. After 15 seconds the same request returns quoteToken is invalid whether or not a ticket was created — so after a timeout, never decide from that error: look the ticket up by externalId. See Idempotency and Retries.
  • externalId is your reference, not an idempotency key. It is free text (up to 68 characters) and Avenia doesn't enforce uniqueness. Make it unique on your side and use it to find a ticket after a timeout.
  • Every quote sends inputThirdParty and outputThirdParty. Leaving them out returns 400 InvalidFieldError: InputThirdParty is invalid. Blockchain inputs also need blockchainSendMethod (PERMIT or TRANSFER).
  • Send exactly one of inputAmount or outputAmount.
  • When you act for a sub-account, send the same subAccountId on the quote and on the ticket. If the quote and the ticket name different accounts — including one with subAccountId and one without — the ticket is refused with 400 InvalidFieldError: quoteToken is invalid, the same error as an expired token. On the ticket, subAccountId is a query parameter: POST /v2/account/tickets/?subAccountId=..., not a field in the body.
  • TICKET-COMPLETE is sent for every final outcome, success or failure. Read the ticket status before marking anything as done. The exception is CANCELED: canceling an UNPAID ticket yourself sends no webhook.
  • COP, ARS and MXN only buy and pay out from USDC. See Supported Operations.

Where to go next​

You want toRead
Sign requests and fix a 401Authentication
Run a full quote → ticket in sandboxYour First Operation
See every supported currency pair and its fieldsAvailable Combinations
Understand ticket statuses, failures and failureReasonTicket Lifecycle and Failures
Handle errors and rate limitsErrors and Rate Limits
Operate for sub-accounts and move funds between accountsAccounts and Sub-accounts
Understand fees, BRLA balances and reconciliationFees, Balances and Reconciliation
Receive status updatesWebhooks in Practice