Bank Accounts
All bank account endpoints require
Authorization: Bearer <token>.
Overview
The Bank Accounts API creates PF (Natural Person) and PJ (Legal Person) bank accounts with automated KYC verification. Account creation is asynchronous:
- POST
/v1/bank-accounts/createreturns immediately with statusPROCESSING - KYC verification runs in the background (typically 2–5 minutes for fast-track, up to 24h for manual review)
- Poll GET
/v1/bank-accounts/checkOnboardingor configure a webhook (onboarding-createevent) to track progress
Onboarding State Machine
Accounts transition through these states:
┌───────────┐ ┌──────────────┐ ┌────────┐
│PROCESSING │──→ │ APPROVED │──→ │ ACTIVE │
└───────────┘ └──────────────┘ └────────┘
↓ ↓
└──→ PENDING_MANUAL └──→ REJECTED| State | Description | Integrator Action |
|---|---|---|
| PROCESSING | KYC underway (document analysis + selfie validation) | Poll GET /checkOnboarding every 30s for 5 min, then every 5 min |
| PENDING_MANUAL | Suspicious case (PEP match, unclear docs, address risk) | Await Axia email (up to 24h); user may resubmit docs if requested |
| APPROVED | KYC passed, account created, ready for transactions | Proceed to register PIX key, issue card, or enable transfers |
| REJECTED | KYC failed permanently (invalid document, failed PEP check) | Notify user; offer resubmit option with fresh docs |
| ACTIVE | Account live | Normal operations enabled |
POST /v1/bank-accounts/create
Create a new account for PF or PJ. Request returns immediately (< 100ms) with status PROCESSING.
Headers:
Authorization: Bearer <token>Natural Person (PF)
{
"email": "joao@example.com",
"transactionPassword": "ABC@123def",
"person": {
"fullName": "João da Silva",
"documentNumber": "48059890093",
"birthDate": "1990-03-15",
"motherName": "Maria da Silva",
"phoneNumber": "+5511999999999",
"isPoliticallyExposedPerson": false,
"address": {
"postalCode": "01310100",
"street": "Avenida Paulista",
"number": "1578",
"neighborhood": "Bela Vista",
"city": "São Paulo",
"state": "SP"
}
},
"bankDocuments": {
"documentLink": "https://bucket.s3.amazonaws.com/doc-front.jpg",
"documentBackLink": "https://bucket.s3.amazonaws.com/doc-back.jpg",
"selfieLink": "https://bucket.s3.amazonaws.com/selfie.jpg"
}
}Legal Person (PJ)
{
"email": "empresa@example.com",
"transactionPassword": "XYZ@456abc",
"legalPerson": {
"businessName": "Empresa XYZ Ltda",
"tradingName": "XYZ",
"documentNumber": "12345678000190",
"establishmentDate": "2020-06-15",
"owner": [
{
"fullName": "João da Silva",
"documentNumber": "48059890093",
"email": "joao@example.com",
"phoneNumber": "+5511999999999",
"birthDate": "1990-03-15",
"motherName": "Maria da Silva"
}
]
},
"bankDocuments": {
"documentLink": "https://bucket.s3.amazonaws.com/doc-front.jpg",
"documentBackLink": "https://bucket.s3.amazonaws.com/doc-back.jpg",
"selfieLink": "https://bucket.s3.amazonaws.com/selfie.jpg",
"socialContractLink": "https://bucket.s3.amazonaws.com/contract.pdf"
}
}Response 202 Accepted:
{
"status": "PROCESSING",
"data": {
"onBoardingId": "550e8400-e29b-41d4-a716-446655440000"
}
}Common Errors:
| Code | Cause | Action |
|---|---|---|
| E00201 | Invalid CPF/CNPJ checksum | Validate document before submission |
| E00202 | Email already registered | Use unique email |
| E00203 | Incomplete address | Fill all required fields |
GET /v1/bank-accounts/checkOnboarding
Poll the onboarding status. Returns current state and account details (when approved).
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
onBoardingId | string | Yes | UUID from POST /create response |
documentNumber | string | Alternative | CPF/CNPJ (if onBoardingId lost) |
Example:
curl "https://baas-gtw.axiadigitalsolutions.com/v1/bank-accounts/checkOnboarding?onBoardingId=550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer eyJhbGci..."Response 200 OK (APPROVED):
{
"status": "APPROVED",
"data": {
"onBoardingId": "550e8400-e29b-41d4-a716-446655440000",
"documentNumber": "48059890093",
"accountId": "30054029183",
"bankAccountNumber": "123456",
"bankBranch": "0001",
"accountDigit": "8",
"approvedAt": "2024-03-15T10:30:00Z"
}
}Polling vs Webhook
Polling (GET checkOnboarding)
- Pros: Simple, synchronous, no infrastructure needed
- Cons: Wasteful (many requests), latency (30s–5m delay)
- Recommended: Short windows (e.g., in-app redirect after create)
Webhook (onboarding-create event)
- Pros: Real-time, efficient, event-driven
- Cons: Requires public endpoint, signature validation
- Recommended: Long-running integrations, background jobs
Best Practice: Use both — webhook for fast path, polling as fallback with timeout.
Fluxo Completo (Complete Flow)
// 1. Create account (async)
const createRes = await fetch('/v1/bank-accounts/create', {
method: 'POST',
headers: { 'Authorization': `Bearer ${token}` },
body: JSON.stringify({
email: 'joao@example.com',
transactionPassword: 'ABC@123def',
person: { /* ... */ }
})
});
const { data: { onBoardingId } } = await createRes.json();
// 2. Poll with exponential backoff (5 min timeout)
const startTime = Date.now();
let iteration = 0;
while (Date.now() - startTime < 5 * 60 * 1000) {
const checkRes = await fetch(
`/v1/bank-accounts/checkOnboarding?onBoardingId=${onBoardingId}`,
{ headers: { 'Authorization': `Bearer ${token}` } }
);
const { status, data } = await checkRes.json();
if (status === 'APPROVED') {
console.log('✓ Account ready:', data.accountId);
return data;
} else if (status === 'REJECTED') {
throw new Error('KYC rejected');
} else if (status === 'PENDING_MANUAL') {
console.log('⏳ Awaiting manual review (email sent)');
}
// Backoff: 30s → 1m → 2m (max)
const delay = Math.min(30000 * Math.pow(1.5, iteration), 2 * 60 * 1000);
await new Promise(r => setTimeout(r, delay));
iteration++;
}
throw new Error('Onboarding timeout (5 min)');KYC Requirements
Accepted Documents:
- RG, CNH, Passport, RNE (carteira de identidade, habilitação, passaporte, registro nacional estrangeiro)
Selfie Standards:
- Face fully visible, no sunglasses
- Natural lighting, good contrast
- Recent photo (not old ID photo)
Address:
- Valid CEP (CEP-consulta compatible)
- Full street address required
- Must match ID document
Age & PEP:
- Minimum 18 years old
- PEP (Politically Exposed Person) auto-rejected per Bacen regulation
- Recheck if
isPoliticallyExposedPerson=true
Document Upload
Upload documents before calling POST /create (or use platform file API).
- Accessibility: URLs must be publicly readable (S3 presigned, GCS, Cloudflare, etc.)
- Formats: JPG, PNG only
- Size: Max 5 MB per file
- Recommendation: Upload to object storage, capture presigned URLs, pass to create endpoint
GET /v1/bank-accounts/balance
Get account balance.
Query Parameters:
| Parameter | Type | Required |
|---|---|---|
accountId | string | Yes |
documentNumber | string | Yes |
GET /v1/bank-accounts/history
List transactions for a date range.
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
accountId | string | Yes | Account number |
documentNumber | string | Yes | CPF/CNPJ |
initialDate | string | Yes | yyyy-MM-dd |
endDate | string | Yes | yyyy-MM-dd |
limit | number | No | Page size |
page | number | No | Page number |
POST /v1/bank-accounts/generateInternalTransferRequest
Transfer between accounts within the same institution.
Headers:
x-client-id: <your-tenant-id>
Idempotency-Key: <uuid> (recommended)Request Body:
{
"userId": "cfd11a01-293d-4573-9d28-2d7261d79aaf",
"accountIdFrom": "30054029183",
"accountIdTo": "30054029184",
"amount": 100.50,
"description": "Optional note"
}POST /v1/bank-accounts/generateExternalTransferRequest
Transfer to another bank (TED - Transferência Eletrônica de Débito).
Headers:
x-client-id: <your-tenant-id>
Idempotency-Key: <uuid> (recommended)Request Body:
{
"userId": "cfd11a01-293d-4573-9d28-2d7261d79aaf",
"onBoardingId": "550e8400-e29b-41d4-a716-446655440000",
"idAccount": "30054029183",
"document": "11122233344",
"accountCode": "123",
"branchCode": "371",
"institutionCode": 341,
"name": "Recipient Name",
"value": 67.90,
"bankAccountType": "CACC",
"institutionIspb": "30306294"
}POST /v1/bank-accounts/closeAccount
Close an account (requires MFA).
Request Body:
{
"userId": "cfd11a01-293d-4573-9d28-2d7261d79aaf",
"userAccessToken": "<token>",
"code": "123456",
"account": "30054029183",
"reason": "User request"
}