Programmatically monitor Connect activity with event-driven webhook notifications
Overview
Connect delivers real-time webhook notifications when deposit and withdrawal events occur. These webhooks are sent to Organization-configured endpoint URLs and provide status updates throughout the lifecycle of each transaction.
There are two webhook payload types:
connect_deposit.status_changed - fired when a deposit transitions to a new status
connect_withdrawal.status_changed - fired when a withdrawal transitions to a new status
Authentication and Delivery
Webhooks are delivered via HTTP POST to the URLs configured in your Organization settings (separate URLs for deposits and withdrawals).
Requests are authenticated using Organization-specific KMS-managed credentials.
Failed deliveries are retried with exponential backoff.
Each webhook has a unique event ID used for idempotency - you may safely deduplicate on this ID.
Webhook Security
Request Headers
Header
Description
client-id
Always Connect.
timestamp
Unix timestamp (seconds) when the request was signed.
signature
Base64-encoded RSA-SHA256 signature of the request.
x-zh-hook-payload-type
The webhook payload type (e.g., connect_deposit.status_changed).
Validating the signature
Retrieve Connect's public keys from the JWKS endpoint (GET /v1/jwks).
Reconstruct the signing base string by concatenating: {timestamp}POST{webhook_url}{request_body}
timestamp: the value from the timestamp header
POST: the HTTP method (always POST)
webhook_url: the full URL of your webhook endpoint
request_body: the raw JSON request body
Base64-decode the signature header value.
Verify the decoded signature against the signing base using the RSA public key with PKCS1 v1.5 SHA-256.
Deposit Webhooks
Payload type: connect_deposit.status_changed
Deposit event names
Event Name
Description
connect.deposits.pending
The end user clicked Submit on the Connect SDK, Connect has created a transaction within our system, and we are preparing to initiate the transaction within the connected-accounts' (ie, Coinbase) system
connect.deposits.submitted
The deposit has been created within the connected-accounts' (ie, Robinhood) system
connect.deposits.confirmed
The deposit has been confirmed on-chain
connect.deposits.unexpected
Connect received a deposit that was outside of the normal Auth flow. See full guide here.
Only relevant if you are configured to prevent non-auth deposits
connect.deposits.abandoned
The end user started the deposit flow, but no deposit was received within 30 minutes
connect.deposits.failed
When Connect attempted to initiate the transaction with the connected-account, the connected-account failed the API call.
Note: If you receive a connect.deposits.submitted webhook, followed by an connect.deposits.abandoned one, it means that either the connected-account had an issue processing the transaction or the blockchain itself had an issue processing the transaction. In either case, the user's balance at the connected-account should be re-credited.
Deposit Payload Fields
Top-level fields:
Field
Type
Description
event
string
The event name (ie, connect.deposits.confirmed)
deposit
object
Deposit details (see below)
session
object
Session details (see below)
account
object
Account details (see below)
deposit Object
Field
Type
Always in payload?
Always has a value?
Description
id
string
Yes
Yes
Unique identifier for the deposit
amount
string
Yes
Yes
Deposit amount (ie, .13 BTC)
network
string
Yes
Yes
Blockchain network (ie, ethereum)
asset
string
Yes
Yes
Asset (ie, USD, BTC, or ETH)
created_at
string
Yes
Yes
Timestamp when the deposit was created (ISO 8601).
updated_at
string
Yes
Yes
Timestamp when the deposit was last updated (ISO 8601).
status
string
No
When present, yes
Current status value.
transaction
object
Yes
Yes (but inner fields vary)
On-chain transaction details (see below).
source
object
No
When present, yes
Source of the deposit (see below). Present when the deposit originates from a known integration.
failure_reason
string
No
When present, yes
Reason for failure. Only present when the deposit has failed.
account_label
string
No
When present, yes
Label of the account associated with the withdrawal.
deposit.transaction object
Field
Type
Always in payload?
Always has a value?
Description
hash
string
Yes
No - empty string until transaction is on-chain
Blockchain transaction hash.
to
string
No
When present, yes
Destination address on-chain
block_number
string
No
When present, yes
Block number in which the transaction was included.
value
string
No
When present, yes
Raw on-chain value of the transaction.
deposit.source object (when present)
Field
Type
Description
type
string
Source type: CUSTODIAL, NON_CUSTODIAL, or MANUAL
integration
string
Integration identifier (ie, robinhood, geminietc)
session object
Field
Type
Description
id
string
Session identifier
metadata
object
Key-value metadata attached to the session at creation time
created_at
string
Timestamp when the session was created (ISO 8601)
account object
Field
Type
Description
reference_id
string
Your external reference ID for the account (ie, the participant_code)
Example Deposit Payloads
Example Deposit Payload - connect.deposits.pending