Skip to content

Error Codes

All error responses follow a consistent format:

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

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
}

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:

Terminal window
# Correct
Authorization: Bearer ts_limiter_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
# Wrong product
Authorization: Bearer ts_cache_live_xxx # ❌ Wrong prefix for TinyLimiter

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:

Rate limit exceeded on the management API itself.

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

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
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 (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;

Include the request_id from error responses when contacting support:

Request ID: req_a1b2c3d4e5f6g7h8i9j0k1l2

You can also check response headers:

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