Skip to main content
api.aethis.ai serves engine 0.49.1, which is the contract these pages describe; every response carries engine_version so you can confirm which build answered you. What the deployed engine serves.
Every response from POST /api/v1/public/decide (and POST /rulesets/{id}/explain-failure) carries a small set of envelope fields that let callers reference, verify, and replay a specific decision — without the server having to echo potentially-PII inputs back. If you’re building anything regulated, audited, or support-ticketable, read this page.

The fields

*decision_time is only replay-critical when a rule references wall-clock time.

decision_id

Unique per invocation, format dec_<16 urlsafe chars>. Fresh on every call — two identical requests get different IDs even when the server serves the response from its decision cache. Use it in bug reports, support tickets, and client-side logs. The server emits a structured log line keyed by decision_id, so operators can trace a user-quoted ID back to full context.

inputs_hash

Algorithm-prefixed SHA-256 over the RFC 8785 canonical form of field_values. Invariant under key reordering, whitespace, and 1 vs 1.0 vs 1e0. Lets a caller prove “this decision was computed from exactly these inputs” without the server persisting or echoing the values. The sha256: prefix is forward-compatibility for when the algorithm rotates — parsers should split on : and route by algorithm.

engine_version

Product-prefixed semver, format aethis-core@<semver>. Same value for the lifetime of a server process. Different engine versions can produce different outcomes for identical inputs and rule artefacts if DSL semantics or solver behaviour change — reliable replay requires matching the engine version.

ruleset_version / rulebook_id

Ruleset calls return ruleset_id + ruleset_version; rulebook calls return rulebook_id.

content_digest

sha256:<hex> over the published rule content that produced the decision. This, not ruleset_version, is what replay pins to. ruleset_version is a mutable authoring label — the vN counter, bumped on every publish. A republish of byte-identical content can advance the label while reusing the existing content cut, so two decisions with different labels may have run against identical rules, and matching labels are not by themselves proof of matching rules. content_digest is immutable content identity: it changes whenever the rules change, and only when the rules change. For a published leaf ruleset the candidate always resolves the caller’s slug to this triple — immutable ruleset_id, real ruleset_version, content_digest — on both cold and warm cache paths. Composed rulebook (rulebook_id) responses still report "unknown" for the composition until resolved member identity lands.

How to replay a decision

The envelope is designed for two-party replay: the caller keeps the inputs they sent, the server re-runs the engine when asked.
  1. Retain the original field_values and the full envelope on the caller side.
  2. Re-run POST /decide with the same field_values and ruleset_id.
  3. Verify:
    • inputs_hash matches the retained value → inputs are identical
    • engine_version matches → engine build is the same
    • content_digest matches → the rule content is byte-identical (the strongest of these checks, and the one to rely on)
    • ruleset_id matches → the same published ruleset was resolved
    • ruleset_version matches → same authoring label. Necessary, not sufficient: the label can move without the content changing, so never treat it as artefact identity on its own
    • The new decision equals the original → decision is reproducible
The new response will have a different decision_id and decision_time — those are per-invocation and deliberately excluded from the replay contract.

Caching interaction

The server caches responses for identical (ruleset_id, field_values, flags) combinations for up to 10 minutes. Per-call envelope fields (decision_id, decision_time, inputs_hash, engine_version) are stripped before caching and stamped fresh on every response. A cache hit is invisible from the envelope’s perspective — the ID is fresh, the hash is computed from the caller’s actual inputs, the timestamp is current.

Example

Illustrative — the digest and IDs are placeholders. The field names, and the ruleset_version / content_digest keys, are what api.aethis.ai returns today.

What to log on your side

For audited workloads, retain at minimum:
  • decision_id — your handle for this decision
  • inputs_hash — proves the inputs later
  • engine_version + ruleset_id + content_digest — pins the artefact. Log ruleset_version too for human readability, but resolve any dispute on the digest
  • Your own request correlation ID (e.g. application trace ID)
Retain the raw field_values separately if your compliance regime requires input-level audit; inputs_hash alone is sufficient for reproducibility proof, but not for “what exactly did the user submit” questions.