InvoanceInvoance
Log inStart free
Developers
Search docs…⌘K
Getting started
OverviewConceptsAuthenticationCreate an API key
API reference
EndpointsErrors
Audit Logs
Quick startEvent schemaExporting eventsSDK reference
AI Attestations
Quick startAttestation schemaVerification & proofSDK reference
Events
OverviewSDK reference
Documents
OverviewSDK reference
Traces
OverviewSDK reference
SDKs
PythonNode.jsGoJavaRubyRust.NETPHPcURL
Verification
How it works
Support
API FAQ

Documents SDK

The documents namespace lives under client.documents. Anchoring a document seals its SHA-256 into a signed, append-only record — optionally storing the original bytes (encrypted) for later retrieval — so anyone can later prove a file existed, unaltered, at anchor time. A key needs the write scope to anchor and the read scope to list, get, download, and verify.

Base URL and authentication

All endpoints live under https://api.invoance.com/v1. Authenticate every request with your API key, either as Authorization: Bearer invoance_live_... or as X-API-Key: invoance_live_....

Install

Python
pip install invoance

# The Ed25519 signature verifier (verify_signature) additionally needs PyNaCl:
pip install pynacl

Create a client

Both SDKs read INVOANCE_API_KEY from the environment automatically. You can also pass the key explicitly.

Python
import asyncio
from invoance import InvoanceClient

async def main() -> None:
    # Reads INVOANCE_API_KEY from the environment
    async with InvoanceClient() as client:
        ...
    # Or pass it explicitly:
    # async with InvoanceClient(api_key="invoance_live_...") as client:

asyncio.run(main())

Methods

Anchor a file

RecommendedPOST/document/anchor

Pass a file path or raw bytes; the SDK reads it, computes the SHA-256 hash, and uploads the original bytes (stored encrypted) for later retrieval. Set skip_original (skipOriginal in Node) to anchor the hash only without storing the file.

Python
result = await client.documents.anchor_file(
    file="./invoice.pdf",
    document_ref="Invoice #1042",
    event_type="invoice",
    metadata={"amount": 5230, "currency": "USD"},
    trace_id="9549c332-…",  # optional, attach to a trace
)
print(result.event_id)

Anchor a hash

POST/document/anchor

If you already have the SHA-256 hash, use the low-level method directly. Nothing leaves your machine but the digest and reference — no bytes are uploaded.

Python
result = await client.documents.anchor(
    document_hash="a94a8fe5ccb19ba61c4c0873d391e987…",
    document_ref="Invoice #1042",
)
print(result.event_id)

List documents

GET/document

Page through your document events, newest first. Paginated with optional filters; limit defaults to 50.

Python
page = await client.documents.list(page=1, limit=50)
for d in page.documents:
    print(d.event_id, d.document_ref)

Get a document

GET/document/{event_id}

Retrieve a document event by ID. has_original tells you whether the original bytes were stored at anchor time and can be downloaded.

Python
doc = await client.documents.get("9549c332-a52b-…")
print(doc.document_ref, doc.has_original)

Download the original

GET/document/{event_id}/original

Retrieve the original file bytes, if they were uploaded during anchoring. Returns raw bytes you can write straight to disk.

Python
data = await client.documents.get_original("9549c332-a52b-…")
with open("invoice.pdf", "wb") as f:
    f.write(data)

Verify a document

POST/document/{event_id}/verify

Compare a hash you computed against the anchored document. match_result is true when your digest matches the sealed record.

Python
result = await client.documents.verify(
    "9549c332-a52b-…",
    document_hash="a94a8fe5ccb19ba61c4c0873d391e987…",
)
print(result.match_result)  # True

Errors

Every error is a JSON body of { "error": code, "message": text }. The codes you will meet most often here: invalid_document_hash, missing_document_hash (400), idempotency_key_reuse_mismatch (409), document_not_found (404), original_not_stored (404), payload_too_large (413), and quota_exceeded (429). The full catalog, including quota and rate-limit behavior, lives in the error reference.

Next steps

Documents quick startSDK overviewError reference
Invoance

Neutral digital proof infrastructure for business. Tamper-evident, independently verifiable records.

Subscribe to our newsletter

Products
Platform
How It Works
Developers
Verify
Resources
Help & Legal
Products
  • Event Ledger
  • Document Anchoring
  • AI Attestation
  • Audit Logs
Platform
  • Why Invoance
  • For Compliance Teams
  • For Finance Teams
  • Pricing
How It Works
  • Overview
  • Event Ledger
  • Document Anchoring
  • AI Attestation
Developers
  • Overview
  • Endpoints
  • Authentication
  • Concepts
Verify
  • Verify Document
  • Verify AI Attestation
  • Verify Event
  • Verify Trace
Resources
  • All Resources
  • SOC 2 Guide
  • HIPAA Guide
  • ISO 27001 Guide
Help & Legal
  • Support
  • Status
  • Verification Help
  • FAQ

Invoance provides technical verification and proof infrastructure for digital records. Invoance does not issue legal, financial, or regulatory advice.

Records anchored through Invoance are cryptographically signed and tamper-evident by design. Invoance does not verify the accuracy, legality, or authenticity of document contents, only that a record existed in a specific form at a specific time. Verification links are publicly resolvable and do not require authentication. Invoance does not act as a custodian of funds, a legal authority, or a regulated financial entity. Use of Invoance does not constitute legal compliance. Consult qualified counsel for your specific obligations.

© 2025 – 2026 Invoance, Inc. All rights reserved.••