Skip to content

Errors

The Circadify API uses standard HTTP status codes and returns structured error responses to help you diagnose and handle failures.

All errors follow this structure:

{
"error": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded",
"retryable": true
}
FieldTypeDescription
errorstringMachine-readable error code
messagestringHuman-readable description
retryablebooleanWhether the request can be retried

Rate-limited responses also include a Retry-After header with the number of seconds to wait.

CodeDescriptionResolution
API_KEY_INVALIDThe API key is missing, malformed, revoked, or expiredCheck your key in the developer dashboard. Create a new key if needed.
UNAUTHORIZEDBearer token is missing or invalidRe-authenticate and obtain a fresh token.
CodeDescriptionResolution
FORBIDDENYou do not have permission to access this resourceVerify the session belongs to your account.
DEVELOPER_PENDINGYour account is awaiting approvalWait for the approval email or contact support.
DEVELOPER_SUSPENDEDYour account has been suspendedContact support to resolve.
DEVELOPER_NOT_VERIFIEDYour email address has not been verifiedCheck your inbox for the verification email.
CodeDescriptionResolution
INVALID_REQUESTMissing or invalid request parametersCheck the request body and path parameters against the endpoint documentation.
VERIFICATION_TOKEN_INVALIDEmail verification or password reset token is invalid or expiredRequest a new verification email or password reset.
CodeDescriptionResolution
SESSION_NOT_FOUNDThe session ID does not existSessions expire after a short time. Create a new session.
DEVELOPER_NOT_FOUNDNo developer account found for this identifierCheck the account exists and the ID is correct.
CodeDescriptionResolution
EMAIL_ALREADY_EXISTSAn account with this email already existsLog in with the existing account or use a different email.
CodeDescriptionResolution
SESSION_EXPIREDThe session timed out before completionCreate a new session and retry the measurement.
CodeDescriptionResolution
RATE_LIMIT_EXCEEDEDYou have exceeded the hourly request limit for your planWait for the Retry-After period, then retry. See Rate Limits.
QUOTA_EXCEEDEDYou have exceeded the monthly scan limit for your planUpgrade your plan or wait for the next billing cycle.
CodeDescriptionResolution
INTERNAL_ERRORAn unexpected server error occurredRetry with exponential backoff. If persistent, contact support.
INFERENCE_FAILEDThe inference engine could not process the measurementRetryable. The SDK automatically provides fallback vitals. Retry the full session.
SERVICE_UNAVAILABLEA backend service is temporarily unavailableRetryable. Wait and retry with exponential backoff.
StatusMeaning
200Success
201Created (e.g., new API key)
400Bad Request — invalid parameters
401Unauthorized — invalid or missing credentials
403Forbidden — insufficient permissions
404Not Found — resource does not exist
409Conflict — resource state conflict
410Gone — resource has expired
429Rate Limited — too many requests
500Internal Error — server-side failure
503Service Unavailable — temporary backend issue

For retryable errors (retryable: true), implement exponential backoff:

async function fetchWithRetry(url: string, options: RequestInit, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.ok) return response;
const body = await response.json();
// Don't retry client errors (except rate limits)
if (response.status < 500 && response.status !== 429) {
throw new Error(body.message);
}
if (attempt === maxRetries) {
throw new Error(body.message);
}
// Use Retry-After header if present, otherwise exponential backoff
const retryAfter = response.headers.get('Retry-After');
const delay = retryAfter
? parseInt(retryAfter, 10) * 1000
: Math.min(1000 * Math.pow(2, attempt), 30000);
await new Promise(resolve => setTimeout(resolve, delay));
}
}

Recommended parameters:

ParameterValue
Max retries3
Initial delay1 second
Max delay30 seconds
Backoff multiplier2x