Skip to content
Apier.no
Guides

How to record an action hash with a notary record

Record the SHA-256 hash of an action your agent took, citing your own Apier receipts, and get a receipt that verifies offline. A record proves only that API key K recorded hash H, citing Apier receipts R, at time T.

[Cite this as: Apier.no Docs v0.1.0 — last updated 2026-11-01]

A notary record lets your agent leave a trace of an action it took after checking a company through Apier. You send the SHA-256 hash of the action and the ids of the Apier receipts it relied on. Apier stores the hash, the receipt ids, your key id and the time it recorded them, and nothing else: never the action itself, never free text, never personal data.

What a record proves

A record proves exactly this, word for word, and nothing more:

API key K recorded hash H, citing Apier receipts R, at time T

The claim field of every record carries that sentence. A record does not say that the action happened, that it was authorised or lawful, or that the hash matches any particular document. Keep the action itself, so that you can show later that it hashes to action_hash.

Step 1 — Hash the action

Compute the SHA-256 of the action in your own system and send it as 64 lowercase hex characters. Apier never sees what you hashed.

Step 2 — Record the hash

curl -X POST https://www.apier.no/api/v1/notary/records \
  -H 'Authorization: Bearer apr_free_<your_key_here>' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: <a new UUID for each action>' \
  -d '{"action_hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", "receipt_ids": ["5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a"], "action_type": "payment"}'
FieldMeaning
action_hashRequired. SHA-256 of the action, exactly 64 lowercase hex characters.
receipt_idsRequired. 0 to 50 distinct receipt ids, each one of your own account's receipts.
action_typeOptional. One of payment, contract, onboarding, filing_draft, other.
client_stated_atOptional. Your own time for the action, RFC 3339 with an offset, at most millisecond precision. Stored and shown as stated by you, never as observed by Apier, in UTC with whole milliseconds (2026-11-01T09:00:00+01:00 comes back as 2026-11-01T08:00:00.000Z).

Any other field is rejected with 400 VALIDATION_FAILED. A receipt id that is unknown, or that belongs to another account, gets 404 NOTARY_RECEIPT_NOT_FOUND, and nothing is recorded or charged.

A record costs one company read per distinct org number across the cited receipts, with a minimum of one. The debit and the record are written in one database transaction, so a refused call writes nothing and charges nothing. Send an Idempotency-Key: a retry with the same key returns the stored answer and is never charged twice.

A 503 NOTARY_RECORD_FAILED means the call did not complete and its outcome is unknown: the record may have been written and charged before the answer was lost. A retry with the same Idempotency-Key cannot record or charge twice; it answers 409 IDEMPOTENCY_IN_PROGRESS for the key's 24 hours. A new key may create and charge a second record.

Step 3 — Keep the record and its receipt

The 201 answer carries the record and a signed receipt:

{
  "success": true,
  "data": {
    "record": {
      "id": "6f1c2a3b-4d5e-4f60-8a7b-9c0d1e2f3a4b",
      "api_key_id": "0a1b2c3d-4e5f-4a6b-8c7d-8e9f0a1b2c3d",
      "action_hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
      "action_type": "payment",
      "receipt_ids": ["5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a"],
      "client_stated_at": null,
      "observed_at": "2026-11-01T08:00:01.234Z",
      "claim": "API key K recorded hash H, citing Apier receipts R, at time T",
      "record_hash": "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b",
      "record_hash_algorithm": "notary-record-v1",
      "public_log_seq": 42,
      "companies_billed": 1
    },
    "receipt": { "result": { "id": "6f1c2a3b-4d5e-4f60-8a7b-9c0d1e2f3a4b" }, "kid": "apier-2026", "signature": "<base64url-header>..<base64url-signature>" }
  }
}

The receipt is a detached RS256 signature over the record, made with the key published at /.well-known/jwks.json. Verify it offline exactly as you verify a certificate: see Verify certificate. If signing is unavailable for a moment, the record still stands and receipt is null; read the record again to get a receipt.

Step 4 — Read a record back

GET /api/v1/notary/records/{id} returns the record to any key or sub-key of the account that recorded it, with a freshly signed receipt. Another account's id and an unknown id both get 404 NOTARY_RECORD_NOT_FOUND. Reading a record is not charged.

Step 5 — Find the record in the public log

The record_hash is appended to the public receipt log with kind notary, and the next daily anchor covers it. Anyone holding the record can recompute record_hash as the lowercase SHA-256 hex of notary-record-v1: + id + : + api_key_id + : + action_hash + : + the receipt ids ascending, comma-joined, + : + observed_at, and look it up with entry_hash.

Try it in the sandbox

POST /api/v1/sandbox/notary/records takes the same body and answers with a record of the same shape, built from fixtures only: it looks no receipt up, writes nothing to the public log (public_log_seq is 0) and is never charged. The same key and body give the same record and receipt. The receipt is signed with the public sandbox key, so verify it against /.well-known/sandbox-jwks.json; a sandbox receipt never verifies against the production JWKS.

På norsk

En notarregistrering beviser bare denne faste påstanden, ordrett, og ikke noe mer: «API key K recorded hash H, citing Apier receipts R, at time T». Den sier ikke at handlingen skjedde, at den var godkjent eller lovlig, eller at hashen svarer til et bestemt dokument. Apier lagrer bare hashen, kvitteringsidentifikatorene, nøkkelens id og tidspunktet, aldri selve handlingen.

I sandkassen gir POST /api/v1/sandbox/notary/records en registrering med samme form, laget bare av testdata. Den slår ikke opp kvitteringer, skriver ingenting til den offentlige loggen og koster ingenting. Kvitteringen er signert med den offentlige sandkassenøkkelen og verifiseres mot /.well-known/sandbox-jwks.json, aldri mot produksjonsnøklene.

Building with an LLM? Read llms.txt for agent-oriented integration guidance.