Deposit Status Updates

Overview

Deposits emit one of two webhook payload types depending on how the deposit was initiated. Standard blockchain deposits emit x-zh-hook-payload-type header value of deposit.status_changed, while deposits submitted through the AUTH product (e.g., via AUTH Providers like Robinhood) emit auth_deposit.status_changed. Both events track a deposit as it moves from on-chain detection through compliance review to final crediting, but each uses its own set of state values reflecting its distinct processing pipeline. The table below consolidates the possible states across both deposit types and which type(s) each state applies to.

Deposit Events

Subscribe to this event by setting the x-zh-hook-payload-type header value to deposit.status_changed.
A deposit.status_changed webhook is emitted every time a blockchain deposit transitions between states — for example, when a transaction is first detected on-chain, when it receives enough confirmations, or when the funds are credited to the customer's account.

Deposit Statuses

The state field communicates the current stage of the deposit in zerohash's processing pipeline. state_reason is the list of potential reasons you may receive for the given state. Values are returned in lowercase.

StateState ReasonDescriptionTerminal State
confirmeddeposit_detected_onchainDeposit has received sufficient confirmations and is complete on-chain-
pending_compliancepending_compliance_screeningDeposit waiting for compliance screening-
pending_compliance_reviewrequired_travel_rule_infoDeposit held for compliance review before funds can be credited-
pending_approval
  • auth_approval_required
  • high_notional_value
Deposit exceeds a configured threshold and requires manual approval before settlement-
pending_settlement
  • complete_valid_deposit
  • auth_approval_confirmed
  • admin_approved
Deposit has passed all reviews and is queued for crediting-
completed
  • complete_valid_deposit
  • auth_approval_confirmed
  • admin_approved
  • travel_rule_info_received
  • manual_compliance_approved
  • manual_compliance_recover
Funds have been credited to the customer account.✅
quarantined-Funds will not be credited without manual intervention.✅
recovery_quarantine
  • auth_approval_rejected
  • admin_rejected
  • travel_rule_info_timeout
  • manual_compliance_rejected
Funds have been placed into recovery quarantine pending investigation. Possible scenarios include amounts received below minimum or outside of transaction limits, asset/network mismatch, conversion failures (rare)✅

Payload Schema

FieldTypeDescription
deposit_idstringUnique identifier for the deposit. Use this ID to look up the deposit via GET /deposits/crypto/{deposit_id}.
account_idstringIdentifier of the Zero Hash account that will be credited with the deposited funds.
participant_codestringParticipant code of the customer that owns the receiving account.
transaction_hashstringOn-chain transaction hash associated with the deposit.
statestringCurrent deposit state. See Deposit States for possible values.
state_reasonstringWhy the deposit is in it's current state. Pairs with state to give the full outcome without inspecting history.
assetstringTicker symbol of the deposited asset (e.g., BTC, ETH, USDC).
amountstring (decimal)Amount of the asset that was deposited. Represented as a string to preserve precision.
source_addressstringOn-chain address that funded the deposit.
received_addressstringOn-chain address owned by Zero Hash that received the deposit.
timestampintegerUnix timestamp (seconds) of when this state change occurred. Use this value to determine the relative ordering of events.

Example Payload

{
    "deposit_id": "f6a1c2c4-2a9e-4a01-9b0f-7b9e2c5d8e11",
    "account_id": "PART123.general",
    "participant_code": "PART123",
    "transaction_hash": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
    "state": "confirmed",
    "asset": "ETH",
    "amount": "2.5",
    "source_address": "0x1234567890abcdef1234567890abcdef12345678",
    "received_address": "0x9876543210fedcba9876543210fedcba98765432",
    "timestamp": 1745554838
}

AUTH Deposit Events

Subscribe to this event by setting the x-zh-hook-payload-type header value to auth_deposit.status_changed.
An auth_deposit.status_changed webhook is emitted every time a deposit submitted through the AUTH product transitions states. These webhooks emit for all of the standard events of Deposit Status Updates, but in the context of AUTH, they indicate the first point where zerohash can detect deposits given that the transactions originate from AUTH Providers such as Robinhood.

AUTH Deposit States

The state field communicates the current stage of the deposit in zerohash's processing pipeline. Values are returned in lowercase.

StateDescriptionTerminal State
pendingDeposit has been created and is pending submission in the AUTH flow - user is in progress-
submittedDeposit has been successfully submitted by AUTH Provider and awaiting on-chain detection-
2fa_pendingDeposit is pending 2FA input and validation-
confirmedDeposit has received sufficient on-chain confirmations.✅
failedDeposit has failed - recoverable funds will be available within the /recovery_quarantine subledger.✅
unexpectedFunds were marked as unexpected by the platform and will be made available for recovery within the /recovery_quarantine subledger.✅
abandonedTransaction was not successfully matched within the defined timeout period and has been considered abandoned. Funds will be made available in the /recovery_quarantine subledger.✅
archivedTransaction has been archived and is no longer in a processing state.✅
account_match_pendingAccount name matching is in progress pending a final match.-
account_match_timeoutAccount name matching for travel rule has timed out as deposit could not be found for the transaction ID. Funds will be made available in /recovery_quarantine subledger.✅
account_match_failedAccount matching has failed. Funds have been made available in the /recovery_quarantine subledger.✅

Payload Schema

FieldTypeDetails
deposit_idstring (uuid)Unique deposit identifier
reference_idstringPlatform provided id for the transaction. Present if a reference_id was provided at JWT generation time.
participant_codestringCustomer participant code owning the deposit
platform_codestringPlatform the deposit belongs to
amountstring (decimal)Deposit amount
symbolstringAsset symbol (e.g. USDC.ETH)
statestringCurrent deposit state (see table above), always lowercase
connection_idstring (uuid)AUTH connection tied to the deposit. Renders as an all-zero UUID (00000000-...), not null or omitted, when the deposit has no connection (e.g. manual/legacy deposits)
source_typestringCUSTODIAL, NON_CUSTODIAL, or MANUAL. Omitted if not set
source_integrationstringSource integration of the AUTH deposit
transaction_hashstringOn-chain transaction hash. Omitted until matched on-chain (absent for pending, submitted, 2fa_pending, archived)
block_numberstringSame omission rule as transaction_hash
destination_addressstringzerohash-owned receiving address
failure_reasonstring or nullA failed state from a non-account-validation cause (e.g. address not whitelisted)
account_labelstringFree-text label set at deposit creation. Omitted if empty
travel_rule_match_resultstringpending, valid, invalid, error, or timeout. Only present once the deposit has gone through account validation
feesobjectFee breakdown for the withdrawal. Contents depend on state and fee_payment_model. In pending state, only fee_payment_model is guaranteed; network and withdrawal amounts are populated once the transaction is confirmed, NETTED withdrawals may carry fee amounts earlier.
fees.estimated_networkobjectThe estimated network fee for the deposit based on the transaction parameters (amount, asset, network). Actual deposit fees will be displayed once transaction is submitted in the deposit object.
fees.depositobjectActual deposit fees paid as part of the transaction. This amount may differ from estimated fees.
crypto_amountstring (decimal)Fee amount denominated in the underlying crypto asset.
crypto_assetstringUnderlying crypto asset used to pay the fee
notional_amountstring (decimal)Fee amount converted to the notional currency at the time of the event
notional_currencystringCurrency of notional_amount
estimatedbooleanReturns true if the fee object is estimated; returns false if the fees are the real fees incurred on the transaction.
created_atstring (ISO 8601)Deposit creation timestamp
updated_atstring (ISO 8601)Timestamp of this state change

Example Payload

{
  "deposit_id": "f6a1c2c4-2a9e-4a01-9b0f-7b9e2c5d8e11",
  "reference_id": "f4c9c7ac-396c-43ab-b694-97d9779ba60e",
  "participant_code": "PART456",
  "platform_code": "PLAT123",
  "amount": "100.00",
  "symbol": "USDC.ETH",
  "state": "confirmed",
  "connection_id": "3f29a1e0-1c44-4b3a-9d2e-8a7c6b5f4e10",
  "source_type": "CUSTODIAL",
  "source_integration": "cbase",
  "transaction_hash": "0xabcdef1234567890...",
  "block_number": "18500000",
  "destination_address": "0xZHwallet...",
  "failure_reason": null,
  "account_label": "primary",
  "created_at": "2026-05-05T00:00:00Z",
  "updated_at": "2026-05-05T00:00:01Z"
}

Account-matching states include travel_rule_match_result in addition to the fields above:

{
  "deposit_id": "f6a1c2c4-2a9e-4a01-9b0f-7b9e2c5d8e11",
  "reference_id": "f4c9c7ac-396c-43ab-b694-97d9779ba60e",
  "participant_code": "PART456",
  "platform_code": "PLAT123",
  "amount": "100.00",
  "symbol": "USDC.ETH",
  "state": "account_match_failed",
  "connection_id": "3f29a1e0-1c44-4b3a-9d2e-8a7c6b5f4e10",
  "source_type": "CUSTODIAL",
  "source_integration": "cbase",
  "transaction_hash": "0xabcdef1234567890...",
  "block_number": "18500000",
  "destination_address": "0xZHwallet..."
}