This page is a quick reference, not the standard. The normative text is
HSS-1, and the machine-readable API contract is
openapi.yaml. Where this page and the
standard disagree, the standard wins.
Lowercase slug ^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$. Stable for the life of the log.
seq
0 for the first event, then exactly previous seq + 1.
prev
null at seq 0; otherwise the event hash of seq - 1.
type
^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$. Types below are reserved.
case
OPTIONAL, up to 128 characters. Groups the events of one procedure.
ts
When the issuer states the act happened. Untrusted; the Bitcoin anchor bounds it from above.
public
JSON object, published as-is. Never put personal data here.
docs
Array of document references (may be empty).
actor
Key id of the signer.
The event hash is SHA-256(canonical(event)); the signature is not part of the event. A serialized event MUST NOT
exceed 64 KiB, and unknown top-level fields are rejected under hss: 1.
Passkeys:id is the WebAuthn credential id (base64url); rpId is REQUIRED; alg is -7 (ES256) or -257
(RS256).
Ed25519 keys:alg MUST be -8; id is "ed25519:" + hex(SHA-256(spki))[0:32].
scope.types: exact types or a trailing wildcard ("case.*"); MUST NOT grant system types.
scope.expires: the last event.ts the key may sign.
Roles:admin and official are people; system is a person-less process and MUST carry scope.types;
session keys exist only through session.open. system and session keys MUST NOT sign issuer.*, key.*, or
session.open.
commitment = SHA-256("hardstate/doc/v1" ‖ salt ‖ SHA-256(file)) salt: 32 random bytes
Publishing a document reveals its salt and SHA-256(file) and makes the bytes available. Receipts carry salts in
the URL fragment (/r/<event_hash>#k=<commitment[0:16]>.<salt>,…), which browsers never send to a server.
Every batch root → ≥ 2 public calendars; a standard detached .ots (ots verify -d <root> <file>.ots).
HardState Anchor
Daily. OP_RETURN PUSH36("HSS" ‖ 0x01 ‖ root), script 6a 24 48 53 53 01 <32 bytes> — 36 bytes of payload, 157 vB. Anchor-tree leaf data is 0x03 ‖ batch_root.
The daily anchor costs roughly $48–240/year at typical fee rates (about 1–5 sat/vB). Signet anchors are labelled
as tests and never count as a Bitcoin proof.
Base URL https://api.hardstate.net (http://localhost:8787 locally). Reads are open and keyless. Writes need no API
key — an event is accepted only if it extends its issuer’s log and is signed by an authorized key.