Available events
Each event lists the transfer types it applies to (in parentheses), when it fires, and the recommended action.
Transfer lifecycle (TED OUT, P2P)
transfer.initiated (TED OUT, P2P)
- Trigger: transfer record created after initiation is confirmed.
- Action: update the transfer status in your system; show “transfer in progress” to the customer.
transfer.processing_started (TED OUT, P2P)
- Trigger: Midaz transaction hold succeeded; the transfer is advancing toward completion.
- Action: show the customer that the transfer is being processed.
transfer.rejected (TED OUT)
- Trigger: JD SPB returned a 4xx rejection (invalid data, rule violation).
- Action: notify the customer that the transfer was rejected; funds are already released.
transfer.completed (P2P)
- Trigger: transfer settled successfully.
- Action: notify the customer; generate a receipt; update the balance display.
Reconciliation (TED OUT, TED IN)
transfer.reconciliation_required
- Trigger: a transfer with an unknown outcome was flagged for reconciliation.
- Action: track that the transfer is pending resolution; do not assume success or failure.
transfer.reconciliation_resolved
- Trigger: reconciliation completed and the transfer reached a definitive outcome.
- Action: update the transfer to its final status.
transfer.reconciliation_exhausted
- Trigger: reconciliation gave up after the maximum number of attempts.
- Action: escalate for manual operator review.
transfer.reconciliation_failed
- Trigger: a reconciliation attempt itself failed.
- Action: monitor; the worker will retry on the next cycle.
Incoming transfers (TED IN)
transfer_incoming.completed
- Trigger: inbound TED received, recipient found, credit applied.
- Action: notify the recipient that funds have arrived; update the balance display.
transfer_incoming.chargeback
- Trigger: chargeback message received for a previously completed TED IN (STR0010R2).
- Action: freeze the credited amount; initiate review with your compliance team.
transfer_incoming.undeliverable
- Trigger: inbound TED could not be credited (e.g. recipient account not found).
- Action: investigate; the transfer may be returned to the origin bank.
Returns and initiation
transfer_outgoing.devolution_notified (TED OUT)
- Trigger: a return (devolução) was notified for an outgoing transfer.
- Action: reconcile the returned funds against the original transfer.
payment_initiation.created (TED OUT, P2P)
- Trigger: a payment initiation was created (pre-transfer step).
- Action: optional — track initiations awaiting confirmation.
For TED OUT, the
transfer.completed event is not yet emitted. TED OUT completion is confirmed asynchronously by SPB and will be supported in a future release. Until then, monitor TED OUT status via the Get Transfer endpoint or the reconciliation endpoint.Configuring webhooks
Webhooks are scoped per tenant. There are two ways to register a destination. Self-service API (recommended). Register one or more HTTPS endpoints through the webhook registration API. On creation, the server generates a
signingSecret and returns it once — store it securely and use it to verify the signature on every delivered event. You can also list, update, disable, and delete registrations, rotate the signing secret, and look up the accepted event types. The tenant that owns each registration is derived from the bearer token, never from a request header.
- Create a webhook registration —
POST /v1/webhooks - List webhook registrations —
GET /v1/webhooks - Get, update, and delete a registration
- Rotate the signing secret —
POST /v1/webhooks/{webhookId}/signing-secret/rotate - List supported event types —
GET /v1/webhooks/event-types
WEBHOOK_ENABLED=true, which also requires RabbitMQ and the streaming outbox (STREAMING_ENABLED=true). Destinations come from the registrations above — there is no single static endpoint environment variable. Per-delivery tuning (timeout, max retries) is managed at runtime via systemplane, not env vars. See Bank Transfer configuration.
Payload structure
All webhook events share the same envelope. Envelope fields are stable across event types; the per-event payload sits inside
payload.
| Field | Type | Notes |
|---|---|---|
eventId | string (UUID) | Unique id of this event emission. Use it for at-least-once dedupe on your side. |
version | string | Envelope schema version. Currently v1. |
type | string | Event type, e.g. transfer.completed. |
tenantId | string (UUID) | Organization that owns the transfer. |
transferId | string (UUID) | Present for transfer-scoped events; omitted for tenant-scoped events. |
correlationId | string | Correlates the chain of events produced by one originating request. |
causationId | string | Optional. Id of the event that caused this one (for chained workflows). |
occurredAt | string (RFC3339, UTC) | When the event occurred on the plugin side. |
payload | object | Event-specific fields. Schema depends on type (see below). |
metadata | object | Optional string-to-string map carrying tracing and routing hints. |
transfer.completed for a P2P transfer:
payload shape is per-event-type. For transfer.completed, the fields include status, transferType, midazTransactionId, and confirmationNumber (each emitted only when set). To retrieve amounts, fees, recipient details, or timestamps, fetch the transfer via Get Transfer using the envelope’s transferId.
See the API Reference for full payload schemas for each event type.
Handling delivery failures
If your endpoint does not respond with a 2xx status within 5 seconds (
WEBHOOK_TIMEOUT_MS=5000), the event is retried automatically with exponential backoff and full jitter. After the initial attempt, the plugin makes up to WEBHOOK_MAX_RETRIES retries (default 3) — up to 4 delivery attempts in total. The backoff base is 1 second, doubled per retry, with full jitter applied to each delay:
| Attempt | Delay before this attempt |
|---|---|
| 1 (initial) | Immediate |
| 2 | Random in [0, 1000 ms] |
| 3 | Random in [0, 2000 ms] |
| 4 | Random in [0, 4000 ms] |
WEBHOOK_MAX_RETRIES if your endpoint needs a longer or shorter retry budget. (WEBHOOK_RETRY_BACKOFF_MS controls the broker reconnect backoff, not the per-delivery HTTP retry schedule above.)
To ensure reliable delivery: respond within 5 seconds, use HTTPS with a valid certificate, and return 200 even for events you choose to ignore. Offload any heavy processing to a background queue — keep your webhook handler fast.
Idempotency
Your endpoint may receive the same event more than once. Use the
transferId (and the event name) to deduplicate: if you have already processed that combination, return 200 and take no further action.For developers
For signature validation code (JavaScript, Python, Go), retry implementation, and the full integration checklist, see the Bank Transfer developer guide.

