account_id values, which are assigned to verified entities. If you have an API Key and Secret, your application has its own account_id. You can also create additional account_id values for your business clients or for individual end users.
Three shapes are supported today:
- Business, custodial (KYB) — the existing behavior. The account holds one or more Brale-custodied (
type=internal) on-chain wallets, can originate transfers, and can hold off-chain bank Addresses. - Business, transactional (KYB) — a KYB-verified business that is non-custodial. It has no internal Brale wallet and no stored balance at Brale, and it registers external, self-custody destination addresses.
- Individual, transactional (KYC) — a natural person verified with KYC. The account holds no custody at Brale, cannot originate on-chain transfers, and only receives value through external destination addresses. See Individual accounts.
POST /accounts. Omitting them all preserves today’s business/KYB behavior. See Account types for the full matrix.
Each custodial account_id is associated with one or more custodial (type=internal) onchain wallets, which are represented by address_id values. Off-chain bank accounts are also represented as Addresses (using address_id). Transactional accounts (business or individual) have no internal addresses. The legacy financial_institution_id is deprecated — new integrations should use address_id and the Addresses resource instead.
The account_id is used in the request URL across many Brale API endpoints to scope the request to a specific application or client.
To KYB and approve a business account, we collect key details such as business name and EIN. To KYC an individual account, we collect the person’s legal name, date of birth, address, and government identifier. For more information, see our Compliance Requirements. If additional details are required, Brale will notify you with the steps to complete verification.
Account dimensions
POST /accounts accepts three optional discriminator fields:
Supported combinations:
An unsupported combination is rejected with
422 unsupported_account_combination. The rejection is permanent, so it is safe for clients to cache the error against an idempotency key.
Omitting all three dimension fields produces exactly today’s behavior. Existing integrations that create business accounts do not need to change.
Creating a business account
You are required to pass in business information, controller information, and ultimate beneficial owner information. POSThttps://api.brale.xyz/accounts
Request
Presenting the Brale End-User Agreement
Partners must show the exact Brale End-User Agreement (EUA) to their end users before callingPOST /accounts and capture consent. The most recent version is hosted at https://brale.xyz/legal/end-user-agreement.
Business account — Required vs. Optional Fields
Non-US controllers and beneficial owners
A controller or beneficial owner outside the US is created through the samePOST /accounts call. Only the fields that depend on where the person lives change:
ssn and identity are mutually exclusive and exactly one is required. Sending ssn for a party outside the US returns 400, because an SSN has no meaning there. Use the identity type that matches the document.
The business itself is still US-only. This covers a US business whose controller or owners live elsewhere, not a foreign entity.
Request
state entirely, which is what to do for a country with no subdivision to give.
Owners and controllers can be mixed: a US controller sending ssn alongside an owner outside the US sending identity is a valid request.
Creating an individual account
On the individual path, setentity_type to individual and account_type to transactional. The individual object and tos_attestation are required. Business-only fields (business_name, ein, website, business_controller, beneficial_owners) must not be sent — they are rejected on this path.
POST https://api.brale.xyz/accounts
Request
name is derived from the individual’s first and last name.
Individual account — Required vs. Optional Fields
Identity types
One identity is submitted per person. UseSSN9 for a US taxpayer, or the matching document type for someone outside the US. The same values apply wherever an identity object is accepted: an individual account, and a business controller or beneficial owner.
The region column is guidance on which value to send, not a separate validation: any value in this list is accepted. Jurisdiction comes from the country on the person,
individual.country for an individual account and address.country for a controlling party.
Creating a non-US individual account
Non-US individuals are supported.individual.address.state is optional and free-form, and the postal code accepts any format, so only the identity type and country change. Omit state for countries that have no state or province:
Request
What a transactional account cannot do
The supported shape today is inbound: the account receives value on chain and can be the destination of an on-ramp. See Individual accounts for the end-to-end workflow.Common Errors when creating Accounts
Business path errors
Individual path errors
Account Status
Brale will review the Account and return astatus field denoting the customer’s verification status (KYB for business accounts, KYC for individual accounts). If the customer is in a pending status, you will need to wait for the customer to be verified before creating or linking addresses or bank accounts.
GET https://api.brale.xyz/accounts/:id
Response
Account Statuses
Verification
Account verification is asynchronous. After creating an account, Brale reviews the submitted information — KYB for business accounts, KYC for individual accounts. The lifecycle and webhook events are identical in shape across both. Two integration patterns are supported. Proactive (at onboarding): Stage documents, then either passdoc_submission_ids when creating the account or link them later.
Reactive (documents requested during review): When Brale needs additional documents, subscribe to the account.verification.documents_required webhook event (see Webhook Events). The payload lists each required document (document_kind, display_name, person_label, status). Stage the files, then link them. Alternatively, poll required documents.
account.verification.completed and the account status transitions to complete. When it is declined, Brale emits account.verification.rejected and status becomes rejected.
A decline is terminal. The account will not reach complete on its own and uploading further documents does not reopen it, so do not keep polling a rejected account. Contact Brale if you believe a decline is incorrect.
Using Account ID in every request
All resources in the Brale API (Addresses, Financial Institutions, Transfers, Automations, etc.) are scoped to specific accounts. Supply the ID in the path, never in the body.Every endpoint that contains
{account_id} must be called by including the
account ID in the path. E.g. GET
https://api.brale.xyz/accounts/2Js1YFqlfxgNqC2KTPEjrWIwKU7/addresses. Do not
send the account ID in the body or query string.