Skip to content
Developers

API reference

Read access to a Cadence organization's clinical operations data, plus opt-in writes that schedule sessions and create or update authorizations. Every resource is scoped to the authenticated organization and keyed by an opaque `tokenRef`; protected health information - client names, note narratives - is never returned. Authenticate with `Authorization: Bearer <key>`. Each key carries read scopes (`clients`, `sessions`, `authorizations`, `notes`) and, optionally, write scopes (`sessions:write`, `authorizations:write`); writes are refused without one. Requests are limited to 120 requests per minute per key and per IP, enforced per serving instance; a 429 carries a `Retry-After` header. List endpoints page by keyset cursor (`?cursor=`) in `(createdAt DESC, id DESC)` order.

Getting started

Base URL: https://www.cadenceaba.com/api/v1. Authenticate every request with an organization API key (created in Settings → API, on the Practice plan):

Example request
curl "https://www.cadenceaba.com/api/v1/clients?limit=50" \
  -H "Authorization: Bearer cad_sk_…"

# next page
curl "https://www.cadenceaba.com/api/v1/clients?cursor=<next_cursor>" \
  -H "Authorization: Bearer cad_sk_…"

Responses are JSON and de-identified - clients are keyed by an opaque tokenRef, and PHI (names, note narratives) never leaves, in line with the safeguards on our HIPAA & BAA page. Requests are limited to 120 requests per minute per key and per IP, enforced per serving instance; a 429 carries a Retry-After header. Create endpoints accept an Idempotency-Key header so retries never duplicate. The full machine-readable contract lives at /api/v1/openapi.json.

Scopes

Each key carries a least-privilege set. Read scopes gate the corresponding GET resources; write scopes are opt-in and gate create/update. A key created before scoping existed reads everything and writes nothing.

clientsGET /clients and /clients/{id}
sessionsGET /sessions
authorizationsGET /authorizations and /authorizations/{id}
notesGET /notes
authorizations:writePOST /authorizations and PATCH /authorizations/{id}
sessions:writePOST /sessions

Endpoints

GET/api/v1

Confirms the key works and lists the available resources plus the key's scopes. Requires any valid key - no specific scope.

Responses

  • 200OK
  • 401Missing or invalid API key.
  • 403The key lacks the required scope (`insufficient_scope`), the organization's plan does not include API access (`plan_required`), the workspace has been closed (`workspace_closed`), or the subscription was never started (`subscription_required`). A write to an organization whose subscription has lapsed is refused with `read_only` - reads keep working.
  • 429Too many requests. Back off and retry after the `Retry-After` header's seconds.
GET/api/v1/clients

Requires the `clients` scope.

Parameters

  • limit query · integerMaximum items to return (1-200). Defaults to 50.
  • offset query · integerNumber of items to skip, for offset pagination. Ignored when a `cursor` is supplied.
  • cursor query · stringOpaque keyset cursor from a previous response's `next_cursor`. Preferred over `offset` - it's stable under concurrent inserts. Both paginate the same `(createdAt DESC, id DESC)` ordering.

Responses

  • 200OK
  • 400The request body is missing, malformed, or fails validation.
  • 401Missing or invalid API key.
  • 403The key lacks the required scope (`insufficient_scope`), the organization's plan does not include API access (`plan_required`), the workspace has been closed (`workspace_closed`), or the subscription was never started (`subscription_required`). A write to an organization whose subscription has lapsed is refused with `read_only` - reads keep working.
  • 429Too many requests. Back off and retry after the `Retry-After` header's seconds.
GET/api/v1/clients/{id}

Requires the `clients` scope.

Parameters

  • id path · required · string <uuid>

Responses

  • 200OK
  • 401Missing or invalid API key.
  • 403The key lacks the required scope (`insufficient_scope`), the organization's plan does not include API access (`plan_required`), the workspace has been closed (`workspace_closed`), or the subscription was never started (`subscription_required`). A write to an organization whose subscription has lapsed is refused with `read_only` - reads keep working.
  • 404No such resource in your organization.
  • 429Too many requests. Back off and retry after the `Retry-After` header's seconds.
GET/api/v1/sessions

Requires the `sessions` scope. A `cursor` that this API did not issue is rejected with 400 `invalid_request` rather than restarting from the first page.

Parameters

  • clientId query · string <uuid>Filter to a single client id. Intersected with your organization - a foreign id returns nothing.
  • limit query · integerMaximum items to return (1-200). Defaults to 50.
  • offset query · integerNumber of items to skip, for offset pagination. Ignored when a `cursor` is supplied.
  • cursor query · stringOpaque keyset cursor from a previous response's `next_cursor`. Preferred over `offset` - it's stable under concurrent inserts. Both paginate the same `(createdAt DESC, id DESC)` ordering.

Responses

  • 200OK
  • 400The request body is missing, malformed, or fails validation.
  • 401Missing or invalid API key.
  • 403The key lacks the required scope (`insufficient_scope`), the organization's plan does not include API access (`plan_required`), the workspace has been closed (`workspace_closed`), or the subscription was never started (`subscription_required`). A write to an organization whose subscription has lapsed is refused with `read_only` - reads keep working.
  • 429Too many requests. Back off and retry after the `Retry-After` header's seconds.
POST/api/v1/sessions

Requires the `sessions:write` scope. Creates a `scheduled` session (a calendar slot) - the client is referenced by id; no clinical capture data or direct patient identifiers are accepted. The slot is created unassigned and picked up by whoever starts it.

Parameters

  • Idempotency-Key header · stringMakes a create safe to retry. The first request with a given key is processed and its result stored; a retry with the same key and body replays that result instead of creating a duplicate. Reusing a key with a different body returns 409 `idempotency_key_reused`, and a retry that arrives while the first request is still running returns 409 `idempotency_in_progress`. Keys are remembered for 24 hours; after that the same key starts a new request. A key longer than 255 characters is rejected with 400 `invalid_request`.

Request body - CreateSession

clientIdrequiredstring <uuid>A client in your organization.
scheduledStartrequiredstring <date-time>
scheduledEndstring <date-time>Must be after scheduledStart.
cptCodestringOne of: 97151, 97152, 97153, 97154, 97155, 97156, 97157, 97158.
locationstring · max 40A short place name such as "home", "clinic", or "telehealth".

Responses

  • 201Created
  • 400The request body is missing, malformed, or fails validation.
  • 401Missing or invalid API key.
  • 403The key lacks the required scope (`insufficient_scope`), the organization's plan does not include API access (`plan_required`), the workspace has been closed (`workspace_closed`), or the subscription was never started (`subscription_required`). A write to an organization whose subscription has lapsed is refused with `read_only` - reads keep working.
  • 404No such resource in your organization.
  • 409`duplicate_session`: the client already has a scheduled or in-progress session starting at exactly `scheduledStart` - the existing session's id is returned as `error.sessionId`. `client_inactive`: the client is inactive or discharged, so no session can be booked for them. Also the `Idempotency-Key` conflicts (`idempotency_key_reused`, `idempotency_in_progress`) described under other write endpoints.
  • 429Too many requests. Back off and retry after the `Retry-After` header's seconds.
GET/api/v1/authorizations

Requires the `authorizations` scope.

Parameters

  • clientId query · string <uuid>Filter to a single client id. Intersected with your organization - a foreign id returns nothing.
  • limit query · integerMaximum items to return (1-200). Defaults to 50.
  • offset query · integerNumber of items to skip, for offset pagination. Ignored when a `cursor` is supplied.
  • cursor query · stringOpaque keyset cursor from a previous response's `next_cursor`. Preferred over `offset` - it's stable under concurrent inserts. Both paginate the same `(createdAt DESC, id DESC)` ordering.

Responses

  • 200OK
  • 400The request body is missing, malformed, or fails validation.
  • 401Missing or invalid API key.
  • 403The key lacks the required scope (`insufficient_scope`), the organization's plan does not include API access (`plan_required`), the workspace has been closed (`workspace_closed`), or the subscription was never started (`subscription_required`). A write to an organization whose subscription has lapsed is refused with `read_only` - reads keep working.
  • 429Too many requests. Back off and retry after the `Retry-After` header's seconds.
POST/api/v1/authorizations

Requires the `authorizations:write` scope. The client is referenced by id; no direct patient identifiers are accepted. `unitsUsed` is server-maintained and starts at `unitsUsedBaseline` (0 when omitted). `endDate` must not be before `startDate`.

Parameters

  • Idempotency-Key header · stringMakes a create safe to retry. The first request with a given key is processed and its result stored; a retry with the same key and body replays that result instead of creating a duplicate. Reusing a key with a different body returns 409 `idempotency_key_reused`, and a retry that arrives while the first request is still running returns 409 `idempotency_in_progress`. Keys are remembered for 24 hours; after that the same key starts a new request. A key longer than 255 characters is rejected with 400 `invalid_request`.

Request body - CreateAuthorization

clientIdrequiredstring <uuid>A client in your organization.
cptCoderequiredstringOne of: 97151, 97152, 97153, 97154, 97155, 97156, 97157, 97158.
unitsApprovedrequiredinteger
unitsUsedBaselineintegerUnits already used before Cadence, e.g. when moving to Cadence mid-period. Default 0.
payerstring · max 200
payerEdiIdstring · max 80The payer's EDI id for this authorization's 837P claims - letters, digits, spaces and hyphens (never an X12 delimiter).
authNumberstring · max 100
startDatestring <date-time>
endDatestring <date-time>Must not be before startDate.
statusstringOne of: active, expiring, expired, exhausted, pending. Default active.

Responses

  • 201Created
  • 400The request body is missing, malformed, or fails validation.
  • 401Missing or invalid API key.
  • 403The key lacks the required scope (`insufficient_scope`), the organization's plan does not include API access (`plan_required`), the workspace has been closed (`workspace_closed`), or the subscription was never started (`subscription_required`). A write to an organization whose subscription has lapsed is refused with `read_only` - reads keep working.
  • 404No such resource in your organization.
  • 409The `Idempotency-Key` was already used with a different request body (`idempotency_key_reused`), or the original request with that key is still in progress (`idempotency_in_progress`). Send a new key for a new operation; wait and retry with the same key and body to replay the original.
  • 429Too many requests. Back off and retry after the `Retry-After` header's seconds.
GET/api/v1/authorizations/{id}

Requires the `authorizations` scope.

Parameters

  • id path · required · string <uuid>

Responses

  • 200OK
  • 401Missing or invalid API key.
  • 403The key lacks the required scope (`insufficient_scope`), the organization's plan does not include API access (`plan_required`), the workspace has been closed (`workspace_closed`), or the subscription was never started (`subscription_required`). A write to an organization whose subscription has lapsed is refused with `read_only` - reads keep working.
  • 404No such resource in your organization.
  • 429Too many requests. Back off and retry after the `Retry-After` header's seconds.
PATCH/api/v1/authorizations/{id}

Requires the `authorizations:write` scope. Updates operational fields only - `id`, `clientId`, `cptCode`, and the server-maintained `unitsUsed` are immutable (a new `unitsUsedBaseline` moves `unitsUsed` by the same amount). A change that would leave `endDate` before `startDate` - including moving one end past the other one already stored - is rejected with 400 `invalid_request`.

Parameters

  • id path · required · string <uuid>

Request body - UpdateAuthorization

payerstring · max 200
payerEdiIdstring · max 80The payer's EDI id for this authorization's 837P claims - letters, digits, spaces and hyphens (never an X12 delimiter).
authNumberstring · max 100
unitsApprovedinteger
unitsUsedBaselineinteger
startDatestring <date-time>
endDatestring <date-time>
reauthDueAtstring <date-time>
statusstringOne of: active, expiring, expired, exhausted, pending.

Responses

  • 200Updated
  • 400The request body is missing, malformed, or fails validation.
  • 401Missing or invalid API key.
  • 403The key lacks the required scope (`insufficient_scope`), the organization's plan does not include API access (`plan_required`), the workspace has been closed (`workspace_closed`), or the subscription was never started (`subscription_required`). A write to an organization whose subscription has lapsed is refused with `read_only` - reads keep working.
  • 404No such resource in your organization.
  • 429Too many requests. Back off and retry after the `Retry-After` header's seconds.
GET/api/v1/notes

Note metadata only - the SOAP narrative is PHI and is never returned. Requires the `notes` scope.

Parameters

  • sessionId query · string <uuid>Filter notes to a single session id.
  • limit query · integerMaximum items to return (1-200). Defaults to 50.
  • offset query · integerNumber of items to skip, for offset pagination. Ignored when a `cursor` is supplied.
  • cursor query · stringOpaque keyset cursor from a previous response's `next_cursor`. Preferred over `offset` - it's stable under concurrent inserts. Both paginate the same `(createdAt DESC, id DESC)` ordering.

Responses

  • 200OK
  • 400The request body is missing, malformed, or fails validation.
  • 401Missing or invalid API key.
  • 403The key lacks the required scope (`insufficient_scope`), the organization's plan does not include API access (`plan_required`), the workspace has been closed (`workspace_closed`), or the subscription was never started (`subscription_required`). A write to an organization whose subscription has lapsed is refused with `read_only` - reads keep working.
  • 429Too many requests. Back off and retry after the `Retry-After` header's seconds.

Pagination & errors

Every list endpoint returns { object: "list", data: [...], has_more, next_cursor }. Pass next_cursor back as ?cursor= to fetch the next page; it is a keyset cursor, so rows inserted while you page are never skipped or repeated. Single resources return { object, data }.

Every non-2xx response carries one envelope. The code is stable and safe to branch on; the message is for people and may change.

Error.error

coderequiredstringA stable, machine-readable reason. One of: unauthorized, invalid_key, plan_required, workspace_closed, subscription_required, insufficient_scope, read_only, rate_limited, not_found, client_not_found, client_inactive, invalid_json, invalid_request, idempotency_in_progress, idempotency_key_reused, duplicate_session.
messagerequiredstringA human-readable explanation; wording may change.
sessionIdstring <uuid>Only on `duplicate_session`: the id of the session that already occupies the slot.

Resource shapes

Client

idrequiredstring <uuid>
tokenRefrequiredstringOpaque, de-identified client reference (never PHI).
statusrequiredstringOne of: active, inactive, discharged.
clinicIdrequiredstring <uuid>
createdAtrequiredstring <date-time>

Session

idrequiredstring <uuid>
clientIdrequiredstring <uuid>
clinicIdrequiredstring <uuid>
statusrequiredstringOne of: scheduled, in_progress, capture_complete, note_drafted, signed, billed, canceled, no_show.
cptCodestring | nullPlanned CPT code.
locationstring | null
scheduledStartstring | null <date-time>
scheduledEndstring | null <date-time>
startedAtstring | null <date-time>
endedAtstring | null <date-time>
createdAtrequiredstring <date-time>

Authorization

idrequiredstring <uuid>
clientIdrequiredstring <uuid>
payerstring | null
payerEdiIdstring | nullThe payer's EDI id this authorization's claims are filed under (837P NM1*PR).
authNumberstring | null
cptCoderequiredstring
unitsApprovedrequiredinteger
unitsUsedrequiredinteger`unitsUsedBaseline` plus the units drawn from signed and billed sessions as of Cadence's last utilization recompute for this client - a cached figure that can lag the most recent sessions.
unitsUsedBaselinerequiredintegerUnits used before Cadence started drawing this authorization down (for example, imported from a previous system). Included in `unitsUsed`.
unitsRemainingrequiredintegerDerived: unitsApproved - unitsUsed, so it lags the same way unitsUsed does.
startDatestring | null <date-time>
endDatestring | null <date-time>
reauthDueAtstring | null <date-time>
statusrequiredstringOne of: active, expiring, expired, exhausted, pending.
createdAtrequiredstring <date-time>

Note

idrequiredstring <uuid>
sessionIdrequiredstring <uuid>
clientIdrequiredstring <uuid>
statusrequiredstringOne of: draft, pending_signature, signed, amended.
formatrequiredstring
signedAtstring | null <date-time>
signedByUserIdstring | null <uuid>
createdAtrequiredstring <date-time>

Questions about the API?