Skip to main content

Batch Operations

Submit multiple operations in a single API call. Each operation creates an independent transaction processed in parallel — saving time and reducing rate-limit consumption.

When to Use

  • Airdrops — mint tokens to hundreds of addresses with one API call
  • Multi-transfer — distribute tokens to multiple recipients at once
  • Setup flows — deploy + mint + set roles without multiple API calls
  • Cost savings — one API call instead of N, with fewer rate-limit hits
Rate Limit Savings

A single batch request counts as one request toward your rate limit, regardless of how many operations it contains.

Supported Operations

MethodDescriptionRequired Params
mintMint tokenstoken_id, to, amount
transferTransfer tokenstoken_id, from, to, amount
burnBurn tokenstoken_id, from, amount
approveSet allowancetoken_id, owner, spender, amount

Create a Batch

const batch = await urblock.batch.create({
operations: [
{ method: "mint", token_id: "tok_abc123", params: { to: "0xAAA...", amount: "1000000000000000000" } },
{ method: "mint", token_id: "tok_abc123", params: { to: "0xBBB...", amount: "2000000000000000000" } },
{ method: "mint", token_id: "tok_abc123", params: { to: "0xCCC...", amount: "3000000000000000000" } },
{ method: "transfer", token_id: "tok_abc123", params: { from: "0xAAA...", to: "0xDDD...", amount: "500000000000000000" } },
],
idempotency_key: "batch-airdrop-001",
});

console.log(batch.id); // "bat_abc123"
console.log(batch.status); // "pending"

curl Example

curl -X POST https://api.urblock.io/v1/batch \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"operations": [
{ "method": "mint", "token_id": "tok_abc123", "params": { "to": "0xAAA...", "amount": "1000000000000000000" } },
{ "method": "mint", "token_id": "tok_abc123", "params": { "to": "0xBBB...", "amount": "2000000000000000000" } }
],
"idempotency_key": "batch-001"
}'

Check Batch Status

The batch create response includes the batch status and operation results. Track individual transactions via operations[].transaction_id using urblock.transactions.retrieve():

// Each operation resolves to a transaction
for (const op of batch.operations) {
if (op.transaction_id) {
const tx = await urblock.transactions.retrieve(op.transaction_id);
console.log(`Op ${op.index}: ${tx.status}${tx.tx_hash}`);
}
}

Error Handling

Each operation in a batch is processed independently. If one operation fails, others may still succeed (partial failures are possible):

{
"id": "bat_abc123",
"status": "completed",
"operations": [
{ "index": 0, "status": "confirmed", "tx_hash": "0x..." },
{ "index": 1, "status": "failed", "error": "insufficient_balance" },
{ "index": 2, "status": "confirmed", "tx_hash": "0x..." }
]
}

If an operation fails validation (bad params), it is rejected before submission:

{
"statusCode": 400,
"error": "Bad Request",
"message": "Operation 2 failed: token tok_invalid not found"
}

Common Errors

CodeMeaning
validation_errorInvalid params in one or more operations
token_not_foundReferenced token doesn't exist
insufficient_balanceNot enough tokens for transfer/burn
unauthorizedToken is paused or caller lacks required role
batch_too_largeExceeds maximum operations per batch (10)

Limits

ConstraintValue
Max operations per batch10
Max batch request size1 MB
Rate limit20 requests/minute

Real-World Example: Airdrop

// Airdrop 1000 tokens to a list of winners (max 10 per batch)
const allWinners = ["0xAAA...", "0xBBB...", "0xCCC...", /* ... */];
const AMOUNT = "1000000000000000000000"; // 1000 tokens
const CHUNK_SIZE = 10; // max operations per batch

for (let i = 0; i < allWinners.length; i += CHUNK_SIZE) {
const chunk = allWinners.slice(i, i + CHUNK_SIZE);
const batch = await urblock.batch.create({
operations: chunk.map((to) => ({
method: "mint",
token_id: "tok_abc123",
params: { to, amount: AMOUNT },
})),
idempotency_key: `airdrop-round-1-chunk-${i / CHUNK_SIZE}`,
});
console.log(`Batch ${batch.id}: ${batch.status} (${chunk.length} ops)`);
}

Next Steps