> ## Documentation Index
> Fetch the complete documentation index at: https://docs.artu.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Batch Operations

> Create and update multiple records in a single request

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:

| Mode        | Description                         | Use Case                        |
| ----------- | ----------------------------------- | ------------------------------- |
| **Atomic**  | All succeed or all fail             | Data consistency is critical    |
| **Partial** | Allow some to succeed, some to fail | Best effort, continue on errors |

## Batch Create

### Atomic Mode (Default)

All records must be created successfully, or the entire operation fails:

```typescript theme={null}
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:

```typescript theme={null}
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

```typescript theme={null}
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

```typescript theme={null}
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

```typescript theme={null}
interface AtomicBatchResult<T> {
  atomic: true;
  data: T[];
}
```

### Partial Result

```typescript theme={null}
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:

| Resource       | Create         | Update         |
| -------------- | -------------- | -------------- |
| `clients`      | ✅ `createMany` | ✅ `updateMany` |
| `transactions` | ✅ `createMany` | ✅ `updateMany` |
| `documents`    | ✅ `createMany` | ✅ `updateMany` |
| `alerts`       | ✅ `createMany` | ✅ `updateMany` |

## Best Practices

### Use Atomic for Critical Data

When data consistency is important, use atomic mode:

```typescript theme={null}
// 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:

```typescript theme={null}
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

<Info>
  The API limits batch size to 100 items per request. For larger batches, chunk
  your data.
</Info>

```typescript theme={null}
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:

```typescript theme={null}
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:

```typescript theme={null}
// 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
```
