/me) additionally carry full response models.
Base URL
All paths are under/api/v1 on the production origin:
Conventions
These conventions hold across the entire/api/v1 surface:
- Paths are lowercase kebab-case; JSON bodies and responses are camelCase. One casing, everywhere.
- Envelope: successful responses are
{ "success": true, "<resource>": ... }; errors are{ "success": false, "error": "<message>", "code": "<ERROR_CODE>" }. Server errors (5xx) are always scrubbed to a generic message with codeINTERNAL_ERROR. - Pagination uses opaque keyset cursors: pass
?after=<cursor>&limit=<1..500>and readnextCursorfrom the response. There is no offset paging. - Timestamps are ISO-8601 UTC. Money is always integer cents.
- Soft delete + restore: domains that soft-delete expose
DELETEplus aPOST .../restoreendpoint, and their list endpoints acceptincludeDeleted=truefor sync consumers. - Idempotency: most mutations require an
X-Idempotency-Keyheader — each operation’s reference entry says so. The first response is stored and replayed for identical retries; reusing a key with a different request returns409 IDEMPOTENCY_CONFLICT. Exceptions:POST /leads,PATCH /leads/{leadId}, andPATCH /cases/{caseId}do not consume the header — a blind retry there can create duplicates, so confirm the outcome with a read before retrying. - Optimistic concurrency: revisioned entities (documents, folders) require
If-Match: "<revision>"on writes and return anETag; a stale revision returns409 STALE_REVISION. - State transitions are sub-endpoints (
/complete,/cancel,/transitions,/restore), never mutable status fields. Supported transitions rejected by the resource’s current state return409 INVALID_STATE_TRANSITION; target values outside a request schema’s enum return400 VALIDATION_FAILED. - Financial records are void-not-delete: checks, disbursements, and related money records are never hard-deleted through the API.
Rate limits
Requests are rate limited per API key with a Redis sliding window. Every response carriesX-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset; a 429 response includes Retry-After.
Report execution (
POST /reports/{reportId}/run) additionally enforces a dedicated 5 runs/min budget.
Each operation in the API Reference names its tier via the x-rate-limit-tier extension.
Sensitive data (PII/PHI)
The platform stores protected health information and high-sensitivity PII. The API exposes it only behind hard guardrails:- Isolated, admin-granted scopes.
medical:read,medical:write, and the field-gatingpii:readare never bundled or implied by any other scope, and can only be granted by platform administrators after compliance verification. They cannot be added through self-serve key management. - A responsible human. Keys holding elevated scopes must have an acting attorney configured, so every access is attributable to a person as well as a service account.
- Audited reads. Every request to a PHI-gated endpoint — and every response that includes
pii:readfields — writes a HIPAA audit entry. Reads are audited, not just writes. - No PHI in events or webhooks. Webhook payloads are wakeup-only by design. Feed events for medical entities carry IDs and event type only, and all feed payloads pass sensitive-field redaction. Full records are only available via authenticated GETs.
- Tighter operational limits. The
sensitiverate tier applies, presigned URLs for medical document content expire in 60 seconds (vs. 300 standard), keys holding elevated scopes have a shorter maximum lifetime (1 year), and all PHI/PII responses are served withCache-Control: private, no-store.
pii:read, gated fields (SSN, date of birth, and other sensitive fields) are omitted from responses — not blanked — so their absence is detectable.
A first request
GET /me is the canonical credential health-check: any valid key may call it, no scope required.