Skip to content

Error Codes

When something goes wrong, the SDK throws a CircadifyError instance with a machine-readable code, a human-readable message, and a flag indicating whether the operation can be retried.

All SDK errors are instances of the CircadifyError class, which extends the native Error. You can import both the class and the error code enum for type-safe handling.

import { CircadifyError, CircadifyErrorCode } from '@circadify/sdk';
class CircadifyError extends Error {
code: CircadifyErrorCode; // Machine-readable error code
message: string; // Human-readable description
isRetryable: boolean; // Whether the operation can be retried
}

Use instanceof CircadifyError to distinguish SDK errors from other exceptions:

try {
const result = await sdk.measureVitals({ container });
} catch (error) {
if (error instanceof CircadifyError) {
console.error(`[${error.code}] ${error.message} (retryable: ${error.isRetryable})`);
}
}

These errors originate from the client-side SDK during the measureVitals() lifecycle.

CodeDescriptionRetryable
MISSING_API_KEYNo API key was provided to the constructorNo
INVALID_API_KEYAPI key is malformed or invalidNo
BROWSER_NOT_SUPPORTEDBrowser lacks required APIs (WebAssembly, MediaDevices)No
WASM_LOAD_FAILEDVision Engine WASM modules failed to loadYes
CodeDescriptionRetryable
CAMERA_PERMISSION_DENIEDThe user denied camera accessNo
CAMERA_NOT_AVAILABLENo camera found on the deviceNo
CAMERA_IN_USECamera is already in use by another applicationYes
CodeDescriptionRetryable
CAPTURE_FAILEDFrame capture encountered an errorNo
FACE_NOT_DETECTEDNo face found in the camera feedYes
FACE_DETECTION_TIMEOUTNo face detected within 30 secondsYes
QUALITY_TOO_LOWCapture quality was too poor to produce resultsYes
CANCELLEDMeasurement was cancelled via AbortController or sdk.cancel()No
CodeDescriptionRetryable
NETWORK_ERRORA network request failedYes
UPLOAD_FAILEDUpload to cloud storage failedYes
TIMEOUTPolling for results timed outYes

These errors originate from the Circadify API and are surfaced by the SDK as CircadifyError instances. For the full server-side error reference, see REST API Errors.

CodeHTTP StatusDescriptionRetryable
API_ERRORvariesAPI returned an error responseNo
QUOTA_EXCEEDED429Monthly scan limit exceeded for your planNo
RATE_LIMITED429Hourly request limit exceededYes
SESSION_NOT_FOUND404Session ID does not exist or has expiredNo
SESSION_EXPIRED410Session timed out before completionNo
PROCESSING_FAILED500Server-side inference could not process the measurementNo
UNKNOWNvariesAn unexpected error occurredNo

Wrap measureVitals() in a try/catch and branch on the error code:

import { CircadifySDK, CircadifyError, CircadifyErrorCode } from '@circadify/sdk';
try {
const result = await sdk.measureVitals({
container: document.getElementById('scan-container'),
});
} catch (error) {
if (!(error instanceof CircadifyError)) throw error;
switch (error.code) {
case CircadifyErrorCode.CAMERA_PERMISSION_DENIED:
showMessage('Please allow camera access to measure your vitals.');
break;
case CircadifyErrorCode.QUOTA_EXCEEDED:
showMessage('Monthly scan limit reached. Please upgrade your plan.');
break;
case CircadifyErrorCode.CANCELLED:
// User cancelled — no action needed
break;
default:
if (error.isRetryable) {
showRetryButton(error.message);
} else {
showError(error.message);
}
}
}

For retryable errors, implement exponential backoff:

async function measureWithRetry(sdk: CircadifySDK, options: MeasurementOptions, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await sdk.measureVitals(options);
} catch (error) {
if (!(error instanceof CircadifyError) || !error.isRetryable || attempt === maxRetries) {
throw error;
}
const delay = Math.min(1000 * Math.pow(2, attempt), 30000);
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
}

When the user denies camera access, guide them to their browser settings:

try {
const result = await sdk.measureVitals({ container });
} catch (error) {
if (error instanceof CircadifyError && error.code === CircadifyErrorCode.CAMERA_PERMISSION_DENIED) {
showInstructions(
'Camera access is required. Open your browser settings and allow camera access for this site, then refresh the page.'
);
}
}