Errors
The API uses standard HTTP status codes and returns errors in a consistent JSON format.
Error Response Format
All errors include an error key with a human-readable message:
{
"error": "Not found: Channel"
}
Some errors include additional context:
{
"error": "Monthly limit reached for channel_analysis",
"usage": {
"current": 40,
"limit": 40,
"tier": "pro",
"resets_at": "2026-04-01T00:00:00Z"
}
}
Status Codes
| Code | Name | Description |
|---|---|---|
| 200 | OK | Request succeeded |
| 201 | Created | Resource created successfully |
| 202 | Accepted | Async action queued for processing |
| 400 | Bad Request | Missing or malformed request parameters |
| 401 | Unauthorized | Invalid or missing API key |
| 404 | Not Found | Resource does not exist |
| 422 | Unprocessable Entity | Validation error or business logic constraint |
| 429 | Too Many Requests | Rate limit or monthly usage limit exceeded |
Error Types
400 Bad Request
Returned when a required parameter is missing:
{
"error": "Missing parameter: name"
}
401 Unauthorized
Returned when authentication fails:
{
"error": "Invalid or revoked API key."
}
404 Not Found
Returned when the requested resource does not exist:
{
"error": "Not found: Channel"
}
422 Unprocessable Entity
Returned when a request fails validation or business rules:
{
"error": "Channel has no associated niche. Run analysis first."
}
{
"error": "You must have at least one tracked channel to create a niche."
}
429 Too Many Requests
Returned for rate limit violations:
{
"error": "Rate limit exceeded. Retry after 23 seconds.",
"retry_after": 23
}
Or monthly usage limit violations:
{
"error": "Monthly limit reached for channel_analysis",
"usage": {
"current": 40,
"limit": 40,
"tier": "pro",
"resets_at": "2026-04-01T00:00:00Z"
}
}
Handling Errors
response = requests.get(url, headers=headers)
if response.ok:
data = response.json()
elif response.status_code == 429:
time.sleep(response.json().get("retry_after", 60))
else:
raise Exception(f"API error {response.status_code}: {response.json()['error']}")
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
case response.code.to_i
when 200..202 then JSON.parse(response.body)
when 401 then raise "Auth failed: #{JSON.parse(response.body)['error']}"
when 404 then nil
when 429 then sleep(JSON.parse(response.body)["retry_after"] || 60)
else raise "API error #{response.code}: #{response.body}"
end
const response = await fetch(url, { headers });
if (response.ok) {
const data = await response.json();
} else if (response.status === 429) {
const { retry_after } = await response.json();
await new Promise(r => setTimeout(r, (retry_after || 60) * 1000));
} else {
const { error } = await response.json();
throw new Error(`API error ${response.status}: ${error}`);
}