Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,18 @@
"pages": [
"v2/guides/webhooks-callbacks/introduction",
"v2/guides/webhooks-callbacks/set-up-endpoint",
"v2/guides/webhooks-callbacks/webhook-event-type"
"v2/guides/webhooks-callbacks/webhook-event-type",
"v2/guides/webhooks-callbacks/transaction-webhook-payload-examples",
"v2/guides/webhooks-callbacks/transaction-field-dictionary",
"v2/guides/webhooks-callbacks/tss-request-webhook-payload-examples",
"v2/guides/webhooks-callbacks/tss-request-field-dictionary",
"v2/guides/webhooks-callbacks/wallet-address-webhook-payload-examples",
"v2/guides/webhooks-callbacks/wallet-address-field-dictionary",
"v2/guides/webhooks-callbacks/token-chain-webhook-payload-examples",
"v2/guides/webhooks-callbacks/token-chain-field-dictionary",
"v2/guides/webhooks-callbacks/balance-update-webhook-payload-examples",
"v2/guides/webhooks-callbacks/balance-update-field-dictionary",
"v2/guides/webhooks-callbacks/subscription-scenarios"
]
},
{
Expand Down Expand Up @@ -858,7 +869,18 @@
"pages": [
"v2_cn/guides/webhooks-callbacks/introduction",
"v2_cn/guides/webhooks-callbacks/set-up-endpoint",
"v2_cn/guides/webhooks-callbacks/webhook-event-type"
"v2_cn/guides/webhooks-callbacks/webhook-event-type",
"v2_cn/guides/webhooks-callbacks/transaction-webhook-payload-examples",
"v2_cn/guides/webhooks-callbacks/transaction-field-dictionary",
"v2_cn/guides/webhooks-callbacks/tss-request-webhook-payload-examples",
"v2_cn/guides/webhooks-callbacks/tss-request-field-dictionary",
"v2_cn/guides/webhooks-callbacks/wallet-address-webhook-payload-examples",
"v2_cn/guides/webhooks-callbacks/wallet-address-field-dictionary",
"v2_cn/guides/webhooks-callbacks/token-chain-webhook-payload-examples",
"v2_cn/guides/webhooks-callbacks/token-chain-field-dictionary",
"v2_cn/guides/webhooks-callbacks/balance-update-webhook-payload-examples",
"v2_cn/guides/webhooks-callbacks/balance-update-field-dictionary",
"v2_cn/guides/webhooks-callbacks/subscription-scenarios"
]
},
{
Expand Down Expand Up @@ -1598,4 +1620,4 @@
"destination": "https://www.cobo.com/payments/cn/guides/overview"
}
]
}
}
32 changes: 32 additions & 0 deletions v2/guides/webhooks-callbacks/balance-update-field-dictionary.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
title: "Balance update payload field dictionary"
lang: "en"
description: "Definitions and trigger behavior for BalanceUpdateInfo webhook payload fields."
sidebarTitle: "Balance update field dictionary"
---

import WaasSkillReminder from '/snippets/waas_skill_reminder.mdx';

<WaasSkillReminder />

This page defines high-signal fields and trigger behavior for `BalanceUpdateInfo` webhook events.

### Trigger behavior

Both balance update event types share the same payload shape. Which event type is emitted — `wallet.mpc.balance.updated` or `wallet.web3.balance.updated` — depends on the wallet type that triggered the balance change.

The event fires when Cobo's chain-scanning and balance-refresh pipeline detects a new or changed on-chain balance. It is not a fixed periodic reconciliation job, and it is not gated on transaction-ledger completion.

### Field dictionary

| Field | Description |
|-------|-------------|
| `token_id` | The token or currency whose balance changed. |
| `address` | The on-chain address whose balance was refreshed. |
| `wallet_uuid` | The wallet identifier for this balance payload. This field is named `wallet_uuid`, not `wallet_id`, unlike Transaction and Addresses payloads. |
| `updated_timestamp` | The time when the balance update was recorded. |
| `balance.total` | Total balance for the token at the address. Required by the `Balance` schema. |
| `balance.available` | Balance currently available for use. Required by the `Balance` schema. |
| `balance.pending` | Balance pending final availability. |
| `balance.locked` | Balance locked by platform or workflow constraints. |
| `balance.frozen` | Balance frozen by compliance or risk controls. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
title: "Balance update webhook payload examples"
lang: "en"
description: "Full JSON examples of BalanceUpdateInfo webhook event payloads."
sidebarTitle: "Balance update payload examples"
---

import WaasSkillReminder from '/snippets/waas_skill_reminder.mdx';

<WaasSkillReminder />

This page shows complete `BalanceUpdateInfo` payloads as delivered in `wallet.mpc.balance.updated` and `wallet.web3.balance.updated` webhook events. For the event list, see [Webhook event types and data types](/v2/guides/webhooks-callbacks/webhook-event-type).

`wallet.mpc.balance.updated` and `wallet.web3.balance.updated` use the identical schema and differ only in which wallet type triggered the event.

```json
{
"token_id": "ETH_USDT",
"address": "0x5aeda56215b167893e80b4fe645ba6d5bab767de",
"wallet_uuid": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"updated_timestamp": 1751328600000,
"balance": {
"total": "1250.50",
"available": "1200.00",
"pending": "25.50",
"locked": "20.00",
"frozen": "5.00"
}
}
```
4 changes: 3 additions & 1 deletion v2/guides/webhooks-callbacks/set-up-endpoint.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ When your webhook endpoint receives a webhook event, it should respond with a st

The default timeout for each webhook event is 2 seconds. If the webhook endpoint does not respond or responds with a status code other than `200` or `201`, the WaaS service will continue to retry sending the event. If the number of retry attempts reaches 10 , the WaaS service will stop sending the event and the event status will become `Failed`· You can resend the event by clicking **Retry** on **Cobo Portal** > **Developer** > **WaaS 2.0** > **Webhook Events**.

Webhook events are retained for 7 days after generation. After that window, the event is purged and is no longer retrievable through Cobo Portal or the [List all webhook events](/v2/api-references/developers--webhooks/list-all-webhook-events) / [Retrieve event information](/v2/api-references/developers--webhooks/retrieve-event-information) operations. If you need to backfill missed events, do so before the 7-day window closes, using either the Webhook Event Logs view on **Cobo Portal** > **Developer** > **Webhook Events**, or the [List webhook event logs](/v2/api-references/developers--webhooks/list-webhook-event-logs) and [Retry webhook event by ID](/v2/api-references/developers--webhooks/retry-event) operations.

Cobo does not guarantee that events will be delivered in the order they are generated. For example, creating a transfer will generate the following events:

- `wallets.transaction.created`
Expand Down Expand Up @@ -188,4 +190,4 @@ async def handle_webhook(
<Warning>
- When receiving the webhook events, your endpoint should first return the correct status code promptly and then handle any subsequent processing asynchronously to prevent timeouts.
- Due to the retry mechanism of webhook events, webhook endpoints may sometimes receive the same event multiple times. To protect against duplicate event processing, please log the event IDs, transaction hashes, or transaction IDs you've already processed and refrain from processing those that are already logged.
</Warning>
</Warning>
43 changes: 43 additions & 0 deletions v2/guides/webhooks-callbacks/subscription-scenarios.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: "Webhook subscription scenarios"
lang: "en"
description: "Scenario-based guidance for choosing which webhook event types to subscribe to."
sidebarTitle: "Subscription scenarios"
---

import WaasSkillReminder from '/snippets/waas_skill_reminder.mdx';

<WaasSkillReminder />

This guide helps you choose webhook event subscriptions for common transaction workflows.

### Minimal subscription for deposit auto-crediting

Subscribe to `wallets.transaction.succeeded` for deposit auto-crediting. This event is the only Transaction event that indicates a transaction completed successfully. See the crediting rule in [Transaction events](/v2/guides/webhooks-callbacks/webhook-event-type#transaction-events-depositswithdrawalscontract-callsmessage-signing).

If your organization uses KYT or compliance screening, also track `compliance.kyt.screenings.status.updated` and `compliance.disposition.status.updated` when your business logic requires a final disposition before funds are usable. Compliance screening may complete independently of transaction confirmation, so check both event streams when compliance status affects availability.

### Withdrawal status tracking

Use the following event set to track withdrawal status. For the full status and sub-status reference, see [Transaction statuses](/v2/guides/transactions/status).

| Lifecycle signal | Event | How to use it |
|------------------|-------|---------------|
| Record created | `wallets.transaction.created` | Store the transaction record. Do not treat this as a final result. |
| Status or confirmation changed | `wallets.transaction.updated` | Update UI or internal progress state. Do not credit funds from this event. |
| Terminal success | `wallets.transaction.succeeded` | Mark the withdrawal as completed successfully. |
| Terminal failure | `wallets.transaction.failed` | Mark the withdrawal as failed and trigger your failure-handling flow. |

### created/updated/succeeded overlap

`wallets.transaction.created`, `wallets.transaction.updated`, and `wallets.transaction.succeeded` are not mutually exclusive stages. `wallets.transaction.updated` fires on every change, including transitions that can also produce `wallets.transaction.created` or `wallets.transaction.succeeded`. If your endpoint subscribes to all three, expect `wallets.transaction.updated` to appear alongside the other events at the same lifecycle points, not as a fourth distinct stage.

### Subscriptions are per-endpoint, channel is org-wide

Each webhook endpoint has its own event-type subscription list, but all endpoints in an organization share one org-wide delivery channel. For example, endpoint A can subscribe only to `wallets.transaction.succeeded`, while endpoint B subscribes to `wallets.transaction.created`, `wallets.transaction.updated`, `wallets.transaction.succeeded`, and `wallets.transaction.failed`. Both endpoints belong to the same organization, and each receives only the event types in its own subscription list.

### Webhook + API reconciliation pattern

Use [List all transactions](/v2/api-references/transactions/list-all-transactions) or [Get transaction information](/v2/api-references/transactions/get-transaction-information) as the source of truth for periodic reconciliation against webhook-driven state. This lets you recover from missed deliveries, duplicate deliveries, or processing failures in your own system. For duplicate-delivery handling, see [Important notes](/v2/guides/webhooks-callbacks/set-up-endpoint#important-notes).

Use your Webhook Event Logs to confirm which event patterns apply to transactions initiated outside your API flow, such as Portal-initiated withdrawals or automatic system flows in your organization.
48 changes: 48 additions & 0 deletions v2/guides/webhooks-callbacks/token-chain-field-dictionary.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
title: "Token and chain payload field dictionary"
lang: "en"
description: "Definitions and trigger behavior for token, chain, and token listing webhook payloads."
sidebarTitle: "Token and chain field dictionary"
---

import WaasSkillReminder from '/snippets/waas_skill_reminder.mdx';

<WaasSkillReminder />

This page defines high-signal fields and trigger behavior for token and chain management webhook events.

### Token scope events

`wallet.token.enabled` and `wallet.token.disabled` report an organization-specific change in which tokens are available to use. Cobo emits these events after an update to a token's visibility scope takes effect. A visibility change from public to public emits no event. When a token becomes public, eligible organizations that have not already explicitly enabled it receive `wallet.token.enabled`. When a token stops being public, eligible organizations that are not explicitly retained receive `wallet.token.disabled`. For non-public tokens, organizations added to the access list receive `wallet.token.enabled`, while organizations removed from it receive `wallet.token.disabled`.

Only organizations that are enabled and already have the token's chain enabled for the relevant wallet type receive these events. No single Portal action or API call always precedes them. Automatic token listing approval is one possible cause, but other token visibility updates can also cause these events.

| Field | Description |
|-------|-------------|
| `tokens` | The affected token record. Although this field is an array, each event carries exactly one token object describing the token whose availability changed for the wallet scope below: `token_id`, `chain_id`, `asset_id`, `symbol`, `name`, `decimal`, `icon_url`, `token_address`, `fee_token_id`, `can_deposit`, `can_withdraw`, `dust_threshold`, `custodial_minimum_deposit_threshold`, and `asset_model_type`. |
| `wallet_type` | The wallet family, such as MPC Wallets or Custodial Wallets, whose token availability changed. |
| `wallet_subtypes` | The affected wallet subtype scope. This field can include more than one value, such as both `Org-Controlled` and `User-Controlled` for MPC Wallets, when the underlying visibility scope maps to multiple subtypes. |

Treat each event as a delta scoped by `wallet_type` and `wallet_subtypes`. For `wallet.token.enabled`, add or refresh the token for those scopes. For `wallet.token.disabled`, stop treating the token as enabled for those scopes. To resynchronize with the current state, call [List enabled tokens](/v2/api-references/wallets/list-enabled-tokens) for your organization and the affected wallet type and subtype.

### Chain scope events

`wallet.chain.enabled` and `wallet.chain.disabled` are emitted by an MFA-guarded organization-facing action. They fire when an organization admin updates which chains their package or wallet type supports.

| Field | Description |
|-------|-------------|
| `chains` | The enabled or disabled chain records. Each item follows `ChainInfo`. |
| `wallet_type` | The wallet family whose chain scope changed. |
| `wallet_subtypes` | The wallet subtypes affected by the chain-scope change. |

### Token listing events

`wallets.token_listing.succeeded` and `wallets.token_listing.failed` are part of an end-user token listing flow. Organizations create requests with `POST wallets/tokens/listing_requests`. Cobo reviews the request, and the succeeded or failed webhook is emitted when the review reaches a final status.

| Field | Description |
|-------|-------------|
| `request_id` | The token listing request identifier. |
| `status` | Final request status. Values are `Submitted`, `Succeeded`, and `Failed`. |
| `source` | Request source. Values are `API` and `Admin`. |
| `feedback` | Review feedback for the request, usually populated when the listing fails. |
| `token` | The token record produced by a successful listing. It follows `TokenInfo`. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
title: "Token and chain webhook payload examples"
lang: "en"
description: "Full JSON examples of token, chain, and token listing webhook event payloads."
sidebarTitle: "Token and chain payload examples"
---

import WaasSkillReminder from '/snippets/waas_skill_reminder.mdx';

<WaasSkillReminder />

This page shows complete payload examples for token and chain management webhook events. For the event list, see [Webhook event types and data types](/v2/guides/webhooks-callbacks/webhook-event-type).

### Token enabled or disabled

`wallet.token.enabled` and `wallet.token.disabled` deliver a `TokensEventData` payload with `tokens`, `wallet_type`, and `wallet_subtypes`.

```json
{
"tokens": [
{
"token_id": "ETH_USDT",
"name": "Tether USD",
"symbol": "USDT",
"chain_id": "ETH",
"decimal": 6,
"token_address": "0xdac17f958d2ee523a2206206994597c13d831ec7"
}
],
"wallet_type": "MPC",
"wallet_subtypes": [
"Org-Controlled",
"User-Controlled"
]
}
```

### Chain enabled or disabled

`wallet.chain.enabled` and `wallet.chain.disabled` deliver a `ChainsEventData` payload with `chains`, `wallet_type`, and `wallet_subtypes`.

```json
{
"chains": [
{
"chain_id": "ETH",
"symbol": "ETH",
"icon_url": "https://example.com/chains/eth.png",
"explorer_tx_url": "https://etherscan.io/tx/{txn_id}",
"explorer_address_url": "https://etherscan.io/address/{address}",
"require_memo": false
}
],
"wallet_type": "MPC",
"wallet_subtypes": [
"Org-Controlled"
]
}
```

### Token listing succeeded or failed

`wallets.token_listing.succeeded` and `wallets.token_listing.failed` deliver a `TokenListing` payload. The payload includes the final request status, request source, optional feedback, and the listed token details.

```json
{
"request_id": "token-listing-20250701-0001",
"chain_id": "ETH",
"contract_address": "0x1234567890abcdef1234567890abcdef12345678",
"wallet_type": "MPC",
"wallet_subtype": "Org-Controlled",
"token": {
"token_id": "ETH_EXAMPLE",
"name": "Example Token",
"symbol": "EXAMPLE",
"chain_id": "ETH",
"decimal": 18,
"token_address": "0x1234567890abcdef1234567890abcdef12345678"
},
"status": "Succeeded",
"source": "API",
"feedback": null,
"created_timestamp": 1751328000000,
"updated_timestamp": 1751328600000
}
```
Loading