Dekimu · provenance docs

API reference

Four public endpoints. All read-only, all CORS-enabled, no auth.

GET /api/v/<id>

Returns the signed claim for a receipt.

Path: https://verify.dekimu.com/api/v/<id>

Query (optional): ?tier=(public_minimal | public_full | metadata_only) and ?reveal=<base64url> for receipts that carry selective-disclosure commitments. Defaults to the receipt's own disclosure mode.

Headers: CORS access-control-allow-origin: *, cache-control: no-store.

Response 200 (shape):

{
  "id": "<id>",
  "kind": "apr.v1",
  "issuer": "commander-app",
  "subject": "<principalId or pseudonym>",
  "iat": 1715520000,
  "kid": "commander-app-2026",
  "body": { /* kind-specific signed body */ },
  "sig": "<base64url Ed25519 signature>",
  "parent": null,
  "disclosure": {
    "applied": "public_minimal",
    "revealVerified": false,
    "revealedKeys": [],
    "available": ["public_minimal", "public_full", "metadata_only"]
  }
}

Errors: 400 invalid_claim_id for malformed IDs, 404 not_found when no claim exists for the ID.

GET /api/proof/<id>

Returns the Merkle inclusion proof for a receipt in its daily audit root.

Path: https://verify.dekimu.com/api/proof/<id>

Headers: cache-control: no-store.

Response 200 (shape):

{
  "v": 2,
  "date": "2026-05-12",
  "rootKid": "audit-root-2026",
  "rootHash": "<hex>",
  "rootSig": "<base64url>",
  "leafIndex": 17,
  "leafHash": "<hex>",
  "path": [{"side":"L"|"R","hash":"<hex>"}, ...],
  "appProof": {
    "app": "commander-app",
    "rootHash": "<hex>",
    "path": [...]
  }
}

The appProof nested object is present when the claim's issuer has its own sub-tree that rolls up into the daily root.

Errors: 404 not_yet_built when the receipt was minted after the most recent root seal (00:05 UTC); the response includes the pending date. 404 not_found when no claim exists.

GET /.well-known/dekimu-claim-keys.json

The canonical catalog of issuer public keys.

Path: https://verify.dekimu.com/.well-known/dekimu-claim-keys.json

Headers: cache-control: public, max-age=60, s-maxage=300, stale-while-revalidate=86400. CORS *.

Response 200 (shape):

{
  "keys": [
    {
      "kid": "commander-app-2026",
      "issuer": "commander-app",
      "alg": "Ed25519",
      "publicKey": "<base64url>",
      "activeFrom": "2026-01-01",
      "retiredAt": null
    },
    { "kid": "miniterms-2026", "issuer": "miniterms", ... },
    { "kid": "designer-2026",  "issuer": "designer",  ... },
    { "kid": "invoiceup-2026", "issuer": "invoiceup", ... }
  ]
}

A companion endpoint /.well-known/dekimu-audit-root-keys.json publishes the public keys used to sign daily roots — same shape, different scope.

GET /api/anchor/health

Liveness signal for the daily anchor cron. Auditors and dashboards poll this.

Path: https://verify.dekimu.com/api/anchor/health

Headers: CORS *.

Response 200 (shape):

{
  "status": "fresh" | "stale" | "missing",
  "expectedBuiltDate": "2026-05-11",
  "lastBuiltDate": "2026-05-11",
  "lastBuiltAt": 1715520300,
  "lastBuiltCount": 142,
  "hoursSinceLastBuild": 9.2,
  "inboxToday": 5,
  "inboxYesterday": 142
}

Status semantics:

  • fresh — yesterday's root was built; normal state.
  • stale — yesterday's root not built but a recent root exists; cron is behind, not dead.
  • missing — no root in the last 5 days; escalate.

Embedding the verification badge

A SVG status badge for any receipt is served from https://verify.dekimu.com/badge/<id>.svg. 200×40 pixels, status-coloured pill, CORS *, cache-control: public, max-age=60, s-maxage=300. Embed in any <img>:

<a href="https://verify.dekimu.com/v/<id>" target="_blank" rel="noopener">
  <img
    src="https://verify.dekimu.com/badge/<id>.svg"
    alt="Verify on Dekimu"
    width="200"
    height="40"
  />
</a>

Versioning + stability

  • Response shapes are additive. New fields may appear; existing fields will not change type or be removed without a major version bump and a 90-day deprecation window announced on the anchor-keys catalog.
  • Key IDs (kid) rotate annually under normal operation, immediately on compromise. Retired keys remain in the catalog so historical receipts can still be verified — theretiredAt field reflects the cutover.
  • The protocol itself is described by the published verifier discovery document at /.well-known/dekimu-apr-verifier.json.