Surfil

API · POST /v1/receipt

Consume exactly one Credit, then sign a savings receipt built on-device from measured facts only. This is the first revenue-attached signed output - the composition of the metering and signing systems, in that order.

Auth

Device token. The receipt's signable content is authored on your device; the edge signs what it is handed and never invents figures.

How it composes

  • Consume - the client sends an operation name; the server prices it (never the client). The decrement is atomic and idempotent - a retry with the same idempotency key replays the stored result byte-for-byte, so no double charge.
  • Sign - the content { body_sha256, frontmatter } is signed Ed25519. If a client lies about body_sha256, offline surfil verify recomputes it from the doc body and reports TAMPERED.

Response · 200

{
  "envelope": {
    "payload":   { "body_sha256": "…", "frontmatter": { } },
    "alg":       "Ed25519",
    "key_epoch": 7,
    "signature": "…"
  }
}

Fail-closed under fault

If consume succeeds but signing fails, the endpoint returns 503 and no receipt - never an unsigned one. The Credit is spent, but the idempotency key makes a retry safe: it replays the consume (no second charge) and re-signs, so the paid-for receipt is delivered exactly once. No envelope means no receipt - the anti-bypass root under fault.

  • 401 - missing or invalid device token.
  • 503 - signing unavailable; no decrement is left dangling once retried.
Verify any receipt yourself with surfil verify - offline, against the published epoch key.