Batch Actions & Event Bus Patterns
Execute bulk operations efficiently using batch actions, custom action types, and Event Bus patterns.
Prerequisites
- A DUAL account with an organization
- At least one template with minted objects
What You'll Build
Real-world tokenization often involves operating on hundreds or thousands of objects simultaneously — airdropping rewards, expiring promotions, or updating properties in bulk. In this tutorial you'll create custom action types, execute batch actions, and learn Event Bus patterns for reliable high-throughput operations.
Step 1 — Create a Custom Action Type
Action types define what operations can be performed on objects. DUAL ships with built-in types (Transfer, Drop, Pickup), but you can create your own for domain-specific logic.
curl -X POST https://gateway-48587430648.europe-west6.run.app/ebus/action-types \
-H "Authorization: Bearer $DUAL_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"action_type": {
"name": "Redeem",
"description": "Mark a reward token as redeemed",
"template": "my-org::reward-token::v1",
"state_changes": {
"properties.redeemed": true,
"properties.redeemed_at": "{{timestamp}}"
}
}
}'The state_changes field defines what happens to the object when this action fires. Template variables like {{timestamp}} are resolved at execution time.
Step 2 — Execute a Single Action
Test your custom action on a single object first. All actions — including custom ones — go through the /ebus/execute endpoint:
curl -X POST https://gateway-48587430648.europe-west6.run.app/ebus/execute \
-H "Authorization: Bearer $DUAL_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"action": {
"Redeem": {
"id": "your-object-id"
}
}
}'Check the object to confirm the properties changed:
curl https://gateway-48587430648.europe-west6.run.app/objects/{objectId} \
-H "Authorization: Bearer $DUAL_TOKEN" \
| jq '.properties'Step 3 — Execute Batch Actions
The batch endpoint lets you execute the same action across multiple objects in a single API call. This is far more efficient than individual requests.
curl -X POST https://gateway-48587430648.europe-west6.run.app/ebus/actions/batch \
-H "Authorization: Bearer $DUAL_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"actions": [
{ "action": { "Redeem": { "id": "object-id-1" } } },
{ "action": { "Redeem": { "id": "object-id-2" } } },
{ "action": { "Redeem": { "id": "object-id-3" } } }
]
}'The response returns an array of results — one per action — so you can check which succeeded and which failed.
Step 4 — Query Action History
View the execution history for any object to audit what happened and when:
curl "https://gateway-48587430648.europe-west6.run.app/objects/{objectId}/activity" \
-H "Authorization: Bearer $DUAL_TOKEN"What's Next?
Now that you can operate at scale, try Organization Roles & Permissions to control who can execute which actions.