Skip to content

API conventions

A few conventions hold across the whole API. Learn them once and every endpoint behaves predictably.

Discovery root

The API is self-describing. GET /v1 returns a link map (HATEOAS _links) to the main resources, and the full machine-readable spec lives at GET /v1/openapi.json (OpenAPI 3.1). Most resource responses also include a _links block pointing at related resources (a job → its results, a member → their timeline, and so on).

Terminal window
curl https://api.commissionsight.com/v1 # discovery root
curl https://api.commissionsight.com/v1/openapi.json
curl https://api.commissionsight.com/v1/health # liveness (no auth)

Errors — RFC 9457 problem+json

Every error is an RFC 9457 problem document, served as application/problem+json:

{
"type": "about:blank",
"title": "No statement format is configured for this carrier yet…",
"status": 422,
"detail": "…optional, human-readable specifics…",
"instance": "/v1/files",
"code": "carrier_not_configured" // stable, machine-readable — switch on this
}

Switch on code (stable) rather than title (human copy that may be reworded). Common codes include bad_request, validation_error, not_found, conflict, carrier_not_configured, account_not_provisioned, period_exists, already_retracted, nothing_to_rescore, and rate_limited. Standard HTTP status codes apply (2xx success, 4xx your request, 5xx us).

Idempotent uploads

POST /v1/files accepts an Idempotency-Key header. Re-sending the same key for the same account returns the existing job instead of creating a duplicate — safe to retry a flaky upload:

Terminal window
curl -X POST "https://api.commissionsight.com/v1/files" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: humana-2026-04-v1" \
-F file=@statement.csv -F carrierId=$CARRIER_ID -F periodYear=2026 -F periodMonth=4

The response carries "idempotent": true when an existing job was returned.

Idempotency is distinct from period_exists: re-sending the same upload with the same key replays the original job, whereas a different file landing on a carrier+period that already has one is refused with 409 period_exists until you opt in with replace=true. See Uploading statements.

Rate limits

Requests are rate-limited per API token. Over the limit, the API returns 429 (problem+json, Rate limit exceeded) with a Retry-After header (seconds) — back off for that long and retry. Health checks are exempt.

Pagination

List endpoints return a data array plus a pagination object. Two styles are used:

  • Offset (members, jobs, comparisons-backed lists): ?limit=&offset=pagination: { limit, offset, hasMore }. Increase offset by limit until hasMore is false.
  • Cursor (files): ?limit=&cursor=pagination: { limit, nextCursor, hasMore }. Pass the returned nextCursor as the next cursor.

Limits are capped server-side (typically 200), so always page rather than assuming one response holds everything.

Versioning & base URL

All endpoints are under https://api.commissionsight.com/v1. The version prefix changes only on a breaking change; additive fields are not breaking, so tolerate unknown fields in responses.