Verify a document hash
/v1/verificationsSubmits a document hash and returns a verdict — Audrie's answer to "does this document check out, and what do you know about it".
Both cryptographic checks are recomputed server-side for your request. Nothing in the request body is trusted beyond the identifiers used to look records up: a client that lies about a hash can only produce a verdict that fails its own verification.
Works with or without a credential. See Disclosure tiers.
What you get back
verdict is a single value you can branch on. It is derived from the
four checks in matches[].checksPerformed plus revocation state, and it
fails closed: anything Audrie cannot fully substantiate is never reported
as verified.
Every determinate outcome — no_record included — returns 200 with a
verdict. A hash Audrie holds no record of is information, not a failed
request.
mode is partial on every response. Read the field rather than
hardcoding the value.
One hash, several records
You do not pick the record. One hash can legitimately have several records — a re-signing, or several parties authenticating the same document — so the response returns every anchored match, ordered by anchor time, earliest first. The timeline is the answer.
verdict asserts that some valid anchored authentication exists, not
that a particular party made it. Read each match's own status,
signerStanding and signerHint before attributing a document to
anyone.
Signer standing is live
signerStanding is recomputed at request time. A certificate issued
earlier carries a frozen snapshot; this endpoint does not. The two can
legitimately disagree, and the live value is the current answer.
Errors
A 400 here means originalDocHash is not sha256: followed by 64
lowercase hex characters, reference is longer than 128 characters or
contains a control character, or the body is not a JSON object.
error.details names the field.
Authorization
apiKey Authorization: Bearer aud_live_…
Optional on POST /v1/verifications, which answers without any
credential. Required to list or read verifications back.
Send exactly one Authorization header. A credential that is present and
does not work is refused rather than downgraded to the anonymous tier.
Issue a key in the portal under Settings → Organisation → API credentials; it is shown once, at creation.
Two scopes exist. verifications:read covers every verification
operation and is on every key. records:write covers
POST /v1/records and is granted only on a live credential whose
organisation holds the organisation-issued authentication add-on at the
moment the key is minted — a test key never receives it, because
there is no sandbox ledger and the records it would create would be
permanent — scopes are fixed then and never widen afterwards, because a
credential's recorded scopes are what an auditor reads to know what that
key could do on a given date. Buying the add-on later means minting a new
key; the old one keeps verifying.
Scopes, rotation, revocation, the live and test prefixes and what to
do about a leaked key:
https://audrie.io/docs/authentication
In: header
Request Body
application/json
The document hash to verify, and an optional identifier of your own.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/verifications" \ -H "Content-Type: application/json" \ -d '{ "originalDocHash": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }'{ "verdict": "verified", "disclosureTier": "public", "assuranceLevel": "audrie.registry.v1", "mode": "partial", "originalDocHash": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "verifiedAt": "2026-08-21T04:11:09Z", "matches": [ { "recordId": "8f7d2c11-2b3e-4a5f-9c8d-1e2f3a4b5c6d", "kind": "pdf_embedded", "status": "active", "recordIssuedAt": "2026-05-02T22:14:51Z", "signerType": "user", "signerStanding": "good_standing", "signerHint": "Wren & Associates LLP", "checksPerformed": { "hashBinding": "pass", "userSignature": "pass", "serverSeal": "pass", "anchorStatus": "anchored" }, "anchor": { "topicId": "0.0.4915623", "transactionId": "0.0.1234@1746223981.000000000", "sequenceNumber": 8814, "consensusAt": "2026-05-02T22:14:51.221Z", "mirrorNodeUrl": "https://mainnet-public.mirrornode.hedera.com/api/v1/transactions/0.0.1234-1746223981-000000000" } } ]}List your organisation's verifications GET
Returns your organisation's verification log, newest first. Scoped to the calling key's organisation and environment: a `test` key never sees `live` verifications. Anonymous verifications are attributable to no one and are not logged, so a credential is required. Rows carry the verdict as it was recorded. They carry no `matches`: to get matches for a hash, `POST` it, which is the operation that computes them. Cursor-paginated. See [Pagination](https://audrie.io/docs/pagination). ## Errors Every query parameter is rejected rather than ignored or clamped. An unparseable `from`, an out-of-range `limit` or a cursor that does not decode all answer `400` with the offending field in `error.details` — a silently different page is worse than a refusal on a log you reconcile against.
Read one verification back GET
Returns one verification as it was recorded. Scoped to the calling key's organisation and environment. `matches` is always `[]` here. Matches are derived from the document hash rather than stored, so this operation answers "what did we tell you, and when". To get current matches, `POST` the hash again, which is the operation that computes them. ## Errors A `404` means the id does not exist, belongs to another organisation, or belongs to another environment. These are not distinguished, and a malformed id answers the same way. Existence is not disclosed.