Batch Operations
Batch Operations and Bulk Updates
Learn how to efficiently update multiple records at once using batch operations, reducing the number of API calls and improving performance.
Why Use Batch Operations?
Instead of making 100 individual API calls to update 100 records, make 1 batch update call. This is faster, uses fewer rate limit points, and is more efficient.
Check Batch Update Count
Before executing a batch update, check how many records will be affected:
POST /api/v1/data-tables/{tableId}/records/batch-update-check
Headers:
X-Tadabase-App-id: your_app_id
X-Tadabase-App-Key: your_app_key
X-Tadabase-App-Secret: your_app_secret
Content-Type: application/json
Body:
{
"filters": {
"condition": "AND",
"items": [
{
"field_id": "status",
"operator": "is",
"val": "pending"
}
]
}
}
Response
{
"type": "success",
"total": 45,
"msg": "45 records will be updated"
}
⚠️ Always Check First
Always use batch-update-check before executing a batch update to verify the number of records that will be affected. This prevents accidental bulk updates to wrong records.
Execute Batch Update
Update multiple records at once based on filter conditions:
POST /api/v1/data-tables/{tableId}/records/batch-update
Headers:
X-Tadabase-App-id: your_app_id
X-Tadabase-App-Key: your_app_key
X-Tadabase-App-Secret: your_app_secret
Content-Type: application/json
Body:
{
"conditions": [
{
"condition": "AND",
"items": [
{
"field_id": "status",
"operator": "is",
"val": "pending"
}
]
}
],
"values": [
{
"field_id": "status",
"value": "approved",
"val_type": "normal"
},
{
"field_id": "approved_date",
"value": "2024-01-27",
"val_type": "normal"
}
]
}
Response
{
"type": "success",
"total": 45,
"msg": "45 records updated successfully"
}
Batch Update Structure
Conditions Array
Defines which records to update:
"conditions": [
{
"condition": "AND",
"items": [
{
"field_id": "field_slug",
"operator": "is",
"val": "value"
}
]
}
]
Values Array
Defines what to update (note: uses "value" not "val"):
"values": [
{
"field_id": "field_slug",
"value": "new_value",
"val_type": "normal"
}
]
Value Types
| val_type | Description | Example |
|---|---|---|
normal |
Static value | "value": "Active" |
formula |
Formula expression | "value": "{field1} + {field2}" |
field |
Copy from another field | "value": "source_field_slug" |
Common Batch Update Patterns
1. Status Updates
// Approve all pending orders
{
"conditions": [
{
"condition": "AND",
"items": [
{
"field_id": "status",
"operator": "is",
"val": "pending"
}
]
}
],
"values": [
{
"field_id": "status",
"value": "approved",
"val_type": "normal"
}
]
}
2. Date Stamping
// Set processed date for all unprocessed records
{
"conditions": [
{
"condition": "AND",
"items": [
{
"field_id": "processed_date",
"operator": "is blank"
}
]
}
],
"values": [
{
"field_id": "processed_date",
"value": "2024-01-27",
"val_type": "normal"
}
]
}
3. Bulk Assignment
// Assign all unassigned tickets to a user
{
"conditions": [
{
"condition": "AND",
"items": [
{
"field_id": "assigned_to",
"operator": "is blank"
},
{
"field_id": "priority",
"operator": "is",
"val": "high"
}
]
}
],
"values": [
{
"field_id": "assigned_to",
"value": "user_id_here",
"val_type": "normal"
}
]
}
4. Numeric Updates
// Increase price by 10% for active products
{
"conditions": [
{
"condition": "AND",
"items": [
{
"field_id": "status",
"operator": "is",
"val": "active"
}
]
}
],
"values": [
{
"field_id": "price",
"value": "{price} * 1.1",
"val_type": "formula"
}
]
}
5. Copy Field Values
// Copy temporary field to permanent field
{
"conditions": [
{
"condition": "AND",
"items": [
{
"field_id": "temp_value",
"operator": "is not blank"
}
]
}
],
"values": [
{
"field_id": "permanent_value",
"value": "temp_value",
"val_type": "field"
}
]
}
Safe Batch Update Workflow
async function safeBatchUpdate(tableId, conditions, values) {
// Step 1: Check count
const checkResponse = await fetch(
`https://api.tadabase.io/api/v1/data-tables/${tableId}/records/batch-update-check`,
{
method: 'POST',
headers: {
'X-Tadabase-App-id': 'your_app_id',
'X-Tadabase-App-Key': 'your_app_key',
'X-Tadabase-App-Secret': 'your_app_secret',
'Content-Type': 'application/json'
},
body: JSON.stringify({
filters: conditions[0]
})
}
);
const checkData = await checkResponse.json();
console.log(`Will update ${checkData.total} records`);
// Step 2: Confirm with user
const confirmed = confirm(`Update ${checkData.total} records?`);
if (!confirmed) {
console.log('Batch update cancelled');
return null;
}
// Step 3: Execute update
const updateResponse = await fetch(
`https://api.tadabase.io/api/v1/data-tables/${tableId}/records/batch-update`,
{
method: 'POST',
headers: {
'X-Tadabase-App-id': 'your_app_id',
'X-Tadabase-App-Key': 'your_app_key',
'X-Tadabase-App-Secret': 'your_app_secret',
'Content-Type': 'application/json'
},
body: JSON.stringify({
conditions,
values
})
}
);
const updateData = await updateResponse.json();
console.log(`Updated ${updateData.total} records successfully`);
return updateData;
}
// Usage
await safeBatchUpdate(
'lGArg7rmR6',
[
{
condition: "AND",
items: [
{ field_id: "status", operator: "is", val: "pending" }
]
}
],
[
{ field_id: "status", value: "approved", val_type: "normal" }
]
);
Complex Batch Updates
Multiple Field Updates
{
"conditions": [
{
"condition": "AND",
"items": [
{
"field_id": "status",
"operator": "is",
"val": "pending"
}
]
}
],
"values": [
{
"field_id": "status",
"value": "approved",
"val_type": "normal"
},
{
"field_id": "approved_date",
"value": "2024-01-27",
"val_type": "normal"
},
{
"field_id": "approved_by",
"value": "admin_user_id",
"val_type": "normal"
},
{
"field_id": "notes",
"value": "Bulk approved on 2024-01-27",
"val_type": "normal"
}
]
}
Nested Conditions
{
"conditions": [
{
"condition": "AND",
"items": [
{
"field_id": "status",
"operator": "is",
"val": "active"
}
],
"child": [
{
"condition": "any",
"items": [
{
"field_id": "email",
"operator": "contains",
"val": "@example.com"
},
{
"field_id": "email",
"operator": "contains",
"val": "@test.com"
}
]
}
]
}
],
"values": [
{
"field_id": "email_verified",
"value": "1",
"val_type": "normal"
}
]
}
Batch Update with Formulas
Calculate New Values
// Add 10% tax to all prices
{
"conditions": [
{
"condition": "AND",
"items": [
{
"field_id": "tax_added",
"operator": "is unchecked"
}
]
}
],
"values": [
{
"field_id": "price_with_tax",
"value": "{price} * 1.1",
"val_type": "formula"
},
{
"field_id": "tax_added",
"value": "1",
"val_type": "normal"
}
]
}
Concatenate Fields
// Create full name from first and last name
{
"conditions": [
{
"condition": "AND",
"items": [
{
"field_id": "full_name",
"operator": "is blank"
}
]
}
],
"values": [
{
"field_id": "full_name",
"value": "{first_name} & ' ' & {last_name}",
"val_type": "formula"
}
]
}
Alternative: Loop with Individual Updates
Sometimes you need individual record processing:
async function updateWithLogic(tableId) {
// Get records to update
const response = await fetch(
`https://api.tadabase.io/api/v1/data-tables/${tableId}/records`,
{
method: 'POST',
headers: {
'X-Tadabase-App-id': 'your_app_id',
'X-Tadabase-App-Key': 'your_app_key',
'X-Tadabase-App-Secret': 'your_app_secret',
'Content-Type': 'application/json'
},
body: JSON.stringify({
filters: {
condition: "AND",
items: [
{ field_id: "needs_processing", operator: "is checked" }
]
}
})
}
);
const data = await response.json();
// Process each record individually with custom logic
for (const record of data.items) {
let newValue;
// Custom logic per record
if (record.category === 'A') {
newValue = record.price * 1.1;
} else if (record.category === 'B') {
newValue = record.price * 1.2;
} else {
newValue = record.price * 1.05;
}
// Update individual record
await fetch(
`https://api.tadabase.io/api/v1/data-tables/${tableId}/records/${record.id}`,
{
method: 'POST',
headers: {
'X-Tadabase-App-id': 'your_app_id',
'X-Tadabase-App-Key': 'your_app_key',
'X-Tadabase-App-Secret': 'your_app_secret',
'Content-Type': 'application/json'
},
body: JSON.stringify({
new_price: newValue
})
}
);
// Rate limit friendly - delay between requests
await new Promise(resolve => setTimeout(resolve, 500));
}
}
Performance Considerations
When to Use Batch Updates
| Scenario | Best Approach |
|---|---|
| Same update for many records | ✅ Batch update |
| Simple conditions, static values | ✅ Batch update |
| Need to update 1000+ records | ✅ Batch update |
| Different logic per record | ❌ Individual updates |
| Need to call external API per record | ❌ Individual updates |
| Complex conditional logic | ❌ Individual updates |
Batch Update Limits
- No explicit limit on number of records updated
- Large batch updates may take time to process
- Consider breaking very large updates (10,000+) into smaller batches
- Monitor for timeouts on extremely large operations
Error Handling
async function batchUpdateWithErrorHandling(tableId, conditions, values) {
try {
// Check first
const checkResponse = await fetch(
`https://api.tadabase.io/api/v1/data-tables/${tableId}/records/batch-update-check`,
{
method: 'POST',
headers,
body: JSON.stringify({ filters: conditions[0] })
}
);
const checkData = await checkResponse.json();
if (checkData.type === 'error') {
throw new Error(`Check failed: ${checkData.msg}`);
}
console.log(`Will update ${checkData.total} records`);
if (checkData.total === 0) {
console.log('No records to update');
return null;
}
// Execute update
const updateResponse = await fetch(
`https://api.tadabase.io/api/v1/data-tables/${tableId}/records/batch-update`,
{
method: 'POST',
headers,
body: JSON.stringify({ conditions, values })
}
);
const updateData = await updateResponse.json();
if (updateData.type === 'error') {
throw new Error(`Update failed: ${updateData.msg}`);
}
return updateData;
} catch (error) {
console.error('Batch update error:', error);
throw error;
}
}
Best Practices
- Always check first: Use batch-update-check to verify record count
- Test with small dataset: Test batch updates on a few records first
- Use specific conditions: Be very specific with filter conditions
- Backup data: Export records before large batch operations
- Log operations: Log batch updates for audit trail
- Use formulas wisely: Test formula syntax with individual records first
- Consider timing: Run large batch operations during off-peak hours
- Monitor results: Verify the update count matches expectations
Complete Example: Batch Status Update Tool
class BatchUpdateTool {
constructor(tableId) {
this.tableId = tableId;
}
async checkCount(filters) {
const response = await fetch(
`https://api.tadabase.io/api/v1/data-tables/${this.tableId}/records/batch-update-check`,
{
method: 'POST',
headers,
body: JSON.stringify({ filters })
}
);
return await response.json();
}
async execute(conditions, values) {
const response = await fetch(
`https://api.tadabase.io/api/v1/data-tables/${this.tableId}/records/batch-update`,
{
method: 'POST',
headers,
body: JSON.stringify({ conditions, values })
}
);
return await response.json();
}
async updateStatus(fromStatus, toStatus, requireConfirmation = true) {
const conditions = [
{
condition: "AND",
items: [
{
field_id: "status",
operator: "is",
val: fromStatus
}
]
}
];
// Check count
const checkResult = await this.checkCount(conditions[0]);
console.log(`Found ${checkResult.total} records with status "${fromStatus}"`);
if (checkResult.total === 0) {
console.log('No records to update');
return null;
}
// Confirm if needed
if (requireConfirmation) {
const confirmed = confirm(
`Update ${checkResult.total} records from "${fromStatus}" to "${toStatus}"?`
);
if (!confirmed) {
console.log('Update cancelled');
return null;
}
}
// Execute update
const values = [
{
field_id: "status",
value: toStatus,
val_type: "normal"
},
{
field_id: "status_changed_date",
value: new Date().toISOString().split('T')[0],
val_type: "normal"
}
];
const result = await this.execute(conditions, values);
console.log(`Updated ${result.total} records`);
return result;
}
}
// Usage
const batchTool = new BatchUpdateTool('lGArg7rmR6');
// Update all pending to approved
await batchTool.updateStatus('pending', 'approved');
// Update without confirmation
await batchTool.updateStatus('draft', 'published', false);
Next Steps
Learn how to run and monitor automated tasks via the API:
→ Tasks API - Running and Monitoring
Discover how to trigger tasks, check their status, and manage task execution.
We'd love to hear your feedback.