Skip to main content
Batch operations allow you to create or update multiple records efficiently in a single API call.

Atomic vs Partial Mode

Batch operations support two modes:
ModeDescriptionUse Case
AtomicAll succeed or all failData consistency is critical
PartialAllow some to succeed, some to failBest effort, continue on errors

Batch Create

Atomic Mode (Default)

All records must be created successfully, or the entire operation fails:
const result = await sdk.clients.createMany([
  { type: ClientType.Individual, name: "Juan García", ... },
  { type: ClientType.Individual, name: "María López", ... },
  { type: ClientType.Company, name: "Empresa S.A.", ... },
]);

if (result.atomic) {
  console.log("All created successfully!");
  console.log("Created:", result.data.length);

  for (const client of result.data) {
    console.log(`- ${client.id}: ${client.name}`);
  }
}

Partial Mode

Allow some records to succeed even if others fail:
const result = await sdk.clients.createMany(
  [
    { type: ClientType.Individual, name: "Juan García", ... },
    { type: "invalid", name: "" }, // This will fail
    { type: ClientType.Company, name: "Empresa S.A.", ... },
  ],
  { atomic: false }
);

if (!result.atomic) {
  console.log(`Succeeded: ${result.succeeded.length}`);
  console.log(`Failed: ${result.failed.length}`);

  // Process successful items
  for (const item of result.succeeded) {
    console.log(`Created at index ${item.index}: ${item.data.id}`);
  }

  // Handle failures
  for (const item of result.failed) {
    console.log(`Failed at index ${item.index}: ${item.error.message}`);
  }
}

Batch Update

Atomic Mode

const result = await sdk.clients.updateMany([
  { id: "client_a", data: { name: "New Name A" } },
  { id: "client_b", data: { name: "New Name B" } },
]);

if (result.atomic) {
  console.log("All updated:", result.data.length);
}

Partial Mode

const result = await sdk.clients.updateMany(
  [
    { id: "client_a", data: { name: "New Name A" } },
    { id: "nonexistent", data: { name: "Will Fail" } },
    { id: "client_c", data: { name: "New Name C" } },
  ],
  { atomic: false },
);

if (!result.atomic) {
  // Handle partial results
  console.log(`Updated: ${result.succeeded.length}`);
  console.log(`Failed: ${result.failed.length}`);
}

Result Types

Atomic Result

interface AtomicBatchResult<T> {
  atomic: true;
  data: T[];
}

Partial Result

interface PartialBatchResult<T> {
  atomic: false;
  succeeded: Array<{
    index: number;
    data: T;
  }>;
  failed: Array<{
    index: number;
    error: {
      code: string;
      message: string;
    };
  }>;
}

Supported Resources

Batch operations are available on these resources:
ResourceCreateUpdate
clientscreateManyupdateMany
transactionscreateManyupdateMany
documentscreateManyupdateMany
alertscreateManyupdateMany

Best Practices

Use Atomic for Critical Data

When data consistency is important, use atomic mode:
// If any client fails, we don't want partial data
const result = await sdk.clients.createMany(clients);

if (result.atomic) {
  // All clients created - safe to proceed
  await notifyUserOfSuccess(result.data);
}

Use Partial for Best Effort

When you want to create as many records as possible:
const result = await sdk.clients.createMany(clients, { atomic: false });

if (!result.atomic) {
  // Process what succeeded
  for (const item of result.succeeded) {
    await processClient(item.data);
  }

  // Log failures for retry
  for (const item of result.failed) {
    await logFailure(clients[item.index], item.error);
  }
}

Batch Size Limits

The API limits batch size to 100 items per request. For larger batches, chunk your data.
function chunk<T>(array: T[], size: number): T[][] {
  const chunks: T[][] = [];
  for (let i = 0; i < array.length; i += size) {
    chunks.push(array.slice(i, i + size));
  }
  return chunks;
}

// Process large dataset in chunks
const allClients = [...]; // 500 clients
const chunks = chunk(allClients, 100);

const results = [];
for (const batch of chunks) {
  const result = await sdk.clients.createMany(batch, { atomic: false });
  results.push(result);
}

Error Recovery

Retry failed items from a partial batch:
async function createWithRetry(clients: CreateClientInput[], maxRetries = 3) {
  let pending = clients;
  let allCreated: Client[] = [];

  for (let attempt = 0; attempt < maxRetries && pending.length > 0; attempt++) {
    const result = await sdk.clients.createMany(pending, { atomic: false });

    if (!result.atomic) {
      // Collect succeeded
      allCreated.push(...result.succeeded.map((s) => s.data));

      // Prepare failed items for retry
      pending = result.failed.map((f) => clients[f.index]);
    }
  }

  return {
    created: allCreated,
    failed: pending,
  };
}

Type-Safe Results

TypeScript overloads ensure type-safe results:
// Atomic mode (default) - returns AtomicBatchResult
const atomic = await sdk.clients.createMany(clients);
// atomic.atomic is true, atomic.data is Client[]

// Partial mode - returns PartialBatchResult
const partial = await sdk.clients.createMany(clients, { atomic: false });
// partial.atomic is false, partial.succeeded and partial.failed are arrays