Home
Home/Developers/Documents
Ed25519 signaturesSHA-256 hashes8 SDKs
Status
Sign inStart free
Home
Start here
Overview
Authentication
Errors
FAQ
API
Events
Canonical JSON and hashes
Documents
Anchoring a file
AI attestations
Attestation schema
Verifying attestations
Traces
Sealing a trace
Audit logs
Organizations
Streams
Portal
Public proof
Event schema
Exporting events
Integrations
Clerk
Auth0
Embeddable viewer
All endpoints
Reference
SDKs
Node.js
Python
Go
Java
Ruby
Rust
.NET
PHP
REST
Verification
API · Documents

Documents

Anchor the SHA-256 hash of a file to a signed, append-only ledger record and check a file against it later.

sha-256 · 3a352297…2592
sha-256 · 6093b7f5…556c

A document record is a SHA-256 hash that your tenant anchored at a point in time, with an optional human-readable reference, an event type, a JSON metadata object and, if you choose to upload it, the original file bytes. You compute the hash on your side; the backend never needs the file to anchor it.

On anchor the backend checks the hash format, the metadata size, the optional original bytes and the optional trace, reserves a document from your monthly quota, and publishes the record to a writer queue. The writer signs a payload made of the tenant id, the API key id, the event type, the hash and the anchor timestamp with the tenant's Ed25519 key, stores the row in the append-only event ledger, and stores the original in object storage when one was sent.

To check a file later, hash it again and call verify; the backend compares the submitted hash with the anchored one and returns both. To check the signature itself, fetch the record and verify signature_b64 over signed_payload_b64 with public_key_b64, or use the public proof page for the event id.

Endpoints
POST/v1/document/anchorAnchor a documentGET/v1/documentList documentsGET/v1/document/{event_id}Get a documentGET/v1/document/{event_id}/originalDownload the originalPOST/v1/document/{event_id}/verifyVerify a document hash
Limits
document_hashexactly 64 hexadecimal characters (a SHA-256 digest)
metadataup to 8,192 bytes once serialized as JSON
original_bytes_b641 byte to 5 MiB after base64 decoding, and the decoded bytes must hash to document_hash
Request body8,462,336 bytes (about 8.1 MB) on the anchor route, sized so a 5 MiB original fits once base64-encoded, plus metadata and the envelope; the other document routes keep the 2 MB framework default
List page size1 to 500 per page, default 50; values outside the range are clamped, not rejected
Documents per monththe plan's documents_per_month, consumed on every anchor call including ones later rejected with 400 or 409
Verifications per monththe plan's api_verifications_per_month, consumed on every verify call with a well-formed hash
Rate limitthe plan's rate_limit_per_sec per tenant (default 10) and 60 times that per minute, shared by all keys of the tenant
Idempotency-Keyone completed response is replayed for 24 hours; an in-flight reservation lasts 120 seconds
Endpoints
POST/v1/document/anchor
API keywriteIdempotency-Key

Anchor a document

Anchors a SHA-256 hash, with optional reference, type, metadata, original bytes and trace, and returns the new event id once the record is queued for signing.

Headers
Idempotency-Keystring

Optional key that makes retries safe; the same key with the same body replays the first response for 24 hours.

Request body
document_hashhex · required · exactly 64 hex characters

SHA-256 digest of the file; trimmed and lowercased before validation and storage.

document_refstring · default Untitled

Human-readable label for the document, such as the file name.

event_typestring · default document_anchor

Classification stored with the record and included in the signed payload.

original_bytes_b64string · 1 byte to 5 MiB decoded; the anchor route's request body limit is sized to fit this

The file itself, standard base64 with padding; the decoded bytes must hash to document_hash and are stored for later download.

metadataobject · up to 8,192 bytes serialized

Arbitrary JSON stored next to the record and returned by get.

trace_iduuid

Id of an open trace owned by the tenant; the document is attached to it and the trace must not be sealed or sealing.

  • The 201 is returned once the record is on the writer queue; the ledger row, signature and stored original are written shortly after, so a get immediately afterwards can return 404 document_not_found for a moment.
  • The monthly document quota is incremented before validation and before the duplicate check, so a request that ends in 400 or 409 still consumes one document.
  • The duplicate-hash check runs before the idempotency replay: a retry with the same Idempotency-Key gets the cached 201 only while the first request is still being written, and 409 document_already_anchored once the row exists.
  • A retry while the first request is still in flight under the same Idempotency-Key returns 202 with a body of {"status": "processing"}; that reservation expires after 120 seconds and a completed response is replayed for 24 hours.
  • original_bytes_b64 is validated after the idempotency reservation is taken and a rejection there does not release it, so a request that fails with one of the original_bytes errors leaves its Idempotency-Key reserved for up to 120 seconds; a retry in that window gets 202 processing.
  • Idempotency-Key is trimmed and ignored when empty; unlike the events endpoint, this endpoint enforces no length limit on it.
  • The anchor route sets its own request body limit of 8,462,336 bytes, sized for a 5 MiB original once base64-encoded plus metadata and the envelope; an original just over 5 MiB still reaches the handler and gets original_bytes_too_large, while a body over the route limit gets 413 payload_too_large in the JSON error shape.
  • original_bytes_b64 must be standard base64 with padding; the URL-safe alphabet is rejected with invalid_original_bytes_base64.
  • document_hash is trimmed and lowercased, so uppercase hex is accepted and stored lowercase; the uniqueness check is per tenant.
  • There is no retention field on this request; the retention applied to the record and its original comes from the plan's retention_days and is set by the writer.
  • created_at is serialized with nanosecond fraction and a +00:00 offset, for example 2026-09-22T08:14:07.512345678+00:00.
  • A body that is not valid JSON, does not match the schema or is sent without a JSON Content-Type gets invalid_json (400), invalid_request (422) or unsupported_media_type (415) in the JSON error shape.
  • Every SDK also has a file helper (anchorFile, anchor_file, AnchorFile or AnchorFileAsync) that reads a file, computes the hash, base64-encodes the bytes into original_bytes_b64 and calls this endpoint; pass skipOriginal or skip_original to anchor the hash only.
Node.js
import { readFileSync } from "node:fs";
import { createHash } from "node:crypto";
import { InvoanceClient } from "invoance";

const file = readFileSync("./INV-2026-0917.pdf");
const documentHash = createHash("sha256").update(file).digest("hex");

// Reads INVOANCE_API_KEY from the environment.
const client = new InvoanceClient();

const result = await client.documents.anchor({
  documentHash,
  documentRef: "INV-2026-0917.pdf",
  eventType: "invoice.issued",
  metadata: { invoice_number: "INV-2026-0917", amount: 5230, currency: "USD" },
  idempotencyKey: "anchor-" + documentHash,
});
console.log(result.event_id, result.status);
Response · 201
{
  "event_id": "7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4",
  "created_at": "2026-09-22T08:14:07Z",
  "document_hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
  "status": "accepted"
}
Response fields
event_iduuid

Id of the new document record; use it with get, original, verify and the public proof page.

created_attimestamp (ISO 8601)

When the request was accepted; also the ts value inside the signed payload.

document_hashhex

The hash as stored, lowercase.

statusstring

Always accepted; the ledger row is written by the writer shortly after. One of accepted.

Errors
missing_api_key401

Neither an Authorization header nor an X-API-Key header was sent.

invalid_authorization_scheme401

The Authorization header is present but does not start with Bearer.

invalid_api_key_format401

The key does not start with invoance_live_.

invalid_api_key401

No active key matches the value sent.

api_key_revoked401

The key exists but has been revoked.

ip_not_allowed403

The key has IP rules and the caller's address is not on the list.

rate_limited429

The tenant exceeded its plan's requests per second or 60 times that per minute; Retry-After is set.

api_key_lookup_failed500

The key could not be looked up in the database.

insufficient_scope403

The key does not have the write scope.

invalid_api_context401

The authenticated context has no API key id; not expected for key-authenticated calls.

payment_required402

The tenant's subscription is past due and the plan is not the free developer tier.

feature_not_available403

The plan's documents_per_month limit is 0.

quota_exceeded429

The tenant has used its documents_per_month for the current billing period.

invalid_json400

The body is not valid JSON; the message carries the parser's position.

unsupported_media_type415

The Content-Type header is not application/json.

invalid_request422

The JSON does not match the request schema, for example a missing document_hash; the message names the field.

payload_too_large413

The whole JSON body is over the anchor route's limit of 8,462,336 bytes. A 5 MiB original fits; an original just over 5 MiB gets original_bytes_too_large instead.

invalid_document_hash400

document_hash is not exactly 64 hex characters after trimming.

invalid_metadata400

metadata could not be serialized; not reachable with valid JSON.

metadata_too_large400

metadata serializes to more than 8,192 bytes.

trace_not_found404

trace_id was sent and no trace with that id belongs to the tenant.

trace_not_open409

trace_id points at a trace whose status is sealed or sealing.

trace_invalid_status400

trace_id points at a trace in a status other than open, sealed or sealing.

document_already_anchored409

A record with the same document_hash already exists for the tenant.

idempotency_key_reuse_mismatch409

The Idempotency-Key was already used with a different request body.

invalid_original_bytes_base64400

original_bytes_b64 is not valid standard base64.

original_bytes_empty400

original_bytes_b64 decodes to zero bytes.

original_bytes_too_large400

original_bytes_b64 decodes to more than 5 MiB.

original_bytes_hash_mismatch400

The SHA-256 of the decoded original does not equal document_hash.

quota_check_failed500

The plan limits or the Redis quota counter could not be read.

db_error500

The trace status lookup failed.

internal_error500

The duplicate-hash lookup failed.

hash_decode_failed500

The validated hash could not be decoded; not expected.

serialization_failed500

The queue envelope or the response could not be serialized.

ingest_failed500

Publishing to the writer queue failed; the idempotency reservation is released so a retry can re-ingest.

GET/v1/document
API keyread

List documents

Returns a page of the tenant's active document records, newest first, with optional date and reference filters.

Query parameters
pageinteger · default 1

1-based page number; values below 1 are raised to 1.

limitinteger · 1 to 500 · default 50

Records per page; clamped into the allowed range rather than rejected.

date_fromtimestamp (ISO 8601)

Only records anchored at or after this instant.

date_totimestamp (ISO 8601)

Only records anchored before this instant (exclusive).

document_refstring

Only records whose document_ref equals this value exactly.

  • Only records with access_tier active are returned; sealed records past retention are left out of both documents and total.
  • Ordering is anchored_at descending; there is no cursor, so page through with page and limit.
  • date_from is inclusive and date_to is exclusive on anchored_at; a value that does not parse as an RFC 3339 timestamp is rejected by the framework with a plain-text 400.
  • document_ref is an exact, case-sensitive match, not a prefix or substring search.
  • Each distinct tenant, page, limit and filter combination is cached in Redis for 30 seconds, so a record anchored a moment ago can be missing until the cache expires.
  • A key with the write scope passes the read check, so either scope can list.
  • created_at is serialized with a fractional second and a Z suffix, for example 2026-09-22T08:14:07.512345Z.
Node.js
import { InvoanceClient } from "invoance";

// Reads INVOANCE_API_KEY from the environment.
const client = new InvoanceClient();

const page = await client.documents.list({
  limit: 25,
  dateFrom: "2026-09-01T00:00:00Z",
});
console.log(page.total, page.has_more);
for (const d of page.documents) {
  console.log(d.event_id, d.document_ref, d.has_original);
}
Response · 200
{
  "documents": [
    {
      "event_id": "7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4",
      "document_ref": "INV-2026-0917.pdf",
      "document_hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
      "event_type": "invoice.issued",
      "has_original": true,
      "created_at": "2026-09-22T08:14:07Z"
    }
  ],
  "page": 1,
  "limit": 50,
  "total": 1,
  "has_more": false
}
Response fields
documentsobject[]

The records on this page, ordered by anchor time descending.

documents[].event_iduuid

Id of the document record.

documents[].document_refstring

The reference given at anchor time, or Untitled.

documents[].document_hashhex

The anchored SHA-256 digest, lowercase.

documents[].event_typestring

The type given at anchor time, or document_anchor.

documents[].has_originalboolean

True when an original was uploaded and stored.

documents[].created_attimestamp (ISO 8601)

When the record was anchored.

pageinteger

The page returned, after clamping.

limitinteger

The page size used, after clamping.

totalinteger

Number of active records matching the filters across all pages.

has_moreboolean

True when a later page exists.

Errors
missing_api_key401

Neither an Authorization header nor an X-API-Key header was sent.

invalid_authorization_scheme401

The Authorization header is present but does not start with Bearer.

invalid_api_key_format401

The key does not start with invoance_live_.

invalid_api_key401

No active key matches the value sent.

api_key_revoked401

The key exists but has been revoked.

ip_not_allowed403

The key has IP rules and the caller's address is not on the list.

rate_limited429

The tenant exceeded its plan's requests per second or 60 times that per minute; Retry-After is set.

api_key_lookup_failed500

The key could not be looked up in the database.

insufficient_scope403

The key has neither the read nor the write scope.

db_error500

The count or data query failed.

GET/v1/document/{event_id}
API keyread

Get a document

Returns one document record with its hash, the signed payload, the Ed25519 signature and public key, the metadata and the issuing organization.

Path parameters
event_iduuid · required

Id returned by anchor.

  • To check the signature locally, base64-decode signed_payload_b64, signature_b64 and public_key_b64 and run an Ed25519 verify over the payload bytes with the 32-byte key; the payload's document_hash_hex must equal the hash of your file.
  • A record past retention is sealed and returns 410 retention_expired rather than 404, so a client can tell an expired record from an unknown id; verify still works on sealed records.
  • Each successful read writes a usage row (resource documents, action read) in the background; it does not consume a quota.
  • A key with the write scope passes the read check, so either scope can read.
  • created_at is serialized with nanosecond fraction and a +00:00 offset, for example 2026-09-22T08:14:07.512345678+00:00.
  • domain_verified_at and logo_url are omitted from organization when they are null.
  • The Node SDK types organization and metadata as optional and the Go, Rust and .NET SDKs as nullable, but the backend always returns organization and returns metadata as an object.
Node.js
import { InvoanceClient } from "invoance";

// Reads INVOANCE_API_KEY from the environment.
const client = new InvoanceClient();

const doc = await client.documents.get("7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4");
console.log(doc.document_hash, doc.has_original, doc.created_at);
console.log(doc.organization?.issuer_name, doc.organization?.domain_verified);
Response · 200
{
  "event_id": "7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4",
  "tenant_id": "3f9d2c8e-6b41-4a7d-9e2f-8c1b5a7d0e63",
  "document_ref": "INV-2026-0917.pdf",
  "document_hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
  "signature_b64": "RiqZH7z7hje5RxOS8WcCxs0i1ZjbKBKXrRRLXWCLzSM1CC/sFx9zkKcRl80jjI4O9RcOnsZ/RB1yfuBzo9PK+g==",
  "signed_payload_b64": "eyJ2IjoyLCJ0ZW5hbnRfaWQiOiIzZjlkMmM4ZS02YjQx…",
  "public_key_b64": "M/EMiSYgI9YYW5CkEgBnaHAuljw8cuyoaOUbcLH5OPQ=",
  "has_original": true,
  "metadata": {
    "invoice_number": "INV-2026-0917",
    "amount": 5230,
    "currency": "USD"
  },
  "created_at": "2026-09-22T08:14:07Z",
  "organization": {
    "name": "Northwind Traders",
    "issuer_name": "Northwind Traders Ltd",
    "primary_domain": "northwind.example",
    "domain_verified": true,
    "domain_verified_at": "2026-08-30T11:02:45Z",
    "logo_url": "https://cdn.invoance.com/logos/northwind.png"
  }
}
Response fields
event_iduuid

Id of the document record.

tenant_iduuid

Tenant that anchored the document; also inside the signed payload.

document_refstring

The reference given at anchor time, or Untitled.

document_hashhex

The anchored SHA-256 digest, lowercase.

signature_b64string

Base64 of the 64-byte Ed25519 signature over the exact bytes of signed_payload_b64.

signed_payload_b64string

Base64 of the JSON the tenant key signed: v, tenant_id, actor_type, actor_id, event_type, document_hash_hex and ts.

public_key_b64string

Base64 of the tenant's raw 32-byte Ed25519 public key; also published at the public keys endpoint.

has_originalboolean

True when an original was uploaded and stored.

metadataobject

The metadata object sent at anchor time, or an empty object when none was sent.

created_attimestamp (ISO 8601)

When the record was anchored.

organizationobject

The issuing organization as recorded for the tenant that anchored the document.

organization.namestring

Organization name.

organization.issuer_namestring

Name the organization signs as.

organization.primary_domainstring

Primary domain of the organization.

organization.domain_verifiedboolean

True when the primary domain has passed DNS verification.

organization.domain_verified_attimestamp (ISO 8601)

When the domain was verified; omitted when it has not been.

organization.logo_urlstring

Logo URL; omitted when the organization has none.

Errors
missing_api_key401

Neither an Authorization header nor an X-API-Key header was sent.

invalid_authorization_scheme401

The Authorization header is present but does not start with Bearer.

invalid_api_key_format401

The key does not start with invoance_live_.

invalid_api_key401

No active key matches the value sent.

api_key_revoked401

The key exists but has been revoked.

ip_not_allowed403

The key has IP rules and the caller's address is not on the list.

rate_limited429

The tenant exceeded its plan's requests per second or 60 times that per minute; Retry-After is set.

api_key_lookup_failed500

The key could not be looked up in the database.

insufficient_scope403

The key has neither the read nor the write scope.

invalid_path_parameter400

event_id is not a UUID.

document_not_found404

No record with this id belongs to the tenant, or the writer has not stored it yet.

retention_expired410

The record is sealed because its plan retention window and grace period have passed.

db_error500

The lookup query failed.

GET/v1/document/{event_id}/original
API keyread

Download the original

Returns the file bytes that were uploaded with the anchor request, as an application/octet-stream body.

Path parameters
event_iduuid · required

Id returned by anchor.

  • The body is the file exactly as uploaded, not JSON; the response carries Content-Type application/octet-stream and Content-Disposition inline, and no file name.
  • Only records with access_tier active are served, so a sealed record's original returns 404 document_not_found even though the record still verifies.
  • Originals the writer stores in object storage are streamed on every call; originals stored in the database are cached in Redis for 5 minutes.
  • This route uses the framework path extractor, so a non-UUID event_id gets a plain-text 400 rather than the JSON error shape.
  • No quota is consumed and no usage row is written by this endpoint.
  • The same handler also serves the dashboard at /v1/documents/{event_id}/original with session auth; the API path is the one above.
Node.js
import { writeFileSync } from "node:fs";
import { InvoanceClient } from "invoance";

// Reads INVOANCE_API_KEY from the environment.
const client = new InvoanceClient();

const bytes = await client.documents.getOriginal("7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4");
writeFileSync("./INV-2026-0917.pdf", Buffer.from(bytes));
console.log(bytes.byteLength);
Response · 200
<the original file bytes; Content-Type: application/octet-stream, Content-Disposition: inline>
Errors
missing_api_key401

Neither an Authorization header nor an X-API-Key header was sent.

invalid_authorization_scheme401

The Authorization header is present but does not start with Bearer.

invalid_api_key_format401

The key does not start with invoance_live_.

invalid_api_key401

No active key matches the value sent.

api_key_revoked401

The key exists but has been revoked.

ip_not_allowed403

The key has IP rules and the caller's address is not on the list.

rate_limited429

The tenant exceeded its plan's requests per second or 60 times that per minute; Retry-After is set.

api_key_lookup_failed500

The key could not be looked up in the database.

insufficient_scope403

The key has neither the read nor the write scope.

document_not_found404

No original was uploaded for this record, the record does not belong to the tenant, or the record is sealed.

db_query_failed500

The lookup query failed.

r2_fetch_failed500

The object could not be read from object storage.

POST/v1/document/{event_id}/verify
API keyread

Verify a document hash

Compares a SHA-256 hash you supply with the hash anchored under the event id and returns whether they match, both hashes and the anchor time.

Path parameters
event_iduuid · required

Id returned by anchor.

Request body
document_hashhex · required · exactly 64 hex characters

SHA-256 digest of the file you hold now; compared byte for byte with the anchored digest.

  • This compares hashes only; it does not check the Ed25519 signature and there is no signature_valid field. To check the signature, fetch the record with get and verify signature_b64 over signed_payload_b64 with public_key_b64.
  • The lookup has no access_tier filter, so a sealed record past retention can still be verified even though get returns 410 and original returns 404 for it.
  • Hash validation runs before the quota check, so a malformed document_hash returns 400 without consuming a verification; a well-formed one consumes one api_verifications_per_month whether or not it matches.
  • Each call writes a verification_events row in the background with status verified or failed, source api and is_public false; it appears in the dashboard's verification history.
  • The anchored hash, reference and organization are cached in Redis for 60 seconds per event_id.
  • document_hash is decoded as hex without lowercasing, so uppercase input is accepted; submitted_hash comes back lowercase.
  • A key with the write scope passes the read check, so either scope can verify.
  • anchored_at is serialized with a fractional second and a Z suffix, for example 2026-09-22T08:14:07.512345Z.
  • A body that is not valid JSON is rejected by the framework with a plain-text 400, 415 or 422 rather than the JSON error shape.
Node.js
import { readFileSync } from "node:fs";
import { createHash } from "node:crypto";
import { InvoanceClient } from "invoance";

const file = readFileSync("./INV-2026-0917.pdf");
const documentHash = createHash("sha256").update(file).digest("hex");

// Reads INVOANCE_API_KEY from the environment.
const client = new InvoanceClient();

const result = await client.documents.verify("7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4", {
  documentHash,
});
console.log(result.match_result, result.anchored_hash, result.anchored_at);
Response · 200
{
  "event_id": "7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4",
  "match_result": true,
  "document_ref": "INV-2026-0917.pdf",
  "anchored_hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
  "submitted_hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
  "anchored_at": "2026-09-22T08:14:07Z",
  "organization": {
    "name": "Northwind Traders",
    "issuer_name": "Northwind Traders Ltd",
    "primary_domain": "northwind.example",
    "domain_verified": true,
    "domain_verified_at": "2026-08-30T11:02:45Z",
    "logo_url": "https://cdn.invoance.com/logos/northwind.png"
  }
}
Response fields
event_iduuid

The id that was checked.

match_resultboolean

True when submitted_hash equals anchored_hash.

document_refstring

The reference stored with the record.

anchored_hashhex

The digest stored at anchor time, lowercase.

submitted_hashhex

The digest you sent, re-encoded lowercase.

anchored_attimestamp (ISO 8601)

When the record was anchored.

organizationobject

The issuing organization as recorded for the tenant that anchored the document.

organization.namestring

Organization name.

organization.issuer_namestring

Name the organization signs as.

organization.primary_domainstring

Primary domain of the organization.

organization.domain_verifiedboolean

True when the primary domain has passed DNS verification.

organization.domain_verified_attimestamp (ISO 8601)

When the domain was verified; omitted when it has not been.

organization.logo_urlstring

Logo URL; omitted when the organization has none.

Errors
missing_api_key401

Neither an Authorization header nor an X-API-Key header was sent.

invalid_authorization_scheme401

The Authorization header is present but does not start with Bearer.

invalid_api_key_format401

The key does not start with invoance_live_.

invalid_api_key401

No active key matches the value sent.

api_key_revoked401

The key exists but has been revoked.

ip_not_allowed403

The key has IP rules and the caller's address is not on the list.

rate_limited429

The tenant exceeded its plan's requests per second or 60 times that per minute; Retry-After is set.

api_key_lookup_failed500

The key could not be looked up in the database.

insufficient_scope403

The key has neither the read nor the write scope.

invalid_path_parameter400

event_id is not a UUID.

bad_request400

document_hash is not exactly 64 hex characters.

payment_required402

The tenant's subscription is past due and the plan is not the free developer tier.

feature_not_available403

The plan's api_verifications_per_month limit is 0.

quota_exceeded429

The tenant has used its api_verifications_per_month for the current billing period.

document_not_found404

No record with this id belongs to the tenant.

quota_check_failed500

The plan limits or the Redis quota counter could not be read.

db_error500

The lookup query failed.

Terms
document_hashThe lowercase hex SHA-256 digest of the file, computed by the caller and stored as the identity of the record.
document_refA free-text label for the document, such as a file name or invoice number; defaults to Untitled.
event_typeA free-text classification stored with the record and included in the signed payload; defaults to document_anchor.
originalThe file bytes uploaded with the anchor request, stored in object storage and served back by the original endpoint.
has_originalTrue when an original was uploaded with the anchor and is available for download.
anchored_atThe timestamp the ledger row records for the anchor; returned as created_at on most endpoints.
signed payloadThe JSON the tenant key signed: version, tenant id, actor type and id, event type, hash and timestamp.
sealedA record past its plan retention window plus grace; hidden from list, 410 on get, 404 on original, still verifiable.
match_resultTrue when the hash submitted to verify equals the anchored hash byte for byte.

Proof infrastructure. Records are hashed, signed with your organization's Ed25519 key, and stored append-only, so anyone can check them later.

Products

  • Audit Logs
  • Event Ledger
  • AI Attestation
  • Document Anchoring
  • Traces

Developers

  • Documentation
  • API reference
  • SDKs
  • How it works
  • How traces seal
  • System status

Verify

  • Audit Log
  • Event
  • AI Attestation
  • Document
  • Trace

Company

  • Company overview
  • What is Invoance
  • Pricing
  • Security
  • Compliance teams
  • Finance teams
  • Partners
  • Brand assets
  • Resources
  • Help center
  • Contact
© 2025 – 2026 Invoance, Inc. All rights reserved.© 2026 Invoance, Inc. All rights reserved.
PrivacyLegal noticeLegal FAQ