Usage API
🚧 Beta. The Heidi Usage API is currently in beta. Endpoints, request/response shapes, and the set of available queries may change ahead of general availability. Handle unknown
error_codevalues gracefully and pin to a specific queryname. Breaking changes will be announced before GA.
Overview
The Heidi Usage API exposes partner-facing usage analytics over your Heidi data as named, pre-defined queries returned as paginated rows. It is separate from the Heidi API (clinical scribe) — different base URL and its own query surface, but the same credentials.
Base URL
There is no cross-region routing layer — pick the endpoint for the region whose data you're querying. All endpoints sit under the /api/v1/usage path.
| Region | Base URL |
|---|---|
| Australia | https://au.api.heidihealth.com |
| United States | https://us.api.heidihealth.com |
| United Kingdom / EU West | https://uk.api.heidihealth.com |
| EU Central | https://eu.api.heidihealth.com |
| Canada | https://ca.api.heidihealth.com |
Specification
Find the Swagger definition here and download a Postman collection here.
Authentication
Send either credential as a header on every request (same as the Heidi API):
Heidi-Api-Key: <your api key>— your partner API key (recommended).Authorization: Bearer <jwt>— a Heidi open-api JWT.
A request with neither returns 401 MISSING_CREDENTIAL.
Request lifecycle
The Usage API uses a POST-to-start / GET-to-page model:
- POST
/api/v1/usagewith a querynamestarts the query and returns the first page (200). If the query is still running it returns202— poll theGETwith the returnedstatement_id. - Each response carries a fully-formed
next_page_url. Follow it with aGET(same auth header) untilnext_page_urlisnullandhas_moreisfalse.
POST /api/v1/usage
Heidi-Api-Key: <your api key>
Content-Type: application/json
{
"name": "user_daily_report",
"limit": 500,
"params": { "since": "2026-06-01" }
}{
"statement_id": "01f1848c-d205-1886-83c9-f61e2aad23bb",
"data": [ { "report_date": "2026-06-01", "…": "…" } ],
"has_more": true,
"next_page_url": "https://au.api.heidihealth.com/api/v1/usage/01f1848c-d205-1886-83c9-f61e2aad23bb?name=user_daily_report&offset=500&limit=500"
}GET /api/v1/usage/01f1848c-d205-1886-83c9-f61e2aad23bb?name=user_daily_report&offset=500&limit=500
Heidi-Api-Key: <your api key>Paging with GET is cheap — it reads cached result chunks and does not re-run the warehouse query. A running statement expires after ~10 minutes; following a next_page_url too late returns 410 STATEMENT_EXPIRED (re-POST to start again).
Idempotency
Pass an Idempotency-Key header (a UUID) on the POST to make retries safe — useful from cron jobs. Same key + same body within 10 minutes replays the cached response; same key + a different body returns 422 IDEMPOTENCY_KEY_MISMATCH.
Cancelling
DELETE /api/v1/usage/{statement_id} requests cancellation of a running statement (204 No Content).
Errors
Every non-2xx response uses a typed body so you can switch on error_code rather than parsing strings:
{
"error_code": "MISSING_CREDENTIAL",
"detail": "provide either `Heidi-Api-Key` header or `Authorization: Bearer <jwt>`",
"recovery_hint": "Provide either `Heidi-Api-Key: <key>` or `Authorization: Bearer <jwt>`."
}error_code | HTTP | When |
|---|---|---|
MISSING_CREDENTIAL | 401 | No Heidi-Api-Key / Authorization header |
INVALID_CREDENTIAL | 401 | Wrong or expired credential |
UNKNOWN_QUERY | 404 | Unrecognised query name |
STATEMENT_EXPIRED | 410 | next_page_url followed too late (~10 min) |
INVALID_PARAMS | 422 | Request failed validation |
INVALID_DATE_RANGE | 422 | until < since or a malformed date |
INVALID_WINDOW | 422 | offset / limit out of range |
IDEMPOTENCY_KEY_MISMATCH | 422 | Reused an Idempotency-Key with a different body |
RATE_LIMITED | 429 | Per-organization rate limit exceeded |
QUERY_FAILED | 500 | The warehouse query itself failed |
WAREHOUSE_DEGRADED | 503 | The analytics warehouse is failing health checks — retry after ~30s |
Rate limits
Requests are rate-limited per organization. Exceeding the limit returns 429 RATE_LIMITED — back off and retry.
Available queries
See Queries for the current query catalogue and column shapes.