PIX2STABLE - STABLE2PIX
You have received your credentials, and now we’ll walk through a very common use case: PIX to STABLE (e.g., BRLA, USDC, USDM...) and the return flow: STABLE to PIX. An important note: while this use case is demonstrated using subaccounts, it can also be applied to the main account only.
What Will We Cover Here?
- Login
- KYC
- Subaccount creation
- Subaccount KYC
- About Webhooks
- PIX IN – Sending balances to your subaccounts
- Viewing balances in your subaccounts
- PIX OUT – Withdrawing funds from a subaccount
- Using a brCode
- Using a PIX key
Login
Once you receive your credentials, use the following endpoint to authenticate and receive your JWT.
We highly recommend creating API Keys for security and convenience
.
HTTP POST Request
https://api.sandbox.avenia.io:10952/v2/auth/login
Sample JSON Body
{
"email": "your.email@provider.com",
"password": "UseAStrongPassword123!"
}
cUrl Example
curl -X POST "https://api.sandbox.avenia.io:10952/v2/auth/login" \\
-H "Content-Type: application/json" \\
-d '{
"email": "your.email@provider.com",
"password": "UseAStrongPassword123!"
}'
Upon a successful login (HTTP 200), you will receive an email with a token to validate your login.
Validate Login
Using the token (emailToken) sent to your email, call the following endpoint to receive your authentication codes (JWT):
HTTP POST Request
https://api.sandbox.avenia.io:10952/v2/auth/validate-login
Sample JSON Body
{
"email": "your.email@provider.com",
"emailToken": "777777"
}
cUrl Example
curl -X POST "https://api.sandbox.avenia.io:10952/v2/auth/validate-login" \\
-H "Content-Type: application/json" \\
-d '{
"email": "your.email@provider.com",
"emailToken": "777777"
}'
JSON Response
{
"accessToken": "eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"refreshToken": "eyJhbdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
KYC Main Account
KYC (Know Your Customer) is essential to track who is moving or receiving funds.
We’ll soon see that, to perform KYC on a subaccount, it’s enough to include the subAccountId field as a parameter in the request.
HTTP POST Request
https://api.sandbox.avenia.io:10952/v2/kyc/level-1/api
Field | Type | Required | Description |
---|---|---|---|
fullName | string | Yes | The complete name of the individual. |
dateOfBirth | string | Yes | The date of birth of the individual (Format: YYYY-MM-DD). |
countryOfDocument | string | Yes | The country issuing the document. |
documentType | string | Yes | The type of document (must be one of ID, Passport, Driver's License). |
documentNumber | string | Yes | The number of the document. |
countryOfTaxId | string | Yes | The country where the tax identification number was issued. |
taxIdNumber | string | Yes | The tax identification number of the individual. |
string | No | The email address of the individual. | |
phone | string | No | The phone number of the individual. |
country | string | Yes | The country of residence. |
state | string | Yes | The state/province of residence. |
city | string | Yes | The city of residence. |
zipCode | string | Yes | The postal code of the residence. |
streetAddress | string | Yes | The street address of the residence. |
All countries and states follow the ISO Alpha-3 standard (Example: USA-CA)
Sample JSON Body
{
"fullName": "Jane Doe",
"dateOfBirth": "1999-08-16",
"countryOfDocument": "BRA",
"documentType": "Passport",
"documentNumber": "UJ252482",
"countryOfTaxId": "BRA",
"taxIdNumber": "75764220173",
"country": "BRA",
"state": "SP",
"city": "SP",
"zipCode": "12243010",
"streetAddress": "Rua Madre Paula"
}
cUrl Example
curl -X POST "https://api.sandbox.avenia.io:10952/v2/kyc/level-1/api"
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
-H "Content-Type: application/json"
-d '{
"fullName": "Jane Doe",
"dateOfBirth": "1999-08-16",
"countryOfDocument": "BRA",
"documentType": "Passport",
"documentNumber": "UJ252482",
"countryOfTaxId": "BRA",
"taxIdNumber": "75764220173",
"country": "BRA",
"state": "SP",
"city": "SP",
"zipCode": "12243010",
"streetAddress": "Rua Madre Paula"
}
JSON Response
{
"id": "1ee11163-9tjb-4389-9f84-074ccff7085d"
}
KYC - Track KYC Validation
Before proceeding, ensure that the KYC for the main account has been successfully validated. Use the following GET endpoint:
HTTP GET Request
https://api.sandbox.avenia.io:10952/v2/kyc/attempts/**YOUR-KYC-ID-HERE**
cUrl Example
curl -X GET "https://api.sandbox.avenia.io:10952/v2/kyc/attempts/{kyc-attempt-id}" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
JSON Response - COMPLETED example
{
"attempt": {
"id": "e51359cd-04b0-4bbc-bf7d-0ee515112d74",
"levelName": "level-1",
"submissionData": null,
"status": "COMPLETED",
"result": "APPROVED",
"resultMessage": "",
"retryable": false,
"createdAt": "2025-03-25T07:39:40.54713Z",
"updatedAt": "2025-03-25T07:39:40.54713Z"
}
}
JSON Response - PENDING example
{
"attempt": {
"id": "b83802a1-afe9-46ac-96d6-ade6c5961bd3",
"levelName": "level-1",
"submissionData": null,
"status": "PENDING",
"result": "",
"resultMessage": "",
"retryable": false,
"createdAt": "2025-03-26T22:50:14.201695Z",
"updatedAt": "2025-03-26T22:50:14.201695Z"
}
}
JSON Response - REJECT example
{
"attempt": {
"id": "5bafd6cd-ec40-4dd3-83e0-a5af117c304a",
"levelName": "level-1",
"submissionData": null,
"status": "COMPLETED",
"result": "REJECTED",
"resultMessage": "name does not match",
"retryable": false,
"createdAt": "2025-03-26T22:50:14.201695Z",
"updatedAt": "2025-03-26T22:50:14.201695Z"
}
}
Create Subaccount
To register your client, create a subaccount. Subaccounts allow the Main Account (you) to manage your clients.
HTTP POST Request
https://api.sandbox.avenia.io:10952/v2/account/sub-accounts
Field | Type | Description |
---|---|---|
accountType | string | Specify "INDIVIDUAL" for a personal subaccount. |
name | string | A name for the subaccount (e.g., "Jane Doe"). |
Sample JSON Body
{
"accountType": "INDIVIDUAL",
"name": "Jane Doe"
}
cUrl Example
curl -X POST "https://api.sandbox.avenia.io:10952/v2/account/sub-accounts" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json"
-d '{
"accountType": "INDIVIDUAL",
"name": "Jane Doe"
}'
JSON Response
The response will include the ID of the created subaccount.
{
"id": "1ee0a663-922b-4389-9f84-074ccff7085d"
}
KYC for Subaccount
KYC (Know Your Customer) is essential to track who is moving or receiving funds. For subaccounts,
perform KYC using the API endpoint below. Be sure to pass the subAccountId
parameter.
Since this operation is performed for a subaccount, you must include the field as an endpoint parameter subAccountId.
HTTP POST Request
https://api.sandbox.avenia.io:10952/v2/kyc/level-1/api?subAccountId=1ee0a663-922b-4389-9f84-074ccff7085d
Field | Type | Required | Description |
---|---|---|---|
fullName | string | Yes | The complete name of the individual. |
dateOfBirth | string | Yes | The date of birth of the individual (Format: YYYY-MM-DD). |
countryOfDocument | string | Yes | The country issuing the document. |
documentType | string | Yes | The type of document (must be one of ID, Passport, Driver's License). |
documentNumber | string | Yes | The number of the document. |
countryOfTaxId | string | Yes | The country where the tax identification number was issued. |
taxIdNumber | string | Yes | The tax identification number of the individual. |
string | No | The email address of the individual. | |
phone | string | No | The phone number of the individual. |
country | string | Yes | The country of residence. |
state | string | Yes | The state/province of residence. |
city | string | Yes | The city of residence. |
zipCode | string | Yes | The postal code of the residence. |
streetAddress | string | Yes | The street address of the residence. |
All countries and states follow the ISO Alpha-3 standard (Example: USA-CA)
Sample JSON Body
{
"fullName": "Jane Doe",
"dateOfBirth": "1999-08-16",
"countryOfDocument": "BRA",
"documentType": "Passport",
"documentNumber": "UJ252482",
"countryOfTaxId": "BRA",
"taxIdNumber": "75764220173",
"country": "BRA",
"state": "SP",
"city": "SP",
"zipCode": "12243010",
"streetAddress": "Rua Madre Paula"
}
cUrl Example
curl -X POST "https://api.sandbox.avenia.io:10952/v2/kyc/level-1/api?subAccountId=1ee0a663-922b-4389-9f84-074ccff7085d"
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
-H "Content-Type: application/json"
-d '{
"fullName": "Jane Doe",
"dateOfBirth": "1999-08-16",
"countryOfDocument": "BRA",
"documentType": "Passport",
"documentNumber": "UJ252482",
"countryOfTaxId": "BRA",
"taxIdNumber": "75764220173",
"country": "BRA",
"state": "SP",
"city": "SP",
"zipCode": "12243010",
"streetAddress": "Rua Madre Paula"
}
JSON Response
{
"id": "1ee11163-9tjb-4389-9f84-074ccff7085d"
}
Track KYC Subaccount Validation
Before proceeding, ensure that the KYC for the subaccount has been successfully validated. Use the following GET endpoint:
Since this operation is performed for a subaccount, you must include the field as an endpoint parameter subAccountId.
HTTP GET Request
https://api.sandbox.avenia.io:10952/v2/kyc/attempts/**YOUR-KYC-ID-HERE**?subAccountId=1ee0a663-922b-4389-9f84-074ccff7085d
cUrl Example
curl -X GET "https://api.sandbox.avenia.io:10952/v2/kyc/attempts/{kyc-attempt-id}?subAccountId=1ee0a663-922b-4389-9f84-074ccff7085d" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
JSON Response - COMPLETED example
{
"attempt": {
"id": "e51359cd-04b0-4bbc-bf7d-0ee515112d74",
"levelName": "level-1",
"submissionData": null,
"status": "COMPLETED",
"result": "APPROVED",
"resultMessage": "",
"retryable": false,
"createdAt": "2025-03-25T07:39:40.54713Z",
"updatedAt": "2025-03-25T07:39:40.54713Z"
}
}
JSON Response - PENDING example
{
"attempt": {
"id": "b83802a1-afe9-46ac-96d6-ade6c5961bd3",
"levelName": "level-1",
"submissionData": null,
"status": "PENDING",
"result": "",
"resultMessage": "",
"retryable": false,
"createdAt": "2025-03-26T22:50:14.201695Z",
"updatedAt": "2025-03-26T22:50:14.201695Z"
}
}
JSON Response - REJECT example
{
"attempt": {
"id": "5bafd6cd-ec40-4dd3-83e0-a5af117c304a",
"levelName": "level-1",
"submissionData": null,
"status": "COMPLETED",
"result": "REJECTED",
"resultMessage": "name does not match",
"retryable": false,
"createdAt": "2025-03-26T22:50:14.201695Z",
"updatedAt": "2025-03-26T22:50:14.201695Z"
}
}
About Webhooks
Before we begin the Operations section, we’ll share a guide for integrating webhooks—this will allow you to receive real‑time updates for every stage of a Ticket event. A Ticket event refers to any update related to a created ticket (i.e., a money movement) within your Account; it may also involve a SubAccount. Events can have multiple statuses, such as TICKET‑CREATED, DEPOSIT‑PROCESSING, and so on.
We recommend following these steps in order:
Send funds to subAccount
We’ll simulate funding a SubAccount (your client) with US$165.00 via a PIX conversion from Brazilian Reais to a dollar stablecoin.
To do this, we first need to generate a QUOTE, which represents the exact amount to be transferred to the Main Account.
The quote is only valid for 15 seconds!
Here, to operate on behalf of a SubAccount, you need to include the subAccountId
parameter—this ensures that all operations are performed within the SubAccount rather than the Main Account.
HTTP GET Request
https://api.sandbox.avenia.io:10952/v2/account/quote/fixed-rate?subAccountId=YOUR-SUBACCOUNT-ID-HERE
Field | Value | Description | Required |
---|---|---|---|
inputCurrency | BRL | The currency in which the subAccount (in this case, Brazilian Reais). | yes |
inputPaymentMethod | PIX | The payment method in this case PIX method. | yes |
outputAmount | 165 | The amount that the subAccount receive (e.g., 98.58 = R$98.58). | yes |
outputCurrency | USDM | The currency in which the subAccount will receive funds. (in this case USDM stable) | yes |
outputPaymentMethod | INTERNAL | The method by which the subAccount will receive funds (as an internal balance). | yes |
inputThirdParty | false | Since the subaccount’s funds are sourced from the own subAccount, this field is not needed. | yes |
outputThirdParty | false | For payments to a subaccount, this should remain false (change to true if paying a third party). | yes |
cUrl Example
curl -X GET "https://api.sandbox.avenia.io:10952/v2/account/quote/fixed-rate?inputCurrency=BRL&inputPaymentMethod=PIX&outputAmount=165&outputCurrency=USDM&outputPaymentMethod=INTERNAL&inputThirdParty=false&outputThirdParty=false&subAccountId=YOUR-SUBACCOUNT-ID-HERE" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
JSON Response
{
"quoteToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.quoteToken....",
"inputCurrency": "BRL",
"inputPaymentMethod": "PIX",
"inputAmount": "975.11",
"outputCurrency": "USDM",
"outputPaymentMethod": "INTERNAL",
"outputAmount": "165",
"markupAmount": "0",
"markupCurrency": "",
"inputThirdParty": false,
"outputThirdParty": false,
"appliedFees": [
{
"type": "Markup Fee",
"description": "Total markup fees represented in the input currency.",
"amount": "0",
"currency": "BRL"
},
{
"type": "In Fee",
"description": "Fees due to input currency and input payment method.",
"amount": "0.2",
"currency": "BRL"
},
{
"type": "Conversion Fee",
"description": "Fees due to conversion from input currency to output currency.",
"amount": "8.77599",
"currency": "BRL"
},
{
"type": "Out Fee",
"description": "Fees due to output currency and output payment method.",
"amount": "0",
"currency": "BRL"
},
{
"type": "Gas Fee",
"description": "Fees due to blockchain transaction costs.",
"amount": "0",
"currency": "BRL"
}
],
"basePrice": "5.855378",
"pairName": "USDMBRL"
}
Ticket - Closing the Order
With the quote in hand, we will initiate the order closing process—referred to as "Ticket"—where the quote is finalized and the requested operation is executed, which in our case is a transfer to our subAccount.
Here, to operate on behalf of a SubAccount, you need to include the subAccountId
parameter—this ensures that all operations are performed within the SubAccount rather than the Main Account.
Field | Value | Description | Required |
---|---|---|---|
quoteToken | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.quoteToken.... | The quoteToken obtained from the get quote endpoint. | yes |
ticketBlockchainOutput | beneficiaryWalletId | Contains details regarding the ticket blockchain output. | yes |
└ beneficiaryWalletId | 00000000-0000-0000-0000-000000000000 | Here we set the ID of your subAccount as a zero id, which makes Avenia API link this id to your subAccount, who made the request | yes |
HTTP POST Request
https://api.sandbox.avenia.io:10952/v2/account/tickets?subAccountId=YOUR-SUBACCOUNT-ID-HERE
Sample JSON Body
Remember that here we pass a zeroed uuid because we are linking your subAccount to this deposit (who will receive the funds)
{
"quoteToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.quoteToken....",
"ticketBlockchainOutput": {
"beneficiaryWalletId": "00000000-0000-0000-0000-000000000000"
}
}
cUrl Example
curl -X POST "https://api.sandbox.avenia.io:10952/v2/account/tickets?subAccountId=YOUR-SUBACCOUNT-ID-HERE" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" \
-d '{
"quoteToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.quoteToken....",
"ticketBlockchainOutput": {
"beneficiaryWalletId": "00000000-0000-0000-0000-000000000000"
}
}
JSON Response
Here, we can see that the brCode is received, which represents the PIX payment code. The ticket will remain in a pending state until the PIX payment is completed.
If you’ve already registered a webhook for the TICKET
event, you will start receiving webhook notifications from this point onward.
{
"brCode": "00020126810014br.gov.bcb.pix01365c2c61a1-134b-4c34-958f-ea3122ac717f0219Avenia Ticket Payment5204000053039865406975.285802BR5917Avenia API Ltda6009Sao Paulo622905253Uu0qFigaAnwGdmmDJp3R9Yuz6304DE64",
"expiration": "2025-04-14T13:58:47.609482542Z",
"id": "b73767f7-1343-4176-9298-fffc85ea71a4"
}
In the sandbox environment, the PIX payment is simulated within a few seconds.
Verify status from Ticket
An alternative to continuously checking the ticket history to track its current stage is to use webhooks instead.
Next, verify if the ticket status is PAID by checking the tickets by id endpoint.
Keep in mind that the operation is still being performed by the subaccount, so it’s also necessary to include the subAccountId parameter here.
HTTP GET Request
https://api.sandbox.avenia.io:10952/v2/account/tickets/YOUR-TICKET-UUID-HERE?subAccountId=YOUR-SUBACCOUNT-ID-HERE
cUrl Example
curl -X GET "https://api.sandbox.avenia.io:10952/v2/account/tickets/b73767f7-1343-4176-9298-fffc85ea71a4?subAccountId=YOUR-SUBACCOUNT-ID-HERE" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
JSON Response
Note: The status can be in: UNPAID PROCESSING PAID FAILED PARTIAL-FAILED
{
"ticket": {
"id": "b73767f7-1343-4176-9298-fffc85ea71a4",
"externalId": "",
"workspaceId": "2ac803ad-faf7-489f-9c1a-c6a64072e699",
"userId": "05505dde-c2e4-47c5-bd5c-071b4c4bb6a4",
"status": "PAID",
"reason": "",
"failureReason": "",
"createdAt": "2025-04-14T13:53:47.618039Z",
"updatedAt": "2025-04-14T13:54:10.516442Z",
"expiresAt": "2025-04-14T13:58:47.609482Z",
"quote": {
"id": "6c2f3fcf-cb64-4fb5-96c4-51597b764bfd",
"ticketId": "b73767f7-1343-4176-9298-fffc85ea71a4",
"inputCurrency": "BRL",
"inputPaymentMethod": "PIX",
"inputAmount": "975.28",
"outputCurrency": "USDM",
"outputPaymentMethod": "INTERNAL",
"outputAmount": "165",
"markupCurrency": "",
"markupAmount": "0",
"sendMethod": "",
"inputThirdParty": false,
"outputThirdParty": false,
"basePrice": "5.856378",
"appliedFees": [
{
"type": "Markup Fee",
"amount": "0",
"currency": "BRL",
"rebatable": false,
"description": "Total markup fees represented in the input currency."
},
{
"type": "In Fee",
"amount": "0.2",
"currency": "BRL",
"rebatable": true,
"description": "Fees due to input currency and input payment method."
},
{
"type": "Conversion Fee",
"amount": "8.77752",
"currency": "BRL",
"rebatable": true,
"description": "Fees due to conversion from input currency to output currency."
},
{
"type": "Out Fee",
"amount": "0",
"currency": "BRL",
"rebatable": true,
"description": "Fees due to output currency and output payment method."
},
{
"type": "Gas Fee",
"amount": "0",
"currency": "BRL",
"rebatable": false,
"description": "Fees due to blockchain transaction costs."
}
],
"pairName": "USDMBRL",
"outputBrCode": "",
"createdAt": "2025-04-14T13:53:47Z"
},
"rebate": {
"id": "004992b7-4974-4960-8d0f-78c1ccf0be8a",
"ticketId": "b73767f7-1343-4176-9298-fffc85ea71a4",
"amount": "4.48876",
"currency": "BRLA",
"destinationWalletAddress": "0xb6e8860883039b6db937639b94e9a10ff7971bb6"
},
"brazilianFiatSenderInfo": {
"id": "b8c67775-5395-485e-ac54-9961332eed39",
"ticketId": "b73767f7-1343-4176-9298-fffc85ea71a4",
"name": "Ada Capital Gestao de Recursos Ltda",
"taxId": "45981761000100",
"bankCode": "20018183",
"branchCode": "0001",
"accountNumber": "5703785980624896",
"accountType": "payment",
"endToEndId": "e20018183202504141353vrljpogicti"
},
"blockchainReceiverInfo": {
"id": "b789bf87-3b38-49de-9558-c59a3a043ab7",
"ticketId": "b73767f7-1343-4176-9298-fffc85ea71a4",
"walletAddress": "0xe41A4a64564D19f98867a4b43E743a7D988c9d68",
"walletChain": "INTERNAL",
"walletMemo": "",
"txHash": "0xcef0ec80e723472b0d12e526fb12cdc3e94a695ffd538bea54dc7065068a9781"
},
"brlPixInputInfo": {
"id": "01115639-3e21-4218-a009-256071d6502f",
"ticketId": "b73767f7-1343-4176-9298-fffc85ea71a4",
"referenceLabel": "3Uu0qFigaAnwGdmmDJp3R9Yuz",
"additionalData": "Avenia Ticket Payment",
"brCode": "00020126810014br.gov.bcb.pix01365c2c61a1-134b-4c34-958f-ea3122ac717f0219Avenia Ticket Payment5204000053039865406975.285802BR5917Avenia API Ltda6009Sao Paulo622905253Uu0qFigaAnwGdmmDJp3R9Yuz6304DE64"
}
}
}
Checking subAccount balance
Here, we’ll retrieve all current balances for your or subaccount.
Keep in mind that the operation is still being performed by the subaccount, so it’s also necessary to include the subAccountId parameter here.
HTTP Get Request
https://api.sandbox.avenia.io:10952/v2/account/balances?subAccountId=YOUR-SUBACCOUNT-ID-HERE
Example Json Response
{
"balances": {
"BRLA": "0",
"USDC": "0",
"USDT": "0",
"USDM": "165.00000"
}
}
Subaccount Performing a Withdrawal - BrCode
Quote
Let’s prepare the withdrawal through the subaccount.
Generate a quote to determine the exact amount to be transferred.
Since the subaccount will be the one doing the ticketing (closing the order), it must be passed on to all the endpoints in this section!
The quote is only valid for 15 seconds!
Note: We have omitted the quoteToken for better readability, remembering that it is a JWT.
Notice that the outputAmount reflects the brCode value, while the inputAmount includes fees.
The fee values may vary depending on the operation.
HTTP GET Request
https://api.sandbox.avenia.io:10952/v2/account/quote/fixed-rate?subAccountId=1ee0a663-922b-4389-9f84-074ccff7085d
Field | Value | Description |
---|---|---|
subAccountId | 1ee0a663-922b-4389-9f84-074ccff7085d | ID of the subaccount paying the brCode. |
inputCurrency | USDM | Currency used by the subaccount for payment (Brazilian Reais). |
inputPaymentMethod | INTERNAL | Payment method (subaccount’s internal balance). |
outputCurrency | BRL | Currency in which the brCode will be paid (BRL only). |
outputPaymentMethod | PIX-BRCODE | Payment method for the payout (via PIX brCode). |
inputThirdParty | false | Indicates funds come from the subaccount itself. |
outputThirdParty | false | Set to true if the brCode is paid to a third party. |
blockchainSendMethod | PERMIT | Specifies that the transfer is automatically handled by Avenia API. |
outputBrCode | 00020101021226890014br.gov.bcb.pix2567brcode-h.sandbox.starkinfra.com/v2/... | The brCode that the user will pay. |
Some BrCodes do not have a specified value. In such cases, provide either the inputAmount or the outputAmount—only one amount is allowed, so do not include both.
cUrl Example
curl -X GET "https://api.sandbox.avenia.io:10952/v2/account/quote/fixed-rate?subAccountId=1ee0a663-922b-4389-9f84-074ccff7085d&inputCurrency=USDM&inputPaymentMethod=INTERNAL&outputCurrency=BRL&outputPaymentMethod=PIX-BRCODE&inputThirdParty=false&outputThirdParty=false&blockchainSendMethod=PERMIT&outputBrCode=00020101021226890014br.gov.bcb.pix2567brcode-h.sandbox.starkinfra.com/v2/fe6d7d3c6d014a9fb9db61cf40a0ee4c5204000053039865802BR5925Ada%20Capital%20Gestao%20de%20Rec6009Sao%20Paulo62070503***6304E066" \\
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
JSON Response
{
"quoteToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.quoteToken....",
"inputCurrency": "BRLA",
"inputCurrency": "USDM",
"inputPaymentMethod": "INTERNAL",
"inputAmount": "8.687072",
"outputCurrency": "BRL",
"outputPaymentMethod": "PIX-BRCODE",
"outputAmount": "50",
"markupAmount": "0",
"markupCurrency": "",
"blockchainSendMethod": "PERMIT",
"inputThirdParty": false,
"outputThirdParty": false,
"appliedFees": [
{
"type": "Markup Fee",
"description": "Total markup fees represented in the input currency.",
"amount": "0",
"currency": "USDM"
},
{
"type": "In Fee",
"description": "Fees due to input currency and input payment method.",
"amount": "0",
"currency": "USDM"
},
{
"type": "Conversion Fee",
"description": "Fees due to conversion from input currency to output currency.",
"amount": "0",
"currency": "USDM"
},
{
"type": "Out Fee",
"description": "Fees due to output currency and output payment method.",
"amount": "0.170334",
"currency": "USDM"
},
{
"type": "Gas Fee",
"description": "Fees due to blockchain transaction costs.",
"amount": "0",
"currency": "USDM"
}
],
"basePrice": "5.870793",
"pairName": "USDMBRL"
}
Ticket - Closing the Order
With the quote in hand, initiate the ticket operation to finalize the order. The subaccount will use the quote to execute the payment.
HTTP POST Request
https://api.sandbox.avenia.io:10952/v2/account/tickets?subAccountId=1ee0a663-922b-4389-9f84-074ccff7085d
Sample JSON Body
{
"quoteToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.quoteToken...."
}
cUrl Example
curl -X POST "https://api.sandbox.avenia.io:10952/v2/account/tickets?subAccountId=1ee0a663-922b-4389-9f84-074ccff7085d" \\
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \\
-H "Content-Type: application/json" \\
-d '{
"quoteToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.quoteToken...."
}'
JSON Response
{
"id": "a14d6b53-e573-4e68-b34a-2a1b717eb448"
}
Verify status from Ticket
To verify the ticket status, use the following GET endpoint:
Note: The status can be in: UNPAID PROCESSING PAID FAILED PARTIAL-FAILED
HTTP GET Request
https://api.sandbox.avenia.io:10952/v2/account/tickets/a14d6b53-e573-4e68-b34a-2a1b717eb448?subAccountId=1ee0a663-922b-4389-9f84-074ccff7085d
cUrl Example
curl -X GET "https://api.sandbox.avenia.io:10952/v2/account/tickets/a14d6b53-e573-4e68-b34a-2a1b717eb448?subAccountId=1ee0a663-922b-4389-9f84-074ccff7085d" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
JSON Response
{
"ticket": {
"id": "c7f1e168-2989-45c7-a0be-de8371ab0dcc",
"externalId": "",
"workspaceId": "2ac803ad-faf7-489f-9c1a-c6a64072e699",
"userId": "05505dde-c2e4-47c5-bd5c-071b4c4bb6a4",
"status": "PAID",
"reason": "",
"failureReason": "",
"createdAt": "2025-04-14T17:00:32.934368Z",
"updatedAt": "2025-04-14T17:01:05.452338Z",
"expiresAt": "2025-04-14T17:05:32.93273Z",
"quote": {
"id": "cf584823-ff5f-4cb5-b050-88991873d856",
"ticketId": "c7f1e168-2989-45c7-a0be-de8371ab0dcc",
"inputCurrency": "USDM",
"inputPaymentMethod": "INTERNAL",
"inputAmount": "8.692995",
"outputCurrency": "BRL",
"outputPaymentMethod": "PIX-BRCODE",
"outputAmount": "50",
"markupCurrency": "",
"markupAmount": "0",
"sendMethod": "PERMIT",
"inputThirdParty": false,
"outputThirdParty": false,
"basePrice": "5.866793",
"appliedFees": [
{
"type": "Markup Fee",
"amount": "0",
"currency": "USDM",
"rebatable": false,
"description": "Total markup fees represented in the input currency."
},
{
"type": "In Fee",
"amount": "0",
"currency": "USDM",
"rebatable": true,
"description": "Fees due to input currency and input payment method."
},
{
"type": "Conversion Fee",
"amount": "0",
"currency": "USDM",
"rebatable": true,
"description": "Fees due to conversion from input currency to output currency."
},
{
"type": "Out Fee",
"amount": "0.17045",
"currency": "USDM",
"rebatable": true,
"description": "Fees due to output currency and output payment method."
},
{
"type": "Gas Fee",
"amount": "0",
"currency": "USDM",
"rebatable": false,
"description": "Fees due to blockchain transaction costs."
}
],
"pairName": "USDMBRL",
"outputBrCode": "00020126740014br.gov.bcb.pix0136d5f144f6-a81c-4dc4-a922-0d8a999a580c0212Avenia Deposit5204000053039865802BR5917Avenia API Ltda6009Sao Paulo62100506000003630474CD",
"createdAt": "2025-04-14T17:00:32Z"
},
"rebate": {
"id": "c5395251-6e09-42c0-9c65-20641704f961",
"ticketId": "c7f1e168-2989-45c7-a0be-de8371ab0dcc",
"amount": "0.49825",
"currency": "BRLA",
"destinationWalletAddress": "0xb6e8860883039b6db937639b94e9a10ff7971bb6"
},
"brazilianFiatReceiverInfo": {
"id": "0f222399-5999-4963-a678-bf37cb4b586d",
"ticketId": "c7f1e168-2989-45c7-a0be-de8371ab0dcc",
"taxId": "45.981.761/0001-00",
"userName": "Ada Capital Gestao de Recursos Ltda",
"bankCode": "00020126740014br.gov.bcb.pix0136d5f144f6-a81c-4dc4-a922-0d8a999a580c0212Avenia Deposit5204000053039865802BR5917Avenia API Ltda6009Sao Paulo62100506000003630474CD",
"brCode": "00020126740014br.gov.bcb.pix0136d5f144f6-a81c-4dc4-a922-0d8a999a580c0212Avenia Deposit5204000053039865802BR5917Avenia API Ltda6009Sao Paulo62100506000003630474CD",
"endToEndId": "e20018183202504141700tmr7f1lyplb"
},
"blockchainSenderInfo": {
"id": "9ac928d2-dba1-43c9-a338-faf26989f486",
"ticketId": "c7f1e168-2989-45c7-a0be-de8371ab0dcc",
"walletAddress": "0xe41A4a64564D19f98867a4b43E743a7D988c9d68",
"txHash": "0x34bc4f07090ef5a686a3a78a50f49c298707cc1b8231d4c267a5042cd4eda85b"
},
"brlPixOutputInfo": {
"id": "147de45c-3547-4f7f-be5f-50055f1aa5ca",
"ticketId": "c7f1e168-2989-45c7-a0be-de8371ab0dcc",
"pixMessage": "",
"senderAccountBankName": "starkbank",
"senderAccountNumber": "4790427303542784"
},
"blockchainInputInfo": {
"id": "e492feb0-b90f-4884-9ac7-7c789ddb37a2",
"ticketId": "c7f1e168-2989-45c7-a0be-de8371ab0dcc",
"r": "",
"s": "",
"v": 0,
"nonce": 0,
"deadline": 0,
"personalSignature": "",
"personalSignatureDeadline": 0
}
}
}
Subaccount Performing a Withdrawal - PixKey
Let’s go through the process of withdrawing BRL from your subaccount using a PIX key (e.g., CPF, RANDOM, phone number, etc.).
Quote
In the following steps, the operation is still performed through the subaccount, so including the subAccountId
parameter is mandatory.
Given this, your quote request must include the following fields:
HTTP Get Request
https://api.sandbox.avenia.io:10952/v2/account/quote/fixed-rate?subAccountId=1ee0a663-922b-4389-9f84-074ccff7085d
Field | Value | Description |
---|---|---|
subAccountId | 1ee0a663-922b-4389-9f84-074ccff7085d | ID of the subaccount paying the brCode. |
inputCurrency | USDM | Currency used by the subaccount for payment (Brazilian Reais). |
inputPaymentMethod | INTERNAL | Payment method (subaccount’s internal balance). |
outputCurrency | BRL | Currency in which the brCode will be paid (BRL only). |
outputPaymentMethod | PIX | Payment method for the payout (via PIX brCode). |
inputThirdParty | false | Indicates funds come from the subaccount itself. |
outputThirdParty | false | Set to true if the brCode is paid to a third party. |
blockchainSendMethod | PERMIT | Specifies that the transfer is automatically handled by Avenia API. |
cUrl Example
curl -X GET "https://api.sandbox.avenia.io:10952/v2/account/quote/fixed-rate?subAccountId=1ee0a663-922b-4389-9f84-074ccff7085d&inputCurrency=USDM&inputPaymentMethod=INTERNAL&outputCurrency=BRL&outputPaymentMethod=PIX&inputThirdParty=false&outputThirdParty=false&blockchainSendMethod=PERMIT" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
JSON Response
{
"quoteToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.quoteToken....",
"id": "c7f1e168-2989-45c7-a0be-de8371ab0dcc",
"inputCurrency": "USDM",
"inputPaymentMethod": "INTERNAL",
"inputAmount": "8.550804",
"outputCurrency": "BRL",
"outputPaymentMethod": "PIX",
"outputAmount": "50",
"markupAmount": "0",
"markupCurrency": "",
"blockchainSendMethod": "PERMIT",
"inputThirdParty": false,
"outputThirdParty": false,
"appliedFees": [
{
"type": "Markup Fee",
"description": "Total markup fees represented in the input currency.",
"amount": "0",
"currency": "USDM"
},
{
"type": "In Fee",
"description": "Fees due to input currency and input payment method.",
"amount": "0",
"currency": "USDM"
},
{
"type": "Conversion Fee",
"description": "Fees due to conversion from input currency to output currency.",
"amount": "0",
"currency": "USDM"
},
{
"type": "Out Fee",
"description": "Fees due to output currency and output payment method.",
"amount": "0.034066",
"currency": "USDM"
},
{
"type": "Gas Fee",
"description": "Fees due to blockchain transaction costs.",
"amount": "0",
"currency": "USDM"
}
],
"basePrice": "5.870793",
"pairName": "USDMBRL"
}
Ticket
Now moving forward to the withdrawal step directly from the subaccount, we’ll follow the same principle: the subAccountId must be included as a parameter in the request.
Here, there are two important options: you can either specify a pixKey (such as CPF, email, CNPJ, etc.) or provide the full bank account details.
Full Bank Account Details
Field | Description |
---|---|
userName | Full name of the bank account holder. |
bankCode | Code identifying the bank (e.g., 260 for NuBank). |
branchCode | Branch number of the bank where the account is held. |
accountNumber | Bank account number. |
accountType | Type of the bank account. Allowed values: checking , payment , savings , salary . |
Just PIX Key
Field | Description |
---|---|
pixKey | Unique PIX key associated with the account. |
Remember to provide only one of the two options: either the pixKey
or all bank account fields
— not both.
Making the payment using a pixKey
HTTP Post Request
https://api.sandbox.avenia.io:10952/v2/account/tickets?subAccountId=180c3b08-9713-4115-8b00-2a2ec7d0c225
Sample JSON Body
{
"quoteToken": "",
"ticketBrlPixOutput": {
"pixKey": "50.224.164/0001-70"
}
}
JSON Response
And as a response, you will receive the ID of the created ticket. If a webhook for this specific ticket is already registered, it will also be triggered.
{
"id": "55ea4ebf-60fb-4c47-8a97-00f7659f4762"
}
Verify status from Ticket
To verify the ticket status, use the following GET endpoint:
Note: The status can be in: UNPAID PROCESSING PAID FAILED PARTIAL-FAILED
HTTP GET Request
https://api.sandbox.avenia.io:10952/v2/account/tickets/a14d6b53-e573-4e68-b34a-2a1b717eb448?subAccountId=1ee0a663-922b-4389-9f84-074ccff7085d
cUrl Example
curl -X GET "https://api.sandbox.avenia.io:10952/v2/account/tickets/55ea4ebf-60fb-4c47-8a97-00f7659f4762?subAccountId=1ee0a663-922b-4389-9f84-074ccff7085d" \
-H "Authorization: Bearer eyJhdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
JSON Response
{
"ticket": {
"id": "55ea4ebf-60fb-4c47-8a97-00f7659f4762",
"externalId": "",
"workspaceId": "2ac803ad-faf7-489f-9c1a-c6a64072e699",
"userId": "180c3b08-9713-4115-8b00-2a2ec7d0c225",
"status": "PAID",
"reason": "",
"failureReason": "",
"createdAt": "2025-04-14T19:01:09.173483Z",
"updatedAt": "2025-04-14T19:01:13.62169Z",
"expiresAt": "2025-04-14T19:06:09.173221Z",
"quote": {
"id": "5716deac-018d-4adb-ab3c-f845fcf886df",
"ticketId": "55ea4ebf-60fb-4c47-8a97-00f7659f4762",
"inputCurrency": "USDM",
"inputPaymentMethod": "INTERNAL",
"inputAmount": "8.547892",
"outputCurrency": "BRL",
"outputPaymentMethod": "PIX",
"outputAmount": "50",
"markupCurrency": "",
"markupAmount": "0",
"sendMethod": "PERMIT",
"inputThirdParty": false,
"outputThirdParty": false,
"basePrice": "5.872793",
"appliedFees": [
{
"type": "Markup Fee",
"amount": "0",
"currency": "USDM",
"rebatable": false,
"description": "Total markup fees represented in the input currency."
},
{
"type": "In Fee",
"amount": "0",
"currency": "USDM",
"rebatable": true,
"description": "Fees due to input currency and input payment method."
},
{
"type": "Conversion Fee",
"amount": "0",
"currency": "USDM",
"rebatable": true,
"description": "Fees due to conversion from input currency to output currency."
},
{
"type": "Out Fee",
"amount": "0.034055",
"currency": "USDM",
"rebatable": true,
"description": "Fees due to output currency and output payment method."
},
{
"type": "Gas Fee",
"amount": "0",
"currency": "USDM",
"rebatable": false,
"description": "Fees due to blockchain transaction costs."
}
],
"pairName": "USDMBRL",
"outputBrCode": "",
"createdAt": "2025-04-14T19:01:08Z"
},
"rebate": {
"id": "830900fc-739e-42ca-a10b-156260098f97",
"ticketId": "55ea4ebf-60fb-4c47-8a97-00f7659f4762",
"amount": "0.099629",
"currency": "BRLA",
"destinationWalletAddress": "0xb6e8860883039b6db937639b94e9a10ff7971bb6"
},
"brazilianFiatReceiverInfo": {
"id": "ccc7e955-5f27-46ba-8969-7c1e214dd097",
"ticketId": "55ea4ebf-60fb-4c47-8a97-00f7659f4762",
"pixKey": "50224164000170",
"endToEndId": ""
},
"blockchainSenderInfo": {
"id": "24ed8a42-9f33-4f18-b205-d503d37ede18",
"ticketId": "55ea4ebf-60fb-4c47-8a97-00f7659f4762",
"walletAddress": "0x81c114C8C6258188866Ac2211e5801693b003C01",
"txHash": ""
},
"brlPixOutputInfo": {
"id": "2bf0ef60-02ec-4760-9087-d7eb75f8ee22",
"ticketId": "55ea4ebf-60fb-4c47-8a97-00f7659f4762",
"pixMessage": "",
"senderAccountBankName": "starkbank",
"senderAccountNumber": "4790427303542784"
},
"blockchainInputInfo": {
"id": "dc1dddff-54a0-4f24-b294-27f9674139c6",
"ticketId": "55ea4ebf-60fb-4c47-8a97-00f7659f4762",
"r": "",
"s": "",
"v": 0,
"nonce": 0,
"deadline": 0,
"personalSignature": "",
"personalSignatureDeadline": 0
}
}
}
Reversals
Let’s take a closer look at what happens when there’s a response to a sent Pix. It’s also good to remember that to get real-time insight into what’s happening, you should register and activate your webhooks
.
When a return of funds is detected, a new ticket will be created. The inputAmount
of this new ticket will reflect the amount returned by the customer. Consequently, the outputAmount
will be set at the moment the new ticket is generated — and that value will be credited back to your account in Avenia's, specifically to the Avenia Account that generated the refunded ticket
.
A Ticket Event webhook will be triggered, just like with any new ticket.
Pay attention to the reason
field — it will contain a message linking both operations (indicating that it was a refund). For example:
Pay out reversed by customer. Original ticket id UUID-OF-THE-ORIGINAL-TICKET.