Skip to main content
POST
/
v1
/
async
/
task
/
batch
Create batch async tasks
curl --request POST \
  --url https://api.cloro.dev/v1/async/task/batch \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
[
  {
    "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"
    }
  }
]
'
{
  "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": 1,
        "createdAt": "2026-04-09T15:00:00.000Z",
        "idempotencyKey": "batch-chatgpt-001"
      },
      "credits": {
        "creditsToCharge": 10,
        "creditsCharged": null
      }
    }
  ]
}

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.
Each task in the batch accepts the same fields as a single async task: taskType, payload, and optionally priority, idempotencyKey, and webhook.
For submitting a single task, see the async requests guide.

Request constraints

ConstraintValue
Minimum tasks per request1
Maximum tasks per request500
Queue capacity checkAll-or-nothing — the batch is rejected if it would exceed your organization’s 100,000 task queue limit
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.

Per-task error codes

When a task fails validation within a batch, its result includes one of these error codes:
CodeDescription
VALIDATION_ERRORThe task failed schema validation. details includes field-level errors.
RESOURCE_ALREADY_EXISTSThe idempotencyKey was already used (either in a previous request or earlier in the same batch).
INSUFFICIENT_CREDITSNot enough credits remaining for this task. Credits are tracked per task within the batch.
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, on the other hand, only affect the individual task.

Example usage

Submit a batch of tasks

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"
      }
    }
  ]'

Response with partial success

When some tasks succeed and others fail, the response includes results for every task:
{
  "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"
      }
    }
  ]
}

Use cases

Bulk monitoring across providers

Submit tasks to multiple AI providers simultaneously to compare responses:
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:
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:
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 });
}

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Body

application/json
Required array length: 1 - 500 elements
taskType
enum<string>
required

The AI provider to use for this task.

Available options:
AIMODE,
GOOGLE,
GOOGLE_NEWS,
GEMINI,
CHATGPT,
COPILOT,
PERPLEXITY,
GROK
Example:

"CHATGPT"

payload
object
required

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
integer
default:1

Task priority level (1-10). Higher numbers are processed first. Defaults to 1.

Required range: 1 <= x <= 10
Example:

5

idempotencyKey
string

Unique string to prevent duplicate task creation. Must be unique across your account.

Example:

"batch-chatgpt-001"

webhook
object

Webhook configuration for task completion notification.

Response

Batch processed. Check the summary and individual results for per-task success or failure.

success
boolean
required

Always true for a successfully processed batch (individual tasks may still fail).

Example:

true

summary
object
required

Aggregate counts for the batch.

results
object[]
required

Per-task results preserving the original input order by index.