Legacy TinyLimiter documentation. About this product

All error responses follow a consistent format:

{
  "error": {
    "code": "error_code",
    "message": "Human-readable description",
    "request_id": "req_xxx"
  }
}

HTTP Status Codes

400 Bad Request

Invalid request body or missing required fields.

{
  "error": {
    "code": "bad_request",
    "message": "Missing or invalid \"namespace\" field",
    "request_id": "req_a1b2c3d4..."
  }
}

Common causes:

  • Invalid JSON body
  • Missing required field (namespace, identifier, limit, window)
  • Invalid field type (e.g., string instead of number for limit)
  • Negative or zero values for limit or window

Fix: Check your request body matches the expected format:

{
  "namespace": "api",
  "identifier": "user_123",
  "limit": 100,
  "window": 60000
}

401 Unauthorized

Missing or invalid API key.

{
  "error": {
    "code": "unauthorized",
    "message": "Invalid API key format",
    "request_id": "req_a1b2c3d4..."
  }
}

Common causes:

  • Missing Authorization header
  • Invalid key format (doesn't match ts_limiter_{mode}_{32chars})
  • Revoked API key
  • Using wrong product key (e.g., ts_cache_ on TinyLimiter)

Fix: Verify your API key:

# Correct
Authorization: Bearer ts_limiter_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6

# Wrong product
Authorization: Bearer ts_cache_live_xxx  # ❌ Wrong prefix for TinyLimiter

402 Payment Required

Live mode key requires active subscription.

{
  "error": {
    "code": "payment_required",
    "message": "Live mode API keys require an active subscription. Subscribe at dashboard.tinyscale.io or use a test mode key.",
    "request_id": "req_a1b2c3d4..."
  }
}

Common causes:

  • Using live key without subscription
  • Subscription canceled or expired
  • Payment method declined

Fix:

429 Too Many Requests

Rate limit exceeded on the management API itself.

{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests",
    "request_id": "req_a1b2c3d4..."
  }
}

:::note This is for TinyScale's own API rate limits (not your rate limits). The /v1/check endpoint returns allowed: false in the response body, not a 429 status. :::

500 Internal Server Error

Server-side error.

{
  "error": {
    "code": "internal_error",
    "message": "Internal server error",
    "request_id": "req_a1b2c3d4..."
  }
}

What to do:

  1. Retry the request after a brief delay
  2. If persistent, check our status page
  3. Contact support with the request_id

Error Handling Best Practices

async function checkRateLimit(userId) {
  try {
    const response = await fetch('https://limiter.tinyscale.io/v1/check', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.TINYSCALE_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        namespace: 'api',
        identifier: userId,
        limit: 100,
        window: 60000,
      }),
    });

    if (!response.ok) {
      const error = await response.json();
      
      switch (response.status) {
        case 401:
          console.error('Invalid API key:', error.error.message);
          // Fall through - allow request (fail open)
          return true;
        case 402:
          console.error('Subscription required:', error.error.message);
          // Fall through - allow request (fail open)
          return true;
        case 500:
          console.error('TinyScale error:', error.error.request_id);
          // Fail open - don't block users due to our outage
          return true;
        default:
          console.error('Unexpected error:', error);
          return true;
      }
    }

    const { data } = await response.json();
    return data.allowed;
    
  } catch (networkError) {
    // Network failure - fail open
    console.error('Network error calling TinyScale:', networkError);
    return true;
  }
}

Fail Open vs Fail Closed

Fail open (recommended): If TinyScale is unavailable, allow the request.

// Fail open - don't block legitimate users
if (error) return true;

Fail closed: If TinyScale is unavailable, reject the request.

// Fail closed - strict enforcement
if (error) return false;

:::tip We recommend fail open for most use cases. Blocking legitimate users due to an infrastructure issue is worse than temporarily allowing extra requests. :::

Debugging

Include the request_id from error responses when contacting support:

Request ID: req_a1b2c3d4e5f6g7h8i9j0k1l2

You can also check response headers:

curl -i https://limiter.tinyscale.io/v1/check ...
# X-Request-Id: req_a1b2c3d4e5f6g7h8i9j0k1l2