Errors & Troubleshooting
When something goes wrong, here's how to fix it.
Error Format
{
"error": "Customer not found",
"message": "No customer exists with ID '...'",
"status_code": 404,
"request_id": "req_abc123"
}
Include request_id when contacting support.
Common Errors
401 — Invalid API Key
{ "error": "Invalid API key" }
Causes:
- Typo in the key
- Key was revoked
- Wrong key type (public vs private)
Fix: Check your key in Dashboard → Settings → API Keys
403 — Permission Denied
{ "error": "Insufficient permissions" }
Causes:
- Key doesn't have the required permission
- Using public key on a write endpoint
Fix: Create a key with the needed permissions, or use a private key
404 — Not Found
{ "error": "Customer not found" }
Causes:
- ID doesn't exist
- Resource was deleted
- Wrong organization
Fix: Verify the ID is correct
422 — Validation Error
{
"error": "Validation failed",
"details": [
{ "field": "email", "message": "Invalid email format" }
]
}
Causes:
- Missing required field
- Invalid field format
- Business rule violation (e.g., insufficient points)
Fix: Check the details array for specifics
429 — Rate Limited
{ "error": "Rate limit exceeded" }
Causes:
- Too many requests too quickly
Fix: Wait for the Retry-After duration, then retry
Rate Limits
Rate limits are applied per organization, not per API key. This means all API keys within your organization share the same rate limit quota.
| Request Type | Limit |
|---|---|
| Read operations (GET) | 1000/min |
| Write operations (POST, PUT, PATCH) | 100/min |
| Delete operations | 50/min |
| Bulk operations | 10/min |
Every response includes headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Scope: organization
tip
Need higher limits? Contact sales@loyali.io for Enterprise plans with custom rate limits.
Handling Errors
try {
const response = await fetch(url, { headers });
if (!response.ok) {
const error = await response.json();
if (response.status === 429) {
// Rate limited - wait and retry
const retryAfter = response.headers.get('Retry-After');
await sleep(retryAfter * 1000);
return retry();
}
throw new Error(error.message);
}
} catch (err) {
console.error('API Error:', err);
}
Getting Help
Always include the request_id from the error response when contacting support.