Skip to main content
The cloro API uses a credit-based billing system with concurrency limits to ensure fair usage and service reliability.

Credits system

How credits work

  • Each API request consumes credits based on the endpoint and features used
  • Credits are deducted from your account balance when requests complete successfully
  • Failed requests (4xx errors) don’t consume credits
  • Credit information is included in response headers
  • See Request & Response for endpoint pricing details

Response headers

All monitoring endpoints include these headers in successful responses:

Credit information

HeaderDescription
X-Credits-RemainingNumber of credits remaining in your account
X-Credits-ChargedNumber of credits charged for this request

Concurrency information

HeaderDescription
X-Concurrent-LimitMaximum number of concurrent requests allowed
X-Concurrent-CurrentCurrent number of concurrent requests
X-Concurrent-RemainingNumber of remaining concurrent slots available

Concurrency limits

How concurrency works

  • Concurrency limits control how many requests you can run simultaneously
  • Limits are per API key/account
  • Exceeding limits results in 429 Too Many Requests errors
  • Limits help ensure service stability for all users

Example scenario

Request 1: X-Concurrent-Limit: 10
Request 1: X-Concurrent-Current: 1
Request 1: X-Concurrent-Remaining: 9

Request 2: X-Concurrent-Limit: 10
Request 2: X-Concurrent-Current: 2
Request 2: X-Concurrent-Remaining: 8

Handling concurrency limits

When you receive a 429 error:
{
  "error": {
    "code": "CONCURRENT_LIMIT_EXCEEDED",
    "message": "Concurrent limit exceeded",
    "details": {
      "limit": 10
    },
    "timestamp": "2025-01-15T12:00:00.000Z"
  }
}
Implement retry logic with exponential backoff:
async function makeRequestWithRetry(requestFn, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await requestFn();
    } catch (error) {
      if (error.status === 429 && i < maxRetries - 1) {
        const delay = Math.pow(2, i) * 1000; // Exponential backoff
        await new Promise((resolve) => setTimeout(resolve, delay));
        continue;
      }
      throw error;
    }
  }
}

Monitoring usage

Track credit consumption

function trackCredits(response) {
  const creditsRemaining = response.headers["x-credits-remaining"];
  const creditsCharged = response.headers["x-credits-charged"];

  console.log(`Credits charged: ${creditsCharged}`);
  console.log(`Credits remaining: ${creditsRemaining}`);

  // Alert if running low
  if (creditsRemaining < 100) {
    console.warn("Low credit balance - consider topping up");
  }
}

Monitor concurrency

function monitorConcurrency(response) {
  const limit = parseInt(response.headers["x-concurrent-limit"]);
  const current = parseInt(response.headers["x-concurrent-current"]);
  const remaining = parseInt(response.headers["x-concurrent-remaining"]);

  const usagePercent = (current / limit) * 100;

  if (usagePercent > 80) {
    console.warn(`High concurrency usage: ${usagePercent.toFixed(1)}%`);
  }
}

Getting help

Credit issues

  • Low balance: Top up your account via your dashboard
  • Unexpected charges: Check request logs and verify which features were enabled
  • Billing questions: Contact support with request IDs

Limit issues

  • Frequent 429 errors: Consider implementing request queuing
  • Need higher limits: Contact support to discuss rate limit increases
  • Concurrency spikes: Monitor usage patterns and implement throttling

Troubleshooting checklist

  1. Check headers: Monitor X-Credits-Remaining and X-Concurrent-Remaining
  2. Verify requests: Ensure you’re only requesting needed features
  3. Implement retries: Use exponential backoff for 429 errors
  4. Monitor usage: Track credit consumption and concurrency patterns
  5. Optimize queries: Make prompts efficient and specific