Skip to main content

Webhook Events

Event envelope

All webhook events use a JSON envelope:

Managing accounts and event fan-in

If your integration uses managed accounts or individual accounts, a single managing account can receive events for every account it manages.
  • A webhook subscription owned by a managing account receives events for every account it manages, plus its own.
  • A webhook subscription owned by a managed account receives only that account’s own events.
This is derived from the subscription’s owner. There is no scope parameter to set when creating the subscription. To attribute an event to the correct managed account, read data.account_id from the payload. It is present on payment.completed, transfer.created, and transfer.failed, in addition to the account.verification.* events that already carry it. Your handler should branch on type.

transfer.created

Emitted when a Brale transfer is created. Example:
Notes:
  • Treat data.id as the transfer ID.
  • data.account_id identifies the account the transfer belongs to. Managing accounts use this to attribute events to a specific managed account.
  • Additional fields may be present as the transfer schema evolves.
  • Your integration should ignore unknown fields.

transfer.completed

Emitted when a Brale transfer reaches complete status. Use this event to replace polling transfer status. Example:
Notes:
  • Treat data.id as the transfer ID.
  • Treat data.status as the completed transfer state.
  • Additional fields may be present as the transfer schema evolves.
  • Your integration should ignore unknown fields.

transfer.failed

Emitted when a Brale transfer reaches failed status. Use this event to react to permanent transfer failures (e.g., ACH returns or other rail/provider failures). For ACH-specific return details, inspect data.failure.ach_return. Example:
Notes:
  • Treat data.id as the transfer ID.
  • data.account_id identifies the account the transfer belongs to. Managing accounts use this to attribute events to a specific managed account.
  • Treat data.status as the failed transfer state.
  • data.failure is usually populated for transfer.failed, but may be null when Brale does not have structured failure details. Always null-check before reading nested fields.
  • data.failure.retriable indicates whether the failure is retriable. Spelled retriable, not retryable.
  • data.failure.ach_return is only set for ACH return failures. See the transfer failure field for the full schema.
  • Additional fields may be present as the transfer schema evolves.
  • Your integration should ignore unknown fields.

payment.completed

Emitted when a payment reaches complete status. Example:
Notes:
  • data.account_id identifies the account the payment belongs to. Managing accounts use this to attribute events to a specific managed account.

transfer.canceled

Emitted when a Brale transfer is canceled. Example:
Notes:
  • Treat data.id as the transfer ID.
  • Treat data.status as the canceled transfer state.
  • Additional fields may be present as the transfer schema evolves.
  • Your integration should ignore unknown fields.

account.verification.documents_required

Emitted when Brale’s KYB review determines one or more documents must be uploaded. Use this event to prompt the account holder to submit the requested documents. For each document with status: "pending_upload", stage the file (use document_kind and person_label from the payload), then link staged submissions. You can also poll required documents instead of using this webhook. Example:
Notes:
  • Treat data.account_id as the account ID.
  • Each entry in data.documents describes a required document. status is pending_upload until the document is submitted.
  • Include person_label when staging individual (KYC) documents.
  • Your integration should ignore unknown fields.

account.verification.completed

Emitted when account verification completes and the account is enabled. Example:
Notes:
  • Treat data.account_id as the account ID.
  • Treat data.status as the completed verification state (complete).
  • This event fires only when the account reaches complete status.
  • Your integration should ignore unknown fields.

account.verification.rejected

Emitted when account verification is declined. This is the terminal outcome for a review: the account will not become complete on its own, and no further verification events follow. Example:
Notes:
  • Treat data.account_id as the account ID.
  • Treat data.status as the declined verification state (rejected).
  • The account’s status from GET /accounts/{account_id} becomes rejected at the same time, so polling and webhooks agree.
  • Uploading more documents does not reopen a declined account. Contact Brale if you believe a decline is incorrect.
  • Your integration should ignore unknown fields.
Subscriptions to the account.verification.* wildcard receive this event automatically. If you subscribed to account.verification.completed by name, add account.verification.rejected to your subscription to be told about declines.

Handling future event types

Brale may add new event types over time. Best practices:
  • Use GET /accounts/{account_id}/webhooks/event_types to discover supported events.
  • Branch on event.type.
  • Acknowledge unknown event types safely.
  • Ignore unknown fields in data.
  • Do not assume event ordering.
  • To automatically receive future events in a family (e.g., new transfer.* or account.* events), subscribe with a namespace wildcard like transfer.* or account.* when you create or update a subscription. Wildcards work for every event family.