Sessions
Create measurement sessions, upload measurement data, and retrieve results via the REST API.
Sessions represent a single vital signs measurement workflow. SDK integrations normally manage these calls for you.
Session Lifecycle
-
Create a session via
POST /sdk/session/start. -
Upload the SDK-prepared measurement payload to the secure upload URL returned by the API.
-
Notify the API via
POST /sdk/session/upload-complete. The API accepts the upload and starts processing. -
Read the result by polling
GET /sdk/session/{sessionId}/result.
The low-level upload payload format is not documented publicly. Use an SDK unless Circadify has approved direct upload access for your integration.
Create a Session
POST /sdk/session/starthttpHeaders:
X-API-Key: ck_live_your_key_here
Content-Type: application/jsonhttpRequest body (optional):
{
"demographics": {
"age": 35,
"sex": "M",
"fitzpatrick": 3
}
}jsonDemographics are optional but can improve measurement quality when provided.
Response 200 OK:
{
"session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"expires_at": "2026-05-24T18:00:00.000Z",
"upload_url": "https://upload.circadify.com/uploads/a1b2c3...",
"status": "pending"
}json| Field | Type | Description |
|---|---|---|
session_id | string | Unique session identifier |
expires_at | string | ISO-8601 timestamp when the session expires |
upload_url | string | Secure URL for the SDK-prepared upload payload |
status | string | Initial session status, usually pending |
Upload Measurement Payload
SDKs upload the measurement payload automatically. Approved direct REST integrations upload the SDK-prepared binary payload to the upload_url returned from session creation:
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: application/octet-stream" \
--data-binary @measurement-payload.binbashThe upload payload is not raw video, raw frames, or a public media format. The low-level payload structure is intentionally private and may change between SDK versions.
Notify Upload Complete
POST /sdk/session/upload-completehttpHeaders:
X-API-Key: ck_live_your_key_here
Content-Type: application/jsonhttpRequest body:
{
"session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}jsonResponse 202 Accepted:
{
"session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "processing"
}jsonAfter this response, poll GET /sdk/session/{sessionId}/result until the session reaches completed or failed. SDKs handle this polling automatically.
Session Statuses
| Status | Description |
|---|---|
pending | Session initialized, awaiting upload completion |
uploaded | Upload has completed and is awaiting processing |
processing | Processing in progress |
completed | Results available |
failed | Processing failed |
expired | Session timed out before completion |
Errors
| Status | Error Code | Description |
|---|---|---|
400 | INVALID_REQUEST | Missing session_id or invalid parameters |
401 | API_KEY_INVALID | Invalid, revoked, or missing API key |
403 | FORBIDDEN | Session does not belong to this developer |
404 | SESSION_NOT_FOUND | Session ID does not exist |
410 | SESSION_EXPIRED | Session expired before completion |
422 | failed | Processing failed; the result response includes an error message |
429 | RATE_LIMIT_EXCEEDED | Sandbox (ck_test_) request rate limit exceeded (best-effort, retryable) |
429 | QUOTA_EXCEEDED | Monthly scan quota exhausted on a production (ck_live_) key (not retryable) |
On POST /sdk/session/start, a live key whose monthly scan quota is exhausted returns 429 QUOTA_EXCEEDED (retryable: false) — track usage on the Usage page in the developer portal. No Retry-After header is emitted on either 429.
See Errors for the full error reference.
Next Steps
- Results - Interpret vital signs data
- Rate Limits - Understand rate and quota limits
- Data Flow - High-level lifecycle