Record a decision. Verify its receipt.

Three steps from a synthetic decision to a receipt you can check locally.

Prerequisites: the Recourse checkout, Node.js and npm, curl, jq, and xz on Linux x64. Use the in-repository schema. Every field D-002 names is implemented and tested against the source packet; conformance to architecture Section 4 is partial and docs/conformance/D-002.md records each field as present, renamed or missing.

  1. Start the local preview

    From the repository root, install the pinned dependencies and start the launcher. Leave it running; it holds the demo credentials only in process memory.

    Terminal 1: local setup
    cd recourse
    npm ci
    npm run local

    Open the playground at http://127.0.0.1:18788/playground/index.html. If it is already running on these ports, use that session. The launcher serves the review pages on RECOURSE_PORT, default 18788, and the Worker on RECOURSE_WORKER_PORT, default 18787. Set both if either port is taken. The local browser bridge supplies authentication without exposing an API key to the browser.

  2. Record a synthetic ADR

    In a second terminal, from recourse/, submit the included public-only sample. Keep the same idempotency key and payload when retrying this decision. Use a new key for a new decision.

    Terminal 2: synthetic record
    curl --fail --silent --show-error \
      http://127.0.0.1:18788/dev/api/v1/adr \
      -H 'Origin: http://127.0.0.1:18788' \
      -H 'Content-Type: application/json' \
      -H 'Idempotency-Key: quickstart-decision-001' \
      --data-binary @public/playground/sample.json \
      --output accepted.json

    The response may already be Durable (durable on the wire). Wait for Sealed before fetching its receipt. The sample has private_fields: {}. Reusing a request key with a changed payload returns a conflict; correct the request before retrying. Free includes 50,000 decisions a month; read the payload, retention and search allowances.

  3. Verify the sealed receipt

    Development signer means integrity under a published dev key and no independently trusted time.

    Download the Linux x64 verifier, then extract it in recourse/. The compressed download contains a standalone executable.

    Extract verifier
    xz --decompress --keep recourse-verify-linux-x64.xz
    mv recourse-verify-linux-x64 recourse-verify
    chmod +x recourse-verify

    Poll for Sealed, fetch the receipt, and pass the development key fingerprint explicitly. Backlog can delay a seal beyond the next minute.

    Poll, fetch and verify
    ADR_ID=$(jq -er '.records[0].adr_id' accepted.json)
    # Poll through the normal minute boundary; backlog may delay sealing.
    for attempt in $(seq 1 24); do
      ACK=$(curl --fail --silent --show-error \
        -H 'Origin: http://127.0.0.1:18788' \
        "http://127.0.0.1:18788/dev/api/v1/adr/$ADR_ID/status" | jq -er '.ack')
      [ "$ACK" = sealed ] && break
      sleep 5
    done
    [ "$ACK" = sealed ] || { echo "Still pending; retry status later."; exit 1; }
    curl --fail --silent --show-error \
      -H 'Origin: http://127.0.0.1:18788' \
      "http://127.0.0.1:18788/dev/api/v1/adr/$ADR_ID/receipt" \
      --output receipt.json
    DEV_PIN=$(curl --fail --silent --show-error \
      -H 'Origin: http://127.0.0.1:18788' \
      http://127.0.0.1:18788/dev/api/v1/status | jq -er '.trust.key_fingerprint')
    ./recourse-verify receipt.json --dev-pin "$DEV_PIN"

    A matching development pin checks integrity under that key. The pin above comes from the same local service, so this proves service consistency, not independent trusted time. For independent verification, distribute the trust anchor separately.

    For an offline check of the shipped fixture, download demo-receipt.json and use its separately captured public development trust metadata:

    Verify the shipped demo fixture
    ./recourse-verify demo-receipt.json --dev-pin 1243d4dabe0c7218105918b3fd94be21d6a25973c4f1b4d4eb777a7543a4c9a1

    Exit 0 means every required check and explicit trust match passed. It does not establish decision correctness. See the verifier reference for tamper checks and trust limits.

Received: request acknowledged. Acknowledged is not durable. Durable: committed to the configured persistence layer. Sealed: included in a signed root with a receipt. The API wire values remain accepted, durable and sealed. Searchable-through is a separate index coverage watermark: not available in this preview.

Connect a server-side application

For a separately configured tenant, use environment-only credentials against POST /v1/adr. The local bridge is for this preview; it is not a hosted authentication mechanism.

Authenticated API shape
# Server environment: RECOURSE_URL, RECOURSE_TENANT_ID, RECOURSE_API_KEY
curl --fail --silent --show-error "$RECOURSE_URL/v1/adr" \
  -H "Authorization: Bearer $RECOURSE_API_KEY" \
  -H "X-Tenant-ID: $RECOURSE_TENANT_ID" \
  -H 'Idempotency-Key: example-decision-001' \
  -H 'Content-Type: application/json' \
  --data-binary @public/playground/sample.json

Use HTTPS outside loopback development. Never expose these environment values through a client bundle, client state or a URL.

Choose your integration