REST API Errors
The Meter API uses standard HTTP status codes and returns JSON error messages.
HTTP status codes
| Code | Meaning | Description |
|---|
200 | OK | Request succeeded |
201 | Created | Resource created successfully |
400 | Bad Request | Invalid request parameters |
401 | Unauthorized | Invalid or missing API key |
403 | Forbidden | Valid key but insufficient permissions |
404 | Not Found | Resource doesn’t exist |
500 | Internal Server Error | Server-side error |
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]