Skip to main content

What are Async Requests?

Think of an asynchronous (async) request like sending a package with a tracking number. Instead of waiting at the post office until the package is delivered (a synchronous process), you hand it over, get a taskId (your tracking number), and are free to do other things. You can then either receive a delivery notification (a webhook) or check the tracking status online yourself (polling). Our async API works the same way. You submit a task, we give you a taskId, and we process your request in the background.

When to use async requests

This approach is ideal when:
  • Your application, especially if it’s running in a serverless environment, has short execution time limits.
  • You want to submit a large number of requests quickly without waiting for each one to complete.
  • You need to build a more resilient system that isn’t dependent on a single, long-running connection.

How it works: a two-step process

The entire process involves two simple steps: making a request and then fetching the result.

Step 1: make an API request

First, you send an API request. If you include a webhook.url, we’ll notify you when the job is done. If you omit it, you will need to poll for the result.
curl -X POST "https://api.cloro.dev/v1/task" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d 
    "{
    "taskType": "CHATGPT",
    "idempotencyKey": "your-custom-identifier-123",
    "webhook": {
      "url": "https://your-app.com/webhook-handler"
    },
    "payload": {
      "prompt": "What is the weather in New York?",
      "country": "US"
    }
  }"
Identifying your requests with idempotencyKeyYou can optionally include an idempotencyKey in your request. This is a unique string you create that allows you to easily identify and reference your requests in your own system.
We’ll acknowledge your request and provide a taskId.
{
  "success": true,
  "task": {
    "id": "b27a21e1-7c39-4aa2-a347-23e828c426f9",
    "taskType": "CHATGPT",
    "status": "QUEUED",
    "createdAt": "2025-11-10T15:00:00.000Z",
    "idempotencyKey": "your-custom-identifier-123"
  },
  "credits": {
    "creditsToCharge": 10,
    "creditsCharged": 0
  }
}
Now, you can store this taskId and wait for the results.

Step 2: receive the results

You have two options for retrieving the results of your task. A webhook is an automated message sent from our servers to yours when your task is complete. If you provided a webhook.url in your request, we will send an HTTP POST request to that URL containing the full result.
{
  "task": {
    "id": "b27a21e1-7c39-4aa2-a347-23e828c426f9",
    "taskType": "CHATGPT",
    "status": "COMPLETED",
    "createdAt": "2025-11-10T15:00:00.000Z",
    "idempotencyKey": "your-custom-identifier-123"
  },
  "credits": {
    "creditsToCharge": 10,
    "creditsCharged": 10
  },
  "response": {
    "model": "gpt-5-mini",
    "text": "The weather in New York is currently sunny...",
    "html": "<p>The weather in New York is currently sunny...</p>",
    "sources": [],
    "shoppingCards": [],
    "entities": [],
    "markdown": "The weather in New York is currently sunny...",
    "searchQueries": ["weather in New York"]
  }
}
Responding to a webhook To let us know you’ve received the webhook, your server must respond with a 2xx status code (e.g., 200 OK). If we don’t receive a successful response, we’ll try again. We will attempt to deliver a webhook up to 5 times with an exponential backoff strategy. If an attempt fails, the next one will be scheduled for:
  • Attempt 2: ~2 minutes later
  • Attempt 3: ~4 minutes later
  • Attempt 4: ~8 minutes later
  • Attempt 5: ~16 minutes later
// Example: A simple server endpoint to receive the webhook
app.post('/webhook-handler', (req, res) => {
  // It's best to process the result asynchronously
  console.log(req.body);

// Immediately send a 200 OK to acknowledge receipt
res.status(200).send();
});

Option B: Polling

If you don’t provide a webhook URL, you can periodically check for the result yourself. This is called “polling.” You can make a GET request to our Get task status endpoint using the taskId you received in Step 1. Once the task is complete, the response will contain the full result.
curl -X GET "https://api.cloro.dev/v1/task/YOUR_TASK_ID" \
  -H "Authorization: Bearer YOUR_API_KEY"

Understanding Limits

The asynchronous system has a two-step process for handling limits to provide both flexibility and fairness.

1. Task Submission Limits

When you submit a task, we only check two things:
  • Credit Limit: We verify you have enough credits for the task.
  • Queue Limit: Your organization can have a maximum of 100,000 tasks waiting in the queue. If you exceed this, you will receive a 429 Too Many Requests error. Please contact our team if you need this limit increased.

2. Task Processing Limits

Once your task is in the queue, our scheduler picks it up for processing. This is where your subscription’s concurrency limit is enforced. For example, if your plan allows 10 concurrent requests, our scheduler will process up to 10 of your tasks in parallel. Tasks are processed in the order they were received (FIFO).