Understand API error responses, status codes, error codes, and retry strategies.
❌ Error Handling
The Sayify.pro API uses standard HTTP status codes and structured JSON error bodies to tell you exactly what went wrong.
📦 Error Response Format
Most errors return a JSON object with error and code fields:
{
"error": "name is required",
"code": "NAME_REQUIRED"
}
Validation errors may include more descriptive messages:
{
"error": "Slug \"my-form\" is already in use",
"code": "SLUG_CONFLICT"
}
Some DRF-standard errors return a detail field instead:
{
"detail": "Authentication credentials were not provided."
}
For field-level validation, the response includes per-field messages:
{
"name": ["This field is required."],
"slug": ["A link with this slug already exists in your workspace."]
}
📊 Status Codes
✅ Success Codes
| Code | Meaning |
|---|---|
200 OK |
Request succeeded. |
201 Created |
Resource successfully created. |
200 OK |
Resource successfully deleted (returns confirmation message). |
⚠️ Client Error Codes
| Code | Meaning | Common Cause |
|---|---|---|
400 Bad Request |
Invalid request body. | Missing required fields, invalid data types, slug conflict. |
401 Unauthorized |
Authentication failed. | Missing or invalid API key. |
403 Forbidden |
Insufficient permissions. | Key missing required scope, plan limit reached. |
404 Not Found |
Resource doesn't exist. | Invalid UUID, wrong endpoint, missing trailing slash. |
405 Method Not Allowed |
Wrong HTTP method. | Using GET on a POST-only endpoint. |
429 Too Many Requests |
Rate limit exceeded. | Slow down and retry with backoff. |
🔴 Server Error Codes
| Code | Meaning |
|---|---|
500 Internal Server Error |
Something went wrong on our end. Contact support if persistent. |
503 Service Unavailable |
Temporary maintenance or overload. Retry after a short wait. |
🏷️ Error Codes
Named error codes help you programmatically handle specific failure scenarios:
| Error Code | HTTP Status | Description |
|---|---|---|
NAME_REQUIRED |
400 |
The name field is missing from the request body. |
SLUG_CONFLICT |
400 |
The provided slug already exists in this workspace. Omit it to auto-generate. |
CREATE_FAILED |
400 |
Unexpected error during resource creation — check request body. |
LINK_LIMIT_REACHED |
403 |
Workspace has hit its plan's link quota — upgrade to create more. |
INSUFFICIENT_SCOPE |
403 |
API key lacks the required scope (e.g. links:read, links:write). |
🔄 Retry Strategy
For 429 and 5xx errors, use exponential backoff:
Python
import time
import requests
def api_request(url, headers, max_retries=3):
for attempt in range(max_retries):
response = requests.get(url, headers=headers)
if response.status_code == 200:
return response.json()
if response.status_code in (429, 500, 503):
wait_time = (2 ** attempt) # 1s, 2s, 4s
time.sleep(wait_time)
continue
# Client error — don't retry
response.raise_for_status()
raise Exception("Max retries exceeded")
JavaScript
async function apiRequest(url, headers, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, { headers });
if (response.ok) return response.json();
if ([429, 500, 503].includes(response.status)) {
const waitMs = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s
await new Promise(r => setTimeout(r, waitMs));
continue;
}
throw new Error(`API Error: ${response.status} ${response.statusText}`);
}
throw new Error("Max retries exceeded");
}
[!TIP]
When rate-limited (429), the response includes aRetry-Afterheader indicating how many seconds to wait before retrying.
💡 Tips
- Always check the
codefield — it's more reliable than parsing error messages. - Don't retry
400or401errors — these indicate a problem with your request, not a transient failure. - Log delivery IDs — for webhook errors, log
X-Sayify-Delivery-Idfor debugging. - Contact support — if you consistently get
500errors, create a support ticket.
🎓 What's Next?
- Authentication — API key creation and security.
- Endpoints — Full endpoint reference with payloads.
- API Overview — Base URL, request format, pagination.
Was this page helpful?
Report an issue
→