Skip to main content

Documentation Index

Fetch the complete documentation index at: https://developers.datagrid.com/llms.txt

Use this file to discover all available pages before exploring further.

The Datagrid API enforces rate limits to protect the platform from abuse and ensure fair usage across all consumers.

Default rate limit

The default rate limit is 200 requests per 60-second sliding window, but individual endpoints may enforce their own limits. Check the X-RateLimit-Limit response header to see the effective limit for any given endpoint. The limit is scoped per teamspace, endpoint path, and HTTP method. For example, POST /v1/converse and GET /v1/agents maintain independent rate limit windows within the same teamspace.

Response headers

Every Datagrid API response includes rate limit headers so you can monitor your usage proactively:
HeaderDescriptionExample
X-RateLimit-LimitMaximum requests allowed in the current window200
X-RateLimit-RemainingRequests remaining in the current window195
X-RateLimit-ResetUnix epoch second when the current window resets1741275120
Retry-AfterSeconds until the window resets (present when X-RateLimit-Remaining is 0, including on 429 responses)30

429 Too Many Requests

When the rate limit is exceeded, the API returns a 429 status code with the following body:
{
  "status_code": 429,
  "statusCode": 429,
  "error": "rate_limit_exceeded",
  "message": "Rate limit exceeded",
  "mitigation": "Implement exponential backoff and retry with delays",
  "retryable": true,
  "details": {
    "reason": "Rate limit exceeded. Please retry after the current window resets."
  }
}
statusCode is deprecated and will be removed in a future version. Use status_code instead.
The response also includes the Retry-After header indicating how many seconds to wait before retrying.

Batch prediction rate limits

Batch prediction endpoints also use 429 Too Many Requests, but they return RFC 9457 problem details (application/problem+json) instead of the legacy JSON shape above.
{
  "type": "https://api.datagrid.com/errors/rate_limit_exceeded",
  "title": "Rate Limit Exceeded",
  "status": 429,
  "detail": "Too many batch prediction requests are already in progress for this teamspace."
}
Batch prediction 429 responses may also include:
HeaderDescription
X-RateLimit-LimitThe numeric limit for the rule that rejected the request.
X-RateLimit-RemainingRemaining capacity for the matched rule, usually 0 on 429.
X-RateLimit-ResetUnix epoch second when capacity is expected to reset, when applicable.
RateLimit-PolicyThe batch admission-control rule that rejected the request.
RateLimitCurrent limit state for the matched policy.
Retry-AfterSeconds to wait before retrying.
Batch create requests can be rejected by organization concurrency, enqueued-item, create-rate, or temporary global-capacity policies. Treat these responses as retryable and honor Retry-After before submitting more batch work.

Best practices

The official Python and TypeScript/JavaScript SDKs automatically retry 429 responses up to 2 times with exponential backoff. You can configure this via the maxRetries option:
Python
from datagrid_ai import Datagrid

client = Datagrid(max_retries=5)  # default is 2; set to 0 to disable
TypeScript
import Datagrid from 'datagrid-ai';

const client = new Datagrid({ maxRetries: 5 }); // default is 2; set to 0 to disable
If you are using the SDK, you typically do not need to implement your own retry logic.
If you are calling the API directly (without the SDK), implement retry logic yourself. When you receive a 429, wait for the number of seconds specified in the Retry-After header before retrying. If Retry-After is not available, use exponential backoff starting at 1 second, doubling with each retry up to a maximum of 60 seconds.
Python
import time
import httpx

def request_with_backoff(client, **kwargs):
    max_retries = 5
    delay = 1

    for attempt in range(max_retries):
        response = client.post(**kwargs)
        if response.status_code != 429:
            return response

        retry_after = response.headers.get("Retry-After")
        wait = int(retry_after) if retry_after else delay
        time.sleep(wait)
        delay = min(delay * 2, 60)

    return response
TypeScript
async function requestWithBackoff(
  fn: () => Promise<Response>,
  maxRetries = 5
): Promise<Response> {
  let delay = 1000;

  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fn();
    if (response.status !== 429) return response;

    const retryAfter = response.headers.get("Retry-After");
    const wait = retryAfter ? parseInt(retryAfter, 10) * 1000 : delay;
    await new Promise((resolve) => setTimeout(resolve, wait));
    delay = Math.min(delay * 2, 60_000);
  }

  return fn();
}
Check the X-RateLimit-Remaining header on every response. If it drops below a threshold (e.g., 10% of the limit), slow down your request rate before hitting a 429.
Since rate limits are scoped per endpoint path and HTTP method, you can make concurrent requests to different endpoints without them counting against the same window.