API Response Codes & Rate Limits
Complete list of Lead Distro AI API HTTP status codes, error response shapes, rate limits, and exponential backoff recipe for ingest and ping endpoints.
Last updated:
HTTP Status Codes
| Status | Meaning | Body |
|---|---|---|
| 201 Created | Lead accepted and distributed | Lead object with `id`, `status: ACCEPTED`, `buyer_id` |
| 200 OK | Lead accepted but no buyer available | Lead object with `status: UNMATCHED` |
| 400 Bad Request | Validation failure (missing required field, wrong type, format) | Error object with `field_errors` array |
| 401 Unauthorized | API key missing or invalid | Error object with `error: unauthorized` |
| 403 Forbidden | Supplier not attached to the campaign | Error object with `error: forbidden` |
| 404 Not Found | Campaign ID doesn't exist | Error object with `error: campaign_not_found` |
| 422 Unprocessable Entity | Lead failed inbound filters or suppression | Error with `filter_errors` array naming the rules that caught the lead |
| 429 Too Many Requests | Rate limit exceeded | Error with `retry_after` (seconds) |
| 500 Internal Server Error | Lead Distro AI bug — retry with backoff | Generic error message |
| 503 Service Unavailable | Temporary maintenance — retry with backoff | Generic error message |
Error Response Shape
{
"error": "validation_failed",
"message": "One or more fields failed validation",
"field_errors": [
{ "field": "phone", "code": "invalid_format", "message": "Phone must be 10-15 digits" },
{ "field": "case_type", "code": "required", "message": "case_type is required for this campaign" }
]
}Rate Limits
| Endpoint | Default limit | Burst |
|---|---|---|
| POST /api/v1/ingest | 100 RPS per supplier | 200 RPS for 10 seconds |
| POST /api/v1/ping | 500 RPS per supplier | 1,000 RPS for 10 seconds |
| GET /api/v1/leads/lookup | 10 RPS per supplier | 20 RPS for 5 seconds |
When you hit the limit, Lead Distro AI returns 429 with a `retry_after` header (seconds) and a `Retry-After` HTTP header per RFC 7231. Implement exponential backoff in your integration.
Exponential Backoff Recipe (Node.js)
async function postLeadWithBackoff(payload, maxRetries = 5) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const res = await fetch('https://app.leaddistro.ai/api/v1/ingest', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': process.env.LEADDISTRO_API_KEY,
},
body: JSON.stringify(payload),
});
if (res.status !== 429 && res.status !== 503) return res;
const retryAfter = Number(res.headers.get('retry-after')) || 2 ** attempt;
await new Promise(r => setTimeout(r, retryAfter * 1000));
}
throw new Error('Max retries exceeded');
}Frequently Asked Questions
What HTTP status code does Lead Distro AI return when a lead is accepted?
201 Created when the lead is accepted and distributed to a buyer. 200 OK with `status: UNMATCHED` when validation passes but no buyer is available (all caps hit, no matching filters). Both are 'success' from an API standpoint — your integration should handle both as successful posts.
What's the default rate limit on the ingest endpoint?
100 requests per second per supplier API key, with burst allowance up to 200 RPS for 10 seconds. The ping endpoint has a higher limit (500 RPS, burst 1,000) since pings are lighter than full posts. High-volume agencies can request elevated limits — contact support with your expected RPS.
How do I handle a 429 Too Many Requests response?
Wait the number of seconds in the `retry_after` field (or the `Retry-After` HTTP header), then retry with exponential backoff if subsequent requests also 429. Recommended: max 5 retry attempts with backoff of `2^attempt` seconds. After max retries, queue the lead for delayed retry rather than dropping it.
What's the difference between 400 and 422?
400 Bad Request = validation failed on a structural level (missing required field, wrong data type, malformed JSON). 422 Unprocessable Entity = data was valid but business logic rejected it (failed inbound filters, on a suppression list, campaign-level duplicate detection). 400 = fix the integration; 422 = the lead doesn't match the campaign's criteria.
Does Lead Distro AI return a Retry-After header on 429?
Yes — both as a custom JSON field (`retry_after` in seconds) and as the standard `Retry-After` HTTP header. Use whichever your HTTP client surfaces more easily. The values are equivalent.
Should I retry on 500 errors?
Yes — 500 indicates a transient Lead Distro AI server issue. Retry with exponential backoff (same recipe as 429). 5xx errors typically resolve within 1-2 retries. If a single lead keeps 500-ing across 5 attempts, log it and queue for delayed retry — Lead Distro AI's error tracking will surface the issue on our side.
Related Articles
Lead Ingest API
Complete Lead Distro AI API reference. Ingest leads via REST endpoints with field validation, signed webhooks, authentication, rate limits, and full example requests for every lead distribution endpoint.
API Authentication
Authenticate Lead Distro AI API requests with the supplier x-api-key header. Key generation, rotation, header format, error codes (401/403), and FAQs.
Webhook Signing & Verification
Verify Lead Distro AI webhook payloads with HMAC-SHA256 signatures. Signing secret format, X-LeadDistro-Signature header, and verification recipes in Node, Python, PHP.
If you have any questions, send us an email at support@leaddistro.ai