Skip to main content

Error Response Format

When an error occurs, the API returns a JSON response with details:
{
  "error": {
    "code": "invalid_api_key",
    "message": "The API key provided is invalid.",
    "status": 401
  }
}
FieldDescription
codeMachine-readable error code
messageHuman-readable description
statusHTTP status code

Error Codes

Authentication Errors (4xx)

CodeStatusDescriptionSolution
invalid_api_key401API key is invalid or malformedCheck your API key is correct
missing_api_key401No API key providedAdd Authorization: Bearer <key> header
expired_api_key401API key has been revokedGenerate a new key in the dashboard
insufficient_permissions403Key doesn’t have required permissionsUse a key with appropriate permissions

Request Errors (4xx)

CodeStatusDescriptionSolution
invalid_request400Request body is malformedCheck your JSON syntax
missing_required_field400Required field is missingInclude all required fields
invalid_field_value400Field value is invalidCheck field types and formats
limit_not_found404Limit doesn’t existVerify the limit ID
meter_not_found404Meter doesn’t existVerify the meter ID
rate_limit_exceeded429Too many API requestsSlow down and retry with backoff

Limit Check Responses

These are not errors, but responses from limits.check:
ResponseMeaningAction
allowed: trueUsage is within limitsProceed with the operation
allowed: false, reason: "limit_exceeded"Customer exceeded a limitBlock or notify customer

Server Errors (5xx)

CodeStatusDescriptionSolution
internal_error500Unexpected server errorRetry the request; contact support if persistent
timeout504Request timed outRetry the request

Handling Errors in SDKs

Python

from limitry import Limitry
from limitry.errors import (
    AuthenticationError,
    NotFoundError,
    RateLimitError,
    APIError
)

client = Limitry()

try:
    response = client.limits.check(customer_id="cust_123")
except AuthenticationError as e:
    print(f"Check your API key: {e.message}")
except NotFoundError as e:
    print(f"Resource not found: {e.message}")
except RateLimitError as e:
    print(f"Rate limited. Retry after: {e.retry_after}s")
except APIError as e:
    print(f"API error: {e.code} - {e.message}")

TypeScript

import Limitry from '@limitry/sdk';
import {
  AuthenticationError,
  NotFoundError,
  RateLimitError,
  APIError
} from '@limitry/sdk';

const client = new Limitry();

try {
  const response = await client.limits.check({ customerId: 'cust_123' });
} catch (e) {
  if (e instanceof AuthenticationError) {
    console.error('Check your API key:', e.message);
  } else if (e instanceof NotFoundError) {
    console.error('Resource not found:', e.message);
  } else if (e instanceof RateLimitError) {
    console.error(`Rate limited. Retry after: ${e.retryAfter}s`);
  } else if (e instanceof APIError) {
    console.error(`API error: ${e.code} - ${e.message}`);
  }
}

Handling Check Responses

The limits.check response isn’t an error, but you should handle both cases:
response = client.limits.check(customer_id="cust_123")

if response.allowed:
    # Proceed with the API call
    result = call_api()
    
    # Record the usage
    client.events.record(
        customer_id="cust_123",
        event_type="api_call",
        values={"requests": 1}
    )
else:
    # Handle the denial
    exceeded = [l for l in response.limits if l.exceeded]
    raise LimitExceededError(f"Limit exceeded: {exceeded[0].name}")

Limitry API Rate Limits

The Limitry API itself has rate limits:
LimitValue
Requests per minute1,000
Requests per day100,000
These are limits for calling the Limitry API, separate from the rate limits you configure for your customers.

Retry Strategy

For transient errors (5xx, timeouts), implement retry with exponential backoff:
import time
from limitry import Limitry
from limitry.errors import APIError

client = Limitry()

def check_with_retry(customer_id, max_retries=3):
    for attempt in range(max_retries):
        try:
            return client.limits.check(customer_id=customer_id)
        except APIError as e:
            if e.status >= 500 and attempt < max_retries - 1:
                time.sleep(2 ** attempt)  # 1s, 2s, 4s
                continue
            raise

response = check_with_retry("cust_123")

Getting Help

If you encounter persistent errors:
  1. Check the Status Page for outages
  2. Review logs in the dashboard
  3. Contact support@limitry.com with:
    • Error code and message
    • Request ID (from response headers)
    • Timestamp of the error