Error Reference
Complete reference for all API error codes with resolution steps.
Error Reference
All API errors return JSON with two fields:
error- Human-readable error messagecode- Machine-readable error code (SCREAMING_SNAKE_CASE)
{
"error": "Human-readable error message",
"code": "MACHINE_READABLE_CODE"
}Use the code field in your application logic to handle specific error types programmatically.
Authentication Errors
MISSING_API_KEY
HTTP Status: 401 Unauthorized
Description: The X-API-Key header was not provided in the request.
Response:
{
"error": "Unauthorized",
"code": "MISSING_API_KEY"
}Resolution:
- Include the
X-API-Keyheader in your request - Verify the header name is exactly
X-API-Key(case-sensitive) - Ensure your HTTP client is configured to send custom headers
Example Fix:
# Missing header (causes error)
curl "https://api.3xx.app/v1/lookup?project=<project_id>&path=/test"
# Correct request
curl "https://api.3xx.app/v1/lookup?project=<project_id>&path=/test" \
-H "X-API-Key: redir_live_your_key_here"INVALID_API_KEY
HTTP Status: 401 Unauthorized
Description: The provided API key is malformed, invalid, revoked, or does not belong to the specified project.
Response:
{
"error": "Unauthorized",
"code": "INVALID_API_KEY"
}Resolution:
- Verify you copied the complete API key (format:
redir_live_+ 32 characters) - Check that the key hasn't been revoked in your project settings
- Confirm the key belongs to the project you're querying
- Generate a new API key if the original was lost or compromised
Common Causes:
- Truncated API key (missing characters)
- Using test key (
redir_test_) in production - Key was revoked by team member
- Wrong project ID in query parameter
Validation Errors
MISSING_PROJECT
HTTP Status: 400 Bad Request
Description: The required project query parameter was not provided.
Response:
{
"error": "Missing project parameter",
"code": "MISSING_PROJECT"
}Resolution:
- Add
?project=YOUR_PROJECT_IDto your request URL - Find your project ID in the Dashboard under project settings
Example Fix:
# Missing project parameter (causes error)
curl -H "X-API-Key: redir_live_your_key_here" \
"https://api.3xx.app/v1/lookup?path=/test"
# Correct request
curl -H "X-API-Key: redir_live_your_key_here" \
"https://api.3xx.app/v1/lookup?project=<project_id>&path=/test"MISSING_PATH
HTTP Status: 400 Bad Request
Description: The required path query parameter was not provided (lookup endpoint only).
Response:
{
"error": "Missing path parameter",
"code": "MISSING_PATH"
}Resolution:
- Add
&path=/your/pathto your request URL - Ensure the path starts with
/(forward slash)
Example Fix:
# Missing path parameter (causes error)
curl -H "X-API-Key: redir_live_your_key_here" \
"https://api.3xx.app/v1/lookup?project=<project_id>"
# Correct request
curl -H "X-API-Key: redir_live_your_key_here" \
"https://api.3xx.app/v1/lookup?project=<project_id>&path=/blog/old-post"MISSING_FORMAT
HTTP Status: 400 Bad Request
Description: The required format query parameter was not provided (export endpoint only).
Response:
{
"error": "Missing format parameter",
"code": "MISSING_FORMAT"
}Resolution:
- Add
&format=FORMATto your export request - Choose from valid formats:
csv,nginx,nginx-map-exact,nginx-map-prefix,haproxy,haproxy-map-exact,haproxy-map-prefix
Example Fix:
# Missing format parameter (causes error)
curl -H "X-API-Key: redir_live_your_key_here" \
"https://api.3xx.app/v1/export?project=<project_id>"
# Correct request
curl -H "X-API-Key: redir_live_your_key_here" \
"https://api.3xx.app/v1/export?project=<project_id>&format=csv"INVALID_FORMAT
HTTP Status: 400 Bad Request
Description: The format parameter value is not one of the supported export formats.
Response:
{
"error": "Invalid format. Use one of: csv, nginx, nginx-map-exact, nginx-map-prefix, haproxy, haproxy-map-exact, haproxy-map-prefix",
"code": "INVALID_FORMAT"
}Resolution:
- Check the format parameter for typos
- Use one of the 7 valid formats listed in the error message
Valid Formats:
csv- Comma-separated valuesnginx- Nginx configurationnginx-map-exact- Nginx map (exact matches)nginx-map-prefix- Nginx map (prefix matches)haproxy- HAProxy configurationhaproxy-map-exact- HAProxy map (exact matches)haproxy-map-prefix- HAProxy map (prefix matches)
Example Fix:
# Invalid format (causes error)
curl -H "X-API-Key: redir_live_your_key_here" \
"https://api.3xx.app/v1/export?project=<project_id>&format=apache"
# Correct request
curl -H "X-API-Key: redir_live_your_key_here" \
"https://api.3xx.app/v1/export?project=<project_id>&format=nginx"Rate Limiting Errors
RATE_LIMIT_EXCEEDED
HTTP Status: 429 Too Many Requests
Description: You have exceeded your per-minute rate limit for the current tier.
Response:
{
"error": "Too Many Requests",
"code": "RATE_LIMIT_EXCEEDED"
}Response Headers:
Retry-After: 45
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1706745600Rate Limits by Tier:
- Free: 100 requests per minute
- Pro: 1,000 requests per minute
- Enterprise: Unlimited
Resolution:
- Wait for the time specified in
Retry-Afterheader (in seconds) - Reduce request frequency to stay within limit
- Implement exponential backoff for retries
- Upgrade to a higher tier for increased limits
Example Retry Logic:
async function lookupWithRetry(path) {
try {
return await lookup(path);
} catch (error) {
if (error.code === 'RATE_LIMIT_EXCEEDED') {
const retryAfter = error.retryAfter || 60;
console.log(`Rate limited. Waiting ${retryAfter}s...`);
await sleep(retryAfter * 1000);
return await lookup(path);
}
throw error;
}
}Rate limits are enforced per API key. Using multiple keys from the same project shares the organization's limit.
QUOTA_EXCEEDED
HTTP Status: 429 Too Many Requests
Description: You have exhausted your monthly API quota for the current billing period.
Response:
{
"error": "Monthly API Quota Exceeded",
"code": "QUOTA_EXCEEDED"
}Response Headers:
Retry-After: 2592000
X-Quota-Limit: 10000
X-Quota-Remaining: 0
X-Quota-Reset: 1709251200Monthly Quotas by Tier:
- Free: 10,000 requests per month
- Pro: 1,000,000 requests per month
- Enterprise: Unlimited
Resolution:
- Immediate: Upgrade your plan to increase quota
- Wait: Quota resets at the start of next billing period (see
X-Quota-Resetheader) - Optimize: Cache responses client-side to reduce API calls
Tier Upgrade Options:
- Free → Pro: 100x quota increase (10k → 1M requests/month)
- Pro → Enterprise: Unlimited requests
Quota limits are cumulative across all API keys in your organization, not per-key.
General Errors
METHOD_NOT_ALLOWED
HTTP Status: 405 Method Not Allowed
Description: The API only supports GET requests. You sent a different HTTP method (POST, PUT, DELETE, etc.).
Response:
{
"error": "Method Not Allowed",
"code": "METHOD_NOT_ALLOWED"
}Resolution:
- Change your request to use the
GETmethod - Verify your HTTP client is configured correctly
Example Fix:
# Wrong method (causes error)
curl -X POST "https://api.3xx.app/v1/lookup?project=<project_id>&path=/test" \
-H "X-API-Key: redir_live_your_key_here"
# Correct method
curl -X GET "https://api.3xx.app/v1/lookup?project=<project_id>&path=/test" \
-H "X-API-Key: redir_live_your_key_here"NOT_FOUND
HTTP Status: 404 Not Found
Description: The requested endpoint does not exist, or (for exports) no deployment data is available.
Response:
{
"error": "Not Found",
"code": "NOT_FOUND"
}Common Causes:
- Wrong endpoint path: Verify you're using
/v1/lookupor/v1/export - No deployment: Export endpoint requires at least one deployment
- Version not found: Requested version number doesn't exist
Resolution for Endpoint Not Found:
- Check the URL path for typos
- Verify you're using the correct base URL
- Valid endpoints:
/v1/lookup,/v1/export
Resolution for Export Not Found:
# First deploy your configuration in the Dashboard
# Then retry the export requestIf requesting a specific version, verify the version number exists:
# List available versions in your Dashboard
# Or omit the version parameter to get latest:
curl -H "X-API-Key: redir_live_your_key_here" \
"https://api.3xx.app/v1/export?project=<project_id>&format=csv"Response Headers
When a 429 error occurs, the response includes special headers to help you handle rate limits and quotas:
Rate Limit Headers
Available on RATE_LIMIT_EXCEEDED errors:
| Header | Description |
|---|---|
| Retry-After | Seconds to wait before retrying |
| X-RateLimit-Limit | Maximum requests per minute for your tier |
| X-RateLimit-Remaining | Requests remaining (always 0 when limit exceeded) |
| X-RateLimit-Reset | Unix timestamp when rate limit resets |
Quota Headers
Available on QUOTA_EXCEEDED errors:
| Header | Description |
|---|---|
| Retry-After | Seconds until quota resets (typically ~30 days) |
| X-Quota-Limit | Monthly quota for your tier |
| X-Quota-Remaining | Requests remaining (always 0 when quota exceeded) |
| X-Quota-Reset | Unix timestamp when quota resets (billing period end) |
Error Handling Best Practices
Check Status Code First
Always check the HTTP status code before parsing the response body:
const response = await fetch(url, { headers });
if (response.status === 204) {
// No redirect found - not an error
return null;
}
if (!response.ok) {
const error = await response.json();
throw new Error(`API error: ${error.code}`);
}
return await response.json();Handle Specific Error Codes
Switch on error codes for precise error handling:
try {
const result = await lookupRedirect(path);
} catch (error) {
switch (error.code) {
case 'RATE_LIMIT_EXCEEDED':
// Wait and retry
await sleep(error.retryAfter * 1000);
return await lookupRedirect(path);
case 'QUOTA_EXCEEDED':
// Notify user to upgrade
showUpgradePrompt();
break;
case 'INVALID_API_KEY':
// Credentials issue - log out user
handleAuthFailure();
break;
default:
// Unknown error
console.error('API error:', error);
}
}Respect Retry-After Header
Always honor the Retry-After header on 429 responses:
import time
import requests
def lookup_with_retry(path, max_retries=3):
for attempt in range(max_retries):
response = requests.get(url, headers=headers)
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
print(f"Rate limited. Waiting {retry_after}s...")
time.sleep(retry_after)
continue
return response
raise Exception("Max retries exceeded")See Also
- API Reference Overview - Authentication, rate limits, quotas
- Lookup Endpoint - Lookup endpoint documentation
- Export Endpoint - Export endpoint documentation