Skip to main content

Errors & Rate Limits

This page covers HTTP status codes, error response format, rate limiting, and common troubleshooting steps.

Error Response Format

All API errors return a consistent JSON structure:

{
"error": "RESOURCE_NOT_FOUND",
"message": "Campaign not found"
}

Errors may include additional context in the detail field:

{
"error": "VALIDATION_ERROR",
"message": "Validation failed",
"detail": [
{ "field": "commission_amount", "message": "Must be a positive number" },
{ "field": "name", "message": "Required field" }
]
}

Optional fields may also be present:

  • path — Request path that triggered the error
  • request_id — Unique correlation ID for tracing through logs
  • retry_after — Seconds to wait before retrying (rate limits, timeouts)

HTTP Status Codes

CodeMeaningCommon Cause
200OKRequest succeeded
201CreatedResource created successfully
204No ContentDelete succeeded
400Bad RequestMalformed JSON or invalid parameters
401UnauthorizedMissing or expired token
403ForbiddenInsufficient permissions or scopes
404Not FoundResource does not exist
409ConflictDuplicate resource or state conflict
422Unprocessable EntityValidation errors
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnexpected server error (contact support)

Error Codes

Error CodeDescription
AUTH_REQUIREDMissing authentication token
AUTH_INVALID_CREDENTIALSInvalid email or password
AUTH_TOKEN_EXPIREDAccess token has expired; refresh it
AUTH_TOKEN_INVALIDToken is malformed or revoked
AUTH_INSUFFICIENT_PERMISSIONSAPI key lacks the required scope
RESOURCE_NOT_FOUNDThe requested resource does not exist
RESOURCE_CONFLICTResource state conflict or duplicate unique key
RESOURCE_ALREADY_EXISTSA resource with the same unique key exists
RESOURCE_LOCKEDResource is locked and cannot be modified
VALIDATION_ERROROne or more fields failed validation
VALIDATION_FIELD_REQUIREDRequired field is missing
VALIDATION_FIELD_INVALIDField value is invalid
VALIDATION_INVALID_REQUESTRequest body is malformed
BUSINESS_RULE_VIOLATIONAction violates business rules
BUSINESS_QUOTA_EXCEEDEDPlan limit reached (e.g., max links, max calls)
BUSINESS_LIMIT_EXCEEDEDFeature limit reached
BUSINESS_RATE_LIMIT_EXCEEDEDToo many requests; slow down
EXTERNAL_SERVICE_ERRORThird-party service error (Stripe, PayPal, etc.)
EXTERNAL_TIMEOUTThird-party service timeout
EXTERNAL_UNAVAILABLEThird-party service unavailable
INTERNAL_ERRORUnexpected server error
INTERNAL_DATABASE_ERRORDatabase operation failed
INTERNAL_DATABASE_CONNECTION_ERRORCannot connect to database
INTERNAL_DATABASE_INTEGRITY_ERRORData integrity constraint violation
OPERATION_FAILEDOperation failed for unknown reason
OPERATION_TIMEOUTOperation exceeded time limit
OPERATION_CANCELLEDOperation was cancelled

Rate Limits

Rate limits are applied per endpoint category, with higher limits for authenticated users and premium tier users. Limits are enforced using a sliding window algorithm.

Rate Limit Categories

CategoryEndpointsLimit per Minute
Auth status/auth/status, /auth/csrf-token3,600
Auth operations/auth/, /login, /register, /token1,200
Payments/payment, /stripe, /paypal, /billing60
Email/email, /send-summary20
Analytics/analytics, /dashboard, /reports, /stats500
AI endpoints/ai/, /content-wizard30
Affiliate/affiliates, /commissions, /earnings120
Admin/admin, /manage, /control300
Health checks/health, /status, /ping1,000
DefaultAll other endpoints200

User Tier Multipliers:

  • Anonymous: 1.0x
  • Authenticated: 2.0x
  • Premium tier: 5.0x
  • Admin: 10.0x

For example, an authenticated user on the default category gets 200 × 2.0 = 400 requests per minute.

When rate limited, you receive a 429 response:

{
"error": "BUSINESS_RATE_LIMIT_EXCEEDED",
"message": "Too many requests to analytics endpoints. Limit: 500 per minute.",
"retry_after": 60
}

Authentication Rate Limits

Additional strict rate limits apply to security-sensitive auth endpoints per IP address:

EndpointLimitWindow
Login5 attempts15 minutes
2FA verification5 attempts5 minutes
Email verification3 attempts15 minutes
Password reset request3 attempts15 minutes
Password reset confirm10 attempts15 minutes
Token refresh60 attempts15 minutes
Export operations10 attempts15 minutes

When an auth endpoint is rate limited, the response includes a Retry-After header:

HTTP/1.1 429 Too Many Requests
Retry-After: 42
Content-Type: application/json

{
"error": "rate_limit_exceeded",
"message": "Too many requests. Please try again later.",
"retry_after": 42
}

Troubleshooting

ProblemSolution
401 on every requestCheck that your token is in the Authorization: Bearer <token> header
401 after working previouslyYour access token expired; use the refresh endpoint at /api/auth/refresh
403 with a valid tokenVerify your API key/token has the required permissions
404 for a known resourceCheck the resource ID and ensure you have access to it
422 validation errorsReview the detail array for specific field validation issues
429 rate limitedCheck the retry_after field and wait before retrying; implement exponential backoff
500 server errorRetry once after 5 seconds; contact support if persistent

Best Practices

  • Always include the retry_after header or response field when you receive a 429 response.
  • Implement automatic retry with exponential backoff for rate limit (429) and server (5xx) errors.
  • Log the error field for programmatic error handling and debugging.
  • Use the narrowest API key scopes and permissions to minimize the blast radius of a leaked token.
  • Monitor your request volume against the rate limit tiers to avoid unexpected rate limiting.
  • For bulk operations (e.g., generating many links), consider using dedicated bulk endpoints like /api/batch-link-generator which have optimized rate limits.

Next Steps