Create batch tasks
Queue many asynchronous extraction jobs with one call, up to 500 at a time, and get back an independent result for every job in the batch.
Overview
When you need to launch a large number of async tasks, sending them one at a time adds network round-trips and slows down high-volume pipelines. The batch endpoint collapses that work into a single request: pass an array of task objects and cloro processes each one on its own.
Each entry in the array uses the same shape as a standalone async task, so a batch can freely mix providers and prompts. The key characteristics to keep in mind:
- Independent validation. Every task is checked on its own. A single malformed entry is rejected without stopping the valid ones from being queued.
- Ordered, per-task results. The response returns a
resultsarray where each element carries the outcome for one task and anindexthat maps back to its position in your request. - Batch-level capacity gate. Before any task is queued, cloro confirms your queue can hold the entire batch. If the batch would overflow the limit, the whole request is turned away with a
429and nothing is created.
To submit a single job instead, use the Create async task endpoint.
Request body
The body is a JSON array containing 1 to 500 task objects. Each object supports the following fields.
| Field | Type | Description |
|---|---|---|
taskType | enum (string), required | Target AI provider for the task. One of AIMODE, GOOGLE, GOOGLE_NEWS, GEMINI, CHATGPT, COPILOT, PERPLEXITY, GROK. |
payload | object, required | Provider-specific request data. Must contain at least a prompt (or query for Google Search), plus optional fields such as country. |
priority | integer, optional | Scheduling weight from 1 to 10; higher values run sooner. Defaults to 1. |
idempotencyKey | string, optional | Caller-supplied key that must be unique across your account. Reusing a key prevents a duplicate task from being created. |
webhook | object, optional | Delivery target for completion notifications; contains a url that cloro calls when the task finishes. |
Authentication uses a bearer token supplied in the Authorization header as Bearer <token>.
Constraints
| Field | Type | Description |
|---|---|---|
| Minimum tasks | integer | At least 1 task object per request. |
| Maximum tasks | integer | No more than 500 task objects per request. |
| Queue capacity | rule | All-or-nothing. The batch is refused if accepting it would push you past the 100,000-task queue ceiling. |
| Body shape | rule | A non-array or empty body returns 422 Unprocessable Entity before any task is inspected. |
Per-task error codes
When an individual task fails validation, its result carries one of these codes in the error object.
| Field | Type | Description |
|---|---|---|
VALIDATION_ERROR | code | The task did not pass schema validation; details lists the offending fields. |
RESOURCE_ALREADY_EXISTS | code | The idempotencyKey was already seen, either in an earlier request or elsewhere in this same batch. |
INSUFFICIENT_CREDITS | code | Your remaining credit balance cannot cover this task. Credits are accounted for per task. |
Response fields
| Field | Type | Description |
|---|---|---|
success | boolean | True whenever the batch itself was processed; individual tasks may still have failed. |
summary | object | Roll-up counts: total, succeeded, and failed. |
results | object[] | One entry per submitted task, in input order. Each has index, a success flag, and either a task plus credits object or an error object. |
Response example
{
"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"
}
}
]
}
Request example
curl -X POST "https://api.cloro.cloud/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" }
}
]'
Notes
- Read the
summary.failedcount first, then walkresultsand resubmit only the entries whosesuccessisfalse— assign fresh idempotency keys on the retry. - The batch capacity check is global to the request: a single over-limit batch fails every task at once, whereas validation problems stay scoped to the offending task.
- Questions about batch limits or credit accounting can go to [email protected].