Overview
The Axiom API is the rule-native HTTP interface for searching, retrieving, explaining, and executing Axiom RuleSpecs — machine-readable encodings of statutes, regulations, and agency policy, with provenance back to the legal source.
| Environment | Base URL |
|---|---|
| Production | https://api.axiom.org |
| Staging | https://api-staging.axiom.org (behind deployment protection) |
https://api.axiom-foundation.org and https://axiom-api-eta.vercel.app are aliases of the same production deployment.
- All endpoints live under
/v1; breaking changes require a new version namespace. - Request and response bodies are JSON. The OpenAPI 3.1 contract is served at
/v1/openapi.jsonwithout a key. - Every response carries an
x-request-idheader; send your own to have it echoed and stamped intometa.request_id. Quote it when reporting issues. - Caching: authenticated
GETreads of rules, programs, variables, the runtime package list, package graphs, root inputs, artifacts, composed graphs, nodes, subgraphs, corpus subtrees, and the certification ledger sendcache-control: private, no-cache. A200from one of them carries a weakETag; send it back asIf-None-Matchand an unchanged response comes back as a304with no body. The docs pages,/v1/openapi.json, and/v1/public/validation/bundledsendpublic, no-cache. Every other response, including calculations, admin routes, and the health, readiness, and version probes, isno-store. - Responses in the standard envelope report the certification mode and ledger they were served under in
meta.certified, except errors from the authentication and rate-limit layer; see Certification.
Quickstart
1 — Get an API key. Issue yourself a trial key — no signup, expires in 14 days, scoped to reads and calculation. Durable keys are issued by Axiom administrators. Store it in a secret manager; the server keeps only a hash.
curl -s -X POST https://api.axiom.org/v1/keys/trial
export AXIOM_API_KEY="axiom_..." # from the response's data.keyexport AXIOM_API_KEY="axiom_..."2 — Discover what is executable. Never hardcode program ids; list the runtime packages and read each package’s inputs, outputs, and ready-to-run sample_request:
curl -s https://api.axiom.org/v1/runtime/packages \
-H "x-api-key: $AXIOM_API_KEY"3 — Calculate. Post a household to /v1/calculate. The response returns outputs for the variables you requested plus a trace attributing every value to the RuleSpec rule that produced it. You can also paste a key into the field in the header above and run every example on this page live with the Try it tab.
Authentication & scopes
All /v1 endpoints except /v1/health, /v1/ready, /v1/version, /v1/openapi.json, /v1/keys/trial, and /v1/public/validation/bundled require an API key, in either header (if both are present, x-api-key wins):
x-api-key: <key>
Authorization: Bearer <key>Every key carries scopes; * passes every check. A key that authenticates but lacks the required scope receives 403 insufficient_scope. A missing, unknown, expired, or revoked key receives 401 unauthorized — the response deliberately does not distinguish those cases.
| Scope | Grants |
|---|---|
rules:read | capabilities, programs, variables, runtime packages and their graphs, root inputs, artifacts, search, rule detail and versions, the certification ledger, node reads, corpus subtrees |
sources:read | rule source references |
graphs:read | rule dependencies, composed graphs, subgraphs |
calculate:run | household calculation: single, batch, and jobs |
compat:policyengine | the PolicyEngine household compatibility endpoint, for migrating partners only |
admin:parity | parity cases and runs |
admin:analytics | usage analytics, monthly usage, validation runs |
admin:keys | key listing, issuance, and runtime revocation; registry reindex; the trial kill switches; the admin audit trail |
admin:audit | certification closure defects |
Any /v1 route not listed defaults to requiring rules:read.
No key yet? Issue yourself a trial key — no signup, 14-day expiry, rules:read + sources:read + graphs:read + calculate:run, 30 requests/minute, and a compute-unit quota (10,000 CU by default). Durable keys and the admin:* scopes are issued by administrators.
Response envelope
Every JSON response uses one envelope. meta.request_id echoes your x-request-id header when provided, otherwise it is a server-generated UUID. meta.environment is one of local, dev, staging, production. meta.certified reports the certification state the response was served under: enforcement (permissive or enforced), certified_set_version (a digest of the ledger entries, empty for a valid ledger with no entries, or invalid:… for a ledger that failed validation), and, when the ledger is valid, its ledger_id and vintage. Errors raised by the authentication and rate-limit layer (like the 401 below) carry only request_id, api_version, and environment. The PolicyEngine-compatible /v1/household/{country_id}/calculate endpoint uses its own envelope, with no meta.
{
"status": "ok",
"data": {
"\u2026": "\u2026"
},
"meta": {
"request_id": "0f1a6c89-be3c-48e5-81ed-b9df5b166d71",
"api_version": "0.1.0",
"environment": "production",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}{
"status": "error",
"error": {
"code": "unauthorized",
"message": "A valid API key is required."
},
"meta": {
"request_id": "c99be9cf-a85b-4590-8045-22232efb79fe",
"api_version": "0.1.0",
"environment": "staging"
}
}An optional data object carries machine-readable detail, e.g. retry_after_seconds on 429s.
Certification
The API serves encoded law as nodes: rules, parameters, inputs, and relations, each with a durable legal id. A certification ledger lists the nodes that carry a certificate. What the ledger controls depends on the deployment’s enforcement mode, permissive or enforced, which its operator sets with AXIOM_CERTIFIED_ENFORCEMENT; any value other than enforced, including none, selects permissive. Responses in the standard envelope report the mode and ledger in meta.certified (see Response envelope for the exceptions), including GET /v1/ready, which needs no key.
This deployment: enforcement: permissive, ledger bootstrap-empty with 0 entries. Uncertified nodes are served, and no node carries a certificate.
permissive (the default): the ledger labels nodes but does not limit what is served. Nodes are served whether or not they are in the ledger, and no request is refused or narrowed for lack of a certificate. Package graphs, /v1/nodes, and /v1/subgraph cover each package’s exercised closure (the dependency closure of its graph roots, or of its default outputs when it declares none), so an encoded node outside it is 404 uncertified_node in this mode whatever the ledger says. A served node that is in the ledger carries its certificate (certificateId on graph rules, certificates on rule details, certificate on node reads, provenance.certificates on calculations). That marks ledger membership only; it says nothing about whether the node’s dependencies are certified. The certified counts on runtime packages, /v1/certified, and closure defects are still computed against the ledger.
enforced: surfaces built on compiled or composed graphs serve a node only if it is in the ledger and so is everything it depends on, transitively (rules, inputs, and relations). They gate each package’s whole compiled graph rather than its exercised closure, so they can serve certified nodes that permissive omits. An input or relation counts as certified only under every spelling of it: its graph node, each execution slot or configured relation behind it, and any relation id a served formula prints (a relation only under the spellings formulas call it by; and a rule whose formula, parameter table or other text prints any uncertified legal id, in a relation call, a string literal or anywhere else, as printed or as a reader sees it, is not served). Requests addressed by root compile their subtree and apply the same check. Rule reads and search check ledger membership only. Per surface:
| Surface | Under enforced |
|---|---|
Package graphs, /v1/nodes, /v1/subgraph | Only servable nodes of the whole compiled graph, with every reference to other nodes removed. A package with nothing servable returns 200 with rules: []. A node id or subgraph root that is not servable is 404 uncertified_node, the same response as an unknown id. |
| Package detail, runtime packages, capabilities | Outputs, default_outputs, graph_roots, and output aliases keep only servable outputs. An entity input slot is kept only when the input it feeds is servable and its own legal id is in the ledger, so an output is never served while a slot feeding it is hidden; an input whose slots show (in their values, default, dtype or entity kind’s name) anything outside the ledger is not servable, and an entity kind whose name prints anything outside the ledger is left out, from the sample request too; configured relations follow the relation they feed. Every shape of the sample_request keeps only served names (facts may also name servable outputs), and household shapes the gate does not know are dropped. Count sources (count_from) and household_aliases drop the names of nodes the package withholds; request vocabulary that names no node stays. |
/v1/graph/compose | Rules that are not servable are removed, and certified.withheld_count counts them. A rule focus that is not itself servable, or a file focus none of whose own rules is servable, is 404 uncertified_node. |
/v1/calculate, batch, jobs | A package calculation that names any output that is not servable is refused whole with 422 uncertified_node; batch and job entries fail individually, inside a 200 or 202 response. Without variables, only servable default outputs are computed, and the request is refused if there are none. Requests addressed by root get the same check over their compiled subtree, run on the subtree as encoded, so a caller fact that pins a rule does not change what is servable. Under enforced a root serves something when any output of its subtree is servable (a #rule root, only when that rule is the root file’s own and servable), a root that serves nothing refuses every output, and warnings announce only pins of servable rules. Under enforced an unknown #rule root answers exactly as a withheld one. On package calculations caller-supplied household.relations pass only when served (an unknown and a withheld relation are both dropped); root calculations refuse an unknown and a withheld relation alike with 400 invalid_household. Text the rules engine writes is served only where it names nothing withheld, read the way the gate reads what a rule prints: an error message that prints a legal id outside the nodes the package or root serves, or text no ledger can hold, is replaced by a generic message with the same code; trace steps and warnings that print one are dropped, as are trace steps whose rule, variable or dependency is the name of a withheld node; and a result whose output values or runtime id print one is refused with runtime_error (502 here, per entry in batches and jobs). |
/v1/variables and variable-addressed /v1/calculate | Package rows come from the gated package detail. A row served from a corpus root appears only when that root’s compiled subtree serves the output, and then carries the rule’s own legal id; a root that cannot be fetched or compiled right now is left out and checked again after a minute, and the whole catalog is gated afresh every ten minutes (a re-encode can change a root’s closure without the ledger rotating). Rows answered from the request itself (legal_id: null) remain. Variable-addressed calculations dispatch through this catalog, so a withheld variable is reported exactly like an unknown one. |
/v1/runtime/root-inputs | Only the input slots a servable rule of the subtree reads, under the slot rule above. A root that serves nothing (under the rule in the calculate row above) is 404 uncertified_node. |
| Household compatibility | Outputs that are not servable are listed as unsupported (“does not compute this variable yet”), whether a runtime package or a corpus root computes them, and the request returns 422 with axiom.code: "uncertified_node" only when a package or root it needs has no servable output. For a corpus root, the translated request sends and echoes only served input slots and pins only servable rules, even when the root serves no slot at all, and the served catalogs and the calculation read one snapshot of the mirror. For a runtime package, the native_request and assumptions echoes omit the names of nodes the package withholds (the engine still receives every fact), and axiom.warnings says when they did. A refusal names the PolicyEngine variables asked for, not the Axiom symbols they translate to. |
/v1/search, /v1/rules/*, /v1/programs | A rule entry is served only with its symbols that are in the ledger (no closure check) and returns 404 not_found if it has none. Version formula text is withheld (formula_withheld), dependency lists keep only served rules, and programs with no served rules are omitted. Under enforced, a summary is withheld (summary_withheld) if it prints an identifier-shaped token that is not one of that rule’s served names, or a legal id that is not one of its served ids, compared exactly as spelled. A name token is a run of ASCII letters, digits and underscores and of the characters Unicode’s confusables data maps to them, including any joiners between them (characters that are neither those nor separators: combining marks, symbols, invisible characters); it is identifier-shaped when it can be read with an underscore, or with a digit and a letter, excluding English numeric ordinals. A token holding a look-alike or a joiner is never a served name. Names are read as printed and as decoded, each also with HTML tags and comments removed as a best effort; clients render summaries as plain text. Legal ids use the shared printed-reference reader and must identify this rule’s served symbols. Plain words, numbers and punctuation remain prose. This check uses only the source summary and that rule’s served names and ids, treating an unserved identifier alike whether its definition is withheld or missing. A withheld symbol can still appear as ordinary prose when its name is spelled as a plain word, a pure number or an ordinal, when an accented letter joins its parts, or when a renderer assembles it from Markdown or HTML; this cannot reveal whether that symbol exists. Search returns a module only when the query matches what is served of it, excluding withheld summary text. |
/v1/parity/cases, /v1/parity/run | A case is listed and run only when every output it requests, expects, traces, pins, or compares against an external engine (each comparison’s mapped and traced Axiom variables) is servable, no input name in its household names a withheld node, and every legal id it cites, in the case and in its latest external results, read the way the gate reads what a rule prints, is a served node. Other cases are omitted from both routes, not reported as skipped. A run’s error message, calculation_trace and warnings follow the calculate row’s rule for engine text. |
| Not gated, by design | Under enforced these serve the same as under permissive: /v1/public/validation/bundled (comparison evidence about nodes not yet certified is public by the launch taxonomy, like the pending queue on /v1/certified); /v1/corpus/subtrees (file-level discovery: file ids, not nodes); the static pages /docs, /docs/mcp, and /v1/openapi.json, whose recorded examples name real ids. Root-addressed requests distinguish an unknown file (404 root_not_found), a composition, and a file that does not compile before the gate, as compose distinguishes an unknown focus; rule ids within a file are not distinguishable. |
An empty ledger certifies nothing. Under permissive every package is served, with no certificates; under enforced the API is ready and the surfaces above serve no nodes. A ledger that fails validation (missing file, wrong format, malformed fields or entries, duplicate entries, a synthetic axiom: id, or a fixture ledger in production; an entry’s legal_id is a jurisdiction such as us-ca or uk-isle-of-wight, :, a citation path, which may hold a colon as us-la:statutes/47:297/4 does, #, and the node’s name) also certifies nothing: /v1/certified reports ledger.status: "invalid", and meta.certified.certified_set_version starts with invalid:. Under enforced, /v1/ready then returns 503 not_ready and nothing is served. Under permissive, readiness and serving are unchanged, and calculations carry no provenance.
Errors
| HTTP | error.code | Meaning |
|---|---|---|
| 400 | invalid_request | Malformed JSON, missing/invalid field, or an input over its cap; the message states the exact constraint. |
| 400 | invalid_household | The runtime rejected the household: compiled runtimes validate explicit household.relations entries against the program’s declared relations; the fixture runtime also checks for a missing household size or a negative income. |
| 400 | invalid_root | /v1/runtime/root-inputs got a root that is not a legal id. |
| 401 | unauthorized | Missing, unknown, expired, or revoked API key. |
| 403 | insufficient_scope | Key lacks the required scope; the message names it. |
| 404 | not_found | Unknown rule id, runtime package, key id, or route. |
| 404 | root_not_found | A root-addressed calculation or root inputs request names a root with no encoded module, or a #rule that is not one of that module’s own rules. |
| 409 | key_id_conflict | A key with the requested id already exists (key issuance). |
| 413 | payload_too_large | Body exceeds the byte limit (default 262,144 bytes). |
| 400 | unsupported_parameter | as_of was passed as a query parameter to a route without point-in-time retrieval. Only GET /v1/rules/{rule_id} and GET /v1/rules/{rule_id}/versions accept it (see rule versions). An as_of in a search body is 400 invalid_request. |
| 422 | unsupported_program | No configured runtime package matches program_id/jurisdiction. |
| 422 | composition_root | A root-addressed request names a composition module. Compositions assemble programs; they are not run by root. |
| 422 | composition_in_closure | The root’s import closure includes a composition module. |
| 422 | closure_incomplete | A module the root imports is missing from the encoding mirror. |
| 422 | closure_too_large | The root’s import closure exceeds 120 modules. |
| 422 | compile_failed | The root’s closure does not compile to an executable program. |
| 404 / 422 | uncertified_node | 404 from /v1/nodes/{node_id} and /v1/subgraph when the id or a root is not a served node (in either mode), and from /v1/graph/compose and /v1/runtime/root-inputs under enforced when the focused rule, or every rule of a focused file, is not servable, or when a root serves nothing. 422 from /v1/calculate under enforced when a requested output, or every default output, is not servable (package- and root-addressed alike); batch and job entries report it per entry. See Certification. |
| 429 | rate_limited | Per-key rate limit exceeded. |
| 429 | auth_throttled | Too many failed authentication attempts from your client. |
| 429 | quota_exhausted | The key’s compute-unit quota is used up. |
| 429 | capacity_exhausted | A trial-key calculation found the compute-unit capacity shared by all trial keys used up for the day or month. |
| 500 | internal_error | Unexpected server error; message is always generic — quote meta.request_id. |
| 502 | runtime_error | The calculation engine failed or timed out. Under enforced, an engine message that names something the deployment does not serve is replaced by a generic message, and a result that would print one is refused with this code (see Certification). |
| 503 | not_ready | From /v1/ready: a dependency is unavailable, or degraded without failing open (see readiness). Also returned by endpoints that read the rulespec mirror (composed graphs, corpus subtrees, root inputs, root-addressed calculations) when none is configured. |
| 503 | auth_not_configured | API-key auth required but no keys configured server-side. |
| 503 | store_unavailable | The shared store was unreachable for an operation that needs it: verifying a registry-issued key (on any route), an admin operation, a global analytics read, submitting or polling a job, persisting a new trial key (and, in production, minting one without a distributed store), or the quota check on a trial-key calculation. |
| 503 | trial_disabled | An operator has switched off trial-key traffic. |
| 503 | minting_disabled | Self-service trial keys are off in this environment, or an operator has paused minting. |
| 503 | audit_unavailable | An admin action (registry reindex, kill switch) took effect, but its audit entry did not persist. |
{
"status": "error",
"error": {
"code": "invalid_request",
"message": "`query` must be at least 2 characters."
},
"meta": {
"request_id": "030c92ec-78bd-4f06-a761-b106c7940c61",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}From POST /v1/search with {"query":"x"}: one character violates the two-character minimum.
External comparison diagnostics
GET /v1/parity/cases can return HTTP 200 with an errored external comparison. These codes occur in external_comparisons[].latest_result.error.code, or latest_result.last_attempt.error.code when a failed attempt retains an earlier result. They describe that comparison, not a top-level API failure.
| Diagnostic code | Meaning |
|---|---|
axiom_run_unavailable | The production parity response was unavailable. |
axiom_case_skipped | The parity run returned no result for the case, including when its package was unavailable. |
declaration_unverified | The parity run did not report the comparison declaration fingerprint. |
declaration_mismatch | The parity run measured a different declaration from the pinned corpus. |
axiom_case_errored | The Axiom parity case errored. |
axiom_case_drifted | The Axiom parity case did not match its expected outputs. |
axiom_known_deviation | The Axiom case has a tracked known deviation and was not compared with another engine. |
unsupported_version | No endpoint is configured for the requested external engine or version. |
engine_unreachable | The external engine request failed or timed out. |
engine_http_error | The external engine returned a non-success HTTP status, recorded in http_status. |
engine_invalid_result | The external engine returned invalid JSON, an invalid result object, or a non-ok body status. |
engine_identity_missing | The external engine response did not identify its model. |
missing_value | The comparison has no mappings or lacks a numeric value on either side. |
Rate limits & throttling
Per-key rate limits. Each key has a fixed-window limit (default 120 requests / 60 s; per-key overrides set at issuance), shared across all API instances. Every response to a request that passes authentication and its scope check includes:
x-ratelimit-limit: 120
x-ratelimit-remaining: 118
x-ratelimit-reset: 1782941434x-ratelimit-reset is a Unix timestamp (seconds) for the end of the current window. Exceeding the limit returns 429 rate_limited with a retry-after header and data.retry_after_seconds. Back off until the window resets.
Failed-auth throttling. After 20 failed authentication attempts within 300 seconds from one client (first x-forwarded-for hop), every further request from that client that presents a key — valid or not — receives 429 auth_throttled until the window expires. Requests that present no key get 401 and are neither counted nor throttled, public routes are never throttled, and successful authentication never counts toward the throttle.
Compute-unit quotas. A key can carry a compute-unit (CU) quota: trial keys get 10,000 CU by default, and administrators can set quota_cu when issuing a key. Every authenticated request costs 1 CU, and every engine run 5 CU more by default. POST /v1/calculate charges its run up front, and a batch or job of n entries charges 5n up front, so a spent quota refuses them with 429 quota_exhausted before anything runs. Other engine runs (PolicyEngine household compatibility, parity runs, and any further runs a variable-addressed calculation needs) are charged as each one starts, and a refused charge fails that run with runtime_error. Responses to a key with a quota carry x-quota-limit and x-quota-remaining. The quota is not a rate: it resets only when its counter expires, one day after the key does (15 days after first use for a key with no expiry). Trial keys also share a capacity, by default 200,000 CU per UTC day and 2,000,000 CU per month across all trial traffic. A trial calculation refused for capacity during authentication or its upfront reservation gets 429 capacity_exhausted before execution. If capacity is exhausted at a later engine run, a native variable-addressed calculation can return a partial HTTP 200 result with the refused variable marked unsupported and reason capacity_exhausted; household compatibility instead returns HTTP 502 with runtime_error and message capacity_exhausted.
Request limits & CORS
| Limit | Value | On violation |
|---|---|---|
| Request body size | 262,144 bytes (256 KiB) | 413 payload_too_large |
query length | 2–500 characters | 400 invalid_request |
program_id, jurisdiction | ≤ 120 characters | 400 invalid_request |
variables | ≤ 100 strings, each ≤ 200 chars | 400 invalid_request |
limit (search) | clamped to 1–50, default 20; must be finite | clamped; non-finite → 400 |
CORS is disabled by default: no access-control-* headers are emitted, so third-party browser origins cannot call the API (this page can — it is served from the same origin). Server-to-server clients are unaffected. Browser use cases require the operators to allowlist your origin; preflights then permit GET/POST with content-type, authorization, x-api-key, and x-request-id, and expose the request-id and rate-limit headers.
Endpoints
Every response example below is a real recorded exchange (values reflect the environment’s configured rule index and runtime; response shapes are stable). With an API key in the header field above, the Try it tab runs each request live against api.axiom.org from this page — same origin, no CORS involved. Keys are kept in session storage only.
GET/v1/healthpublic
Liveness probe: 200 whenever the process serves requests. No dependency checks.
curl -s https://api.axiom.org/v1/healthconst res = await fetch("https://api.axiom.org/v1/health");
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.get(
"https://api.axiom.org/v1/health",
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"service": "axiom-api",
"live": true
},
"meta": {
"request_id": "8fe891e7-aa04-44cd-9838-a395dbf1dc54",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}GET/v1/readypublic
Readiness probe checking every dependency: auth configuration, the shared counter store, the rule index, the calculation runtime, and the certified-ledger, whose detail describes the ledger and, under permissive, says that uncertified nodes are served. data.status is the worst dependency status. data.ready is true when every dependency is ready, and also when each one that is not is degraded with fails_open: true (requests still succeed without it; data.status then reads degraded). The response is 200 when data.ready is true, otherwise 503 not_ready with the same data shape so you can see exactly which dependency is at fault. The certified-ledger dependency is always ready under permissive; under enforced a ledger that fails validation makes it degraded. See Certification.
curl -s https://api.axiom.org/v1/readyconst res = await fetch("https://api.axiom.org/v1/ready");
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.get(
"https://api.axiom.org/v1/ready",
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"ready": true,
"status": "ready",
"source": "static-rulespec-index",
"dependencies": [
{
"name": "auth",
"status": "ready",
"detail": "1 configured API key"
},
{
"name": "counter-store",
"status": "ready",
"detail": "in-memory (per-instance rate limits and analytics)"
},
{
"name": "static-rulespec-index",
"status": "ready",
"detail": "5571 indexed RuleSpec files"
},
{
"name": "compiled-package-runtime",
"status": "ready",
"detail": "6 compiled packages configured"
},
{
"name": "certified-ledger",
"status": "ready",
"detail": "empty ledger (ledger bootstrap-empty); enforcement: permissive — uncertified nodes are served (launch posture)"
}
]
},
"meta": {
"request_id": "1bcb29c1-7c47-435d-bba7-6e8941f012a5",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}GET/v1/versionpublic
Deployed API version and environment.
curl -s https://api.axiom.org/v1/versionconst res = await fetch("https://api.axiom.org/v1/version");
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.get(
"https://api.axiom.org/v1/version",
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"api_version": "0.1.0",
"environment": "local"
},
"meta": {
"request_id": "6330264b-e82b-4f26-85e8-e09751309348",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}GET/v1/public/validation/bundledpublic
The validation snapshot committed with this deployment: the last comparison run, its summary, and the partner demand summary. Read-only and never live — it reads nothing from the shared store, so it answers even when the store is degraded, and it cannot show anything newer than the build. The validation dashboard falls back to it when no viewer key is configured; live runs, analytics and API health stay behind admin:analytics.
curl -s https://api.axiom.org/v1/public/validation/bundledconst res = await fetch("https://api.axiom.org/v1/public/validation/bundled");
const payload = await res.json();
console.log(payload.data.summary);import httpx
payload = httpx.get("https://api.axiom.org/v1/public/validation/bundled").json()
print(payload["data"]["summary"])GET/v1/openapi.jsonpublic
The complete OpenAPI 3.1 document — the canonical machine-readable contract, suitable for client generation. Served without the response envelope.
curl -s https://api.axiom.org/v1/openapi.jsonconst res = await fetch("https://api.axiom.org/v1/openapi.json");
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const spec = await res.json();
console.log(spec.info.version, Object.keys(spec.paths).length);import requests
res = requests.get(
"https://api.axiom.org/v1/openapi.json",
timeout=30,
)
res.raise_for_status()
spec = res.json()
print(spec["info"]["version"], len(spec["paths"]))GET/v1/capabilitiesrules:read
Machine-readable manifest for portals and agents: API version, environment, endpoint map, repository source and program count, the certification ledger (certified_ledger, as on /v1/certified), runtime status, the full package list, and one sample_request per executable package. Poll this instead of hardcoding capabilities.
curl -s https://api.axiom.org/v1/capabilities \
-H "x-api-key: $AXIOM_API_KEY"const res = await fetch("https://api.axiom.org/v1/capabilities", {
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
},
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.get(
"https://api.axiom.org/v1/capabilities",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"api_version": "0.1.0",
"environment": "local",
"openapi_url": "/v1/openapi.json",
"endpoints": {
"programs": "/v1/programs",
"search": "/v1/search",
"rules": "/v1/rules/{rule_id}",
"calculate": "/v1/calculate",
"runtime_packages": "/v1/runtime/packages",
"parity_cases": "/v1/parity/cases",
"parity_run": "/v1/parity/run"
},
"repository": {
"source": "static-rulespec-index",
"status": "ready",
"program_count": 234
},
"certified_ledger": {
"status": "valid",
"ledger_id": "bootstrap-empty",
"issued_at": "2026-07-27T00:00:00Z",
"fixture": false,
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
},
"entry_count": 0,
"certified_set_version": "empty"
},
"runtime": {
"name": "compiled-package-runtime",
"status": "ready",
"detail": "6 compiled packages configured",
"package_count": 6,
"packages": [
{
"program_id": "snap",
"jurisdiction": "us-ny",
"runtime_id": "axiom-rules-engine:us-ny-snap",
"mode": "compiled",
"status": "ready",
"default_outputs": [
"snap_standard_utility_allowance",
"snap_limited_utility_allowance",
"snap_individual_utility_allowance",
"snap_income_limit_exemption_for_categorically_eligible_household",
"snap_standard_deduction",
"snap_maximum_allotment",
"snap_earned_income_deduction_for_net_income",
"snap_excess_medical_deduction_for_net_income",
"snap_minimum_benefit",
"snap_household_residency_eligible",
"snap_resource_eligible",
"snap_full_excess_shelter_deduction_applies",
"snap_standard_gross_income_eligible"
],
"output_count": 172,
"entity_count": 2,
"input_count": 153,
"certified_node_count": 0,
"certified_output_count": 0
},
{
"program_id": "snap",
"jurisdiction": "us-az",
"runtime_id": "axiom-rules-engine:us-az-snap",
"mode": "compiled",
"status": "ready",
"default_outputs": [
"snap_telephone_utility_allowance_eligible",
"az_limited_utility_allowance_amount",
"az_standard_utility_allowance_amount",
"snap_net_income_before_shelter",
"snap_household_has_elderly_or_disabled_member"
],
"output_count": 149,
"entity_count": 2,
"input_count": 134,
"certified_node_count": 0,
"certified_output_count": 0
},
{
"program_id": "snap",
"jurisdiction": "us-ca",
"runtime_id": "axiom-rules-engine:us-ca-snap",
"mode": "compiled",
"status": "ready",
"default_outputs": [
"snap_standard_utility_allowance",
"snap_net_income_limit_100_percent_fpl_48_states_dc",
"snap_maximum_allotment",
"snap_minimum_benefit",
"snap_net_income_before_shelter",
"snap_household_residency_eligible",
"snap_resource_eligible",
"snap_standard_gross_income_eligible"
],
"output_count": 130,
"entity_count": 3,
"input_count": 120,
"certified_node_count": 0,
"certified_output_count": 0
},
{
"program_id": "co-snap",
"jurisdiction": "us-co",
"runtime_id": "axiom-rules-engine:us-co-co-snap",
"mode": "compiled",
"status": "ready",
"default_outputs": [
"household_initial_month",
"snap_initial_month_proration_applies",
"snap_initial_month_proration_factor",
"state_agency_rounds_thirty_percent_net_income_up",
"co_snap_expanded_categorical_gross_income_limit",
"snap_countable_unearned_income",
"household_entitled_to_excess_medical_deduction",
"snap_individual_utility_allowance",
"snap_limited_utility_allowance",
"snap_one_utility_allowance",
"snap_standard_utility_allowance",
"dependent_care_deduction",
"child_support_deduction",
"medical_deduction",
"snap_sponsor_resources_counted",
"snap_liquid_resource_value"
],
"output_count": 429,
"entity_count": 3,
"input_count": 585,
"certified_node_count": 0,
"certified_output_count": 0
},
{
"program_id": "canada-workers-benefit",
"jurisdiction": "ca",
"runtime_id": "axiom-rules-engine:ca-canada-workers-benefit",
"mode": "compiled",
"status": "ready",
"default_outputs": [
"canada_workers_benefit_line_45300",
"canada_workers_benefit_refundable_credit_after_acwb",
"cwb_basic_amount",
"cwb_adjusted_family_net_income"
],
"output_count": 91,
"entity_count": 2,
"input_count": 14,
"certified_node_count": 0,
"certified_output_count": 0
},
{
"program_id": "worker-pit",
"jurisdiction": "be",
"runtime_id": "axiom-rules-engine:be-worker-pit",
"mode": "compiled",
"status": "ready",
"default_outputs": [
"belgium_pit_pilot_federal_and_local_tax_before_withholding",
"belgium_pit_taxable_income",
"belgium_employee_social_security_ordinary_worker_contribution",
"belgium_pit_pilot_worker_net_professional_income",
"belgium_pit_pilot_article_289ter1_low_wage_work_bonus_credit"
],
"output_count": 125,
"entity_count": 2,
"input_count": 7,
"certified_node_count": 0,
"certified_output_count": 0
}
],
"sample_requests": [
{
"program_id": "snap",
"jurisdiction": "us-ny",
"sample_request": {
"program_id": "snap",
"jurisdiction": "us-ny",
"household": {
"entities": {
"Household": {
"household:1": {
"all_household_members_experiencing_homelessness": false,
"child_support_deduction": 0,
"dependent_care_deduction": 0,
"first_full_month_benefit_level": 0,
"homeless_household_free_shelter_all_month": false,
"homeless_household_has_shelter_costs": false,
"household_applies_following_more_than_30_days_not_certified": false,
"household_billed_separately_for_non_telephone_standard_utility": false,
"household_certified_for_participation_in_food_stamp_program": false,
"household_contains_individual_participating_in_more_than_one_household_or_project_area": false,
"household_entitled_to_excess_medical_deduction": false,
"household_entitled_to_heap_or_liheaa_payment": false,
"household_has_earned_income_budgeted_for_snap": false,
"household_has_out_of_pocket_dependent_care_expenses": false,
"household_in_central_meter_housing_charged_only_for_excess_heating_or_cooling": false,
"household_in_project_area_solely_for_vacation": false,
"household_incurred_or_anticipated_basic_service_cost_for_one_telephone": false,
"household_incurred_or_anticipated_heating_or_cooling_costs_separate_from_rent_or_mortgage": false,
"household_initial_month": false,
"household_is_migrant_or_seasonal_farmworker_household": false,
"household_lives_in_application_state": true,
"household_member_disqualified_for_failure_to_comply_with_periodic_reporting_requirements": false,
"household_member_disqualified_for_failure_to_comply_with_work_requirements": false,
"household_member_disqualified_for_intentional_program_violation": false
}
},
"Person": {
"person:1:1": {
"adequate_child_care_unavailable_to_attend_class_and_meet_student_work_requirement": false,
"alaska_subsistence_hunts_or_fishes_30_hours_weekly": false,
"alien_status_documentation_missing_or_unwilling": false,
"assigned_or_placed_in_higher_education_through_qualifying_employment_training_program": false,
"enrolled_at_least_half_time": false,
"enrolled_in_business_technical_trade_or_vocational_school_requiring_high_school_diploma": false,
"enrolled_in_college_or_university_degree_program": false,
"enrolled_through_jobs_or_successor_program": false,
"federal_minimum_wage": 7.25,
"federal_or_state_minimum_wage": 7.25,
"known_student_refused_work_study_assignment": false,
"member_abawd_monthly_work_hours": 0,
"member_abawd_weekly_work_hours": 0,
"member_accepted_bona_fide_suitable_employment_offer_if_offered": true,
"member_age": 30,
"member_age_16_or_17_is_not_household_head_or_attends_school_or_training_half_time": false,
"member_age_24_or_younger_and_was_in_foster_care_on_attaining_age_18": false,
"member_authorized_to_receive_family_assistance_nonemergency_safety_net_or_ssi_benefits_but_not_yet_paid": false,
"member_combines_work_and_work_program_20_hours_weekly": false,
"member_covered_by_abawd_time_limit_waiver": false,
"member_determined_eligible_for_family_assistance_or_nonemergency_safety_net_benefits": false,
"member_family_assistance_nonemergency_safety_net_or_ssi_benefits_suspended_or_being_recouped": false,
"member_family_assistance_or_nonemergency_safety_net_grant_amount": 0,
"member_has_additional_three_month_abawd_eligibility": false
}
}
},
"facts": {
"household_size": 2,
"snap_gross_monthly_income": 1200,
"shelter_costs": 900
},
"period": "2026-01"
},
"variables": [
"snap_standard_utility_allowance",
"snap_limited_utility_allowance",
"snap_individual_utility_allowance",
"snap_income_limit_exemption_for_categorically_eligible_household",
"snap_standard_deduction",
"snap_maximum_allotment",
"snap_earned_income_deduction_for_net_income",
"snap_excess_medical_deduction_for_net_income",
"snap_minimum_benefit",
"snap_household_residency_eligible",
"snap_resource_eligible",
"snap_full_excess_shelter_deduction_applies",
"snap_standard_gross_income_eligible"
]
}
},
{
"program_id": "snap",
"jurisdiction": "us-az",
"sample_request": {
"program_id": "snap",
"jurisdiction": "us-az",
"household": {
"entities": {
"Household": {
"household:1": {
"az_utility_allowance_participant_count": 1,
"budgetary_unit_billed_separately_for_utility_expenses": false,
"budgetary_unit_has_participant_who_is_elderly_or_has_disability": false,
"budgetary_unit_has_verified_allowable_utility_expenses": false,
"budgetary_unit_heating_or_cooling_expenses_exceed_energy_assistance_payments": false,
"budgetary_unit_obligated_to_pay_allowable_utility_expenses": false,
"budgetary_unit_obligated_to_pay_at_least_two_non_heating_or_non_cooling_utility_expenses": false,
"budgetary_unit_obligated_to_pay_heating_or_cooling_expense_separately_from_rent_or_mortgage_on_regular_basis": false,
"budgetary_unit_obligated_to_pay_only_telephone_expense": false,
"budgetary_unit_received_liheap_payment": false,
"household_contains_individual_participating_in_more_than_one_household_or_project_area": false,
"household_entitled_to_excess_medical_deduction": false,
"household_in_project_area_solely_for_vacation": false,
"household_initial_month": false,
"household_lives_in_application_state": true,
"household_shelter_costs_incurred": 0,
"household_size": 1,
"liheap_annual_payment_amount": 0,
"liheap_payment_received_in_application_month_or_lookback_period": false
}
},
"Person": {
"person:1:1": {
"adequate_child_care_unavailable_to_attend_class_and_meet_student_work_requirement": false,
"alaska_subsistence_hunts_or_fishes_30_hours_weekly": false,
"alien_status_documentation_missing_or_unwilling": false,
"assigned_or_placed_in_higher_education_through_qualifying_employment_training_program": false,
"enrolled_at_least_half_time": false,
"enrolled_in_business_technical_trade_or_vocational_school_requiring_high_school_diploma": false,
"enrolled_in_college_or_university_degree_program": false,
"enrolled_through_jobs_or_successor_program": false,
"federal_minimum_wage": 7.25,
"federal_or_state_minimum_wage": 7.25,
"known_student_refused_work_study_assignment": false,
"member_abawd_monthly_work_hours": 0,
"member_abawd_weekly_work_hours": 0,
"member_accepted_bona_fide_suitable_employment_offer_if_offered": true,
"member_age": 30,
"member_age_16_or_17_is_not_household_head_or_attends_school_or_training_half_time": false,
"member_age_24_or_younger_and_was_in_foster_care_on_attaining_age_18": false,
"member_combines_work_and_work_program_20_hours_weekly": false,
"member_covered_by_abawd_time_limit_waiver": false,
"member_has_additional_three_month_abawd_eligibility": false,
"member_has_deportation_or_removal_withheld": false,
"member_has_documentary_or_collateral_evidence_of_ssn_application_or_every_effort": true,
"member_has_eligible_military_connection": false,
"member_is_amerasian_immigrant": false
}
}
},
"facts": {
"budgetary_unit_participant_count": 3,
"na_budgetary_unit_is_eligible": true,
"na_net_income": 1442,
"snap_gross_monthly_earned_income": 1800,
"snap_total_monthly_unearned_income": 0,
"snap_excess_shelter_deduction_for_net_income": 0,
"minimum_na_allotment": 24,
"thrifty_food_plan_amount_for_budgetary_unit_size": 768,
"initial_month_proration_applies": false,
"prorated_initial_month_na_benefit": 0
},
"period": "2026-01"
},
"variables": [
"snap_telephone_utility_allowance_eligible",
"az_limited_utility_allowance_amount",
"az_standard_utility_allowance_amount",
"snap_net_income_before_shelter",
"snap_household_has_elderly_or_disabled_member"
]
}
},
{
"program_id": "snap",
"jurisdiction": "us-ca",
"sample_request": {
"program_id": "snap",
"jurisdiction": "us-ca",
"household": {
"entities": {
"Household": {
"household:1": {
"household_contains_individual_participating_in_more_than_one_household_or_project_area": false,
"household_entitled_to_excess_medical_deduction": false,
"household_has_heating_and_cooling_costs_separate_from_rent_or_mortgage": false,
"household_in_project_area_solely_for_vacation": false,
"household_initial_month": false,
"household_lives_in_application_state": true,
"resident_of_battered_women_and_children_shelter_and_prior_abusive_household_member": false,
"snap_allowable_monthly_child_support_payments": 0,
"snap_allowable_monthly_dependent_care_expenses": 0,
"snap_categorically_eligible_for_resource_exemption": false,
"snap_claimed_homeless_shelter_deduction": 0,
"snap_countable_financial_resources": 0,
"snap_income_exclusions": 0,
"snap_initial_month_prorated_allotment": 0,
"snap_total_medical_expenses": 0,
"snap_total_monthly_unearned_income": 0
}
},
"Person": {
"person:1:1": {
"adequate_child_care_unavailable_to_attend_class_and_meet_student_work_requirement": false,
"alaska_subsistence_hunts_or_fishes_30_hours_weekly": false,
"alien_status_documentation_missing_or_unwilling": false,
"assigned_or_placed_in_higher_education_through_qualifying_employment_training_program": false,
"enrolled_at_least_half_time": false,
"enrolled_in_business_technical_trade_or_vocational_school_requiring_high_school_diploma": false,
"enrolled_in_college_or_university_degree_program": false,
"enrolled_through_jobs_or_successor_program": false,
"federal_minimum_wage": 7.25,
"federal_or_state_minimum_wage": 7.25,
"known_student_refused_work_study_assignment": false,
"member_abawd_monthly_work_hours": 0,
"member_abawd_weekly_work_hours": 0,
"member_accepted_bona_fide_suitable_employment_offer_if_offered": true,
"member_age": 30,
"member_age_16_or_17_is_not_household_head_or_attends_school_or_training_half_time": false,
"member_age_24_or_younger_and_was_in_foster_care_on_attaining_age_18": false,
"member_combines_work_and_work_program_20_hours_weekly": false,
"member_covered_by_abawd_time_limit_waiver": false,
"member_has_additional_three_month_abawd_eligibility": false,
"member_has_deportation_or_removal_withheld": false,
"member_has_documentary_or_collateral_evidence_of_ssn_application_or_every_effort": true,
"member_has_eligible_military_connection": false,
"member_is_amerasian_immigrant": false
}
},
"SnapUnit": {
"household:1": {
"coupon_allotment_table_monthly_allotment_for_household_size_and_net_income": 1
}
}
},
"facts": {
"household_size": 2,
"snap_gross_monthly_earned_income": 1200,
"household_shelter_costs_incurred": 900
},
"period": "2026-01"
},
"variables": [
"snap_standard_utility_allowance",
"snap_net_income_limit_100_percent_fpl_48_states_dc",
"snap_maximum_allotment",
"snap_minimum_benefit",
"snap_net_income_before_shelter",
"snap_household_residency_eligible",
"snap_resource_eligible",
"snap_standard_gross_income_eligible"
]
}
},
{
"program_id": "co-snap",
"jurisdiction": "us-co",
"sample_request": {
"program_id": "co-snap",
"jurisdiction": "us-co",
"household": {
"entities": {
"Household": {
"household:1": {
"accessible_joint_resource_value": 0,
"actual_documented_boarder_room_and_meal_costs": 0,
"actual_reimbursed_non_living_expense": 0,
"all_household_members_are_residents_of_shelter_for_battered_women_and_children": false,
"all_household_members_experiencing_homelessness": false,
"allowable_self_employment_business_costs_for_period": 0,
"annual_contract_income": 0,
"annual_self_employment_income": 0,
"anticipated_capital_gains_next_12_months": 0,
"anticipated_income_amount_reasonably_certain": false,
"anticipated_income_certain_portion": 0,
"anticipated_income_change_requires_adjustment": false,
"anticipated_income_reasonably_certain": false,
"anticipated_income_receipt_month_reasonably_certain": false,
"anticipated_monthly_allowable_self_employment_business_costs": 0,
"anticipated_monthly_self_employment_income": 0,
"anticipated_self_employment_income_for_projection_period": 0,
"applicant_maintains_residence_in_county_or_district_for_purpose_other_than_vacation": false,
"applicant_resides_in_county_or_district_without_permanent_dwelling_or_fixed_mailing_address": false,
"application_date": "2026-01-01",
"assistance_payments": 0,
"available_trust_dividends": 0,
"average_income_per_pay_period": 0,
"average_monthly_child_support_paid": 0,
"average_rental_property_management_hours_per_week": 0
}
},
"Person": {
"person:1:1": {
"abawd_snap_benefit_months_in_36_month_period": 0,
"adequate_child_care_unavailable_to_attend_class_and_meet_student_work_requirement": false,
"alaska_subsistence_hunts_or_fishes_30_hours_weekly": false,
"alien_status_documentation_missing_or_unwilling": false,
"assigned_or_placed_in_higher_education_through_qualifying_employment_training_program": false,
"attending_high_school": false,
"battered_noncitizen_child_or_parent_no_longer_resides_with_abuser": false,
"battered_noncitizen_has_approved_or_pending_qualifying_immigration_petition": false,
"child_earned_income": 0,
"child_lives_with_parent_or_under_parental_control": false,
"child_student_at_least_half_time": false,
"child_turns_18_in_current_month": false,
"child_under_18": false,
"countable_months_measured_within_abawd_calendar_month_period": false,
"dependent_child_age": 0,
"dependent_household_member_age": 0,
"disqualified_for_ipv_or_fraud": false,
"employment_contract_renewable_on_annual_basis": false,
"employment_training_program_accepts_self_initiated_placement": false,
"employment_training_program_has_higher_education_enrollment_component": false,
"enrolled_at_least_half_time": false,
"enrolled_at_least_half_time_in_institution_of_higher_education": false,
"enrolled_full_time_in_school_or_training_program_that_is_not_institution_of_higher_education": false,
"enrolled_in_business_technical_trade_or_vocational_school_requiring_high_school_diploma": false,
"enrolled_in_college_or_university_degree_program": false
}
},
"Payment": {
"household:1": {
"advance_on_wages_reasonably_anticipated": false,
"client_was_receiving_snap_benefits_when_joined_vista": false,
"household_anticipates_receiving_previously_withheld_wages": false,
"household_member_age_years": 0,
"household_member_under_parental_control_of_another_adult_member": false,
"month_is_month_wages_would_otherwise_have_been_paid_by_employer": false,
"payment_amount": 0,
"payment_is_advance_on_wages": false,
"payment_is_allowance_paid_under_wioa": false,
"payment_is_boarder_contribution_to_household_for_shelter_expenses": false,
"payment_is_boarder_direct_payment_to_household_for_room_or_meals": false,
"payment_is_countable_employment_income_received_by_higher_education_student_in_fellowship_with_work_requirement": false,
"payment_is_countable_employment_income_received_by_higher_education_student_in_state_work_study": false,
"payment_is_earnings_from_wioa_on_the_job_training": false,
"payment_is_for_services_as_employee": false,
"payment_is_from_vocational_or_rehabilitation_program_recognized_by_federal_state_or_local_government": false,
"payment_is_garnishment_from_employee_services": false,
"payment_is_government_payment_from_agricultural_stabilization_and_conservation_service": false,
"payment_is_llc_or_s_corporation_owner_regular_earned_income": false,
"payment_is_money_from_rental_or_lease_of_self_employment_property": false,
"payment_is_money_from_sale_of_capital_goods_services_or_property_connected_to_self_employment_enterprise": false,
"payment_is_money_legally_obligated_to_employee_and_diverted_to_third_party_for_employee_household_expenses": false,
"payment_is_pre_strike_or_current_striker_income_selected_under_striker_rule": false,
"payment_is_reimbursement": false,
"payment_is_sick_leave_vacation_or_bonus_pay": false
}
}
},
"facts": {
"household_size": 2,
"snap_gross_monthly_income": 1200,
"shelter_costs": 900
},
"period": "2026-01"
},
"variables": [
"household_initial_month",
"snap_initial_month_proration_applies",
"snap_initial_month_proration_factor",
"state_agency_rounds_thirty_percent_net_income_up",
"co_snap_expanded_categorical_gross_income_limit",
"snap_countable_unearned_income",
"household_entitled_to_excess_medical_deduction",
"snap_individual_utility_allowance",
"snap_limited_utility_allowance",
"snap_one_utility_allowance",
"snap_standard_utility_allowance",
"dependent_care_deduction",
"child_support_deduction",
"medical_deduction",
"snap_sponsor_resources_counted",
"snap_liquid_resource_value"
]
}
},
{
"program_id": "canada-workers-benefit",
"jurisdiction": "ca",
"sample_request": {
"program_id": "canada-workers-benefit",
"jurisdiction": "ca",
"household": {
"entities": {
"Household": {
"household:1": {}
},
"Family": {
"household:1": {
"advanced_canada_workers_benefit_payments_received": 0,
"claimant_is_eligible_for_disability_tax_credit": false,
"has_eligible_dependant": false,
"has_eligible_spouse": false,
"has_eligible_spouse_or_eligible_dependant": false,
"is_alberta_resident": false,
"is_nunavut_resident": false,
"is_quebec_resident": false,
"spouse_adjusted_net_income": 0,
"spouse_is_eligible_for_disability_tax_credit": false,
"spouse_working_income": 0
}
}
},
"facts": {
"claimant_working_income": 9000,
"adjusted_family_net_income": 20000,
"claimant_adjusted_net_income": 20000
},
"period": "2025"
},
"variables": [
"canada_workers_benefit_line_45300",
"canada_workers_benefit_refundable_credit_after_acwb",
"cwb_basic_amount",
"cwb_adjusted_family_net_income"
]
}
},
{
"program_id": "worker-pit",
"jurisdiction": "be",
"sample_request": {
"program_id": "worker-pit",
"jurisdiction": "be",
"household": {
"entities": {
"Household": {
"household:1": {}
},
"Person": {
"person:1:1": {}
}
},
"facts": {
"belgium_pit_article_23_worker_remuneration": 40000,
"belgium_pit_article_466_tax_share_on_nonprofessional_movable_income": 0,
"belgium_pit_article_466bis_hypothetical_total_tax_if_treaty_exempt_foreign_professional_income_were_belgian": 0,
"belgium_pit_article_466bis_treaty_exempt_foreign_professional_income_base_applies": false,
"belgium_pit_communal_additional_tax_rate": 0.06,
"belgium_pit_agglomeration_additional_tax_rate": 0.01,
"belgium_worker_work_bonus_supplied_reference_annual_remuneration": 0
},
"period": "2025"
},
"variables": [
"belgium_pit_pilot_federal_and_local_tax_before_withholding",
"belgium_pit_taxable_income",
"belgium_employee_social_security_ordinary_worker_contribution",
"belgium_pit_pilot_worker_net_professional_income",
"belgium_pit_pilot_article_289ter1_low_wage_work_bonus_credit"
]
}
}
]
}
},
"meta": {
"request_id": "34098a06-cf56-4878-8f6d-ca8961638dcc",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}GET/v1/programsrules:read
Every program with indexed RuleSpecs and per-program rule counts. Appearing here means the program’s rules are searchable; whether it is executable is determined by runtime packages.
curl -s https://api.axiom.org/v1/programs \
-H "x-api-key: $AXIOM_API_KEY"const res = await fetch("https://api.axiom.org/v1/programs", {
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
},
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.get(
"https://api.axiom.org/v1/programs",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"programs": [
{
"id": "co-snap",
"name": "US Co Co SNAP",
"jurisdiction": "us-co",
"description": "RuleSpecs indexed for co-snap in us-co.",
"rule_count": 1,
"status": "available"
}
]
},
"meta": {
"request_id": "4c8c81a4-ed56-4612-b3c4-dbf3fb199fa1",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}Truncated: 233 more program entries omitted.
GET/v1/variablesrules:read
The variables catalog: every output a caller can request and every input a caller can supply, flat and filterable — assembled from the package registry and the mapping registry, never authored. Rows carry name, kind (output|input), entity, dtype, period, jurisdiction, and durable legal_id. Which package or root serves an output is deliberately absent: serving identity is response provenance, not a routing contract. Filters: jurisdiction, kind, q (substring), limit (≤500), offset.
curl -s "https://api.axiom.org/v1/variables?kind=output&jurisdiction=us-co" \
-H "x-api-key: $AXIOM_API_KEY"POST/v1/searchrules:read
Token search over rule ids, citation paths, names, summaries, and symbols. Every whitespace-separated token of two or more characters must match. A search index has no version axis, so as_of is refused: as a query parameter with 400 unsupported_parameter, in the body with 400 invalid_request. Point-in-time retrieval is on rule reads and rule versions.
| Field | Type | Req. | Constraints |
|---|---|---|---|
query | string | yes | 2–500 characters |
jurisdiction | string | no | exact match, e.g. us-az |
program_id | string | no | exact match, e.g. snap |
limit | number | no | clamped 1–50, default 20 |
curl -s -X POST https://api.axiom.org/v1/search \
-H "x-api-key: $AXIOM_API_KEY" \
-H "content-type: application/json" \
-d '{"query": "gross income test", "jurisdiction": "us-az", "limit": 3}'const res = await fetch("https://api.axiom.org/v1/search", {
method: "POST",
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"query": "gross income test",
"jurisdiction": "us-az",
"limit": 3
}),
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.post(
"https://api.axiom.org/v1/search",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
json={
"query": "gross income test",
"jurisdiction": "us-az",
"limit": 3
},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"query": "gross income test",
"results": [
{
"id": "us-az.des_faa5_na_eligibility_and_benefit_determination_gross_income_test",
"citation_path": "us-az/policy/des/faa5/na-eligibility-and-benefit-determination/gross-income-test",
"name": "Faa5 Na Eligibility And Benefit Determination Gross Income Test",
"jurisdiction": "us-az",
"program_id": "snap",
"document_class": "policy",
"status": "encoded",
"source_count": 1
},
{
"id": "us-az.des_faa5_na_eligibility_and_benefit_determination_net_income_test",
"citation_path": "us-az/policy/des/faa5/na-eligibility-and-benefit-determination/net-income-test",
"name": "Faa5 Na Eligibility And Benefit Determination Net Income Test",
"jurisdiction": "us-az",
"program_id": "snap",
"document_class": "policy",
"status": "encoded",
"source_count": 1
},
{
"id": "us-az.des_faa5_ca_benefit_determination_payment_standard_test",
"citation_path": "us-az/policy/des/faa5/ca-benefit-determination/payment-standard-test",
"name": "Faa5 Ca Benefit Determination Payment Standard Test",
"jurisdiction": "us-az",
"program_id": "rulespec",
"document_class": "policy",
"status": "encoded",
"source_count": 1
}
]
},
"meta": {
"request_id": "07ca184d-d348-420b-84d3-2bac12d8ba8d",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}GET/v1/rules/{rule_id}rules:read
One rule by stable rule id (e.g. us-az.des_faa5_…_gross_income_test) or by citation path (e.g. us-az/policy/des/faa5/…/gross-income-test) — both resolve; citation paths contain slashes and work directly in the URL. Includes summary, symbols, dependency edges, and full provenance (repo, path, branch, source release).
curl -s https://api.axiom.org/v1/rules/us-az.des_faa5_na_eligibility_and_benefit_determination_gross_income_test \
-H "x-api-key: $AXIOM_API_KEY"const res = await fetch("https://api.axiom.org/v1/rules/us-az.des_faa5_na_eligibility_and_benefit_determination_gross_income_test", {
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
},
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.get(
"https://api.axiom.org/v1/rules/us-az.des_faa5_na_eligibility_and_benefit_determination_gross_income_test",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"rule": {
"id": "us-az.des_faa5_na_eligibility_and_benefit_determination_gross_income_test",
"citation_path": "us-az/policy/des/faa5/na-eligibility-and-benefit-determination/gross-income-test",
"name": "Faa5 Na Eligibility And Benefit Determination Gross Income Test",
"jurisdiction": "us-az",
"program_id": "snap",
"document_class": "policy",
"status": "encoded",
"source_count": 1,
"summary": "The gross income test is applied in eligibility and benefit determinations at 130% or 185% of FPL. Gross income is all countable income received by the budgetary unit, excluding farm self-employment loss; elderly/disabled units use only the net income test, and categorically eligible units need neither gross nor net income tests.",
"symbols": [
"standard_gross_income_fpl_rate",
"expanded_gross_income_fpl_rate",
"na_gross_income_for_income_test",
"applicable_na_gross_monthly_income_standard",
"na_gross_income_test_required",
"na_gross_income_test_passes",
"na_application_denied_due_to_gross_income_test",
"total_countable_income_received_by_budgetary_unit_excluding_farm_self_employment_loss",
"expanded_gross_income_test_applies",
"federal_poverty_level_for_budgetary_unit_size",
"budgetary_unit_contains_elderly_or_disabled_participant",
"budgetary_unit_is_categorically_eligible"
],
"dependencies": [],
"dependents": [],
"version": "current",
"provenance": {
"rulespec_repo": "rulespec-us-az",
"rulespec_path": "policies/des/faa5/na-eligibility-and-benefit-determination/gross-income-test.yaml",
"rulespec_branch": "main",
"source_release": "current"
}
}
},
"meta": {
"request_id": "fed6a4ed-a881-4546-a35e-8a4cf07f61b6",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}GET/v1/rules/{rule_id}/sourcessources:read
Source and provenance references for one rule: official citations with URLs and quotes where captured, plus the repository reference. Source types are official, derived, or repository.
curl -s https://api.axiom.org/v1/rules/us-az.des_faa5_na_eligibility_and_benefit_determination_gross_income_test/sources \
-H "x-api-key: $AXIOM_API_KEY"const res = await fetch("https://api.axiom.org/v1/rules/us-az.des_faa5_na_eligibility_and_benefit_determination_gross_income_test/sources", {
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
},
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.get(
"https://api.axiom.org/v1/rules/us-az.des_faa5_na_eligibility_and_benefit_determination_gross_income_test/sources",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"rule": {
"id": "us-az.des_faa5_na_eligibility_and_benefit_determination_gross_income_test",
"citation_path": "us-az/policy/des/faa5/na-eligibility-and-benefit-determination/gross-income-test",
"name": "Faa5 Na Eligibility And Benefit Determination Gross Income Test",
"jurisdiction": "us-az",
"program_id": "snap",
"document_class": "policy",
"status": "encoded",
"source_count": 1
},
"sources": [
{
"id": "rulespec:us-az.des_faa5_na_eligibility_and_benefit_determination_gross_income_test",
"citation_path": "us-az/policy/des/faa5/na-eligibility-and-benefit-determination/gross-income-test",
"label": "rulespec-us-az:policies/des/faa5/na-eligibility-and-benefit-determination/gross-income-test.yaml",
"url": "https://github.com/TheAxiomFoundation/rulespec-us-az/blob/main/policies/des/faa5/na-eligibility-and-benefit-determination/gross-income-test.yaml",
"quote": null,
"source_type": "repository"
}
]
},
"meta": {
"request_id": "a84bfee1-800d-4a1d-bdf3-2d4f564e5f3d",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}GET/v1/rules/{rule_id}/dependenciesgraphs:read
Upstream rules this rule depends on (dependencies) and downstream rules that depend on it (dependents), as stable rule ids you can fetch recursively.
curl -s https://api.axiom.org/v1/rules/us-az.des_faa5_na_eligibility_and_benefit_determination_gross_income_test/dependencies \
-H "x-api-key: $AXIOM_API_KEY"const res = await fetch("https://api.axiom.org/v1/rules/us-az.des_faa5_na_eligibility_and_benefit_determination_gross_income_test/dependencies", {
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
},
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.get(
"https://api.axiom.org/v1/rules/us-az.des_faa5_na_eligibility_and_benefit_determination_gross_income_test/dependencies",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"rule": {
"id": "us-az.des_faa5_na_eligibility_and_benefit_determination_gross_income_test",
"citation_path": "us-az/policy/des/faa5/na-eligibility-and-benefit-determination/gross-income-test",
"name": "Faa5 Na Eligibility And Benefit Determination Gross Income Test",
"jurisdiction": "us-az",
"program_id": "snap",
"document_class": "policy",
"status": "encoded",
"source_count": 1
},
"dependencies": [],
"dependents": []
},
"meta": {
"request_id": "0844a77b-4a10-492e-98c7-e016644156ee",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}GET/v1/rules/{rule_id}/versionsrules:read
Every version the RuleSpec module retained for each of its symbols, with the valid-time window, citation, and formula or values of each. as_of (YYYY-MM-DD or YYYY-MM) narrows the list to what was in force on that date, at most one version per symbol; symbol narrows it to one variable. The same as_of works on the rule read.
Read coverage before drawing a conclusion from a short list. symbols_single_version counts symbols with no retained history — their earlier text may never have been encoded, or may have been overwritten in place, and the encoding does not distinguish the two. effective_to_inferred marks an end date read off the next version’s start rather than encoded; versions_with_version_level_source counts versions whose citation is tagged on the version itself — only those can attribute a change to the amendment that made it; and formula_withheld marks text suppressed by the certified-serving gate rather than missing from the encoding. The gate withholds formula text only under enforced (see Certification); under permissive formula_withheld is always false.
curl -s "https://api.axiom.org/v1/rules/us.cbp_us_tariff_duty_composition/versions?symbol=section_122_component_rate&as_of=2026-03-01" \
-H "x-api-key: $AXIOM_API_KEY"const res = await fetch("https://api.axiom.org/v1/rules/us.cbp_us_tariff_duty_composition/versions?symbol=section_122_component_rate&as_of=2026-03-01", {
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
},
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data.timeline);import os
import requests
res = requests.get(
"https://api.axiom.org/v1/rules/us.cbp_us_tariff_duty_composition/versions?symbol=section_122_component_rate&as_of=2026-03-01",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]["timeline"]){
"status": "ok",
"data": {
"rule": {
"id": "us.cbp_us_tariff_duty_composition",
"citation_path": "us/policy/cbp/us-tariff-duty/composition",
"name": "Cbp US Tariff Duty Composition",
"jurisdiction": "us",
"program_id": "rulespec",
"document_class": "policy",
"status": "encoded",
"source_count": 1
},
"as_of": "2026-03-01",
"symbol": "section_122_component_rate",
"versions": [
{
"symbol": "section_122_component_rate",
"kind": "derived",
"dtype": "Rate",
"effective_from": "2026-02-24",
"effective_to": "2026-07-23",
"effective_to_inferred": false,
"source": "Section 122 temporary import surcharge composition under heading 9903.03.01",
"source_level": "rule",
"formula": "if entry_is_line_a or entry_is_line_b: 0\nelse: temporary_import_surcharge_rate",
"formula_withheld": false,
"values": null
}
],
"timeline": [
{
"symbol": "section_122_component_rate",
"versions": [
{
"symbol": "section_122_component_rate",
"kind": "derived",
"dtype": "Rate",
"effective_from": "2026-02-24",
"effective_to": "2026-07-23",
"effective_to_inferred": false,
"source": "Section 122 temporary import surcharge composition under heading 9903.03.01",
"source_level": "rule",
"formula": "if entry_is_line_a or entry_is_line_b: 0\nelse: temporary_import_surcharge_rate",
"formula_withheld": false,
"values": null
}
]
}
],
"coverage": {
"indexed": true,
"symbols": 118,
"versions": 139,
"symbols_with_history": 17,
"symbols_single_version": 101,
"versions_with_version_level_source": 0,
"earliest_effective_from": "2026-02-15",
"latest_effective_from": "2026-08-19"
}
},
"meta": {
"request_id": "c56012b4-8794-4f81-8604-5e06ae3d6080",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}GET/v1/runtime/packagesrules:read
The programs the configured calculation runtime can execute right now. Each entry reports mode (fixture or compiled), status, and default_outputs — the variables returned when a calculate request omits variables.
certified_node_count counts the nodes of the package’s compiled graph that enforced would serve (in the ledger, with a fully certified closure), and certified_output_count the non-alias outputs that resolve to such a node (for a package without a compiled graph, both count the non-alias outputs that are in the ledger). Both are computed against the ledger in either mode, so both are 0 on an empty ledger. Under enforced, default_outputs keeps only servable outputs (see Certification).
curl -s https://api.axiom.org/v1/runtime/packages \
-H "x-api-key: $AXIOM_API_KEY"const res = await fetch("https://api.axiom.org/v1/runtime/packages", {
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
},
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.get(
"https://api.axiom.org/v1/runtime/packages",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"packages": [
{
"program_id": "snap",
"jurisdiction": "us-ny",
"runtime_id": "axiom-rules-engine:us-ny-snap",
"mode": "compiled",
"status": "ready",
"default_outputs": [
"snap_standard_utility_allowance",
"snap_limited_utility_allowance",
"snap_individual_utility_allowance",
"snap_income_limit_exemption_for_categorically_eligible_household",
"snap_standard_deduction",
"snap_maximum_allotment",
"snap_earned_income_deduction_for_net_income",
"snap_excess_medical_deduction_for_net_income",
"snap_minimum_benefit",
"snap_household_residency_eligible",
"snap_resource_eligible",
"snap_full_excess_shelter_deduction_applies",
"snap_standard_gross_income_eligible"
],
"output_count": 172,
"entity_count": 2,
"input_count": 153,
"certified_node_count": 0,
"certified_output_count": 0
},
{
"program_id": "snap",
"jurisdiction": "us-az",
"runtime_id": "axiom-rules-engine:us-az-snap",
"mode": "compiled",
"status": "ready",
"default_outputs": [
"snap_telephone_utility_allowance_eligible",
"az_limited_utility_allowance_amount",
"az_standard_utility_allowance_amount",
"snap_net_income_before_shelter",
"snap_household_has_elderly_or_disabled_member"
],
"output_count": 149,
"entity_count": 2,
"input_count": 134,
"certified_node_count": 0,
"certified_output_count": 0
},
{
"program_id": "snap",
"jurisdiction": "us-ca",
"runtime_id": "axiom-rules-engine:us-ca-snap",
"mode": "compiled",
"status": "ready",
"default_outputs": [
"snap_standard_utility_allowance",
"snap_net_income_limit_100_percent_fpl_48_states_dc",
"snap_maximum_allotment",
"snap_minimum_benefit",
"snap_net_income_before_shelter",
"snap_household_residency_eligible",
"snap_resource_eligible",
"snap_standard_gross_income_eligible"
],
"output_count": 130,
"entity_count": 3,
"input_count": 120,
"certified_node_count": 0,
"certified_output_count": 0
},
{
"program_id": "co-snap",
"jurisdiction": "us-co",
"runtime_id": "axiom-rules-engine:us-co-co-snap",
"mode": "compiled",
"status": "ready",
"default_outputs": [
"household_initial_month",
"snap_initial_month_proration_applies",
"snap_initial_month_proration_factor",
"state_agency_rounds_thirty_percent_net_income_up",
"co_snap_expanded_categorical_gross_income_limit",
"snap_countable_unearned_income",
"household_entitled_to_excess_medical_deduction",
"snap_individual_utility_allowance",
"snap_limited_utility_allowance",
"snap_one_utility_allowance",
"snap_standard_utility_allowance",
"dependent_care_deduction",
"child_support_deduction",
"medical_deduction",
"snap_sponsor_resources_counted",
"snap_liquid_resource_value"
],
"output_count": 429,
"entity_count": 3,
"input_count": 585,
"certified_node_count": 0,
"certified_output_count": 0
},
{
"program_id": "canada-workers-benefit",
"jurisdiction": "ca",
"runtime_id": "axiom-rules-engine:ca-canada-workers-benefit",
"mode": "compiled",
"status": "ready",
"default_outputs": [
"canada_workers_benefit_line_45300",
"canada_workers_benefit_refundable_credit_after_acwb",
"cwb_basic_amount",
"cwb_adjusted_family_net_income"
],
"output_count": 91,
"entity_count": 2,
"input_count": 14,
"certified_node_count": 0,
"certified_output_count": 0
},
{
"program_id": "worker-pit",
"jurisdiction": "be",
"runtime_id": "axiom-rules-engine:be-worker-pit",
"mode": "compiled",
"status": "ready",
"default_outputs": [
"belgium_pit_pilot_federal_and_local_tax_before_withholding",
"belgium_pit_taxable_income",
"belgium_employee_social_security_ordinary_worker_contribution",
"belgium_pit_pilot_worker_net_professional_income",
"belgium_pit_pilot_article_289ter1_low_wage_work_bonus_credit"
],
"output_count": 125,
"entity_count": 2,
"input_count": 7,
"certified_node_count": 0,
"certified_output_count": 0
}
]
},
"meta": {
"request_id": "98717de3-c008-441c-b7de-d0b3c48e983b",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}GET/v1/runtime/packages/{jurisdiction}/{program_id}rules:read
Full executable surface for one package: accepted inputs with dtypes and defaults, all output names, aliases, entities, and a ready-to-post sample_request. Omitted inputs use the defaults listed here. 404 for unknown packages. Note the path order: jurisdiction first.
curl -s https://api.axiom.org/v1/runtime/packages/us-co/co-snap \
-H "x-api-key: $AXIOM_API_KEY"const res = await fetch("https://api.axiom.org/v1/runtime/packages/us-co/co-snap", {
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
},
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.get(
"https://api.axiom.org/v1/runtime/packages/us-co/co-snap",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"package": {
"program_id": "co-snap",
"jurisdiction": "us-co",
"runtime_id": "axiom-rules-engine:us-co-co-snap",
"mode": "compiled",
"status": "ready",
"default_outputs": [
"household_initial_month",
"snap_initial_month_proration_applies",
"snap_initial_month_proration_factor",
"state_agency_rounds_thirty_percent_net_income_up",
"co_snap_expanded_categorical_gross_income_limit",
"snap_countable_unearned_income",
"household_entitled_to_excess_medical_deduction",
"snap_individual_utility_allowance",
"snap_limited_utility_allowance",
"snap_one_utility_allowance",
"snap_standard_utility_allowance",
"dependent_care_deduction",
"child_support_deduction",
"medical_deduction",
"snap_sponsor_resources_counted",
"snap_liquid_resource_value"
],
"output_count": 429,
"entity_count": 3,
"input_count": 585,
"default_period": "2026-01",
"outputs": [
{
"name": "excess_shelter_deduction",
"legal_id": "us-co:policies/cdhs/snap/fy-2026-benefit-calculation#snap_excess_shelter_deduction",
"alias_for": "snap_excess_shelter_deduction"
},
{
"name": "gross_income",
"legal_id": "us:regulations/7-cfr/273/10#snap_total_gross_income",
"alias_for": "snap_total_gross_income"
},
{
"name": "snap_benefit_amount",
"legal_id": "us-co:regulations/10-ccr-2506-1/4.207.2#snap_allotment",
"alias_for": "snap_allotment"
}
],
"entities": [
{
"entity": "Household",
"id_template": "household:1",
"count": 1,
"inputs": [
{
"name": "accessible_joint_resource_value",
"dtype": "decimal",
"default": 0,
"legal_id": "us-co:regulations/10-ccr-2506-1/4.409#input.accessible_joint_resource_value"
},
{
"name": "actual_documented_boarder_room_and_meal_costs",
"dtype": "decimal",
"default": 0,
"legal_id": "us-co:regulations/10-ccr-2506-1/4.403.2#input.actual_documented_boarder_room_and_meal_costs"
}
]
},
{
"entity": "Person",
"id_template": "person:1:{index}",
"count_from": "household_size",
"inputs": [
{
"name": "abawd_snap_benefit_months_in_36_month_period",
"dtype": "decimal",
"default": 0,
"legal_id": "us-co:regulations/10-ccr-2506-1/4.411#input.abawd_snap_benefit_months_in_36_month_period"
},
{
"name": "adequate_child_care_unavailable_to_attend_class_and_meet_student_work_requirement",
"dtype": "bool",
"default": false,
"legal_id": "us:regulations/7-cfr/273/5#input.adequate_child_care_unavailable_to_attend_class_and_meet_student_work_requirement"
}
],
"relations": [
{
"name": "us:statutes/7/2012/j#relation.member_of_household",
"tuple": [
"person:1:{index}",
"household:1"
]
}
]
},
{
"entity": "Payment",
"id_template": "household:1",
"count": 1,
"inputs": [
{
"name": "advance_on_wages_reasonably_anticipated",
"dtype": "bool",
"default": false,
"legal_id": "us-co:regulations/10-ccr-2506-1/4.403#input.advance_on_wages_reasonably_anticipated"
},
{
"name": "client_was_receiving_snap_benefits_when_joined_vista",
"dtype": "bool",
"default": false,
"legal_id": "us-co:regulations/10-ccr-2506-1/4.403#input.client_was_receiving_snap_benefits_when_joined_vista"
}
]
}
],
"output_aliases": {
"snap_benefit_amount": "snap_allotment",
"gross_income": "snap_total_gross_income",
"excess_shelter_deduction": "snap_excess_shelter_deduction"
},
"graph_roots": [
"household_initial_month",
"snap_initial_month_proration_applies",
"snap_initial_month_proration_factor"
],
"sample_request": {
"program_id": "co-snap",
"jurisdiction": "us-co",
"household": {
"entities": {
"Household": {
"household:1": {
"accessible_joint_resource_value": 0,
"actual_documented_boarder_room_and_meal_costs": 0
}
},
"Person": {
"person:1:1": {
"abawd_snap_benefit_months_in_36_month_period": 0,
"adequate_child_care_unavailable_to_attend_class_and_meet_student_work_requirement": false
}
},
"Payment": {
"household:1": {
"advance_on_wages_reasonably_anticipated": false,
"client_was_receiving_snap_benefits_when_joined_vista": false
}
}
},
"facts": {
"household_size": 2,
"snap_gross_monthly_income": 1200,
"shelter_costs": 900
},
"period": "2026-01"
},
"variables": [
"household_initial_month",
"snap_initial_month_proration_applies",
"snap_initial_month_proration_factor",
"state_agency_rounds_thirty_percent_net_income_up",
"co_snap_expanded_categorical_gross_income_limit",
"snap_countable_unearned_income",
"household_entitled_to_excess_medical_deduction",
"snap_individual_utility_allowance",
"snap_limited_utility_allowance",
"snap_one_utility_allowance",
"snap_standard_utility_allowance",
"dependent_care_deduction",
"child_support_deduction",
"medical_deduction",
"snap_sponsor_resources_counted",
"snap_liquid_resource_value"
]
},
"artifact": {
"id": "unpinned:us-co-snap.direct",
"sha256": "699cc667166f3588c8da0248107e3759dec59e65abec7466606b64e1a7e00883",
"corpus_sha": null,
"release_tag": null,
"pinned": false
}
}
},
"meta": {
"request_id": "deddf705-05ac-4ce8-8a64-ed492472adb7",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}Truncated: 429 more outputs, 37 more graph roots, 336 more Household inputs, 215 more Person inputs, 28 more Payment inputs, 23 more sample_request inputs for household:1, 23 more sample_request inputs for person:1:1, and 23 more sample_request inputs for household:1 omitted.
GET/v1/runtime/packages/{jurisdiction}/{program_id}/graphrules:read
The program’s rule dependency graph (a DAG) derived from the compiled artifact: every derived and parameter rule with its formula and dependency edges, the inputs and relations it reads, and the terminalOutputs that nothing else consumes. Built for visualizing how outputs are computed. 404 when no compiled graph exists for the package.
Rule nodes carry certificationStatus, plus certificateId when the node is in the ledger. Under permissive the graph is the dependency closure of the package’s graph roots (its default outputs when it declares none), uncertified rules included. Under enforced it is the servable part of the whole compiled graph, not pruned to the graph roots, so it can include certified rules that the permissive graph omits; a package with nothing servable returns 200 with rules: [].
curl -s https://api.axiom.org/v1/runtime/packages/us-co/co-snap/graph \
-H "x-api-key: $AXIOM_API_KEY"const res = await fetch("https://api.axiom.org/v1/runtime/packages/us-co/co-snap/graph", {
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
},
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.get(
"https://api.axiom.org/v1/runtime/packages/us-co/co-snap/graph",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"graph": {
"rules": [
{
"legalId": "us:policies/usda/snap/fy-2026-cola/maximum-allotments#snap_maximum_allotment",
"name": "snap_maximum_allotment",
"fileLegalId": "us:policies/usda/snap/fy-2026-cola/maximum-allotments",
"kind": "derived",
"entity": "Household",
"dtype": "decimal",
"period": "Month",
"unit": "USD",
"source": "USDA SNAP FY 2026 maximum allotments and deductions",
"sourceUrl": null,
"ruleDeps": [
"us:policies/usda/snap/fy-2026-cola/maximum-allotments#snap_maximum_allotment_additional_member",
"us:policies/usda/snap/fy-2026-cola/maximum-allotments#snap_maximum_allotment_table"
],
"inputDeps": [
"us-co:policies/cdhs/snap/fy-2026-benefit-calculation#input.household_size"
],
"relationDeps": [],
"formula": "(snap_maximum_allotment_table[max(min(household_size, 8), 1)]) + ((max((household_size - 8), 0) * snap_maximum_allotment_additional_member[0]))",
"certificationStatus": "encoded"
},
{
"legalId": "us:policies/usda/snap/fy-2026-cola/maximum-allotments#snap_one_person_thrifty_food_plan_cost",
"name": "snap_one_person_thrifty_food_plan_cost",
"fileLegalId": "us:policies/usda/snap/fy-2026-cola/maximum-allotments",
"kind": "derived",
"entity": "Household",
"dtype": "decimal",
"period": "Month",
"unit": "USD",
"source": "USDA SNAP FY 2026 maximum allotments and deductions",
"sourceUrl": null,
"ruleDeps": [
"us:policies/usda/snap/fy-2026-cola/maximum-allotments#snap_maximum_allotment_table"
],
"inputDeps": [],
"relationDeps": [],
"formula": "snap_maximum_allotment_table[1]",
"certificationStatus": "encoded"
}
],
"inputs": [
{
"legalId": "us-co:policies/cdhs/snap/fy-2026-benefit-calculation#input.adequate_child_care_unavailable_to_attend_class_and_meet_student_work_requirement",
"name": "adequate_child_care_unavailable_to_attend_class_and_meet_student_work_requirement",
"fileLegalId": "us-co:policies/cdhs/snap/fy-2026-benefit-calculation",
"sample": null,
"entity": "Person",
"relationLegalId": "us:statutes/7/2012/j#relation.member_of_household"
},
{
"legalId": "us-co:policies/cdhs/snap/fy-2026-benefit-calculation#input.alaska_subsistence_hunts_or_fishes_30_hours_weekly",
"name": "alaska_subsistence_hunts_or_fishes_30_hours_weekly",
"fileLegalId": "us-co:policies/cdhs/snap/fy-2026-benefit-calculation",
"sample": null,
"entity": "Person",
"relationLegalId": "us:statutes/7/2012/j#relation.member_of_household"
}
],
"relations": [
{
"legalId": "us:statutes/7/2012/j#relation.member_of_household",
"name": "member_of_household",
"fileLegalId": "us:statutes/7/2012/j",
"memberInputIds": [
"us-co:policies/cdhs/snap/fy-2026-benefit-calculation#input.adequate_child_care_unavailable_to_attend_class_and_meet_student_work_requirement",
"us-co:policies/cdhs/snap/fy-2026-benefit-calculation#input.alaska_subsistence_hunts_or_fishes_30_hours_weekly"
]
}
],
"ownOutputs": [
"us-co:regulations/10-ccr-2506-1/4.207.2#household_initial_month",
"us-co:regulations/10-ccr-2506-1/4.207.2#snap_initial_month_proration_applies",
"us-co:regulations/10-ccr-2506-1/4.207.2#snap_initial_month_proration_factor"
],
"terminalOutputs": []
}
},
"meta": {
"request_id": "b969b0af-c935-423a-9642-44652effbb4f",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}Truncated: 159 more rules, 210 more inputs, 87 more relation member inputs, and 13 more own outputs omitted.
GET/v1/graph/composegraphs:read
Compose a dependency graph on demand for any encoded rule or file — no compiled runtime package required. Pass focus as a file legal id (us:regulations/47-cfr/54/403) or a single rule (us:regulations/47-cfr/54/403#basic_lifeline_support_amount); the API walks RuleSpec imports breadth-first from the focus file and derives edges from formulas. The response carries the same graph shape as the package graph endpoint, plus the files included in the composition and a truncated flag when the import walk hit the file cap. This is a view of the law’s dependency structure, not an executable compilation. 404 when no encoded file exists for the focus; 503 when the encodings mirror is not configured.
The response also carries certified (served, withheld_count), and rule nodes carry certificationStatus, plus certificateId when the node is in the ledger. Under permissive the composition is served whole (withheld_count: 0). Under enforced rules that are not servable are removed with every reference to them, and a rule focus that is not itself servable, or a file focus none of whose own rules is servable, is 404 uncertified_node.
curl -s 'https://api.axiom.org/v1/graph/compose?focus=us:regulations/47-cfr/54/403' \
-H "x-api-key: $AXIOM_API_KEY"const focus = encodeURIComponent("us:regulations/47-cfr/54/403");
const res = await fetch(`https://api.axiom.org/v1/graph/compose?focus=${focus}`, {
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
},
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.get(
"https://api.axiom.org/v1/graph/compose",
params={"focus": "us:regulations/47-cfr/54/403"},
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"graph": {
"rules": [
{
"legalId": "us:regulations/47-cfr/54/403#basic_lifeline_support_amount",
"name": "basic_lifeline_support_amount",
"fileLegalId": "us:regulations/47-cfr/54/403",
"kind": "parameter",
"entity": null,
"dtype": "Money",
"period": null,
"unit": "USD",
"source": "47 CFR 54.403(a)(1)",
"sourceUrl": null,
"ruleDeps": [],
"inputDeps": [],
"relationDeps": [],
"formula": "9.25",
"certificationStatus": "encoded"
},
{
"legalId": "us:regulations/47-cfr/54/403#standalone_voice_lifeline_support_amount",
"name": "standalone_voice_lifeline_support_amount",
"fileLegalId": "us:regulations/47-cfr/54/403",
"kind": "parameter",
"entity": null,
"dtype": "Money",
"period": null,
"unit": "USD",
"source": "47 CFR 54.403(a)(2)",
"sourceUrl": null,
"ruleDeps": [],
"inputDeps": [],
"relationDeps": [],
"formula": "0",
"certificationStatus": "encoded"
},
{
"legalId": "us:regulations/47-cfr/54/403#only_provider_census_block_standalone_voice_support_amount",
"name": "only_provider_census_block_standalone_voice_support_amount",
"fileLegalId": "us:regulations/47-cfr/54/403",
"kind": "parameter",
"entity": null,
"dtype": "Money",
"period": null,
"unit": "USD",
"source": "47 CFR 54.403(a)(2)(v)",
"sourceUrl": null,
"ruleDeps": [],
"inputDeps": [],
"relationDeps": [],
"formula": "5.25",
"certificationStatus": "encoded"
}
],
"inputs": [
{
"legalId": "us:regulations/47-cfr/54/403#carrier_certifies_full_support_pass_through_to_qualifying_low_income_consumer",
"name": "carrier_certifies_full_support_pass_through_to_qualifying_low_income_consumer",
"fileLegalId": "us:regulations/47-cfr/54/403",
"sample": null,
"entity": "EligibleTelecommunicationsCarrier"
},
{
"legalId": "us:regulations/47-cfr/54/403#carrier_has_received_non_federal_regulatory_approvals_needed_for_rate_reduction",
"name": "carrier_has_received_non_federal_regulatory_approvals_needed_for_rate_reduction",
"fileLegalId": "us:regulations/47-cfr/54/403",
"sample": null,
"entity": "EligibleTelecommunicationsCarrier"
}
],
"relations": [],
"ownOutputs": [
"us:regulations/47-cfr/54/403#basic_lifeline_support_amount",
"us:regulations/47-cfr/54/403#standalone_voice_lifeline_support_amount",
"us:regulations/47-cfr/54/403#only_provider_census_block_standalone_voice_support_amount"
],
"terminalOutputs": [
"us:regulations/47-cfr/54/403#basic_lifeline_support_amount",
"us:regulations/47-cfr/54/403#standalone_voice_lifeline_support_amount",
"us:regulations/47-cfr/54/403#only_provider_census_block_standalone_voice_support_amount"
]
},
"files": [
"us:regulations/47-cfr/54/403"
],
"truncated": false,
"certified": {
"served": 10,
"withheld_count": 0
}
},
"meta": {
"request_id": "e9e05250-5fcc-4edc-8b0d-8ab21c5ca371",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}Truncated: 7 more rules, 14 more inputs, 7 more own outputs, and 7 more terminal outputs omitted.
GET/v1/certifiedrules:read
The certification ledger this deployment serves under, and its enforcement mode. Returns enforcement (permissive or enforced); ledger, with its status (valid or invalid), certified_set_version, and entry_count, plus its identity (ledger_id, issued_at, fixture) and vintage (encoding/engine/corpus releases) when valid, or a detail when invalid; the ledger entries (legal_id, certificate_id, claim computed/attested, evidence_sha256), paginated with limit/offset; status_counts, the nodes /v1/nodes serves counted as certified, validated, or encoded (incomplete_by_declaration is a subset of encoded), plus the number of pending rows; and pending, the listed nodes that are not yet encoded.
What the ledger controls depends on the mode (see Certification). Under permissive it labels nodes but does not limit what is served. Under enforced graph-backed surfaces serve only nodes in the ledger whose dependency closure is also certified, while rule reads and search check ledger membership only. An empty ledger certifies nothing: under permissive every package is served, with no certificates; under enforced the API is ready and serves no nodes. A ledger that fails validation reports status: "invalid" here; under enforced it also makes /v1/ready return 503, and nothing is served. Closure defects are not on this surface; see /v1/admin/certified/defects.
curl -s https://api.axiom.org/v1/certified \
-H "x-api-key: $AXIOM_API_KEY"{
"status": "ok",
"data": {
"enforcement": "permissive",
"ledger": {
"status": "valid",
"ledger_id": "bootstrap-empty",
"issued_at": "2026-07-27T00:00:00Z",
"fixture": false,
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
},
"entry_count": 0,
"certified_set_version": "empty"
},
"status_counts": {
"certified": 0,
"validated": 0,
"encoded": 906,
"incomplete_by_declaration": 0,
"pending": 0
},
"pending": [],
"entries": [],
"pagination": {
"total": 0,
"limit": 100,
"offset": 0
}
},
"meta": {
"request_id": "0698e46a-6cdc-45aa-9693-f99359a1804a",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}GET/v1/admin/certified/defectsadmin:audit
Certification closure defects, computed against the ledger in both modes over each runtime package’s whole compiled graph: rules that are in the ledger but whose dependency closure in that graph is not certified. Rows do not name the package, so a rule shared by several packages can appear more than once. Each defect lists the rule’s legal_id, the defect kind (open_closure), and missing_deps, the direct dependencies that block it: ones not in the ledger, rules that are in the ledger but have an open closure themselves, and, for an input or relation whose graph id is in the ledger, the other spellings of it the ledger lacks (execution slot ids, configured relation ids, or relation ids formulas call it by), plus any legal id the rule’s formula, parameter table or other text prints that the ledger lacks. What a rule prints that no ledger can certify (a token in a legal id’s shape, or a relation-call argument showing a # or :, that the ledger’s grammar rejects, as printed or as a reader sees it; a token with an id’s shape anywhere in it once look-alikes (Unicode’s confusables data among them) stand in for its letters, : or #; and text with bidirectional controls or marks) is listed under ungrammatical_ids, present only when non-empty. Under enforced such a rule is left out of the package graph whose closure it fails, though another package’s graph that closes it can still serve it, and rule reads and search check ledger membership only. Under permissive nothing is withheld on its account. Because missing_deps can name uncertified legal ids, this surface is admin-only diagnostics and never part of the serving plane.
curl -s https://api.axiom.org/v1/admin/certified/defects \
-H "x-api-key: $AXIOM_API_KEY"GET/v1/nodes/{node_id}rules:read
The node-native read surface: one node per URL, addressed by its durable legal id. Literal slashes are preserved and # must be percent-encoded as %23 — e.g. /v1/nodes/us:policies/usda/snap/fy-2026-cola/maximum-allotments%23snap_maximum_allotment. Returns the node’s kind (derived/parameter/input/relation), state, typing, formula, dependency ids, and the packages that serve it; its certification status; its certificate, or null when it is not in the ledger; and, when the ledger is valid, the ledger id and vintage.
The nodes served here are those in the graphs the package graph endpoint serves. Under permissive that includes uncertified nodes, as in the example. Any other id, including an unknown one, is 404 uncertified_node. Under enforced only nodes in the ledger with a fully certified closure are served, so an unknown id and an uncertified id get the same 404 — this surface has no existence oracle.
curl -s "https://api.axiom.org/v1/nodes/us:policies/usda/snap/fy-2026-cola/maximum-allotments%23snap_maximum_allotment" \
-H "x-api-key: $AXIOM_API_KEY"{
"status": "ok",
"data": {
"node": {
"legal_id": "us:policies/usda/snap/fy-2026-cola/maximum-allotments#snap_maximum_allotment",
"kind": "derived",
"state": "derived",
"name": "snap_maximum_allotment",
"file_legal_id": "us:policies/usda/snap/fy-2026-cola/maximum-allotments",
"entity": "Household",
"dtype": "decimal",
"period": "Month",
"unit": "USD",
"source": "USDA SNAP FY 2026 maximum allotments and deductions",
"source_url": null,
"formula": "(snap_maximum_allotment_table[max(min(household_size, 8), 1)]) + ((max((household_size - 8), 0) * snap_maximum_allotment_additional_member[0]))",
"deps": {
"rules": [
"us:policies/usda/snap/fy-2026-cola/maximum-allotments#snap_maximum_allotment_additional_member",
"us:policies/usda/snap/fy-2026-cola/maximum-allotments#snap_maximum_allotment_table"
],
"inputs": [
"us-ny:policies/otda/snap/fy-2026-benefit-calculation#input.household_size"
],
"relations": []
},
"packages": [
{
"program_id": "snap",
"jurisdiction": "us-ny"
},
{
"program_id": "snap",
"jurisdiction": "us-ca"
},
{
"program_id": "co-snap",
"jurisdiction": "us-co"
}
]
},
"certification": {
"status": "encoded"
},
"certificate": null,
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
},
"ledger_id": "bootstrap-empty"
},
"meta": {
"request_id": "1fbca1d9-2509-440f-a008-a046c3354388",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}GET/v1/subgraphgraphs:read
The dependency closure reachable from ?roots=a,b (comma-separated node legal ids, at most 20), over the nodes /v1/nodes serves, in the same ProgramGraph shape as the package graph endpoint. Closures are cut at 500 nodes and flagged truncated. Under permissive the closure includes uncertified nodes; under enforced it holds only nodes in the ledger with a fully certified closure.
Every root must be a node /v1/nodes serves; otherwise the request is 404 uncertified_node.
curl -s "https://api.axiom.org/v1/subgraph?roots=us:policies/usda/snap/fy-2026-cola/maximum-allotments%23snap_maximum_allotment" \
-H "x-api-key: $AXIOM_API_KEY"GET/v1/corpus/subtreesrules:read
Provision discovery over the live-synced rulespec mirror: each module classified as a provision against its served YAML, as presence data (target, jurisdiction, bucket), TTL-cached. Compositions, program definitions, and modules whose classification is absent, stale, or unknown are listed under exclusions with a reason. A listed provision is a candidate for root-addressed execution, not a promise that it runs: it still has to compile (see root inputs). The listing reads the same mirror that compile-on-demand execution reads.
GET/v1/runtime/root-inputsrules:read
Typed input catalog for any compile-on-demand subtree: pass ?root=<file legal id> and receive every input slot the compiled closure reads — name, dtype, default, entity, and closed domains where declared. Run panels build their controls from this. Same closure rules as root-addressed calculate: compositions refuse, and the rulespec mirror must be configured (503 otherwise). Under enforced only the slots a servable rule of the subtree reads are listed, and a root whose compiled subtree serves no output (for a #rule root: whose rule is not servable) is 404 uncertified_node (see Certification).
GET/v1/runtime/artifactsrules:read
The reproducibility inventory: every compiled artifact this deployment serves, with its sha256 and — when lock-pinned — the release tag and corpus commit it was built from. Unpinned artifacts (present in the deployment but absent from the artifact lock) report pinned: false and an unpinned: id with null release fields; unknown provenance is surfaced, never invented. Calculation responses carry the same identity in provenance.artifact.
POST/v1/calculatecalculate:run
Execute a program for one household and return requested variables with a full attribution trace.
| Field | Type | Req. | Constraints |
|---|---|---|---|
program_id | string | yes | from runtime packages |
jurisdiction | string | yes | from runtime packages |
household | object | yes | see below |
variables | string[] | no | defaults to the package’s default_outputs |
The household object supports these conventions (all optional; omitted inputs use package defaults):
| Key | Meaning |
|---|---|
people | Household members: {"person_1": {"age": 42}}. Member count can drive entity counts. |
spm_units | Unit-level facts: {"unit_1": {"household_size": 2, "snap_gross_monthly_income": 1200}}. The first unit feeds the package’s input mappings. |
facts | Flat fact overrides matched by the package’s fact mappings and aliases. |
period | Calculation month, "YYYY-MM". Invalid values fall back to the package default. |
entities | Advanced: direct per-entity input overrides keyed by the entity ids from the package detail. |
relations | Advanced: explicit relation membership. By default every person belongs to every relation the program declares; each relation named here instead carries exactly the listed tuples, e.g. {"name": "qualifying_child_of_tax_unit", "tuples": [["household:1", "person_3"]]} (tuples: [] empties it). Parts are instance ids or people keys, in the relation's declared slot order; a tuple that does not fit is refused with 400 invalid_household. |
Facts are matched to the input slots listed by the package detail by name, so use those names. A few common SNAP fact names, such as household_size, snap_gross_monthly_income, shelter_costs, and age, also reach a package’s own slot names where it declares them. Read the response as: outputs holds each requested variable; each trace entry attributes one variable to the RuleSpec rule and sources that produced it; runtime.mode says whether a fixture or compiled package executed; treat non-empty warnings as “not an authoritative determination.” timings breaks the request’s latency into planning, engine, and normalization.
Failure modes: 400 invalid_request (schema), 400 invalid_household (compiled explicit relation validation or fixture household checks), 422 unsupported_program, 422 uncertified_node (enforced only; see Certification), 502 runtime_error, 413 payload_too_large.
When the ledger is valid, a successful response carries provenance: the ledger id, set version, and vintage, the artifact and engine, and certificates for the requested (or default) outputs that are in the ledger. On an empty ledger certificates is [].
curl -s -X POST https://api.axiom.org/v1/calculate \
-H "x-api-key: $AXIOM_API_KEY" \
-H "content-type: application/json" \
-d @- <<'JSON'
{
"program_id": "co-snap",
"jurisdiction": "us-co",
"household": {
"people": {
"person_1": {
"age": 42
},
"person_2": {
"age": 9
}
},
"spm_units": {
"unit_1": {
"household_size": 2,
"snap_gross_monthly_income": 1200,
"shelter_costs": 900
}
}
},
"variables": [
"snap_benefit_amount",
"snap_net_income"
]
}
JSONconst res = await fetch("https://api.axiom.org/v1/calculate", {
method: "POST",
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"program_id": "co-snap",
"jurisdiction": "us-co",
"household": {
"people": {
"person_1": {
"age": 42
},
"person_2": {
"age": 9
}
},
"spm_units": {
"unit_1": {
"household_size": 2,
"snap_gross_monthly_income": 1200,
"shelter_costs": 900
}
}
},
"variables": [
"snap_benefit_amount",
"snap_net_income"
]
}),
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.post(
"https://api.axiom.org/v1/calculate",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
json={
"program_id": "co-snap",
"jurisdiction": "us-co",
"household": {
"people": {
"person_1": {
"age": 42
},
"person_2": {
"age": 9
}
},
"spm_units": {
"unit_1": {
"household_size": 2,
"snap_gross_monthly_income": 1200,
"shelter_costs": 900
}
}
},
"variables": [
"snap_benefit_amount",
"snap_net_income"
]
},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"engine": "axiom",
"runtime": {
"id": "axiom-rules-engine:us-co-co-snap",
"mode": "compiled"
},
"program_id": "co-snap",
"jurisdiction": "us-co",
"outputs": {
"snap_benefit_amount": 478,
"snap_net_income": 226
},
"trace": [
{
"rule_id": "snap_allotment",
"variable": "snap_benefit_amount",
"value": 478,
"sources": [
"us-co:regulations/10-ccr-2506-1/4.207.2#snap_allotment"
]
},
{
"rule_id": "snap_net_income",
"variable": "snap_net_income",
"value": 226,
"sources": [
"us:statutes/7/2014/e/6/A#snap_net_income"
]
}
],
"warnings": [],
"timings": {
"total_ms": 63,
"plan_ms": 2,
"engine_ms": 61,
"normalize_ms": 0,
"engine_ttfb_ms": 60,
"engine_read_ms": 1
},
"provenance": {
"ledger_id": "bootstrap-empty",
"certified_set_version": "empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
},
"artifact": {
"id": "unpinned:us-co-snap.direct",
"sha256": "699cc667166f3588c8da0248107e3759dec59e65abec7466606b64e1a7e00883",
"corpus_sha": null,
"release_tag": null,
"pinned": false
},
"engine": {
"id": "axiom-rules-engine",
"release": "unreleased",
"sha": "c8e8db1f6066d9aea9611505087403f38f0e7e67",
"mode": "compiled"
},
"certificates": []
}
},
"meta": {
"request_id": "3d1b5566-1b75-4915-8bae-e794b71e6ace",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}POST/v1/calculate/batchcalculate:run
Run up to 25 calculations in one synchronous request. Entries execute concurrently; results return positionally — results[i] always corresponds to requests[i], each independently either {"status":"ok","result":…} or {"status":"error","error":{code,message}}. One invalid entry fails the whole request with a positional message (requests[1]: …) before anything executes; runtime failures of individual entries do not.
For more than 25 households, or work you do not want to hold a connection open for, use async jobs.
curl -s -X POST https://api.axiom.org/v1/calculate/batch \
-H "x-api-key: $AXIOM_API_KEY" \
-H "content-type: application/json" \
-d @- <<'JSON'
{
"requests": [
{
"program_id": "co-snap",
"jurisdiction": "us-co",
"household": {
"spm_units": {
"unit_1": {
"household_size": 2,
"snap_gross_monthly_income": 1200,
"shelter_costs": 900
}
}
},
"variables": [
"snap_benefit_amount"
]
},
{
"program_id": "co-snap",
"jurisdiction": "us-co",
"household": {
"spm_units": {
"unit_1": {
"household_size": 4,
"snap_gross_monthly_income": 2100
}
}
},
"variables": [
"snap_benefit_amount"
]
}
]
}
JSONconst res = await fetch("https://api.axiom.org/v1/calculate/batch", {
method: "POST",
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"requests": [
{
"program_id": "co-snap",
"jurisdiction": "us-co",
"household": {
"spm_units": {
"unit_1": {
"household_size": 2,
"snap_gross_monthly_income": 1200,
"shelter_costs": 900
}
}
},
"variables": [
"snap_benefit_amount"
]
},
{
"program_id": "co-snap",
"jurisdiction": "us-co",
"household": {
"spm_units": {
"unit_1": {
"household_size": 4,
"snap_gross_monthly_income": 2100
}
}
},
"variables": [
"snap_benefit_amount"
]
}
]
}),
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.post(
"https://api.axiom.org/v1/calculate/batch",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
json={
"requests": [
{
"program_id": "co-snap",
"jurisdiction": "us-co",
"household": {
"spm_units": {
"unit_1": {
"household_size": 2,
"snap_gross_monthly_income": 1200,
"shelter_costs": 900
}
}
},
"variables": [
"snap_benefit_amount"
]
},
{
"program_id": "co-snap",
"jurisdiction": "us-co",
"household": {
"spm_units": {
"unit_1": {
"household_size": 4,
"snap_gross_monthly_income": 2100
}
}
},
"variables": [
"snap_benefit_amount"
]
}
]
},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"summary": {
"total": 2,
"succeeded": 2,
"failed": 0
},
"results": [
{
"status": "ok",
"result": {
"engine": "axiom",
"runtime": {
"id": "axiom-rules-engine:us-co-co-snap",
"mode": "compiled"
},
"program_id": "co-snap",
"jurisdiction": "us-co",
"outputs": {
"snap_benefit_amount": 478
},
"trace": [
{
"rule_id": "snap_allotment",
"variable": "snap_benefit_amount",
"value": 478,
"sources": [
"us-co:regulations/10-ccr-2506-1/4.207.2#snap_allotment"
]
}
],
"warnings": [],
"timings": {
"total_ms": 106,
"plan_ms": 0,
"engine_ms": 105,
"normalize_ms": 0,
"engine_ttfb_ms": 103,
"engine_read_ms": 1
},
"provenance": {
"ledger_id": "bootstrap-empty",
"certified_set_version": "empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
},
"artifact": {
"id": "unpinned:us-co-snap.direct",
"sha256": "699cc667166f3588c8da0248107e3759dec59e65abec7466606b64e1a7e00883",
"corpus_sha": null,
"release_tag": null,
"pinned": false
},
"engine": {
"id": "axiom-rules-engine",
"release": "unreleased",
"sha": "c8e8db1f6066d9aea9611505087403f38f0e7e67",
"mode": "compiled"
},
"certificates": []
}
}
},
{
"status": "ok",
"result": {
"engine": "axiom",
"runtime": {
"id": "axiom-rules-engine:us-co-co-snap",
"mode": "compiled"
},
"program_id": "co-snap",
"jurisdiction": "us-co",
"outputs": {
"snap_benefit_amount": 556
},
"trace": [
{
"rule_id": "snap_allotment",
"variable": "snap_benefit_amount",
"value": 556,
"sources": [
"us-co:regulations/10-ccr-2506-1/4.207.2#snap_allotment"
]
}
],
"warnings": [],
"timings": {
"total_ms": 98,
"plan_ms": 0,
"engine_ms": 98,
"normalize_ms": 0,
"engine_ttfb_ms": 98,
"engine_read_ms": 0
},
"provenance": {
"ledger_id": "bootstrap-empty",
"certified_set_version": "empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
},
"artifact": {
"id": "unpinned:us-co-snap.direct",
"sha256": "699cc667166f3588c8da0248107e3759dec59e65abec7466606b64e1a7e00883",
"corpus_sha": null,
"release_tag": null,
"pinned": false
},
"engine": {
"id": "axiom-rules-engine",
"release": "unreleased",
"sha": "c8e8db1f6066d9aea9611505087403f38f0e7e67",
"mode": "compiled"
},
"certificates": []
}
}
}
]
},
"meta": {
"request_id": "e49f0d8c-8144-4642-a32b-099b689acef8",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}POST/v1/jobs/calculatecalculate:run
Submit up to 50 calculations as a detached job. Returns 202 immediately with a job_id and status_url; execution proceeds with bounded concurrency and writes progress to the shared store. Job records live for 24 hours. durable: false means the store is per-instance memory and the job may not be pollable across instances — configure the shared store for production job use.
curl -s -X POST https://api.axiom.org/v1/jobs/calculate \
-H "x-api-key: $AXIOM_API_KEY" \
-H "content-type: application/json" \
-d @- <<'JSON'
{
"requests": [
{
"program_id": "co-snap",
"jurisdiction": "us-co",
"household": {
"spm_units": {
"unit_1": {
"household_size": 2,
"snap_gross_monthly_income": 1200,
"shelter_costs": 900
}
}
},
"variables": [
"snap_benefit_amount"
]
},
{
"program_id": "co-snap",
"jurisdiction": "us-co",
"household": {
"spm_units": {
"unit_1": {
"household_size": 4,
"snap_gross_monthly_income": 2100
}
}
},
"variables": [
"snap_benefit_amount"
]
}
]
}
JSONconst res = await fetch("https://api.axiom.org/v1/jobs/calculate", {
method: "POST",
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"requests": [
{
"program_id": "co-snap",
"jurisdiction": "us-co",
"household": {
"spm_units": {
"unit_1": {
"household_size": 2,
"snap_gross_monthly_income": 1200,
"shelter_costs": 900
}
}
},
"variables": [
"snap_benefit_amount"
]
},
{
"program_id": "co-snap",
"jurisdiction": "us-co",
"household": {
"spm_units": {
"unit_1": {
"household_size": 4,
"snap_gross_monthly_income": 2100
}
}
},
"variables": [
"snap_benefit_amount"
]
}
]
}),
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.post(
"https://api.axiom.org/v1/jobs/calculate",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
json={
"requests": [
{
"program_id": "co-snap",
"jurisdiction": "us-co",
"household": {
"spm_units": {
"unit_1": {
"household_size": 2,
"snap_gross_monthly_income": 1200,
"shelter_costs": 900
}
}
},
"variables": [
"snap_benefit_amount"
]
},
{
"program_id": "co-snap",
"jurisdiction": "us-co",
"household": {
"spm_units": {
"unit_1": {
"household_size": 4,
"snap_gross_monthly_income": 2100
}
}
},
"variables": [
"snap_benefit_amount"
]
}
]
},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"job_id": "job_157b4cd8-fd90-4989-a7d9-f3265f3943f8",
"status": "running",
"total": 2,
"status_url": "/v1/jobs/job_157b4cd8-fd90-4989-a7d9-f3265f3943f8",
"durable": false
},
"meta": {
"request_id": "dd186080-e379-4454-baca-e0146267eeac",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}GET/v1/jobs/{job_id}calculate:run
Poll a submitted job. status progresses pending → running → succeeded | failed; completed/total give progress; on success results holds the positional outcomes exactly as batch returns them. Jobs are visible only to the key that created them — unknown and foreign ids are both 404. Poll with backoff (e.g. 500 ms doubling to 5 s).
curl -s https://api.axiom.org/v1/jobs/job_157b4cd8-fd90-4989-a7d9-f3265f3943f8 \
-H "x-api-key: $AXIOM_API_KEY"const res = await fetch("https://api.axiom.org/v1/jobs/job_157b4cd8-fd90-4989-a7d9-f3265f3943f8", {
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
},
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.get(
"https://api.axiom.org/v1/jobs/job_157b4cd8-fd90-4989-a7d9-f3265f3943f8",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"id": "job_157b4cd8-fd90-4989-a7d9-f3265f3943f8",
"status": "succeeded",
"created_at": "2026-10-03T13:20:29.221Z",
"total": 2,
"completed": 2,
"api_key_id": "docs-example",
"started_at": "2026-10-03T13:20:29.222Z",
"results": [
{
"status": "ok",
"result": {
"engine": "axiom",
"runtime": {
"id": "axiom-rules-engine:us-co-co-snap",
"mode": "compiled"
},
"program_id": "co-snap",
"jurisdiction": "us-co",
"outputs": {
"snap_benefit_amount": 478
},
"trace": [
{
"rule_id": "snap_allotment",
"variable": "snap_benefit_amount",
"value": 478,
"sources": [
"us-co:regulations/10-ccr-2506-1/4.207.2#snap_allotment"
]
}
],
"warnings": [],
"timings": {
"total_ms": 108,
"plan_ms": 0,
"engine_ms": 108,
"normalize_ms": 0,
"engine_ttfb_ms": 108,
"engine_read_ms": 0
},
"provenance": {
"ledger_id": "bootstrap-empty",
"certified_set_version": "empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
},
"artifact": {
"id": "unpinned:us-co-snap.direct",
"sha256": "699cc667166f3588c8da0248107e3759dec59e65abec7466606b64e1a7e00883",
"corpus_sha": null,
"release_tag": null,
"pinned": false
},
"engine": {
"id": "axiom-rules-engine",
"release": "unreleased",
"sha": "c8e8db1f6066d9aea9611505087403f38f0e7e67",
"mode": "compiled"
},
"certificates": []
}
}
}
],
"finished_at": "2026-10-03T13:20:29.433Z"
},
"meta": {
"request_id": "0c25b612-64ce-483f-97d7-73c607e8d8e9",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}Truncated: 1 more result omitted.
POST/v1/household/{country_id}/calculatecompat:policyengine
Migration surface — existing PolicyEngine household-API integrations only. This endpoint requires the dedicated compat:policyengine scope, granted only to keys issued for migrating partners; ordinary API keys (including trial keys) receive 403. New integrations should ignore this section entirely and use POST /v1/calculate with native Axiom variables, which carry full trace and legal-source provenance.
Accepts the PolicyEngine v1 wire format — entity groups (people, tax_units, spm_units, families, households, marital_units) whose variables map period keys to values, with null meaning “compute this” — and mirrors the PolicyEngine response envelope (status/message/result), so a migrating partner can switch base URLs without changing client code.
The axiom sidecar reports exactly what happened: computed lists every variable Axiom calculated (with the package used), unsupported lists every requested variable Axiom cannot cover yet with a precise reason (no mapping, no state on the household, or no executable package for the state). Uncovered variables keep their null in result — partial coverage is expected during migration and is measurable per request. native_request is the exact POST /v1/calculate body the request was translated into, which is what a migrating partner moves to, and assumptions lists the screening facts the compatibility layer presumed for the household.
Constraints: only country_id us; axes are rejected with 400; the state is read from households.*.state_code/state_name; bare-year period keys return annual totals (monthly benefits × 12), monthly keys return monthly values. Coverage currently maps snap onto Axiom’s state SNAP packages. See docs/pe-household-compat.md for the migration process and the comparison harness that guards parity.
curl -s -X POST https://api.axiom.org/v1/household/us/calculate \
-H "x-api-key: $AXIOM_API_KEY" \
-H "content-type: application/json" \
-d @- <<'JSON'
{
"household": {
"people": {
"parent": {
"age": {
"2026": 34
},
"employment_income": {
"2026": 18000
}
},
"child": {
"age": {
"2026": 6
}
}
},
"spm_units": {
"spm": {
"members": [
"parent",
"child"
],
"snap": {
"2026": null
}
}
},
"tax_units": {
"tu": {
"members": [
"parent",
"child"
],
"eitc": {
"2026": null
}
}
},
"households": {
"hh": {
"members": [
"parent",
"child"
],
"state_code": {
"2026": "CO"
}
}
}
}
}
JSON{
"status": "ok",
"message": null,
"result": {
"people": {
"parent": {
"age": {
"2026": 34
},
"employment_income": {
"2026": 18000
}
},
"child": {
"age": {
"2026": 6
}
}
},
"spm_units": {
"spm": {
"members": [
"parent",
"child"
],
"snap": {
"2026": 2976
}
}
},
"tax_units": {
"tu": {
"members": [
"parent",
"child"
],
"eitc": {
"2026": null
}
}
},
"households": {
"hh": {
"members": [
"parent",
"child"
],
"state_code": {
"2026": "CO"
}
}
}
},
"axiom": {
"request_id": "03cd9de2-8d39-4703-b9ff-339fdbcf5ab0",
"engine": "axiom",
"runtime": {
"id": "axiom-rules-engine:us-co-co-snap",
"mode": "compiled"
},
"jurisdiction": "us-co",
"package": {
"program_id": "co-snap",
"jurisdiction": "us-co"
},
"targets": [
{
"kind": "package",
"program_id": "co-snap",
"jurisdiction": "us-co",
"period_scope": "fiscal-year",
"program": "us/snap"
}
],
"period": "2026-01",
"computed": [
{
"entity_group": "spm_units",
"entity_id": "spm",
"variable": "snap",
"period": "2026",
"value": 2976
}
],
"unsupported": [
{
"entity_group": "tax_units",
"entity_id": "tu",
"variable": "eitc",
"period": "2026",
"reason": "No Axiom mapping for this variable yet."
}
],
"native_request": {
"program_id": "co-snap",
"jurisdiction": "us-co",
"household": {
"period": "2026-01",
"spm_units": {
"unit_1": {
"household_size": 2,
"snap_gross_monthly_income": 1500,
"shelter_costs": 0,
"dependent_care_expenses_paid": 0
}
},
"entities": {
"Household": {
"household:1": {
"household_lives_in_application_state": true,
"dependent_care_expense_necessary_for_work_or_training": true
}
},
"Person": {
"person:1:1": {
"member_is_us_citizen": true,
"member_registered_for_work_or_registered_by_state": true
},
"person:1:2": {
"member_is_us_citizen": true,
"member_registered_for_work_or_registered_by_state": true
}
}
}
},
"variables": [
"snap_benefit_amount"
]
},
"assumptions": [
{
"entity": "Household",
"input": "household_lives_in_application_state",
"value": true
},
{
"entity": "Household",
"input": "dependent_care_expense_necessary_for_work_or_training",
"value": true
}
],
"timings": {
"total_ms": 189,
"plan_ms": 0,
"engine_ms": 188,
"normalize_ms": 0,
"engine_ttfb_ms": 188,
"engine_read_ms": 0,
"parse_ms": 0,
"translate_ms": 11,
"compute_ms": 189,
"apply_ms": 0,
"handler_ms": 200
},
"warnings": []
}
}Truncated: 6 more native_request inputs for person:1:1, 6 more native_request inputs for person:1:2, and 7 more assumptions omitted.
GET/v1/parity/casesadmin:parity
Canonical parity checks: fixed calculation requests with expected outputs, tolerances, trace variables, and any external-engine comparisons. runtime_supported tells you whether the active runtime can execute each case.
curl -s https://api.axiom.org/v1/parity/cases \
-H "x-api-key: $AXIOM_API_KEY"const res = await fetch("https://api.axiom.org/v1/parity/cases", {
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
},
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.get(
"https://api.axiom.org/v1/parity/cases",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"cases": [
{
"id": "co-snap-us-co-family-1",
"description": "Colorado SNAP canonical two-person household.",
"program_id": "co-snap",
"jurisdiction": "us-co",
"runtime_supported": true,
"variables": [
"snap_benefit_amount",
"snap_net_income"
],
"axiom_request": {
"program_id": "co-snap",
"jurisdiction": "us-co",
"household": {
"period": "2026-01",
"people": {
"person_1": {
"age": 42
},
"person_2": {
"age": 9
}
},
"spm_units": {
"unit_1": {
"household_size": 2,
"snap_gross_monthly_income": 1200,
"shelter_costs": 900
}
}
},
"variables": [
"snap_benefit_amount",
"snap_net_income"
]
},
"expected_axiom_outputs": {
"snap_benefit_amount": 478,
"snap_net_income": 226
},
"trace_variables": [
"gross_income",
"snap_standard_deduction",
"snap_earned_income_deduction",
"snap_net_income_pre_shelter",
"snap_standard_utility_allowance",
"shelter_costs",
"excess_shelter_deduction",
"snap_net_income",
"snap_maximum_allotment",
"snap_household_food_contribution",
"snap_benefit_amount"
],
"notes": [
"Canonical values are monthly. Convenience input shelter_costs is treated as total shelter costs for this Axiom case.",
"Utility allowance outputs are requested separately so client parity tools can identify whether another engine adds them by default.",
"The Colorado corpus-direct composition rounds the excess shelter deduction to whole dollars (floor(x + 0.5) in us:regulations/7-cfr/273/10#snap_excess_shelter_cost as composed for Colorado): excess shelter is 525 and net income 226; the rounding question is tracked in rulespec-us#1167. The PolicyEngine comparison differs by more than this rounding, because PolicyEngine also applies a standard utility allowance this case omits; the comparison's known_difference records both (axiom-api#257)."
],
"external_comparisons": [
{
"id": "co-snap-policyengine-current",
"engine": "policyengine",
"description": "PolicyEngine current comparison for the Colorado SNAP canonical two-person household, January 2026.",
"request": {
"country_id": "us",
"version": "current",
"household": {
"households": {
"household": {
"members": [
"adult",
"child"
],
"state_code_str": {
"2026": "CO"
}
}
},
"people": {
"adult": {
"age": {
"2026": 42
},
"employment_income": {
"2026": 14400
}
},
"child": {
"age": {
"2026": 9
}
}
},
"spm_units": {
"spm_unit": {
"members": [
"adult",
"child"
],
"snap": {
"2026-01": null
},
"snap_net_income": {
"2026-01": null
},
"snap_assets": {
"2026": 0
},
"housing_cost": {
"2026": 10800
},
"snap_standard_utility_allowance": {
"2026-01": null
},
"snap_utility_allowance": {
"2026-01": null
},
"snap_gross_income": {
"2026-01": null
},
"snap_standard_deduction": {
"2026-01": null
},
"snap_earned_income_deduction": {
"2026-01": null
},
"snap_net_income_pre_shelter": {
"2026-01": null
},
"snap_excess_shelter_expense_deduction": {
"2026-01": null
},
"snap_max_allotment": {
"2026-01": null
},
"snap_expected_contribution": {
"2026-01": null
}
}
},
"tax_units": {
"tax_unit": {
"members": [
"adult",
"child"
]
}
}
}
},
"mappings": [
{
"axiom_variable": "snap_benefit_amount",
"external_path": "result.spm_units.spm_unit.snap.2026-01"
},
{
"axiom_variable": "snap_net_income",
"external_path": "result.spm_units.spm_unit.snap_net_income.2026-01"
}
],
"trace_mappings": [
{
"label": "Gross income",
"axiom_variable": "gross_income",
"external_variable": "snap_gross_income",
"external_paths": [
"result.spm_units.spm_unit.snap_gross_income.2026-01"
]
},
{
"label": "Standard deduction",
"axiom_variable": "snap_standard_deduction",
"external_variable": "snap_standard_deduction",
"external_paths": [
"result.spm_units.spm_unit.snap_standard_deduction.2026-01"
]
},
{
"label": "Earned income deduction",
"axiom_variable": "snap_earned_income_deduction",
"external_variable": "snap_earned_income_deduction",
"external_paths": [
"result.spm_units.spm_unit.snap_earned_income_deduction.2026-01"
]
},
{
"label": "Net income before shelter",
"axiom_variable": "snap_net_income_pre_shelter",
"external_variable": "snap_net_income_pre_shelter",
"external_paths": [
"result.spm_units.spm_unit.snap_net_income_pre_shelter.2026-01"
]
},
{
"label": "Utility allowance",
"axiom_variable": "snap_standard_utility_allowance",
"external_variable": "snap_utility_allowance",
"external_paths": [
"result.spm_units.spm_unit.snap_utility_allowance.2026-01"
]
},
{
"label": "Housing cost",
"axiom_variable": "shelter_costs",
"external_variable": "housing_cost",
"external_paths": [
"result.spm_units.spm_unit.housing_cost.2026"
],
"transform": "annual_to_monthly"
},
{
"label": "Excess shelter deduction",
"axiom_variable": "excess_shelter_deduction",
"external_variable": "snap_excess_shelter_expense_deduction",
"external_paths": [
"result.spm_units.spm_unit.snap_excess_shelter_expense_deduction.2026-01"
]
},
{
"label": "Net income",
"axiom_variable": "snap_net_income",
"external_variable": "snap_net_income",
"external_paths": [
"result.spm_units.spm_unit.snap_net_income.2026-01"
]
},
{
"label": "Maximum allotment",
"axiom_variable": "snap_maximum_allotment",
"external_variable": "snap_max_allotment",
"external_paths": [
"result.spm_units.spm_unit.snap_max_allotment.2026-01"
]
},
{
"label": "Expected contribution",
"axiom_variable": "snap_household_food_contribution",
"external_variable": "snap_expected_contribution",
"external_paths": [
"result.spm_units.spm_unit.snap_expected_contribution.2026-01"
]
},
{
"label": "Benefit amount",
"axiom_variable": "snap_benefit_amount",
"external_variable": "snap",
"external_paths": [
"result.spm_units.spm_unit.snap.2026-01"
]
}
],
"notes": [
"PolicyEngine employment_income and housing_cost are annual inputs, so this request sends $14,400 to represent $1,200/month and $10,800 to represent $900/month.",
"Outputs are read for 2026-01, the month the Axiom case computes (household.period). An annual 2026 value divided by 12 is a mean over months whose parameters differ, not this month's amount.",
"The Housing cost trace row compares Axiom's total shelter_costs with PolicyEngine's housing_cost alone; PolicyEngine adds its utility allowance separately (the Utility allowance row)."
],
"tolerance": {
"amount": 0.01
},
"known_difference": {
"issue": "https://github.com/TheAxiomFoundation/axiom-api/issues/257",
"note": "Measured 2026-10-03 at household.api.policyengine.org/us/calculate_demo (policyengine_bundle model_version 2.9.0) for January 2026: PolicyEngine applies a $594 standard utility allowance on top of the $900 housing cost, which raises its excess shelter cost to 1,118.5 (900 + 594 - 751 / 2), and returns a 744 deduction, its cap for the contiguous US from 2025-10-01, against 525 here; net income is 7 against 226 and the benefit 543 against 478. This case treats shelter_costs as total shelter costs with no utility allowance. With PolicyEngine's utility allowance set to 0, a $1 gap remains (477 / 227 against 478 / 226): Axiom rounds the excess shelter deduction to 525 where PolicyEngine returns 524.5 (rulespec-us#1167). The responses are in evidence/co-snap-policyengine-2026-10-03.json.",
"pinned_engine_outputs": {
"snap_benefit_amount": 543,
"snap_net_income": 7
}
},
"latest_result": {
"case_id": "co-snap-us-co-family-1",
"comparison_id": "co-snap-policyengine-current",
"engine": "policyengine",
"declaration_sha256": "18a41ab4e87074620b5d7fc3f4e241e32921e71ec8d75ad9d537453b36f242a0",
"observed_at": "2026-10-09T14:27:47.814Z",
"status": "known_difference",
"engine_version": "2.18.0",
"engine_identity": {
"model_version": "2.18.0",
"data_version": null,
"dataset": null
},
"engine_endpoint": "https://household.api.policyengine.org/us/calculate_demo",
"engine_route": {
"route_channel": "current",
"backend": "modal",
"request_id": "a301c17f-8d62-4943-90ab-5b8c27a539e7"
},
"axiom": {
"base_url": "https://axiom-api-eta.vercel.app",
"observed_at": "2026-10-09T14:27:46.339Z",
"case_status": "matching",
"period": "2026-01",
"identity": {
"artifact_id": "unpinned:us-co-snap.direct",
"artifact_sha256": "699cc667166f3588c8da0248107e3759dec59e65abec7466606b64e1a7e00883",
"engine": "service@c8e8db1f6066d9aea9611505087403f38f0e7e67"
}
},
"tolerance": {
"amount": 0.01
},
"mappings": [
{
"axiom_variable": "snap_benefit_amount",
"external_path": "result.spm_units.spm_unit.snap.2026-01",
"transform": null,
"axiom_value": 478,
"engine_raw_value": 543,
"engine_value": 543,
"delta": 65,
"within_tolerance": false
},
{
"axiom_variable": "snap_net_income",
"external_path": "result.spm_units.spm_unit.snap_net_income.2026-01",
"transform": null,
"axiom_value": 226,
"engine_raw_value": 7,
"engine_value": 7,
"delta": -219,
"within_tolerance": false
}
],
"trace": [
{
"label": "Gross income",
"axiom_variable": "gross_income",
"external_variable": "snap_gross_income",
"axiom_value": 1200,
"engine_value": 1200,
"delta": 0
},
{
"label": "Standard deduction",
"axiom_variable": "snap_standard_deduction",
"external_variable": "snap_standard_deduction",
"axiom_value": 209,
"engine_value": 209,
"delta": 0
},
{
"label": "Earned income deduction",
"axiom_variable": "snap_earned_income_deduction",
"external_variable": "snap_earned_income_deduction",
"axiom_value": 240,
"engine_value": 240,
"delta": 0
},
{
"label": "Net income before shelter",
"axiom_variable": "snap_net_income_pre_shelter",
"external_variable": "snap_net_income_pre_shelter",
"axiom_value": 751,
"engine_value": 751,
"delta": 0
},
{
"label": "Utility allowance",
"axiom_variable": "snap_standard_utility_allowance",
"external_variable": "snap_utility_allowance",
"axiom_value": 0,
"engine_value": 594,
"delta": 594
},
{
"label": "Housing cost",
"axiom_variable": "shelter_costs",
"external_variable": "housing_cost",
"axiom_value": 900,
"engine_value": 900,
"delta": 0
},
{
"label": "Excess shelter deduction",
"axiom_variable": "excess_shelter_deduction",
"external_variable": "snap_excess_shelter_expense_deduction",
"axiom_value": 525,
"engine_value": 744,
"delta": 219
},
{
"label": "Net income",
"axiom_variable": "snap_net_income",
"external_variable": "snap_net_income",
"axiom_value": 226,
"engine_value": 7,
"delta": -219
},
{
"label": "Maximum allotment",
"axiom_variable": "snap_maximum_allotment",
"external_variable": "snap_max_allotment",
"axiom_value": 546,
"engine_value": 546,
"delta": 0
},
{
"label": "Expected contribution",
"axiom_variable": "snap_household_food_contribution",
"external_variable": "snap_expected_contribution",
"axiom_value": 67.8,
"engine_value": 3,
"delta": -64.8
},
{
"label": "Benefit amount",
"axiom_variable": "snap_benefit_amount",
"external_variable": "snap",
"axiom_value": 478,
"engine_value": 543,
"delta": 65
}
],
"known_difference": {
"issue": "https://github.com/TheAxiomFoundation/axiom-api/issues/257",
"note": "Measured 2026-10-03 at household.api.policyengine.org/us/calculate_demo (policyengine_bundle model_version 2.9.0) for January 2026: PolicyEngine applies a $594 standard utility allowance on top of the $900 housing cost, which raises its excess shelter cost to 1,118.5 (900 + 594 - 751 / 2), and returns a 744 deduction, its cap for the contiguous US from 2025-10-01, against 525 here; net income is 7 against 226 and the benefit 543 against 478. This case treats shelter_costs as total shelter costs with no utility allowance. With PolicyEngine's utility allowance set to 0, a $1 gap remains (477 / 227 against 478 / 226): Axiom rounds the excess shelter deduction to 525 where PolicyEngine returns 524.5 (rulespec-us#1167). The responses are in evidence/co-snap-policyengine-2026-10-03.json."
},
"warnings": [],
"error": null,
"last_attempt": null,
"consecutive_errored_attempts": 0
}
}
],
"tolerance": {
"amount": 0.01
},
"known_deviation": null
}
],
"external_results": {
"source": "bundled",
"format": "axiom/parity-external-results/v1",
"generated_at": "2026-10-09T14:27:49.295Z"
}
},
"meta": {
"request_id": "2db2b5b3-61e5-406f-b982-23384defa8a9",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}Truncated: 3 more cases omitted. As recorded on 2026-10-10 from data/parity-external/latest.json (bundled observations generated 2026-10-09T14:27:49.295Z; snapshot SHA-256 e2ec449c350f7c461aa82d2daba99b20db11225a9896b2199aa03b2825166cbb).
POST/v1/parity/runadmin:parity
Execute every runtime-supported parity case and compare against expected outputs. No request body. Returns a summary (total/matching/different/errored/skipped), per-case variable-level diffs, trace outputs, and skipped_cases with reasons. Run after deployments to confirm calculation behavior.
curl -s -X POST https://api.axiom.org/v1/parity/run \
-H "x-api-key: $AXIOM_API_KEY"const res = await fetch("https://api.axiom.org/v1/parity/run", {
method: "POST",
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
},
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.post(
"https://api.axiom.org/v1/parity/run",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"summary": {
"total": 4,
"matching": 4,
"different": 0,
"errored": 0,
"known_deviation": 0,
"skipped": 0
},
"results": [
{
"id": "co-snap-us-co-family-1",
"description": "Colorado SNAP canonical two-person household.",
"program_id": "co-snap",
"jurisdiction": "us-co",
"status": "matching",
"outputs": {
"snap_benefit_amount": 478,
"snap_net_income": 226
},
"expected_outputs": {
"snap_benefit_amount": 478,
"snap_net_income": 226
},
"trace_outputs": {
"gross_income": 1200,
"snap_standard_deduction": 209,
"snap_earned_income_deduction": 240,
"snap_net_income_pre_shelter": 751,
"snap_standard_utility_allowance": 0,
"shelter_costs": 900,
"excess_shelter_deduction": 525,
"snap_net_income": 226,
"snap_maximum_allotment": 546,
"snap_household_food_contribution": 67.8,
"snap_benefit_amount": 478
},
"calculation_trace": [
{
"rule_id": "snap_allotment",
"variable": "snap_benefit_amount",
"value": 478,
"sources": [
"us-co:regulations/10-ccr-2506-1/4.207.2#snap_allotment"
]
},
{
"rule_id": "snap_net_income",
"variable": "snap_net_income",
"value": 226,
"sources": [
"us:statutes/7/2014/e/6/A#snap_net_income"
]
},
{
"rule_id": "snap_total_gross_income",
"variable": "gross_income",
"value": 1200,
"sources": [
"us:regulations/7-cfr/273/10#snap_total_gross_income"
]
},
{
"rule_id": "snap_standard_deduction",
"variable": "snap_standard_deduction",
"value": 209,
"sources": [
"us:policies/usda/snap/fy-2026-cola/deductions#snap_standard_deduction"
]
},
{
"rule_id": "snap_earned_income_deduction",
"variable": "snap_earned_income_deduction",
"value": 240,
"sources": [
"us:statutes/7/2014/e/2#snap_earned_income_deduction"
]
},
{
"rule_id": "snap_net_income_pre_shelter",
"variable": "snap_net_income_pre_shelter",
"value": 751,
"sources": [
"us:statutes/7/2014/e/6/A#snap_net_income_pre_shelter"
]
},
{
"rule_id": "snap_standard_utility_allowance",
"variable": "snap_standard_utility_allowance",
"value": 0,
"sources": [
"us-co:regulations/10-ccr-2506-1/4.407.31#snap_standard_utility_allowance"
]
},
{
"rule_id": "shelter_costs",
"variable": "shelter_costs",
"value": 900,
"sources": [
"us-co:policies/cdhs/snap/fy-2026-benefit-calculation#shelter_costs"
]
},
{
"rule_id": "snap_excess_shelter_deduction",
"variable": "excess_shelter_deduction",
"value": 525,
"sources": [
"us-co:policies/cdhs/snap/fy-2026-benefit-calculation#snap_excess_shelter_deduction"
]
},
{
"rule_id": "snap_maximum_allotment",
"variable": "snap_maximum_allotment",
"value": 546,
"sources": [
"us:policies/usda/snap/fy-2026-cola/maximum-allotments#snap_maximum_allotment"
]
},
{
"rule_id": "snap_household_food_contribution",
"variable": "snap_household_food_contribution",
"value": 67.8,
"sources": [
"us:statutes/7/2017/a#snap_household_food_contribution"
]
}
],
"notes": [
"Canonical values are monthly. Convenience input shelter_costs is treated as total shelter costs for this Axiom case.",
"Utility allowance outputs are requested separately so client parity tools can identify whether another engine adds them by default.",
"The Colorado corpus-direct composition rounds the excess shelter deduction to whole dollars (floor(x + 0.5) in us:regulations/7-cfr/273/10#snap_excess_shelter_cost as composed for Colorado): excess shelter is 525 and net income 226; the rounding question is tracked in rulespec-us#1167. The PolicyEngine comparison differs by more than this rounding, because PolicyEngine also applies a standard utility allowance this case omits; the comparison's known_difference records both (axiom-api#257)."
],
"comparison": {
"status": "matching",
"changed": [],
"missing": [],
"extra": []
},
"known_deviation": null,
"runtime": {
"id": "axiom-rules-engine:us-co-co-snap",
"mode": "compiled"
},
"warnings": [],
"axiom_identity": {
"artifact_id": "unpinned:us-co-snap.direct",
"artifact_sha256": "699cc667166f3588c8da0248107e3759dec59e65abec7466606b64e1a7e00883",
"engine": "service@c8e8db1f6066d9aea9611505087403f38f0e7e67"
},
"external_comparisons": [
{
"id": "co-snap-policyengine-current",
"declaration_sha256": "18a41ab4e87074620b5d7fc3f4e241e32921e71ec8d75ad9d537453b36f242a0"
}
]
},
{
"id": "snap-us-az-family-1",
"description": "Arizona SNAP canonical three-person household in the package's native fact names, including values for two derived rules.",
"program_id": "snap",
"jurisdiction": "us-az",
"status": "matching",
"outputs": {
"snap_benefit_amount": 335.4,
"snap_net_income": 1442,
"snap_gross_monthly_income": 1800,
"snap_eligible": true,
"snap_excess_shelter_deduction": 0
},
"expected_outputs": {
"snap_benefit_amount": 335.4,
"snap_net_income": 1442,
"snap_gross_monthly_income": 1800,
"snap_eligible": true,
"snap_excess_shelter_deduction": 0
},
"trace_outputs": {
"snap_gross_monthly_income": 1800,
"snap_excess_shelter_deduction": 0,
"snap_net_income": 1442,
"snap_maximum_allotment": 298,
"snap_regular_month_allotment": 335.4,
"snap_benefit_amount": 335.4
},
"calculation_trace": [
{
"rule_id": "na_regular_month_allotment",
"variable": "snap_benefit_amount",
"value": 335.4,
"sources": [
"us-az:policies/des/faa5/na-eligibility-and-benefit-determination/fy-2026-benefit-calculation#na_regular_month_allotment"
]
},
{
"rule_id": "na_net_income",
"variable": "snap_net_income",
"value": 1442,
"sources": [
"us-az:policies/des/faa5/na-eligibility-and-benefit-determination/fy-2026-benefit-calculation#na_net_income"
]
},
{
"rule_id": "snap_gross_monthly_income",
"variable": "snap_gross_monthly_income",
"value": 1800,
"sources": [
"us:policies/usda/snap/state-plan-composition#snap_gross_monthly_income"
]
},
{
"rule_id": "snap_eligible",
"variable": "snap_eligible",
"value": true,
"sources": [
"us-az:policies/des/faa5/na-eligibility-and-benefit-determination/fy-2026-benefit-calculation#snap_eligible"
]
},
{
"rule_id": "snap_excess_shelter_deduction",
"variable": "snap_excess_shelter_deduction",
"value": 0,
"sources": [
"us-az:policies/des/faa5/na-eligibility-and-benefit-determination/fy-2026-benefit-calculation#snap_excess_shelter_deduction"
]
},
{
"rule_id": "snap_maximum_allotment",
"variable": "snap_maximum_allotment",
"value": 298,
"sources": [
"us:policies/usda/snap/fy-2026-cola/maximum-allotments#snap_maximum_allotment"
]
},
{
"rule_id": "na_regular_month_allotment",
"variable": "snap_regular_month_allotment",
"value": 335.4,
"sources": [
"us-az:policies/des/faa5/na-eligibility-and-benefit-determination/fy-2026-benefit-calculation#na_regular_month_allotment"
]
}
],
"notes": [
"Canonical values are monthly. This Arizona SNAP case supplies eight input slots of the admitted DES artifact; na_net_income and snap_excess_shelter_deduction_for_net_income name derived rules, which the API's package path pins only when it executes locally (see known_deviation).",
"This case uses the package's native fact names, including thrifty_food_plan_amount_for_budgetary_unit_size (768). The shared SNAP fact vocabulary (household_size, snap_gross_monthly_income, shelter_costs) also reaches this package's input slots, but it does not set the thrifty food plan amount, which otherwise takes the registry's 292 presumption for any household size (axiom-api#248)."
],
"comparison": {
"status": "matching",
"changed": [],
"missing": [],
"extra": []
},
"known_deviation": null,
"runtime": {
"id": "axiom-rules-engine:us-az-snap",
"mode": "compiled"
},
"warnings": [
"Rule na_net_income was pinned to the caller-supplied value for this calculation.",
"Rule snap_excess_shelter_deduction_for_net_income was pinned to the caller-supplied value for this calculation.",
"known_deviation pin is stale: outputs now match expectations; remove the pin (https://github.com/TheAxiomFoundation/axiom-api/issues/243)."
],
"axiom_identity": {
"artifact_id": "unpinned:us-az-snap.direct",
"artifact_sha256": "382cdddc110e196474ec6fdda14a3961f93b69ab677819ff0c82143b31ffbfa7",
"engine": "service@c8e8db1f6066d9aea9611505087403f38f0e7e67"
},
"external_comparisons": []
},
{
"id": "snap-us-ca-family-1",
"description": "California SNAP canonical two-person household on the corpus-direct CDSS composition.",
"program_id": "snap",
"jurisdiction": "us-ca",
"status": "matching",
"outputs": {
"snap_benefit_amount": 478,
"snap_net_income": 226,
"snap_gross_income": 1200
},
"expected_outputs": {
"snap_benefit_amount": 478,
"snap_net_income": 226,
"snap_gross_income": 1200
},
"trace_outputs": {
"snap_gross_income": 1200,
"snap_standard_deduction": 209,
"snap_net_income_before_shelter": 751,
"snap_net_income": 226,
"snap_maximum_allotment": 546,
"snap_benefit_amount": 478
},
"calculation_trace": [
{
"rule_id": "snap_benefit",
"variable": "snap_benefit_amount",
"value": 478,
"sources": [
"us:policies/usda/snap/state-plan-composition#snap_benefit"
]
},
{
"rule_id": "snap_net_monthly_income",
"variable": "snap_net_income",
"value": 226,
"sources": [
"us:regulations/7-cfr/273/10#snap_net_monthly_income"
]
},
{
"rule_id": "snap_gross_monthly_income",
"variable": "snap_gross_income",
"value": 1200,
"sources": [
"us:policies/usda/snap/state-plan-composition#snap_gross_monthly_income"
]
},
{
"rule_id": "snap_standard_deduction",
"variable": "snap_standard_deduction",
"value": 209,
"sources": [
"us:policies/usda/snap/fy-2026-cola/deductions#snap_standard_deduction"
]
},
{
"rule_id": "snap_net_income_before_shelter",
"variable": "snap_net_income_before_shelter",
"value": 751,
"sources": [
"us:regulations/7-cfr/273/10#snap_net_income_before_shelter"
]
},
{
"rule_id": "snap_maximum_allotment",
"variable": "snap_maximum_allotment",
"value": 546,
"sources": [
"us:policies/usda/snap/fy-2026-cola/maximum-allotments#snap_maximum_allotment"
]
}
],
"notes": [
"Canonical values are monthly. Inputs use the package-native slot names (snap_gross_monthly_earned_income, household_shelter_costs_incurred).",
"The California corpus-direct composition rounds the excess shelter deduction to whole dollars, like Colorado: net income is 226 where PolicyEngine keeps cents (226.5). See the Colorado case's rulespec-us#1167 note; the fifty-cent net-income delta does not move the 478 allotment."
],
"comparison": {
"status": "matching",
"changed": [],
"missing": [],
"extra": []
},
"known_deviation": null,
"runtime": {
"id": "axiom-rules-engine:us-ca-snap",
"mode": "compiled"
},
"warnings": [],
"axiom_identity": {
"artifact_id": "unpinned:us-ca-snap.direct",
"artifact_sha256": "fce6fd9f6d842285709e1a2bd8601486acedf65c3862c2e44eb276ce9823d6f2",
"engine": "service@c8e8db1f6066d9aea9611505087403f38f0e7e67"
},
"external_comparisons": []
},
{
"id": "snap-us-ny-family-1",
"description": "New York SNAP canonical two-person household on the corpus-direct OTDA composition.",
"program_id": "snap",
"jurisdiction": "us-ny",
"status": "matching",
"outputs": {
"snap_benefit_amount": 478,
"snap_net_income": 226.5,
"snap_gross_monthly_income": 1200
},
"expected_outputs": {
"snap_benefit_amount": 478,
"snap_net_income": 226.5,
"snap_gross_monthly_income": 1200
},
"trace_outputs": {
"snap_gross_monthly_income": 1200,
"snap_standard_deduction": 209,
"snap_excess_shelter_deduction_for_net_income": 525,
"snap_net_income": 226.5,
"snap_maximum_allotment": 546,
"snap_benefit_amount": 478
},
"calculation_trace": [
{
"rule_id": "snap_benefit",
"variable": "snap_benefit_amount",
"value": 478,
"sources": [
"us:policies/usda/snap/state-plan-composition#snap_benefit"
]
},
{
"rule_id": "snap_net_income",
"variable": "snap_net_income",
"value": 226.5,
"sources": [
"us:statutes/7/2014/e/6/A#snap_net_income"
]
},
{
"rule_id": "snap_gross_monthly_income",
"variable": "snap_gross_monthly_income",
"value": 1200,
"sources": [
"us:policies/usda/snap/state-plan-composition#snap_gross_monthly_income"
]
},
{
"rule_id": "snap_standard_deduction",
"variable": "snap_standard_deduction",
"value": 209,
"sources": [
"us:policies/usda/snap/fy-2026-cola/deductions#snap_standard_deduction"
]
},
{
"rule_id": "snap_excess_shelter_deduction_for_net_income",
"variable": "snap_excess_shelter_deduction_for_net_income",
"value": 525,
"sources": [
"us:regulations/7-cfr/273/10#snap_excess_shelter_deduction_for_net_income"
]
},
{
"rule_id": "snap_maximum_allotment",
"variable": "snap_maximum_allotment",
"value": 546,
"sources": [
"us:policies/usda/snap/fy-2026-cola/maximum-allotments#snap_maximum_allotment"
]
}
],
"notes": [
"Canonical values are monthly. Convenience input shelter_costs is treated as total shelter costs for this Axiom case.",
"The New York corpus-direct composition keeps cents in net income: excess shelter is 525 and net income 226.5, matching PolicyEngine's 226.5 for the same household. The allotment rounds to 478 either way."
],
"comparison": {
"status": "matching",
"changed": [],
"missing": [],
"extra": []
},
"known_deviation": null,
"runtime": {
"id": "axiom-rules-engine:us-ny-snap",
"mode": "compiled"
},
"warnings": [],
"axiom_identity": {
"artifact_id": "unpinned:us-ny-snap.direct",
"artifact_sha256": "159418ca4e37c15c7b2e2371f6b8caa9c291cf59f94ce5f21ecd8a4972844caf",
"engine": "service@c8e8db1f6066d9aea9611505087403f38f0e7e67"
},
"external_comparisons": []
}
],
"skipped_cases": []
},
"meta": {
"request_id": "f10cb89c-ae69-4d25-8595-94c62b37a875",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}Corpus notes are reproduced verbatim. Arizona’s local-only pin explanation predates #245; this replay applies pins remotely and warns that the inherited corpus pin is stale. As recorded on 2026-10-10 from data/parity-external/latest.json (bundled observations generated 2026-10-09T14:27:49.295Z; snapshot SHA-256 e2ec449c350f7c461aa82d2daba99b20db11225a9896b2199aa03b2825166cbb).
POST/v1/keys/trialno auth
Self-service trial key: no signup, expires after 14 days, scoped to rules:read, sources:read, graphs:read, and calculate:run, rate-limited to 30 requests/minute, with a compute-unit quota (quota_cu, 10,000 CU by default). Issuance is capped per client and globally per day, and every issuance lands in the admin audit trail. The raw key appears exactly once in the response — only its hash is persisted. Durable keys are issued by administrators via /v1/admin/keys.
The optional label (≤ 120 characters) is stored as the key’s note so administrators can tell trials apart.
curl -s -X POST https://api.axiom.org/v1/keys/trial \
-H "content-type: application/json" \
-d '{"label": "quickstart"}'const res = await fetch("https://api.axiom.org/v1/keys/trial", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ label: "quickstart" }),
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data.key); // store it now; only a hash is persistedimport requests
res = requests.post(
"https://api.axiom.org/v1/keys/trial",
json={"label": "quickstart"},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]["key"]) # store it now; only a hash is persisted{
"status": "ok",
"data": {
"key": "axiom_...",
"key_id": "trial_b4c907f2",
"scopes": [
"rules:read",
"sources:read",
"graphs:read",
"calculate:run"
],
"expires_at": "2026-10-17T13:20:29.809Z",
"rate_limit": {
"requests": 30,
"window_seconds": 60
},
"quota_cu": 10000,
"ttl_days": 14,
"durable": false,
"warning": "Store the key value now; only its hash is persisted. Trial keys expire automatically — for a durable key, contact an Axiom administrator."
},
"meta": {
"request_id": "edb75a8c-2f46-47f0-a6b6-5ef9ca8185c8",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}GET/v1/admin/analyticsadmin:analytics
Usage analytics collected in-process since instance start: totals by status code, per-route traffic with latency buckets, per-key usage (key ids only — never key material), auth/security and abuse-control event counters, store errors, and per-package calculation timings (computations for this instance, computations_durable from the shared store). Add ?scope=global to merge the flushed snapshots of every live instance (requires the shared store; 503 store_unavailable if unreachable).
curl -s https://api.axiom.org/v1/admin/analytics \
-H "x-api-key: $AXIOM_API_KEY"const res = await fetch("https://api.axiom.org/v1/admin/analytics", {
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
},
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.get(
"https://api.axiom.org/v1/admin/analytics",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"instance_id": "58f8bbba-ce11-47ec-83c8-f7b910f3b2af",
"collected_since": "2026-10-03T13:20:28.259Z",
"generated_at": "2026-10-03T13:20:29.832Z",
"totals": {
"requests": 32,
"by_status": {
"200": 27,
"201": 3,
"202": 1,
"400": 1
}
},
"auth_events": {
"unauthorized": 0,
"insufficient_scope": 0,
"rate_limited": 0,
"auth_throttled": 0,
"auth_misconfigured": 0,
"auth_store_unavailable": 0
},
"store_errors": 0,
"abuse_events": {},
"routes": [
{
"route": "GET (unmatched)",
"requests": 3,
"success": 3,
"client_errors": 0,
"server_errors": 0,
"avg_duration_ms": 54,
"max_duration_ms": 156,
"latency_buckets": {
"le_25ms": 2,
"le_100ms": 0,
"le_500ms": 1,
"le_2000ms": 0,
"gt_2000ms": 0
}
},
{
"route": "POST /v1/search",
"requests": 2,
"success": 1,
"client_errors": 1,
"server_errors": 0,
"avg_duration_ms": 3,
"max_duration_ms": 3,
"latency_buckets": {
"le_25ms": 2,
"le_100ms": 0,
"le_500ms": 0,
"le_2000ms": 0,
"gt_2000ms": 0
}
},
{
"route": "GET /v1/rules/{rule_id}",
"requests": 2,
"success": 2,
"client_errors": 0,
"server_errors": 0,
"avg_duration_ms": 125,
"max_duration_ms": 249,
"latency_buckets": {
"le_25ms": 1,
"le_100ms": 0,
"le_500ms": 1,
"le_2000ms": 0,
"gt_2000ms": 0
}
}
],
"keys": [
{
"api_key_id": "docs-example",
"requests": 28,
"rate_limited": 0,
"last_used_at": "2026-10-03T13:20:29.829Z"
}
],
"computations": [
{
"package": "us-co/co-snap (compiled)",
"count": 2,
"avg_total_ms": 126,
"avg_plan_ms": 1,
"avg_engine_ms": 125,
"avg_normalize_ms": 0,
"max_total_ms": 189
}
],
"computations_durable": [
{
"package": "us-co/co-snap (compiled)",
"count": 2,
"avg_total_ms": 126,
"avg_plan_ms": 1,
"avg_engine_ms": 125,
"avg_normalize_ms": 0
}
],
"abuse_owner": null
},
"meta": {
"request_id": "727ef63f-ac4f-4579-8523-9632ab9be09d",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}Truncated: 23 more route entries omitted.
GET/v1/admin/usageadmin:analytics
Durable per-key request counts aggregated by calendar month (UTC), retained ~13 months in the shared store — the audit-grade complement to the live analytics snapshot, suitable for partner reporting and quota reviews. ?month=YYYY-MM selects a month (default: current). aggregate_cu reports the compute units trial keys have used today and this month against their shared caps (see quotas).
curl -s https://api.axiom.org/v1/admin/usage \
-H "x-api-key: $AXIOM_API_KEY"const res = await fetch("https://api.axiom.org/v1/admin/usage", {
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
},
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.get(
"https://api.axiom.org/v1/admin/usage",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"month": "2026-10",
"usage": [
{
"api_key_id": "docs-example",
"requests": 28
}
],
"aggregate_cu": {
"daily": {
"period": "2026-10-03",
"used_cu": 0,
"limit_cu": 200000
},
"monthly": {
"period": "2026-10",
"used_cu": 0,
"limit_cu": 2000000
}
},
"store": "memory"
},
"meta": {
"request_id": "fe6e9815-c5ad-4fd9-9429-0a0ac233fd90",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}GET/v1/admin/keysadmin:keys
Configured API keys as metadata: id, source (environment for keys configured on the deployment, store for keys issued at runtime), scopes, registry status, runtime revocation state, prefix, rate limit, owner, timestamps. Key values and hashes are never returned.
curl -s https://api.axiom.org/v1/admin/keys \
-H "x-api-key: $AXIOM_API_KEY"const res = await fetch("https://api.axiom.org/v1/admin/keys", {
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
},
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.get(
"https://api.axiom.org/v1/admin/keys",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"keys": [
{
"id": "docs-example",
"source": "environment",
"scopes": [
"*"
],
"status": "active",
"runtime_revoked": false
},
{
"id": "trial_b4c907f2",
"source": "store",
"scopes": [
"rules:read",
"sources:read",
"graphs:read",
"calculate:run"
],
"status": "active",
"runtime_revoked": false,
"prefix": "axiom_xU9SkLsE",
"rate_limit": {
"requests": 30,
"window_seconds": 60
},
"owner": "trial",
"expires_at": "2026-10-17T13:20:29.809Z",
"created_at": "2026-10-03T13:20:29.809Z"
},
{
"id": "partner-a",
"source": "store",
"scopes": [
"rules:read"
],
"status": "active",
"runtime_revoked": true,
"prefix": "axiom_7cZ5i73g",
"owner": "partner-a-co",
"created_at": "2026-10-03T13:20:29.813Z"
},
{
"id": "partner-b",
"source": "store",
"scopes": [
"rules:read",
"calculate:run"
],
"status": "active",
"runtime_revoked": false,
"prefix": "axiom_45IXGPw1",
"rate_limit": {
"requests": 120,
"window_seconds": 60
},
"owner": "partner-b-co",
"created_at": "2026-10-03T13:20:29.816Z"
}
],
"store": "memory"
},
"meta": {
"request_id": "60ed3c70-0299-4765-9943-d054d3c98cf0",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}POST/v1/admin/keysadmin:keys
Issue a new API key at runtime. The raw key is returned exactly once; only its sha256 hash is persisted (to the shared store, marked by source: "store" in the key listing). The new key authenticates at once on any instance that can reach the shared store. The key listing and runtime revocation read a per-instance copy of the stored keys refreshed every 15 seconds, so they can lag that long. durable: false warns that a memory-store key will not survive restarts — configure the shared store before issuing real keys.
| Field | Type | Req. | Constraints |
|---|---|---|---|
id | string | yes | 3–64 chars, [a-z0-9_-]; must be unique (409 key_id_conflict) |
scopes | string[] | yes | non-empty |
owner, note | string | no | ≤ 120 / ≤ 500 chars |
expires_at | string | no | ISO timestamp |
rate_limit | object | no | {requests, window_seconds}, positive integers |
quota_cu | integer | no | positive; compute-unit quota |
Every issuance is recorded in the audit trail.
curl -s -X POST https://api.axiom.org/v1/admin/keys \
-H "x-api-key: $AXIOM_API_KEY" \
-H "content-type: application/json" \
-d '{"id": "partner-b", "scopes": ["rules:read", "calculate:run"], "owner": "partner-b-co", "rate_limit": {"requests": 120, "window_seconds": 60}}'const res = await fetch("https://api.axiom.org/v1/admin/keys", {
method: "POST",
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"id": "partner-b",
"scopes": [
"rules:read",
"calculate:run"
],
"owner": "partner-b-co",
"rate_limit": {
"requests": 120,
"window_seconds": 60
}
}),
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.post(
"https://api.axiom.org/v1/admin/keys",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
json={
"id": "partner-b",
"scopes": [
"rules:read",
"calculate:run"
],
"owner": "partner-b-co",
"rate_limit": {
"requests": 120,
"window_seconds": 60
}
},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"key": "axiom_...",
"entry": {
"id": "partner-b",
"prefix": "axiom_45IXGPw1",
"scopes": [
"rules:read",
"calculate:run"
],
"status": "active",
"created_at": "2026-10-03T13:20:29.816Z",
"owner": "partner-b-co",
"rate_limit": {
"requests": 120,
"window_seconds": 60
}
},
"durable": false,
"warning": "Store the key value now; only its hash is persisted. The store is per-instance memory: this key is NOT durable across restarts or instances."
},
"meta": {
"request_id": "a86b3203-617c-4a81-8734-ea87e0e4946b",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}POST/v1/admin/keys/{key_id}/revokeadmin:keys
Revoke a key at runtime; takes effect within 30 seconds on every instance (revocations are read through a 30-second cache). durable: true means the revocation lives in the shared store and survives restarts; permanent revocation still requires marking the key revoked in the registry. 404 for unknown ids.
curl -s -X POST https://api.axiom.org/v1/admin/keys/partner-a/revoke \
-H "x-api-key: $AXIOM_API_KEY"const res = await fetch("https://api.axiom.org/v1/admin/keys/partner-a/revoke", {
method: "POST",
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
},
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.post(
"https://api.axiom.org/v1/admin/keys/partner-a/revoke",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"id": "partner-a",
"revoked": true,
"durable": false,
"note": "Revocation is per-instance and non-durable; remove the key from the registry and redeploy for permanence."
},
"meta": {
"request_id": "a7168e14-e9ca-43ab-900c-7df892c96247",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}GET/v1/admin/validation/runsadmin:analytics
History of published validation runs (the PE household comparison harness posts here with --publish). GET /v1/admin/validation/runs lists summaries — parity/drift/coverage totals, real average per-case latency, API version, and the serving contract hash; GET /v1/admin/validation/runs/{run_id} returns one run’s full per-variable rows and per-case phase timings; GET /v1/admin/validation/migration returns the migration ledger (partner demand vs current coverage); POST /v1/admin/validation/runs records a run (180-day retention, audited). The validation dashboard renders this history with trends and run-over-run diffs.
GET/v1/admin/auditadmin:keys
Durable audit trail of admin actions (trial and administrator key issuance, revocation, registry reindexes, kill-switch changes, and recorded validation runs), newest first, up to 200 entries, retained 90 days in the shared store. Each entry records the acting key id, client address, request id, timestamp, action, and target — never key material.
curl -s https://api.axiom.org/v1/admin/audit \
-H "x-api-key: $AXIOM_API_KEY"const res = await fetch("https://api.axiom.org/v1/admin/audit", {
headers: {
"x-api-key": process.env.AXIOM_API_KEY,
},
});
const payload = await res.json();
if (payload.status !== "ok") throw new Error(payload.error.code);
console.log(payload.data);import os
import requests
res = requests.get(
"https://api.axiom.org/v1/admin/audit",
headers={"x-api-key": os.environ["AXIOM_API_KEY"]},
timeout=30,
)
payload = res.json()
assert payload["status"] == "ok", payload["error"]
print(payload["data"]){
"status": "ok",
"data": {
"entries": [
{
"at": "2026-10-03T13:20:29.819Z",
"action": "key.revoked",
"target": "partner-a",
"actor": "docs-example",
"client": null,
"request_id": "a7168e14-e9ca-43ab-900c-7df892c96247"
},
{
"at": "2026-10-03T13:20:29.816Z",
"action": "key.issued",
"target": "partner-b",
"actor": "docs-example",
"client": null,
"request_id": "a86b3203-617c-4a81-8734-ea87e0e4946b",
"detail": {
"scopes": [
"rules:read",
"calculate:run"
],
"owner": "partner-b-co"
}
}
],
"store": "memory"
},
"meta": {
"request_id": "3f227a82-df66-4917-88ba-fef68d3abf7e",
"api_version": "0.1.0",
"environment": "local",
"certified": {
"enforcement": "permissive",
"certified_set_version": "empty",
"ledger_id": "bootstrap-empty",
"vintage": {
"encoding_release": "unreleased",
"engine_release": "unreleased",
"corpus_release": "unreleased"
}
}
}
}Truncated to the two most recent entries.
Abuse controls
GET /v1/admin/kill reads and POST /v1/admin/kill updates the durable trial traffic and mint switches. Both require admin:keys.