Circadify

Error Codes

Reference for all Circadify SDK and API 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.

Error Format

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/web-sdk';
typescript
class CircadifyError extends Error {
  code: CircadifyErrorCode; // Machine-readable error code
  message: string;          // Human-readable description
  isRetryable: boolean;     // Whether the operation can be retried
}
typescript

Use instanceof CircadifyError to distinguish SDK errors from other exceptions:

try {
  const video = document.querySelector('video')!;
  const result = await sdk.measureVitals({ videoElement: video });
} catch (error) {
  if (error instanceof CircadifyError) {
    console.error(`[${error.code}] ${error.message} (retryable: ${error.isRetryable})`);
  }
}
typescript

SDK Error Codes

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

Initialization Errors

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_FAILEDRequired SDK runtime assets failed to loadYes

Camera Errors

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

Capture Errors

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

Network and Processing Errors

CodeDescriptionRetryable
NETWORK_ERRORA network request failedYes
UPLOAD_FAILEDSecure upload failedYes
TIMEOUTPolling for results timed outYes

API Error Codes

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
RATE_LIMITED429Sandbox request rate limit, or monthly scan quota, exceededYes (sandbox rate limit) / No (monthly quota)
SESSION_NOT_FOUND404Session ID does not exist or has expiredNo
SESSION_EXPIRED410Session timed out before completionNo
PROCESSING_FAILED500The measurement could not be processedNo
UNKNOWNvariesAn unexpected error occurredNo
Tip

Retryable errors (isRetryable: true) are safe to retry with exponential backoff. A RATE_LIMITED from the sandbox request rate limit is retryable (back off, then retry); a RATE_LIMITED caused by an exhausted monthly scan quota is not — check your Usage page.

Handling Errors

Basic pattern

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

import { CircadifySDK, CircadifyError, CircadifyErrorCode } from '@circadify/web-sdk';
 
try {
  const result = await sdk.measureVitals({
    videoElement: document.getElementById('preview') as HTMLVideoElement,
  });
} 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.CANCELLED:
      // User cancelled — no action needed
      break;
    default:
      if (error.isRetryable) {
        showRetryButton(error.message);
      } else {
        showError(error.message);
      }
  }
}
typescript

Retry with backoff

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));
    }
  }
}
typescript

Camera permission recovery

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

try {
  const video = document.querySelector('video')!;
  const result = await sdk.measureVitals({ videoElement: video });
} 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.'
    );
  }
}
typescript
Caution

Never retry CAMERA_PERMISSION_DENIED or MISSING_API_KEY errors. These require user or configuration changes before they can succeed.

Next Steps