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

# Create batch tasks

> Submit up to 500 async tasks in a single request. Each task is validated independently — one invalid task does not block others. Returns per-task results with success or failure details.

## Overview

The batch endpoint lets you submit multiple async tasks in a single HTTP request, reducing overhead for high-volume workloads. Instead of making one API call per task, you can send up to **500 tasks at once**.

Key behaviors:

* **Partial success**: Each task is validated independently. One invalid task does not block others from being created.
* **Per-task results**: The response includes a `results` array with success or failure details for each task, preserving the original input order by `index`.
* **All-or-nothing queue check**: Before processing individual tasks, the endpoint verifies that your queue has enough capacity for the entire batch. If it doesn't, the whole batch is rejected with a `429` error.
* **Per-task webhook delivery**: each task fires its own webhook notification as soon as it completes — you don't wait for the full batch to finish. Webhooks arrive in completion order, not submission order.

Each task in the batch accepts the same fields as a single async task: `taskType`, `payload`, and optionally `priority`, `idempotencyKey`, and `webhook`.

<Info>
  For submitting a single task, see the [async requests guide](/guides/making-requests/async).
</Info>

## Request constraints

| Constraint                | Value                                                                                                 |
| ------------------------- | ----------------------------------------------------------------------------------------------------- |
| Minimum tasks per request | 1                                                                                                     |
| Maximum tasks per request | 500                                                                                                   |
| Queue capacity check      | All-or-nothing. The batch is rejected if it would exceed your organization's 100,000 task queue limit |

<Note>
  If the request body is not a valid JSON array or is empty, the endpoint returns a `422 Unprocessable Entity` error before any task-level processing begins.
</Note>

## Per-task error codes

When a task fails validation within a batch, its result includes one of these error codes:

| Code                      | Description                                                                                        |
| ------------------------- | -------------------------------------------------------------------------------------------------- |
| `VALIDATION_ERROR`        | The task failed schema validation. `details` includes field-level errors.                          |
| `RESOURCE_ALREADY_EXISTS` | The `idempotencyKey` was already used (either in a previous request or earlier in the same batch). |
| `INSUFFICIENT_CREDITS`    | Not enough credits remaining for this task. Credits are tracked per task within the batch.         |

<Warning>
  The queue capacity check is **all-or-nothing**. If the batch would exceed your queue limit, every task in the batch is rejected. Per-task validation errors only affect the individual task.
</Warning>

## Example usage

### Submit a batch of tasks

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.cloro.dev/v1/async/task/batch" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '[
      {
        "taskType": "CHATGPT",
        "priority": 5,
        "idempotencyKey": "batch-chatgpt-001",
        "webhook": {
          "url": "https://your-app.com/webhook-handler"
        },
        "payload": {
          "prompt": "What do you know about Acme Corp?",
          "country": "US"
        }
      },
      {
        "taskType": "PERPLEXITY",
        "priority": 3,
        "idempotencyKey": "batch-perplexity-001",
        "payload": {
          "prompt": "Latest news about Acme Corp",
          "country": "US"
        }
      },
      {
        "taskType": "GEMINI",
        "payload": {
          "prompt": "Summarize Acme Corp recent announcements"
        }
      }
    ]'
  ```

  ```javascript Node.js (axios) theme={null}
  import axios from 'axios';

  const apiKey = 'YOUR_API_KEY';
  const url = 'https://api.cloro.dev/v1/async/task/batch';

  const tasks = [
    {
      taskType: 'CHATGPT',
      priority: 5,
      idempotencyKey: 'batch-chatgpt-001',
      webhook: { url: 'https://your-app.com/webhook-handler' },
      payload: { prompt: 'What do you know about Acme Corp?', country: 'US' },
    },
    {
      taskType: 'PERPLEXITY',
      priority: 3,
      idempotencyKey: 'batch-perplexity-001',
      payload: { prompt: 'Latest news about Acme Corp', country: 'US' },
    },
    {
      taskType: 'GEMINI',
      payload: { prompt: 'Summarize Acme Corp recent announcements' },
    },
  ];

  try {
    const response = await axios.post(url, tasks, {
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json',
      },
    });

    const { summary, results } = response.data;
    console.log(`Batch complete: ${summary.succeeded} succeeded, ${summary.failed} failed`);

    for (const result of results) {
      if (result.success) {
        console.log(`Task ${result.index}: ${result.task.id} (${result.task.taskType})`);
      } else {
        console.error(`Task ${result.index} failed: ${result.error.code} - ${result.error.message}`);
      }
    }
  } catch (error) {
    console.error('Batch request failed:', error.response?.data || error.message);
  }
  ```

  ```python Python (requests) theme={null}
  import requests

  api_key = 'YOUR_API_KEY'
  url = 'https://api.cloro.dev/v1/async/task/batch'

  tasks = [
      {
          "taskType": "CHATGPT",
          "priority": 5,
          "idempotencyKey": "batch-chatgpt-001",
          "webhook": {"url": "https://your-app.com/webhook-handler"},
          "payload": {"prompt": "What do you know about Acme Corp?", "country": "US"},
      },
      {
          "taskType": "PERPLEXITY",
          "priority": 3,
          "idempotencyKey": "batch-perplexity-001",
          "payload": {"prompt": "Latest news about Acme Corp", "country": "US"},
      },
      {
          "taskType": "GEMINI",
          "payload": {"prompt": "Summarize Acme Corp recent announcements"},
      },
  ]

  response = requests.post(
      url,
      json=tasks,
      headers={
          "Authorization": f"Bearer {api_key}",
          "Content-Type": "application/json",
      },
  )

  data = response.json()
  summary = data["summary"]
  print(f"Batch complete: {summary['succeeded']} succeeded, {summary['failed']} failed")

  for result in data["results"]:
      if result["success"]:
          task = result["task"]
          print(f"Task {result['index']}: {task['id']} ({task['taskType']})")
      else:
          error = result["error"]
          print(f"Task {result['index']} failed: {error['code']} - {error['message']}")
  ```
</CodeGroup>

### Response with partial success

When some tasks succeed and others fail, the response includes results for every task:

<CodeGroup>
  ```json Response theme={null}
  {
    "success": true,
    "summary": {
      "total": 3,
      "succeeded": 2,
      "failed": 1
    },
    "results": [
      {
        "success": true,
        "index": 0,
        "task": {
          "id": "b27a21e1-7c39-4aa2-a347-23e828c426f9",
          "taskType": "CHATGPT",
          "status": "QUEUED",
          "priority": 5,
          "createdAt": "2026-04-09T15:00:00.000Z",
          "idempotencyKey": "batch-chatgpt-001"
        },
        "credits": {
          "creditsToCharge": 10,
          "creditsCharged": null
        }
      },
      {
        "success": true,
        "index": 1,
        "task": {
          "id": "c38b32f2-8d40-5bb3-b458-34f939d537e0",
          "taskType": "PERPLEXITY",
          "status": "QUEUED",
          "priority": 3,
          "createdAt": "2026-04-09T15:00:00.000Z",
          "idempotencyKey": "batch-perplexity-001"
        },
        "credits": {
          "creditsToCharge": 5,
          "creditsCharged": null
        }
      },
      {
        "success": false,
        "index": 2,
        "error": {
          "code": "INSUFFICIENT_CREDITS",
          "message": "Not enough credits remaining",
          "timestamp": "2026-04-09T15:00:00.000Z"
        }
      }
    ]
  }
  ```
</CodeGroup>

## Use cases

### Bulk monitoring across providers

Submit tasks to multiple AI providers simultaneously to compare responses:

```javascript theme={null}
const providers = ['CHATGPT', 'PERPLEXITY', 'GEMINI', 'COPILOT'];
const prompt = 'What do you know about Acme Corp?';

const tasks = providers.map((taskType, i) => ({
  taskType,
  idempotencyKey: `compare-${Date.now()}-${i}`,
  webhook: { url: 'https://your-app.com/webhook-handler' },
  payload: { prompt, country: 'US' },
}));

const response = await axios.post('https://api.cloro.dev/v1/async/task/batch', tasks, {
  headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
});
```

### Scheduled batch jobs

Process a list of queries in one request instead of submitting them one at a time:

```python theme={null}
from datetime import date

queries = [
    "What is Acme Corp's market position?",
    "Who are Acme Corp's main competitors?",
    "What are Acme Corp's latest product launches?",
]

tasks = [
    {
        "taskType": "CHATGPT",
        "priority": 3,
        "idempotencyKey": f"daily-batch-{date.today()}-{i}",
        "webhook": {"url": "https://your-app.com/webhook-handler"},
        "payload": {"prompt": query, "country": "US"},
    }
    for i, query in enumerate(queries)
]

response = requests.post(
    "https://api.cloro.dev/v1/async/task/batch",
    json=tasks,
    headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
)
```

### Handling partial failures

Check results and retry only the failed tasks:

```javascript theme={null}
const { summary, results } = response.data;

if (summary.failed > 0) {
  const failedTasks = results
    .filter(r => !r.success)
    .map(r => ({
      ...originalTasks[r.index],
      idempotencyKey: `${originalTasks[r.index].idempotencyKey}-retry`,
    }));

  // Retry failed tasks (with new idempotency keys)
  const retryResponse = await axios.post(url, failedTasks, { headers });
}
```


## OpenAPI

````yaml api-reference/openapi.json POST /v1/async/task/batch
openapi: 3.1.0
info:
  title: cloro
  description: API for monitoring AI responses across different providers and regions
  license:
    name: MIT
  version: 1.0.0
servers:
  - url: https://api.cloro.dev
    description: Production server
security:
  - bearerAuth: []
paths:
  /v1/async/task/batch:
    post:
      summary: Create batch async tasks
      description: >-
        Submit up to 500 async tasks in a single request. Each task is validated
        independently — one invalid task does not block others. Returns per-task
        results with success or failure details.
      operationId: createBatchAsyncTasks
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: array
              minItems: 1
              maxItems: 500
              description: Array of task objects to create.
              items:
                $ref: '#/components/schemas/BatchTaskRequest'
            example:
              - taskType: CHATGPT
                priority: 5
                idempotencyKey: batch-chatgpt-001
                webhook:
                  url: https://your-app.com/webhook-handler
                payload:
                  prompt: What do you know about Acme Corp?
                  country: US
              - taskType: PERPLEXITY
                priority: 3
                idempotencyKey: batch-perplexity-001
                payload:
                  prompt: Latest news about Acme Corp
                  country: US
      responses:
        '200':
          description: >-
            Batch processed. Check the summary and individual results for
            per-task success or failure.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BatchTaskResponse'
        '401':
          description: Unauthorized - Authentication error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthenticationError'
        '422':
          description: Validation Error - Request body is not a valid array or is empty
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
        '429':
          description: >-
            Queue Limit Exceeded - The entire batch is rejected because it would
            exceed your organization's queue capacity
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QueueLimitError'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalError'
      security:
        - bearerAuth: []
components:
  schemas:
    BatchTaskRequest:
      type: object
      required:
        - taskType
        - payload
      properties:
        taskType:
          type: string
          enum:
            - AIMODE
            - GOOGLE
            - GOOGLE_NEWS
            - GEMINI
            - CHATGPT
            - COPILOT
            - PERPLEXITY
            - GROK
          description: The AI provider to use for this task.
          example: CHATGPT
        payload:
          type: object
          description: >-
            Provider-specific request payload. Must include at least `prompt`
            (or `query` for Google Search).
          example:
            prompt: What do you know about Acme Corp?
            country: US
        priority:
          type: integer
          description: >-
            Task priority level (1-10). Higher numbers are processed first.
            Defaults to 1.
          minimum: 1
          maximum: 10
          default: 1
          example: 5
        idempotencyKey:
          type: string
          description: >-
            Unique string to prevent duplicate task creation. Must be unique
            across your account.
          example: batch-chatgpt-001
        webhook:
          type: object
          description: Webhook configuration for task completion notification.
          properties:
            url:
              type: string
              format: uri
              description: URL to receive the webhook POST request when the task completes.
              example: https://your-app.com/webhook-handler
          required:
            - url
          additionalProperties: false
      additionalProperties: false
    BatchTaskResponse:
      type: object
      required:
        - success
        - summary
        - results
      properties:
        success:
          type: boolean
          description: >-
            Always true for a successfully processed batch (individual tasks may
            still fail).
          example: true
        summary:
          type: object
          required:
            - total
            - succeeded
            - failed
          description: Aggregate counts for the batch.
          properties:
            total:
              type: integer
              description: Total number of tasks submitted in the batch.
              example: 3
            succeeded:
              type: integer
              description: Number of tasks successfully created.
              example: 2
            failed:
              type: integer
              description: Number of tasks that failed validation or processing.
              example: 1
        results:
          type: array
          description: Per-task results preserving the original input order by index.
          items:
            oneOf:
              - $ref: '#/components/schemas/BatchTaskSuccessResult'
              - $ref: '#/components/schemas/BatchTaskFailureResult'
            discriminator:
              propertyName: success
              mapping:
                'true':
                  $ref: '#/components/schemas/BatchTaskSuccessResult'
                'false':
                  $ref: '#/components/schemas/BatchTaskFailureResult'
    AuthenticationError:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - MISSING_API_KEY
                - INVALID_API_KEY_FORMAT
                - INVALID_OR_EXPIRED_API_KEY
              example: MISSING_API_KEY
            message:
              type: string
              example: Missing or invalid API key
            timestamp:
              type: string
              format: date-time
              example: '2025-01-15T12:00:00.000Z'
    ValidationError:
      type: object
      properties:
        success:
          type: boolean
          example: false
        error:
          type: string
          example: Request validation failed
        details:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
                example: prompt
              message:
                type: string
                example: Prompt cannot be empty
    QueueLimitError:
      type: object
      required:
        - success
        - error
      properties:
        success:
          type: boolean
          example: false
        error:
          type: object
          required:
            - code
            - message
            - timestamp
          properties:
            code:
              type: string
              enum:
                - QUEUE_LIMIT_EXCEEDED
              example: QUEUE_LIMIT_EXCEEDED
            message:
              type: string
              example: Batch would exceed queue capacity
            details:
              type: object
              properties:
                queuedCount:
                  type: integer
                  description: Current number of tasks in the queue.
                  example: 99950
                batchSize:
                  type: integer
                  description: Number of tasks in the submitted batch.
                  example: 100
                maxQueueSize:
                  type: integer
                  description: Maximum allowed queue size.
                  example: 100000
                remainingCapacity:
                  type: integer
                  description: Number of tasks that can still be added to the queue.
                  example: 50
            timestamp:
              type: string
              format: date-time
              example: '2026-04-09T15:00:00.000Z'
    InternalError:
      type: object
      oneOf:
        - properties:
            success:
              type: boolean
              example: false
            error:
              type: string
              example: Maximum retries exceeded
        - properties:
            error:
              type: object
              properties:
                code:
                  type: string
                  example: INTERNAL_SERVER_ERROR
                message:
                  type: string
                  example: Internal server error
                timestamp:
                  type: string
                  format: date-time
                  example: '2025-01-15T12:00:00.000Z'
    BatchTaskSuccessResult:
      type: object
      required:
        - success
        - index
        - task
        - credits
      properties:
        success:
          type: boolean
          enum:
            - true
          description: Indicates this task was created successfully.
          example: true
        index:
          type: integer
          description: The zero-based position of this task in the original request array.
          example: 0
        task:
          allOf:
            - $ref: '#/components/schemas/AsyncTaskSummary'
            - type: object
              properties:
                status:
                  type: string
                  enum:
                    - QUEUED
                  description: Initial status of a newly created task.
                  example: QUEUED
        credits:
          $ref: '#/components/schemas/AsyncTaskCredits'
    BatchTaskFailureResult:
      type: object
      required:
        - success
        - index
        - error
      properties:
        success:
          type: boolean
          enum:
            - false
          description: Indicates this task failed.
          example: false
        index:
          type: integer
          description: The zero-based position of this task in the original request array.
          example: 2
        error:
          type: object
          required:
            - code
            - message
            - timestamp
          properties:
            code:
              type: string
              description: Error code identifying the failure reason.
              enum:
                - VALIDATION_ERROR
                - RESOURCE_ALREADY_EXISTS
                - INSUFFICIENT_CREDITS
              example: VALIDATION_ERROR
            message:
              type: string
              description: Human-readable error message.
              example: Task validation failed
            details:
              type: object
              description: >-
                Additional context about the error, such as field-level
                validation failures.
              example:
                field: payload.prompt
                message: Required
            timestamp:
              type: string
              format: date-time
              description: Timestamp when the error occurred.
              example: '2026-04-09T15:00:00.000Z'
    AsyncTaskSummary:
      type: object
      required:
        - id
        - taskType
        - status
        - priority
        - createdAt
      description: Common task summary fields shared across async task responses.
      properties:
        id:
          type: string
          format: uuid
          description: Unique task identifier.
          example: b27a21e1-7c39-4aa2-a347-23e828c426f9
        taskType:
          type: string
          enum:
            - AIMODE
            - GOOGLE
            - GOOGLE_NEWS
            - GEMINI
            - CHATGPT
            - COPILOT
            - PERPLEXITY
            - GROK
          description: The AI provider for this task.
          example: CHATGPT
        status:
          type: string
          enum:
            - QUEUED
            - PROCESSING
            - COMPLETED
            - FAILED
          description: Current task status.
          example: QUEUED
        priority:
          type: integer
          description: >-
            Task priority level (1-10). Higher numbers are processed first.
            Defaults to 1.
          minimum: 1
          maximum: 10
          example: 1
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the task was created.
          example: '2026-04-09T15:00:00.000Z'
        idempotencyKey:
          type:
            - string
            - 'null'
          description: The idempotency key if one was provided.
          example: batch-chatgpt-001
    AsyncTaskCredits:
      type: object
      required:
        - creditsToCharge
        - creditsCharged
      description: Credit information for an async task.
      properties:
        creditsToCharge:
          type: number
          description: Credits reserved for this task.
          example: 10
        creditsCharged:
          type:
            - number
            - 'null'
          description: Credits actually charged. Null until the task completes.
          example: null
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````