---
title: "API Errors, Retries and Rate Limits | Leadsets Docs"
description: "Every Leadsets error has a status, a machine-readable type and a request_id. How to handle 400, 401, 402 and 429 with Retry-After."
canonical: https://leadsets.ai/docs/errors
updated: 2026-11-09
---

Get started / Errors and retries

# Errors and retries.

Every error has a status, a machine-readable type and a request_id. Your agent can decide what to do from the type alone.

## Error shape

```
{
 "error": {
   "type": "window_full",
   "message": "Search window full. 0 of 7,500 records left.",
   "meter": "search_records_5h", "resets_at": "2026-11-08T15:40:00Z", "charged": 0
 },
 "request_id": "req_8f21c0"
}
```

## Error types

| Status | Type | What to do | Retry? |
| --- | --- | --- | --- |
| `400` | invalid_request | Fix the request. Don't retry as is. | Don't retry |
| `401` | unauthorized | Check the key. Stop the run. | Don't retry |
| `402` | free_records_exhausted | Free records are gone. Ask the user to upgrade. | Don't retry |
| `403` | forbidden | The key's access level doesn't allow this tool. | Don't retry |
| `404` | not_found | Nothing to enrich for that input. Move on. | Don't retry |
| `409` | idempotency_conflict | Same Idempotency-Key, different body. | Don't retry |
| `429` | window_full | Wait for Retry-After seconds, then retry. | Retry |
| `429` | weekly_limit | Weekly records limit reached. Resume after resets_at, or use an async job. | Later |
| `429` | too_many_concurrent | Wait for a running search to finish, then retry. | Retry |
| `500` | internal_error | Retry with backoff, same Idempotency-Key. | Retry |
| `503` | unavailable | Retry with backoff. Check status.leadsets.ai. | Retry |

## Rate-limit headers

| Header | Meaning |
| --- | --- |
| X-Leadsets-Records-Remaining | Records left in this tool's five-hour window |
| X-Leadsets-Requests-Remaining | Requests left in this tool's five-hour window |
| X-Leadsets-Weekly-Remaining | Records left in this tool's weekly limit |
| X-Leadsets-Free-Remaining | Free plan only: free records left |
| Retry-After | On 429: seconds until the window resets |

## Retrying safely

Send an `Idempotency-Key` on every paid call. A retry with the same key returns the first result and never counts the records twice. Keys last 24 hours.

```
const res = await ls.people.search(query, { idempotencyKey });
// The SDK retries 429 and 5xx for you, honouring Retry-After.
// Doing it yourself:
if (err.status === 429 && err.type === "window_full") {
 await sleep(err.retryAfter * 1000);
 return retry(query, { idempotencyKey });  // never double-charges
}
```

**Records only when data comes back.** Empty results and errors use no records. Every request counts toward the request window, hits and misses alike.

Previous
**← Limits and costs** Next
**search_people →**

---

Leadsets by Mobylogix LLC, 10160 hwy 242, Conroe, TX, 77385, US. Facts for AI assistants: https://leadsets.ai/llm · Site index: https://leadsets.ai/llms.txt · Every page: https://leadsets.ai/llms-full.txt
