Get async task status
curl --request GET \
--url https://api.cloro.dev/v1/async/task/{taskId} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.cloro.dev/v1/async/task/{taskId}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.cloro.dev/v1/async/task/{taskId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cloro.dev/v1/async/task/{taskId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.cloro.dev/v1/async/task/{taskId}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.cloro.dev/v1/async/task/{taskId}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloro.dev/v1/async/task/{taskId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"task": {
"id": "b27a21e1-7c39-4aa2-a347-23e828c426f9",
"taskType": "CHATGPT",
"status": "QUEUED",
"priority": 1,
"createdAt": "2026-04-09T15:00:00.000Z",
"latencyMs": null,
"idempotencyKey": "batch-chatgpt-001"
},
"credits": {
"creditsToCharge": 5,
"creditsCharged": null
},
"webhook": {
"url": "https://your-app.com/webhook-handler",
"deliveredAt": "2025-11-10T15:00:05.000Z",
"delivered": true
},
"response": {}
}{
"success": false,
"error": {
"code": "MISSING_API_KEY",
"message": "Missing or invalid API key",
"timestamp": "2025-01-15T12:00:00.000Z"
}
}{
"success": false,
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "Route not found",
"details": {
"id": "/v1/invalid-endpoint"
},
"timestamp": "2025-01-15T12:00:00.000Z"
}
}{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "API key rate limit exceeded",
"timestamp": "2025-01-15T12:00:00.000Z"
}
}{
"success": false,
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "Maximum retries exceeded",
"timestamp": "2025-01-15T12:00:00.000Z"
}
}Async tasks
Get task status
Poll the status and result of an asynchronous task by ID. Returns the task state and, once complete, the full structured result payload.
GET
/
v1
/
async
/
task
/
{taskId}
Get async task status
curl --request GET \
--url https://api.cloro.dev/v1/async/task/{taskId} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.cloro.dev/v1/async/task/{taskId}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.cloro.dev/v1/async/task/{taskId}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cloro.dev/v1/async/task/{taskId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.cloro.dev/v1/async/task/{taskId}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.cloro.dev/v1/async/task/{taskId}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloro.dev/v1/async/task/{taskId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"task": {
"id": "b27a21e1-7c39-4aa2-a347-23e828c426f9",
"taskType": "CHATGPT",
"status": "QUEUED",
"priority": 1,
"createdAt": "2026-04-09T15:00:00.000Z",
"latencyMs": null,
"idempotencyKey": "batch-chatgpt-001"
},
"credits": {
"creditsToCharge": 5,
"creditsCharged": null
},
"webhook": {
"url": "https://your-app.com/webhook-handler",
"deliveredAt": "2025-11-10T15:00:05.000Z",
"delivered": true
},
"response": {}
}{
"success": false,
"error": {
"code": "MISSING_API_KEY",
"message": "Missing or invalid API key",
"timestamp": "2025-01-15T12:00:00.000Z"
}
}{
"success": false,
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "Route not found",
"details": {
"id": "/v1/invalid-endpoint"
},
"timestamp": "2025-01-15T12:00:00.000Z"
}
}{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "API key rate limit exceeded",
"timestamp": "2025-01-15T12:00:00.000Z"
}
}{
"success": false,
"error": {
"code": "INTERNAL_SERVER_ERROR",
"message": "Maximum retries exceeded",
"timestamp": "2025-01-15T12:00:00.000Z"
}
}Poll this endpoint to check the status of an asynchronous task. While the task is
QUEUED (received, waiting) or PROCESSING (actively running), the response carries only the current status. Once it is COMPLETED (finished successfully) or FAILED, the response also includes a response object with the full result or error details, plus a webhook object with the delivery status if you set a webhook.url.
Task retention policy
COMPLETED and FAILED tasks are permanently deleted, response data included, by an hourly cleanup once they are 24 hours old. Age counts from when you created the task, not from when it finished, so fetch results within 24 hours of submitting.
HTML URLs included in responses expire 24 hours after generation, regardless of the task’s retention status.
Example usage
Check a pending task
curl -X GET "https://api.cloro.dev/v1/async/task/b27a21e1-7c39-4aa2-a347-23e828c426f9" \
-H "Authorization: Bearer YOUR_API_KEY"
{
"task": {
"id": "b27a21e1-7c39-4aa2-a347-23e828c426f9",
"taskType": "CHATGPT",
"status": "QUEUED",
"priority": 5,
"createdAt": "2025-11-10T15:00:00.000Z",
"latencyMs": null,
"idempotencyKey": "your-custom-identifier-123"
},
"credits": {
"creditsToCharge": 5,
"creditsCharged": null
}
}
Fetch a completed task
curl -X GET "https://api.cloro.dev/v1/async/task/b27a21e1-7c39-4aa2-a347-23e828c426f9" \
-H "Authorization: Bearer YOUR_API_KEY"
{
"task": {
"id": "b27a21e1-7c39-4aa2-a347-23e828c426f9",
"taskType": "CHATGPT",
"status": "COMPLETED",
"priority": 5,
"createdAt": "2025-11-10T15:00:00.000Z",
"latencyMs": 3420,
"idempotencyKey": "your-custom-identifier-123"
},
"credits": {
"creditsToCharge": 5,
"creditsCharged": 5
},
"webhook": {
"url": "https://your-app.com/webhook-handler",
"deliveredAt": "2025-11-10T15:00:05.000Z",
"delivered": true
},
"response": {
"model": "gpt-5-3-mini",
"text": "...",
"sources": [],
"entities": [],
"map": [],
"citationPills": []
}
}
Authorizations
cloro API key as a bearer token. One key grants every endpoint in this spec; per-key scopes are not available, so a client cannot request a narrower permission. Keys are created and revoked in the dashboard.
Response
Successful response with the task status and result if completed.
Was this page helpful?