Skip to main content

Documentation Index

Fetch the complete documentation index at: https://code4source.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

This page describes how the API meters and charges requests. It applies when your Organization has an active subscription and uses an atk_* API key.

What counts as a billable request

CountsDoes not count
POST /v1/evaluateGET /v1/sources
POST /v1/intersectionsGET /v1/rulesets (list/get)
POST /v1/distancePOST /v1/rulesets (create)
POST /v1/subjects?explain=true (metadata only)
Catalog reads, ruleset writes, and ?explain=true calls never consume quota and are never charged.

Per-request gates

Every billable request passes three gates, in order:
  1. Authentication — the bearer token must be a valid atk_* key issued to your Organization.
  2. Subscription — your subscription must be active. An expired or suspended subscription returns 402 SUBSCRIPTION_INACTIVE and the request is not executed.
  3. Quota — you must be within your contracted monthly cap for the current billing period. Over the cap returns 429 QUOTA_EXCEEDED and the request is not executed.
A request that fails any of these gates is not charged.

Billing period

Quota is counted against your Stripe billing period, not against the calendar month. The boundaries come from your subscription — typically the day of the month you signed up — and are returned in the period_started_at / period_ends_at fields on a 429 response. See Quotas & rate limits.

Idempotency

Send an Idempotency-Key header on every billable request:
POST /v1/evaluate
Idempotency-Key: client-job-2026-04-18-7842
Content-Type: application/json
Authorization: Bearer atk_live_...
Format: [A-Za-z0-9_:.-]{8,128}. Anything else returns 422 IDEMPOTENCY_KEY_INVALID. Keys are scoped per Organization. The contract:
OutcomeHTTPMeaning
Same key, same body, charged200Replay — original response snapshot is returned.
Same key, different body422IDEMPOTENCY_KEY_CONFLICT — pick a new key.
Same key, too many retries429IDEMPOTENCY_KEY_EXHAUSTED — pick a new key.
Same key, snapshot expired410IDEMPOTENCY_REPLAY_EXPIRED — key reusable for a fresh charge.
Replay returns the original response without re-running the evaluation and without charging again. This is the safe way to retry on network errors: the second request either replays the prior result (no extra charge) or runs fresh (one charge total).

DEGRADED responses are not charged

A response with status: "degraded" means at least one source could not be evaluated for an infrastructure reason (upstream provider timeout, transient error). The response is incomplete, not wrong. By default, DEGRADED responses do not consume quota and are not charged. The Idempotency-Key stays reusable, so you can retry the same request once the upstream source recovers and the retry will either succeed (one charge total) or come back DEGRADED again (still zero charges). For the wrappers /v1/intersections, /v1/distance, and /v1/subjects, a single source that fails is reported with status: "failed" on its SourceOutcome. The overall response can still be useful — the other sources returned data — but the request is not charged. See Verdicts for the full status/outcome semantics.
  1. Generate a fresh Idempotency-Key per logical job (a UUID, or your own job id).
  2. On 5xx, network error, or status: "degraded": retry with the same key. You will either replay a charged result, or run fresh.
  3. On 429 QUOTA_EXCEEDED: stop until period_ends_at or contact us to bump the cap.
  4. On 429 RATE_LIMIT_EXCEEDED: back off for Retry-After seconds with exponential backoff + jitter.
  5. On 422 IDEMPOTENCY_KEY_CONFLICT or 429 IDEMPOTENCY_KEY_EXHAUSTED: pick a new key (the original key is locked to a different payload).

Errors

All billing-related errors follow the standard envelope. Match against the code field, not against title or detail. See Errors for the complete code list.