Skip to content

Sessions

Sessions represent a single vital signs measurement workflow. A session is created, receives an upload of the preprocessed RGB tensor, runs through the inference engine, and returns calibrated vital signs in the response. Nothing health-related is stored on our side.

  1. Create a session via POST /sdk/session/start — returns a session ID, secure upload URL, and fallback config.

  2. Upload the preprocessed tensor to the upload URL via a PUT request.

  3. Notify the backend via POST /sdk/session/upload-complete — triggers inference and returns the vital signs synchronously in the response. The tensor and the result are not retained on our side after the response is sent.

POST /sdk/session/start

Headers:

X-API-Key: ck_live_your_key_here
Content-Type: application/json

Request body (optional):

{
"demographics": {
"age": 35,
"sex": "M",
"fitzpatrick": 3
}
}

Demographics are optional but improve measurement accuracy when provided.

Response 200 OK:

{
"session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"expires_at": 1712001800,
"upload_url": "https://upload.circadify.com/uploads/a1b2c3.../video.webm?signature=...",
"fallback_config": {
"heart_rate": { "min": 62, "max": 98 },
"hrv": { "min": 25, "max": 70 },
"respiratory_rate": { "min": 13, "max": 19 },
"spo2": { "min": 96, "max": 99 },
"systolic_bp": { "min": 109, "max": 134 },
"diastolic_bp_offset": { "min": 51, "max": 66 },
"confidence": 0.0
}
}

Response headers:

X-RateLimit-Limit: 300
X-RateLimit-Remaining: 299
X-RateLimit-Reset: 1712005400
X-Usage-Current: 42
X-Usage-Limit: 500
X-Usage-Remaining: 458
FieldTypeDescription
session_idstringUnique session identifier (UUID)
expires_atnumberUnix timestamp when the session expires
upload_urlstringPresigned URL for uploading the preprocessed tensor
fallback_configobjectRanges for generating fallback vitals if inference fails

Upload the preprocessed tensor directly to the upload_url returned from session creation:

Terminal window
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: video/webm" \
--data-binary @tensor.bin

The upload goes directly to secure cloud storage — it does not pass through the API layer. The Content-Type is video/webm for compatibility, but the payload is the binary tensor produced by the SDK’s preprocessing pipeline.

See Data Flow for the exact tensor binary format.

POST /sdk/session/upload-complete

Headers:

X-API-Key: ck_live_your_key_here
Content-Type: application/json

Request body:

{
"session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

Response 200 OK:

{
"session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "completed",
"vitals": {
"heart_rate": 72,
"respiratory_rate": 16,
"hrv": 45.2,
"spo2": 98.1,
"systolic_bp": 122,
"diastolic_bp": 78,
"confidence": 0.87
},
"processing_time_ms": 74200
}

This endpoint triggers inference and returns results synchronously when processing completes. Vital sign results are included directly in the response body. The response always has status completed — if inference fails, fallback vitals with confidence: 0.0 are returned instead of an error.

No health data is stored on our side after this response is delivered. The uploaded tensor is discarded and the result is not retained. The only artifact persisted from a scan is a usage record (one scan credit consumed) for billing and quota.

FieldTypeDescription
session_idstringSession identifier
statusstringAlways completed
vitalsobjectVital signs measurement results
processing_time_msnumberProcessing time in milliseconds (present on successful inference)
StatusDescription
createdSession initialized, awaiting upload
uploadingUpload in progress
processingInference running on backend
completedResults available
failedProcessing failed (fallback vitals may be provided)
expiredSession timed out before completion
StatusError CodeDescription
400INVALID_REQUESTMissing session_id or invalid parameters
401API_KEY_INVALIDInvalid, revoked, or missing API key
403FORBIDDENSession does not belong to this developer
404SESSION_NOT_FOUNDSession ID does not exist
429RATE_LIMIT_EXCEEDEDHourly rate limit exceeded

See Errors for the full error reference.