Developer API
Build checkup.report's wellness capabilities into your own platform — camera-based check-ins, voice, guided sessions, activity and habit logging, and the trends that tie them together. Pick only the pieces you need.
1. Get a key
Sign in to checkup.report, open Account → Developer API, give the key a name (for example "My Fitness Platform"), tick the capability groups you need, and create it.
Send the key on every request as an X-API-Key header:
curl https://checkup.report/api/v1/readiness \
-H "X-API-Key: ck_live_your_key_here"
2. Scopes
A key carries only the capability groups you ticked. A request outside them returns 403.
| Scope | What it unlocks |
|---|---|
scan | Camera check-ins: start, upload the capture, process, read the report, eye capture. |
voice | Voice check-ins, history and baseline. |
breathing_recovery | Guided breathing and post-activity recovery sessions. |
activities | Activity logging (any activity type), history and correlations. |
journal | Daily habit journal entries, history and correlations. |
insights | Trends, timeline and the morning readiness score. |
support | The support assistant (same tools and guardrail as in-app). |
3. Endpoints
| Endpoint | Scope | Notes |
|---|---|---|
POST /api/v1/scan/initiate | scan | Starts a check-in; passes the same allowance gate as the app. |
POST /api/v1/scan/{id}/upload-video | scan | Raw frames, or an on-device colour trace (preferred — video stays on the device). |
POST /api/v1/scan/{id}/process | scan | Runs the pipeline and returns the report. The allowance is consumed here, so a failed capture costs nothing. |
POST /api/v1/scan/{id}/conjunctiva | scan | Optional eye capture, compared with the person's own earlier one. |
GET /api/v1/scan/{id}/results | scan | Re-read a processed report. |
POST /api/v1/voice/checkin | voice | Multipart audio. Requires the account's voice consent; the audio is deleted the moment it is measured. |
GET /api/v1/voice/history · /voice/baseline | voice | 7 days free; wider windows follow the account's plan. |
POST /api/v1/sessions/start | breathing_recovery | Two-scan session; both scans bill as one check-in. |
GET /api/v1/sessions/{id} · /sessions/history | breathing_recovery | Session state and the before/after result. |
POST /api/v1/activities/log | activities | Any activity type (free-text tag) plus optional details. |
GET /api/v1/activities/history · /activities/correlations | activities | Self-relative observations only. |
POST /api/v1/journal/entry | journal | One entry per local day (a repeat updates it). |
GET /api/v1/journal/history · /journal/correlations | journal | Habit ↔ readiness observations. |
GET /api/v1/trends/{metric} · /timeline · /readiness | insights | Same free/premium window rules as the app. |
POST /api/v1/support/chat | support | Same assistant, tools and guardrail as in-app. |
Example: a full check-in
KEY="ck_live_your_key_here"
# 1. Start (the allowance gate runs here)
SCAN=$(curl -s https://checkup.report/api/v1/scan/initiate \
-H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d '{"device_id":"my-platform-user-42"}' | jq -r .scan_id)
# 2. Upload the on-device colour trace
curl -s https://checkup.report/api/v1/scan/$SCAN/upload-video \
-H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d '{"roi_rgb": [[128.4,120.1,110.9], ...], "sampling_rate": 30}'
# 3. Process — returns the report; the check-in is billed here
curl -s https://checkup.report/api/v1/scan/$SCAN/process -X POST \
-H "X-API-Key: $KEY"
{
"scan_id": 8471,
"status": "complete",
"metrics": { "hr": { "value": 68.2, "confidence": 0.71 },
"rr": { "value": 14.1, "confidence": 0.63 } },
"usual_ranges": { "hr": { "low": 62, "high": 74, "baseline": 67.5 } },
"display_summary": "Your check-in is logged. Lately your readings have been holding steady…",
"tier": "free"
}
Example: log an activity
curl -s https://checkup.report/api/v1/activities/log \
-H "X-API-Key: $KEY" -H "Content-Type: application/json" \
-d '{"activity_type":"running","duration_minutes":30,
"perceived_intensity":"moderate","details":{"distance_km":5.2}}'
4. Rate limits
60 requests per minute, per key, returning 429 with a Retry-After header when exceeded. This is infrastructure protection so one buggy integration cannot affect everyone else — it is not a billing limit. What things cost is governed entirely by the account balance described above. Need a higher ceiling? Write to [email protected].
Every call is recorded (endpoint, time, status — never request bodies) and summarised for you at GET /developer/api-keys/{id}/usage, including how many times you have hit the limit — a rising count usually means a retry loop worth fixing.
High-volume use
Once a single key passes 10,000 calls in a calendar month, we ask you to confirm once, from Account → Developer API, that you are building on checkup.report and will follow the Developer API terms (Terms §8.7). Until you do, that key is limited to 10 requests per minute instead of 60 — throttled, never blocked, so a live integration slows down rather than breaking. Confirming takes one tap and restores the full rate immediately. There is no extra charge and nothing to negotiate.
Restricting a key to your servers
Optionally, when you create a key you can list the IP addresses or CIDR ranges allowed to use it; requests from anywhere else are refused with 403. Leave it blank for no restriction — that is the default. Whether or not you pin addresses, we email you the first time a key is used from a source we have not seen before (at most once per key per day, and never blocking the request), so an unexpected copy of your key is visible to you quickly.
Telling your own users
When you create a key you provide the short line you will show your own users — for example "Powered by checkup.report" — so the people whose data flows through us know where their wellness measurements come from. It is stored with the key, and showing it is required by Terms §8.7.
5. Errors
| Status | Meaning |
|---|---|
401 | Missing, unknown or revoked key. |
402 | The account has no check-in allowance left — exactly as the app would refuse. |
403 | The key lacks the scope, the request came from an address outside the key's IP allowlist, the account is suspended, or a required consent is missing. |
404 / 409 / 422 | Not found / wrong step order / invalid payload. |
429 | Rate limit — retry after 60 seconds. The message says whether you hit the standard limit or the tighter high-volume-pending-acknowledgment one. |
6. What you must not do with it
checkup.report is a general wellness product. Everything it returns describes a person's own patterns over time; nothing it returns is a diagnosis, a clinical measurement, or medical advice, and every narrative is screened before it leaves our servers. Your integration must keep that framing:
- Do not present any value or text as a medical measurement, diagnosis, or a reason to start, stop or change treatment.
- Do not use it for medical decisions, emergencies, or the monitoring of any condition.
- Keep the wellness register when you display results — reflections on a person's own patterns, never claims about their health status.
- Show your users what you collect and let them disconnect; their data rights (export, deletion) continue to run through their own checkup.report account.
7. Managing keys
All of these use your normal signed-in session (not the API key):
- POST
/developer/api-keys— create (returns the key once) - GET
/developer/api-keys— list yours - DELETE
/developer/api-keys/{id}— revoke immediately - GET
/developer/api-keys/{id}/usage— call counts - GET
/developer/scopes— the scope catalogue