Skip to main content
This API implements Cloro’s async task contract. For the endpoints it supports, request and response schemas are identical.

The migration

Point CLORO_API_KEY at your anymorph key. Your webhook URL, idempotency keys, task types, and response parsing all stay as they are.

What is implemented

Supported

POST /v1/async/taskPOST /v1/async/task/batchGET /v1/async/task/{id}Webhook callbacks

Not implemented

/v1/monitor/* synchronous endpoints/v1/async/status
The synchronous /v1/monitor/* family is deliberately absent. Every engine here is driven asynchronously; a request that blocks for the minutes a browser run can take is not a shape this service offers.

Where behaviour differs

The most important difference, and the only one that can bite you in production. Cloro absorbs your submission rate behind its own infrastructure. Here, each engine’s capacity is the capacity of its backing pool.GEMINI sustains ~14 QPS. PERPLEXITY sustains ≤2. Browser-driven engines sustain much less. Over-submitting does not produce a 429 — it produces a growing queue and, eventually, FAILED tasks.See Rate limits and capacity.
credits is present on every response because Cloro clients read it. Submit and poll responses report { "creditsToCharge": 0, "creditsCharged": 0 }; webhooks report a per-engine figure mirroring Cloro’s pricing table.Nothing is metered. If you aggregate credits for cost reporting, the numbers will not mean what they used to.
CHATGPT and CLAUDE are region-gated. If no account can serve payload.country, the submission fails immediately with 422 REGION_UNAVAILABLE rather than being accepted.Cloro has no equivalent. A client that assumes every well-formed submission is accepted needs a branch here.
Cloro’s payload.include flags are accepted, but most engines here return a fixed-shape response and ignore them. Only ChatGPT’s anonymous mode honours the full set; several engines honour markdown and rawResponse only.Requesting html from Gemini, for instance, is silently ignored — no error, no field. See the flag support table.
Error handling is otherwise identical to the live Cloro API — same statuses, same error.code strings, same details shape. Validation failures return 400, 401 reports MISSING_API_KEY, 404 reports RESOURCE_NOT_FOUND.The one addition is 422 REGION_UNAVAILABLE, described above. Cloro has no account pools and therefore no equivalent, so a client that has never seen a 422 from Cloro will start seeing them here for CHATGPT and CLAUDE.
GET /v1/async/task/{id} on a FAILED task returns a top-level error field that Cloro’s TaskStatusResponse does not define — and it is a plain string, not the {code, message, timestamp} object used by request-level errors.
A client that treats a truthy body.error as a failed request will misread a successfully-retrieved failed task. Branch on task.status instead.
These differences were established by calling api.cloro.dev directly on 2026-07-09, not by reading its spec. Cloro’s published OpenAPI disagrees with its own API on the validation status code (422 documented, 400 returned) and on the shape of the validation error body (a string, versus the object the API actually sends). Where the two conflict, this API follows the live response.

Engine name mapping

Cloro’s synchronous paths map onto taskType values like this:
GOOGLE requesting AI Overview is a convention inherited from the original client, not a Cloro taskType in its own right. The response is a SERP envelope with aioverview as a nullable member — see the GOOGLE shape.
Engines with no Cloro equivalent: CLAUDE, DEEPSEEK, AMAZON, NAVER_AI_BRIEF, NAVER_AI_MODE.

Verifying the cutover

Run both APIs in parallel for a window and diff the fields you actually consume — in practice response.text, response.sources[], and response.markdown. A shadow comparison catches shape drift that a schema check will not, such as a source list that is populated but ordered differently.