# "Quickstart: REST"

Three curl calls against the hosted service — a credential, a compile, a check — and the exact JSON that comes back.

For anything that speaks HTTPS. Check extracted values against a written policy from a service, a job, or a test, with no SDK.

## 1. A credential, no sign-up

```bash
export DSAIL_CRED=$(curl -s -X POST https://agents.jaxon.ai/v1/credentials/evaluation \
  | python3 -c 'import json,sys; print(json.load(sys.stdin)["credential"])')
```

The token is shown once; the service stores only its hash. Send it on every
call as `x-jaxon-credential`. An evaluation credential is scoped to compile,
check and the prompt pack, and capped; a full credential is issued by Jaxon.

## 2. Compile

```bash
cat > expenses.dsail <<'EOF'
version 1.3;
// @ask amount What is the total amount of this expense claim, in USD?
// @unit amount USD
declare amount as numeric;
// @ask has_receipt Is an itemised receipt attached?
declare has_receipt as boolean;
assert receipt_over_75 { Implies(amount > 75 "USD", has_receipt) };
assert within_cap { amount <= 5000 "USD" };
EOF

curl -s -X POST https://agents.jaxon.ai/v1/compile \
  -H "x-jaxon-credential: $DSAIL_CRED" -H "content-type: application/json" \
  -d "$(python3 -c 'import json; print(json.dumps({"source": open("expenses.dsail").read()}))')"
```

The response carries `ruleset_hash` (the content hash addressing exactly these
bytes), `manifest` (every claim with its question, type and unit), `claim_schema`
(JSON Schema for the claim dictionary), the validation contract a check will
enforce, and `review`, a plain-text rendering for a person to sign.

## 3. Check

```bash
curl -s -X POST https://agents.jaxon.ai/v1/check \
  -H "x-jaxon-credential: $DSAIL_CRED" -H "content-type: application/json" \
  -d '{"ruleset_hash": "<ruleset_hash from step 2>",
       "claims": {"amount": "120 USD", "has_receipt": false}}'
```

```json
{"ok": true,
 "ruleset_hash": "<ruleset_hash>", "unit_library_hash": null,
 "rules": [
   {"rule": "receipt_over_75", "assertions": [
     {"name": "receipt_over_75", "check": "FALSE", "unknown_policy": "neutral",
      "counterexample": "[amount = 120, has_receipt = False]"}]},
   {"rule": "within_cap", "assertions": [
     {"name": "within_cap", "check": "TRUE", "unknown_policy": "neutral"}]}],
 "claims": {"bound": ["amount", "has_receipt"], "unbound": [], "quantities": ["..."]},
 "versions": {"wire_version": "2.4.0", "...": "..."}}
```

Every assertion answers `TRUE`, `FALSE`, `UNKNOWN` or `AMBIGUOUS`; a `FALSE`
carries the rule that decided, with a counterexample. There is no combined
verdict — fold the results yourself, because what a `FALSE` costs is your
decision. The payload is pure over its inputs (no timestamps, no request id),
so the same ruleset and claims return the same bytes every time.

## Where the claim values come from

`GET /v1/prompt-pack/{ruleset_hash}` returns one extraction prompt per claim,
the claim schema and the validation rules. Run those prompts on your own model,
assemble the claim dictionary, submit it. A claim your extraction could not
determine is submitted as the string `"unknown"` — never a guess, never omitted.

## Errors

One envelope for every failure, through every door:

```json
{"ok": false,
 "error": {"code": "VALIDATION_REJECTED", "message": "1 field failed validation",
           "docs": "https://docs.agents.jaxon.ai/errors/validation-rejected.md",
           "failures": [{"field": "amount", "expected": "...", "received": "..."}]},
 "versions": {"...": "..."}}
```

`failures` names every failing field at once, so one corrected resubmission
converges. [Error codes](../reference/errors.md) lists them all; the full route
list is the [REST API reference](../reference/rest-api.md), and the
specification is `GET https://agents.jaxon.ai/openapi.json`.
