The Standard
Receipt Specification v1
A record is only as good as the fetch behind it. A receipt names one fact: this file, named by its hash, came from this source, at this time, under these reuse terms. It does not carry the record itself, and it does not judge whether the record is right. Anyone can recompute the hash and check it for themselves.
The receipt object
Every field of a receipt, read straight from the schema the door answers: one source, never a second copy kept in step by hand.
| Field | Type | Required | Meaning |
|---|---|---|---|
| id | string | Optional | The record this receipt is bound to, together with `kind` and `key`; present when a door serves the receipt beside a record, absent for a sidecar that has no record id. |
| kind | string | Optional | The corpus kind of the record this receipt is bound to; present and absent together with `id` and `key`. |
| key | string | Optional | The record's key within its kind; present and absent together with `id` and `kind`. |
| register | string | Required | The name of the register the file came from. |
| publisher | string | Required | The organization that publishes the register. |
| homeUrl | string (URL) | Optional | The register's home page. |
| sourceUrl | string (URL) | Required | The exact URL the file was fetched from. |
| fileName | string | Required | The name of the published file the hash covers. |
| sha256 | string (hash) | Required | The sha256 hash of the exact bytes named by `fileName`. |
| bytes | integer | Required | The size of the file, in bytes. |
| publishedAt | string (date-time) or string (date) or null | Required | The date the publisher states it released the file; `null` when the publisher states no date. |
| fetchedAt | string (date-time) | Required | The date and time the file was fetched. |
| terms.text | string | Required | The publisher's reuse terms, quoted verbatim. |
| terms.url | string (URL) | Optional | A page where the publisher states those terms. |
| terms.readOn | string (date-time) or string (date) | Optional | The date the terms were read. |
| retained | boolean | Required | Whether the fetched bytes are kept, content-addressed, by the store. `false` is a valid value: some publishers’ terms forbid storing the bytes, and the hash still names them. |
| retainedAt | string (date-time) | Optional | The date and time the bytes were stored; present only when `retained` is `true`. |
| staleAfter | string (date-time) | Optional | The date and time after which the register's own refresh schedule calls this receipt due for a new fetch. |
| supersedingPending | boolean | Optional | Whether a newer fetch is already underway and will supersede this receipt. |
| verify.method | the literal "sha256 of the published file" | Required | Names the check a reader can run; present only when `verify` is given, and present together with `command`. |
| verify.command | string | Required | A command a reader can run to recompute the hash, for example `curl -sL <sourceUrl> | sha256sum`. |
| download | string (URL) or null | Optional | A URL to the retained bytes, or `null` when no download is offered. |
The four rules
- Hash
- The hash is the sha256 of the exact bytes named by the file, and nothing else: not a page's rendered text, not a derived field, the file as the publisher served it.
- History
- A receipt is never edited. A new fetch mints a new receipt, and the old one stays reachable. The history of a register only grows; a later fetch supersedes an earlier one, it does not erase it.
- Correction
- A correction to a record sits beside the record, never written into the receipt. The receipt's fields describe the fetched file alone, and none of them change for a dispute, a flag, or a correction about the record.
- Terms
- The reuse terms are the publisher's own sentence, quoted verbatim, together with the date they were read. They are the publisher's words, not a keeper's summary of them.
Emit a receipt
A keeper emits a receipt one of two ways: a sidecar file beside the published file, or a header on the published file itself. Both carry the same fields, read below from a real, current receipt.
The sidecar
A JSON file named <file>.receipt.json, placed beside the published file it describes.
{
"register": "OIG List of Excluded Individuals/Entities (LEIE)",
"publisher": "U.S. Department of Health and Human Services, Office of Inspector General",
"sourceUrl": "https://oig.hhs.gov/exclusions/downloadables/UPDATED.csv",
"fileName": "UPDATED.csv",
"sha256": "175352046e438bc477fe0f8985c645c3eb492114b449e13a5700b30e00d27417",
"bytes": 15608468,
"publishedAt": "2026-09-10",
"fetchedAt": "2026-09-26T17:02:07.523Z",
"terms": {
"text": "HHS-OIG offers a CSV download of active OIG exclusions that can be used on your local computer or to populate the database program of your choice. The LEIE Database CSV file contains the entire dataset of all exclusions in effect. Individuals and entities who have been reinstated are removed from this file. The Privacy Act prohibits the distribution of SSNs so regardless of your exact process, you'll need to use the Online Search to verify specific individuals and entities.",
"url": "https://oig.hhs.gov/exclusions/exclusions_list.asp",
"readOn": "2026-09-24"
},
"retained": true,
"homeUrl": "https://oig.hhs.gov/exclusions/exclusions_list.asp",
"retainedAt": "2026-09-30T06:02:12.039Z",
"staleAfter": "2026-10-26T17:02:07.523Z",
"supersedingPending": false
}The header
A Link response header on the published file itself, naming a URL that answers with the same fields.
Link: <https://api.pansofica.com/sports-data/corpora/exclusion/sources/latest.receipt.json>; rel="receipt"Validate a receipt
Paste the address of a receipt, or a .receipt.json sidecar. The address is sent on, once, to the validator; nothing about it is kept here.
The mark
A keeper may display this mark once a register's receipts validate against this specification. It answers 404, never a grey badge, when there is no valid receipt yet.
The embed
<img src="https://api.pansofica.com/sports-data/receipts/mark/oig-leie.svg" alt="Receipted">The doors
Every door this page names, as a plain address.
- The schema door: https://api.pansofica.com/sports-data/receipts/spec
- A record with its receipt: https://api.pansofica.com/sports-data/records/exclusion:0000ecfab20bf705451f9714a5da82331522efb8204d200e879c511e71511b80?view=provenance
- A register's own receipts, newest first: https://api.pansofica.com/sports-data/corpora/exclusion/sources