Skip to main content

REST API Errors

The Meter API uses standard HTTP status codes and returns JSON error messages.

HTTP status codes

CodeMeaningDescription
200OKRequest succeeded
201CreatedResource created successfully
400Bad RequestInvalid request parameters
401UnauthorizedInvalid or missing API key
403ForbiddenValid key but insufficient permissions
404Not FoundResource doesn’t exist
500Internal Server ErrorServer-side error

Error response format

All errors return JSON with a detail field:
{
  "detail": "Error message describing what went wrong"
}

Common errors

401 Unauthorized

Cause: Invalid or missing API key
{
  "detail": "Invalid or missing API key"
}
Solutions:
  • Verify Authorization header is included
  • Check API key is correct
  • Ensure key hasn’t been deleted

400 Bad Request

Cause: Invalid request parameters
{
  "detail": "Invalid URL format"
}
Common causes:
  • Missing required fields
  • Invalid field types
  • Malformed JSON
  • Invalid UUIDs
Solutions:
  • Check request body matches expected format
  • Verify all required fields are present
  • Ensure JSON is valid

404 Not Found

Cause: Resource doesn’t exist
{
  "detail": "Strategy not found"
}
Solutions:
  • Verify the UUID is correct
  • Check the resource hasn’t been deleted
  • Ensure you have permission to access it

500 Internal Server Error

Cause: Server-side error
{
  "detail": "Internal server error"
}
Solutions:
  • Retry the request after a delay
  • If persistent, contact support
  • Check API status page

Handling errors

JavaScript

const response = await fetch('https://api.meter.sh/v1/strategies', {
  headers: {
    'Authorization': `Bearer ${apiKey}`,
    'Content-Type': 'application/json'
  }
});

if (!response.ok) {
  const error = await response.json();
  console.error(`API error (${response.status}): ${error.detail}`);

  if (response.status === 401) {
    // Handle authentication error
  } else if (response.status === 404) {
    // Handle not found
  }
}

const data = await response.json();

Python

import requests

response = requests.get(
    'https://api.meter.sh/v1/strategies',
    headers={'Authorization': f'Bearer {api_key}'}
)

if not response.ok:
    error = response.json()
    print(f"API error ({response.status_code}): {error['detail']}")

    if response.status_code == 401:
        # Handle authentication error
        pass
    elif response.status_code == 404:
        # Handle not found
        pass

data = response.json()

curl

response=$(curl -s -w "\n%{http_code}" https://api.meter.sh/v1/strategies \
  -H "Authorization: Bearer sk_live_...")

http_code=$(echo "$response" | tail -n 1)
body=$(echo "$response" | sed '$d')

if [ "$http_code" != "200" ]; then
  echo "Error ($http_code): $body"
fi

Best practices

For 500 errors and network issues, retry with exponential backoff:
async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url, options);

      if (response.status === 500 && i < maxRetries - 1) {
        await new Promise(r => setTimeout(r, 2 ** i * 1000));
        continue;
      }

      return response;
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await new Promise(r => setTimeout(r, 2 ** i * 1000));
    }
  }
}
Always check HTTP status codes before parsing responses:
const response = await fetch(url, options);

// Check before parsing JSON
if (!response.ok) {
  const error = await response.json();
  throw new Error(error.detail);
}

const data = await response.json();
Include request details when logging errors:
if (!response.ok) {
  const error = await response.json();
  console.error('API request failed', {
    status: response.status,
    detail: error.detail,
    url: response.url,
    method: options.method
  });
}

Rate limiting (future)

Rate limits are not yet enforced during beta.
Future rate limiting will use these headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1640995200
429 Too Many Requests:
{
  "detail": "Rate limit exceeded. Retry after 60 seconds."
}

Next steps

Need help?

Email me at [email protected]