# CrawlCheck certificate, v1: issuance, validity and revocation

Status: published 8 October 2026.

## What a certificate says
A certificate (GET /api/certify?domain=) is a signed statement that one measurement of a domain met every criterion on /certificate/<domain>. It names the measurement (`record`), when it was made (`measured_at`) and `expires_at`: 7 days after the measurement. It is free, never sold, and says nothing about the business beyond what crawlers received.

Every certificate carries `status`, the URL to check it.

## Status values
| status | meaning | relying party |
|---|---|---|
| good | no later measurement failed, not expired, no incident, not opted out | rely until next_update |
| revoked | a later measurement failed the criteria before expiry (`reason: failing_measurement`, `by_record`, `failed`) | do not rely; permanent |
| suspended | the domain's verified owner declared an incident (`reason: owner_incident`) | do not rely while it lasts |
| withdrawn | the owner opted the domain out of measurement | do not rely |
| expired | past expires_at | do not rely |
| never_certified | that measurement did not meet the criteria | the certificate is not genuine for that record |
| unknown | no such measurement on record | never treat as good |

A newer certified measurement does not revoke an older certificate; the answer stays good and names `superseded_by`. A dispute that withdraws a finding does not revoke anything either: the certificate remains a true statement about its own day, and the next measurement decides.

## Checking
- `GET /api/v1/certificate/status?domain=<subject>&record=<record>`, or POST the certificate JSON. The answer is signed (kind `crawlcheck-certificate-status`), with `next_update` at most one hour away. Verify with the keys at /keys or `node crawlcheck-verify.mjs status.json`.
- `GET /api/v1/certificates/revocations?since=<time>` is the signed list (kind `crawlcheck-certificate-revocations`): revocations logged from 2026-10-09 and suspensions in force now. Poll every `poll_seconds`; ask the status endpoint for anything older.

## Appeal
- The domain's verified owner can appeal a revocation or a failed criterion by filing a dispute against the measurement (POST /api/disputes, or the dispute form on the report). Disputes are decided on evidence: the site is re-read, an independent observer reads it from another network, and the decision is a signed resolution in the public dispute ledger (/disputes).
- If the appeal is upheld, the finding is withdrawn and the next measurement can certify. The revocation entry is never deleted: it stays in the log and the resolution is linked from the dispute ledger.
- Turnaround and how often CrawlCheck was wrong on appeal are public at /api/v1/disputes/metrics. Paying for a licence does not change the outcome.

## Relying parties
- Before an action that matters (connecting, transacting, publishing a badge as proof), check the status and act only on good.
- If the status cannot be fetched, treat the certificate as not certified for those actions (fail closed). A badge on a page may keep showing the certificate's own dates.
- Revocation is decided from measurements alone: no payment, licence or request changes it.
