Usage Examples

This page provides practical examples of how to interact with the CorpX API using cURL, in the logical order of a typical integration.

Environment Variables

Configure these variables before running the examples:

# OAuth Credentials (provided during onboarding)
export CLIENT_ID="your_client_id"
export CLIENT_SECRET="your_client_secret"
# Account identifiers
export TENANT_ID="your-tenant-uuid"
export ACCOUNT_ID="your-account-uuid"
# Environment URLs
export API_URL="https://tenant.api.corpx.com"
export AUTH_URL="https://auth.api.corpx.com"

1. Authentication

The first step is to obtain an OAuth2 access token using your client credentials.

curl -X POST "${AUTH_URL}/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=${CLIENT_ID}" \
-d "client_secret=${CLIENT_SECRET}"

Successful response:

{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 300
}

Store the token for use in subsequent calls:

export JWT="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."

2. Check Balance

Check the available and locked balance of your account in real time.

curl -X GET "${API_URL}/v1/accounts/${ACCOUNT_ID}/balance" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}"

Response:

{
"accountId": "2e6b725b-84a0-400d-8740-22a5ba0f23e6",
"total": 15000.00,
"locked": 500.00,
"available": 14500.00,
"currency": "BRL",
"updatedAt": "2024-01-15T10:30:00Z",
"locks": [
{
"lockId": "lock-abc123",
"amount": 500.00,
"currency": "BRL",
"reason": "MED investigation",
"medId": "med-12345",
"status": "active",
"createdAt": "2024-01-10T14:00:00Z"
}
]
}

3. Generate Dynamic QR Code (Receiving)

Generate a dynamic QR Code to receive a PIX payment for a specific amount.

curl -X POST "${API_URL}/v1/accounts/${ACCOUNT_ID}/pix/qr-code/dynamic" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"pixKey": "contact@mycompany.com",
"value": 150.00,
"expirationDate": "2024-12-31T23:59:59Z",
"allowChangeValue": false,
"message": "Payment for order #12345",
"identifier": "order-12345",
}'
ValueDescription
IMAGEReturns a Base64 image of the QR Code
EMVReturns only the copy-and-paste string

4. Generate Static QR Code

Static QR Codes do not expire and are ideal for permanent display.

curl -X POST "${API_URL}/v1/accounts/${ACCOUNT_ID}/pix/qr-code/static" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"pixKey": "contact@mycompany.com",
"value": 50.00,
"message": "Donation to project XYZ",
"identifier": "doacao-xyz-001",
}'

5. Check QR Code Status

Check whether the previously generated QR Code has been paid or is still pending.

curl -X GET "${API_URL}/v1/accounts/${ACCOUNT_ID}/pix/qr-code/lookup?identifier=order-12345" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}"

6. PIX Out (Transfer via Key)

Send a PIX to a third-party key (outbound transfer).

Need to send PIX without a PIX key? If you only have the recipient’s bank details (ISPB, branch and account number), use the dedicated endpoint POST /v1/accounts/{accountId}/pix/out/bank-account. See the v1.27.0 changelog for details.

6.1 PIX to CPF

curl -X POST "${API_URL}/v1/accounts/${ACCOUNT_ID}/pix/out" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"accountId": "'${ACCOUNT_ID}'",
"amount": 150.00,
"currency": "BRL",
"keyType": "CPF",
"key": "12345678900",
"description": "Service payment",
"identifier": "order-456"
}'

6.2 PIX to Email

curl -X POST "${API_URL}/v1/accounts/${ACCOUNT_ID}/pix/out" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"accountId": "'${ACCOUNT_ID}'",
"amount": 75.50,
"currency": "BRL",
"keyType": "EMAIL",
"key": "supplier@company.com",
"description": "Pagamento NF 789"
}'

6.3 PIX to Phone

curl -X POST "${API_URL}/v1/accounts/${ACCOUNT_ID}/pix/out" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"accountId": "'${ACCOUNT_ID}'",
"amount": 200.00,
"currency": "BRL",
"keyType": "PHONE",
"key": "+5511999999999",
"description": "Transfer"
}'

6.4 PIX to Random Key (EVP)

curl -X POST "${API_URL}/v1/accounts/${ACCOUNT_ID}/pix/out" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"accountId": "'${ACCOUNT_ID}'",
"amount": 500.00,
"currency": "BRL",
"keyType": "EVP",
"key": "123e4567-e89b-12d3-a456-426614174000",
"description": "Pagamento de fornecedor"
}'

Values for keyType:

ValueDescriptionFormat
CPFRecipient’s CPF11 digits (numbers only)
CNPJRecipient’s CNPJ14 digits (numbers only)
EMAILRecipient’s emailValid email
PHONERecipient’s phone+55 + area code + number
EVPRandom keyUUID v4

Successful response:

{
"transactionId": "txn-abc123-def456",
"status": "APPROVED",
"endToEndId": "E12345678202401151234abcdefghijkl",
"amount": 150.00,
"currency": "BRL"
}

Values for status:

ValueDescription
APPROVEDTransfer approved and completed
PENDINGAwaiting bank confirmation
PROCESSINGIn processing
REJECTEDRejected (check the error message)

6.5 Check Transfer Status

Check the status of a transfer using the E2E ID:

curl -X GET "${API_URL}/v1/accounts/${ACCOUNT_ID}/pix/transactions?endToEndId=E12345678202401151234abcdefghijkl" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}"

Response:

{
"transactionId": "txn-abc123-def456",
"endToEndId": "E12345678202401151234abcdefghijkl",
"status": "COMPLETED",
"type": "CASH_OUT",
"amount": -150.00,
"currency": "BRL",
"description": "PIX - MARIA DA SILVA",
"transactionDate": "2024-01-15T12:34:00-03:00",
"counterparty": {
"name": "MARIA DA SILVA",
"document": "123***01",
"bankCode": "001"
},
"balance": 14350.00
}

Query parameters:

ParameterDescription
accountIdAccount ID (required)
endToEndIdTransaction E2E ID
identifierCharge or reference identifier

Note: At least one of the parameters endToEndId or identifier is required.


7. Pay QR Code (PIX Out via EMV)

Pay a PIX QR Code using the EMV string (copy and paste). Prefer the async flow (/pix/out/qr-code/async). Sync (/pix/out/qr-code) is deprecated (Sunset 2026-11-21).

curl -X POST "${API_URL}/v1/accounts/${ACCOUNT_ID}/pix/out/qr-code/async" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"accountId": "'${ACCOUNT_ID}'",
"emv": "00020126580014br.gov.bcb.pix0136123e4567-e89b-12d3-a456-426614174000520400005303986540010.005802BR5913Loja Exemplo6008Sao Paulo62070503***6304EFGH",
"amount": 150.00,
"description": "Service payment",
"identifier": "pay-qr-async-001"
}'

202 response with status: "ACCEPTED". Final outcome arrives via webhook (pix.out.completed / failed / timeout) or lookup by identifier.

7.2 [DEPRECATED] Pay QR Code synchronously

curl -X POST "${API_URL}/v1/accounts/${ACCOUNT_ID}/pix/out/qr-code" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"accountId": "'${ACCOUNT_ID}'",
"emv": "00020126580014br.gov.bcb.pix0136123e4567-e89b-12d3-a456-426614174000520400005303986540510.005802BR5913Loja Exemplo6008Sao Paulo62070503***6304ABCD",
"amount": 150.00,
"description": "Online purchase payment"
}'

Returns Deprecation / Sunset / Link headers. Migrate to /qr-code/async.


8. Request Refund

Refund a previously received PIX (full refund onlyamount must equal the original value).

curl -X POST "${API_URL}/v1/accounts/${ACCOUNT_ID}/pix/out/refund" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"accountId": "'${ACCOUNT_ID}'",
"originalEndToEnd": "E12345678202401101234abcdefghijkl",
"amount": 150.00,
"currency": "BRL",
"reason": "Product not available in stock"
}'

Response:

{
"refundId": "ref-abc123-def456",
"status": "PROCESSING",
"amount": 150.00,
"currency": "BRL"
}

Values for refund status:

ValueDescription
PROCESSINGRefund in processing
COMPLETEDRefund completed successfully
REJECTEDRefund rejected

9. List Recent Transactions (Statement)

Retrieve the recent transaction history of the account.

curl -X GET "${API_URL}/v1/accounts/${ACCOUNT_ID}/statement?limit=10&order=desc" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}"

Query parameters:

ParameterTypeDescription
pageintegerPage index (0-based)
sizeintegerPage size ceiling (max 500). items may be shorter; page with hasNext
startDatedatetimeStart date filter (ISO 8601)
endDatedatetimeEnd date filter (ISO 8601)
limitintegerTotal record limit (max 1000)
orderstringSort order: asc or desc

10. Manage PIX Keys

10.1 List PIX Keys

curl -X GET "${API_URL}/v1/accounts/${ACCOUNT_ID}/pix/keys" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}"

10.2 Register a New PIX Key

Email and phone require an OTP

POST /v1/accounts/{accountId}/pix/keys with email or phone responds 202 and the facade sends the code. Confirm it with POST .../pix/keys/verify. A delivery failure is 503 otp_send_failed.

curl -X POST "${API_URL}/v1/accounts/${ACCOUNT_ID}/pix/keys" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"keyType": "cpf",
"pixKey": "12345678900"
}'

Values for keyType on registration:

ValueDescription
cpfCPF of the account holder
cnpjCNPJ of the account holder
randomRandom key (EVP) - automatically generated by the system
phoneE.164 phone — 202 + OTP (SMS)
emailEmail — 202 + OTP

10.3 Register a Random Key (EVP)

For random keys, omit the pixKey field:

curl -X POST "${API_URL}/v1/accounts/${ACCOUNT_ID}/pix/keys" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"keyType": "random"
}'

10.4 Delete a PIX Key

curl -X DELETE "${API_URL}/v1/accounts/${ACCOUNT_ID}/pix/keys/contact%40mycompany.com" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}"

11. Query MEDs (Special Return Mechanism)

List the disputes filed against the account. The list is built from the pix.med.opened / pix.med.updated webhooks — without subscribing to them it stays empty. See Disputes (MED).

curl -X GET "${API_URL}/v1/accounts/${ACCOUNT_ID}/pix/med?limit=20" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}"

Parameters:

ParameterValuesDescription
limitintegerMax items (default 50, cap 200)
offsetintegerOffset for pagination

There is no status filter: the API does not expose dispute status. The settlement bank has no infraction-report lookup, so the current state is not verifiable — what the API shows is answered (whether you responded) and the deadline.

11.1 Attach evidence

Three steps, and all of them before answering — an attachment added after the answer does not make it into the defense (409 conflict).

# 1. Upload URL
PRESIGN=$(curl -sS -X POST "${API_URL}/v1/accounts/${ACCOUNT_ID}/pix/med/${MED_ID}/evidence/upload-url" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}" \
-H "Content-Type: application/json" \
-d '{"filename":"comprovante.pdf","contentType":"application/pdf","sizeBytes":184320}')
UPLOAD_URL=$(echo "$PRESIGN" | jq -r .uploadUrl)
KEY=$(echo "$PRESIGN" | jq -r .key)
# 2. PUT straight to storage (no auth header of ours)
curl -X PUT "$UPLOAD_URL" -H "Content-Type: application/pdf" --data-binary @comprovante.pdf
# 3. Register the attachment on the dispute
curl -X POST "${API_URL}/v1/accounts/${ACCOUNT_ID}/pix/med/${MED_ID}/evidence/add" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}" \
-H "Content-Type: application/json" \
-d "{\"key\":\"${KEY}\",\"filename\":\"comprovante.pdf\",\"contentType\":\"application/pdf\",\"sizeBytes\":184320}"

Limits: 5 MB per file, 6 MB and 10 files per dispute, and only PDF/JPEG/PNG/WebP/TXT/CSV. Every file goes through antivirus and sanitization before it counts as evidence (scanStatus).

11.2 Respond to a MED

The account holder has 48h from the opening (clientAnswerDeadline) to state their case. The answer is sent once: a second call gets 409 conflict.

curl -X POST "${API_URL}/v1/accounts/${ACCOUNT_ID}/pix/med/204cc938-da3d-4f04-baf3-0b2e6a2f1283/answer" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}" \
-H "Content-Type: application/json" \
-d '{
"result": "DISAGREE",
"reason": "Legitimate sale: customer registered 14 months ago, delivery confirmed with tracking."
}'

Values for result:

ValueDescription
AGREEAcknowledges the reported fraud
DISAGREEContests the report. Requires reason (422 invalid_payload without it)

The response is 202. It records your defense and forwards it, with the attachments, to the team that conducts the dispute — nothing is sent to the settlement bank by this call and no status changes. There is no decision route: refunding or refusing the disputed PIX is not done by this API.


12. Internal Transfer

Transfer funds between accounts in the same bank (no cost, instant).

curl -X POST "${API_URL}/v1/accounts/${ACCOUNT_ID}/transfers/internal" \
-H "Authorization: Bearer ${JWT}" \
-H "X-Tenant-Id: ${TENANT_ID}" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"branch": "0001",
"account": "123456-7",
"taxNumber": "12345678900",
"value": 500.00,
"message": "Transfer between accounts",
"identifier": "transf-int-12345"
}'

Common Error Handling

Insufficient Balance

{
"errorCode": "insufficient_balance",
"message": "insufficient available balance: 50.00 (total: 100.00, locked: 50.00, requested: 150.00)"
}

Invalid PIX Key

{
"errorCode": "invalid_payload",
"message": "keyType must be one of: CPF, CNPJ, EMAIL, PHONE, EVP"
}

Idempotency Conflict

{
"errorCode": "idempotency_conflict",
"message": "Request with same Idempotency-Key but different payload"
}

Best Practices

  1. Always use Idempotency-Key on POST/PUT/PATCH operations to avoid duplicates
  2. Store the endToEndId of transactions for tracking and refunds
  3. Implement retry with exponential backoff for 5xx errors
  4. Validate the balance before outbound operations for better UX
  5. Configure webhooks to receive real-time notifications

For more details about each endpoint, see the API Reference or the Integration Guide.