Bulk Send enables one-time batch crypto transfers to multiple recipient addresses. It is suitable for payroll payouts, rebate/reward distributions, partner settlements, and revenue sharing for e-commerce/advertising/content platforms. You only need to submit a request containing multiple bulk send items. Cobo will validate each item (address format checks and compliance verification such as KYA) and then decide whether to proceed with on-chain transfers based on the execution mode.
Prerequisites
Before you start, make sure you have completed the following:
- Ensure the source_account has sufficient balance.
- (Recommended) Configure a Webhook Endpoint to receive Bulk Send status updates and drive an automated retry workflow.
1. How to send in batch
1.1 Create a Bulk Send
To create a Bulk Send, provide:
- source_account: Source account ID (e.g., M1001)
- execution_mode: Execution mode (Strict / Partial)
- payout_params: Array of bulk send items. Each item includes:
- token_id
- receiving_address
- amount
- description (recommended: include business-traceable info such as payroll slip No./user ID/batch ID)
1.2 How to choose execution_mode
After receiving a Bulk Send request, Cobo first validates all addresses in the request (including format validation and compliance checks such as KYA). execution_mode determines what happens in two situations: when any item fails validation, and — for Strict batches only — when the on-chain transfer step completes only partially (a partially completed sweep). execution_mode does not guarantee that every item succeeds once validation passes, and it does not provide transaction-level atomicity beyond these two situations. Always check each item’s own status and validation_status instead of assuming a single outcome for the whole batch.
Behavior: Strict vs Partial
execution_mode governs only the failure paths described above. It does not guarantee that a Partial batch’s validated items will all succeed on-chain, or that a Strict batch is atomic beyond these paths. Always inspect each item’s status and validation_status individually, and check the batch status (PartiallyCompleted or Failed) before deciding whether to resend.
Recommended scenarios
Use Strict (strong consistency: all-or-nothing)
- Partner settlements (must take effect consistently within the same batch)
- Vendor payments (finance requires batch-level consistency)
- Any scenario where partial success is unacceptable
Use Partial (high throughput: partial failures allowed, retry later) — recommended whenever a single item’s validation failure must not block the rest of a valid batch:
- Global payroll payouts (large volume; a few bad addresses should not block the whole batch)
- Rebates/rewards airdrops (mixed address quality)
- Tips/revenue distribution for content platforms; merchant payout distribution for e-commerce/ads platforms (retry is acceptable)
Impact summary:
Strict improves financial consistency by failing the whole batch on any validation failure (marking every item NotExecuted) or a partially completed sweep (batch status Failed), but increases operational overhead: a validation failure forces a full resubmission, while a partially completed sweep requires you to inspect each item’s status individually before deciding what to resubmit.
Partial isolates validation failures to the affected items so the rest of the batch proceeds, which scales better and is more automation-friendly, but requires a retry workflow for the failed items.
1.3 Smart contract mechanism for Bulk Send
For Bulk Send on Ethereum, Cobo uses smart contracts to perform batch transfers. For other chains, Cobo uses regular transactions instead. In both cases, Cobo sends a callback message to your registered callback endpoint for each operation so that you can inspect the details and approve or deny execution. The exact mechanism may also vary based on your organization’s configuration — contact Cobo support for details. To learn how to set up and register a callback endpoint, see Introduction to Callbacks.
Approve operation (triggered when allowance is insufficient)
When the smart contract’s allowance for a token is insufficient, an approve call is first triggered on the token contract:
- Function called:
approve
- calldata parameters:
_spender: The batch transfer contract address (see table below)
_value: The transfer amount
Transfer operation
After the approve completes, the actual transfer calls the sendToken function on the batch transfer contract:
- Function called:
sendToken
- calldata parameters:
token: The token contract address (see table below)
recipients: List of recipient addresses
values: Corresponding list of transfer amounts
Contract address reference
Since the contract addresses are fixed for each token, it is recommended to verify the contract addresses and function call information in your callback handler to ensure the callback completes correctly.
2. Webhook-driven automation workflow (failure notification → query items → batch resend)
2.1 Subscribe to Bulk Send status update events
Cobo triggers a webhook event when the Bulk Send status transitions to any of the following:
- Completed
- PartiallyCompleted
- Failed
Webhook payload example (Bulk Send Notification):
Status can be one of:
- Pending
- Validating
- Transferring
- Completed
- PartiallyCompleted
- Failed
Recommendations
- Trigger the resend workflow only when the status enters PartiallyCompleted or Failed. During Validating / Transfering, you may only display or monitor progress.
- Implement webhook signature verification and idempotency handling (the same event may be replayed).
2.2 After a failure notification: query Bulk Send item details
After receiving a PartiallyCompleted or Failed webhook, call List bulk send items to query the status of each bulk send item:
- Path parameter: bulk_send_id
- Operation: list_bulk_send_items
- Summary: List bulk send items
(Example pseudo endpoint)
Each item includes two key status fields:
- status (execution status of the item)
- validation_status (address/compliance validation status)
Rules to focus on:
- If status = Failed or NotExecuted → the item failed
- If validation_status = ValidationFailed → the address did not pass Cobo KYA validation
For both cases, replacing the address is recommended.
2.3 Automated retry: replace addresses and resend in batch
Resend strategy depends on execution_mode:
A) Previous batch used Strict
- Under
Strict, if any item fails validation, the batch fails and every item is marked NotExecuted.
- Under
Strict, if the on-chain transfer step completes only partially, the batch status becomes Failed.
- For the validation-failure path, resubmission must include all items. For a partially completed sweep, inspect each item’s
status individually before deciding what to resubmit — do not assume every item needs resubmission.
Steps (validation-failure path):
- Query items and identify those with
validation_status: ValidationFailed.
- Replace the addresses for those items (or fix other parameters causing failures).
- Resubmit a new Bulk Send containing all items.
For a partially completed sweep, query each item’s status individually and use that to decide which items (if any) to resubmit — do not default to resubmitting the full batch.
B) Previous batch used Partial
- Under
Partial, successful items have already been transferred.
- Therefore, on retry, submit only failed items (reduces the risk of duplicate transfers).
Steps:
- Query items and filter failed items (
status=Failed/NotExecuted or validation_status=ValidationFailed)
- Replace the addresses for failed items
- Create a new Bulk Send containing only these failed items
3. Reference implementation: webhook handling + auto resend (example)
This example demonstrates a typical workflow:
- Receive webhook
- If status is
PartiallyCompleted / Failed, query items
- Filter failed items and replace addresses (address replacement is handled by your business system)
- Create a new Bulk Send for resend
Note: This is illustrative pseudo-code (Node.js style). Adjust based on your actual SDK and signature verification mechanism.
4. Best practices
Always include business-traceable identifiers in description (e.g., batch_id + user_id/employee_id + period) for auditing, reconciliation, diagnosing failures, and address replacement.
- Use different resend strategies for Strict vs Partial:
- Strict: for a validation failure, retry must include all items; for a partially completed sweep, inspect each item’s
status individually before deciding what to resubmit
- Partial: retry only failed items (avoid duplicate payouts)
- Webhook idempotency: use
bulk_send_id + status + updated_timestamp as an idempotency key to avoid duplicated resend triggers.
- Failure classification:
- validation_status=ValidationFailed:prioritize replacing the address
- status=Failed/NotExecuted: also recommended to replace the address (per your rule), and retain the failure reason for risk control and user messaging