Traces API
Create, manage, seal, and export verifiable proof of entire business processes. Traces group events, documents, and AI attestations into a single sealed, cryptographically proven sequence.
All endpoints require API key authentication via the x-api-key header. Traces are free to create, items within them count against your existing quota.
Lifecycle
POST /v1/traces → POST /v1/events (with trace_id) → POST /v1/traces/:id/seal → GET /v1/traces/:id/proofThe trace_id is server-generated. Your application stores it and references it when anchoring events. Events anchored to a trace are processed identically to standalone events, same hashing, same signing. The trace adds a composite proof layer on top.
Endpoints
/v1/tracesCreate a new open trace. Invoance generates the trace_id. Your application stores it and references it when anchoring events.
label is required (max 255 chars). metadata is optional JSON (max 16 KB).
{
"label": "Vendor Onboarding, Acme Corp",
"metadata": {
"department": "procurement",
"initiated_by": "j.smith@acme.com"
}
}{
"trace_id": "tr_abc123...",
"status": "open",
"created_at": "2026-03-17T12:00:00Z",
"label": "Vendor Onboarding, Acme Corp"
}/v1/tracesPaginated list of traces for the authenticated tenant. Filterable by status.
Query params: page (default 1), limit (default 25, max 100), status (open | sealed).
{
"traces": [
{
"trace_id": "tr_abc123...",
"label": "Vendor Onboarding, Acme Corp",
"status": "sealed",
"event_count": 7,
"created_at": "2026-03-17T12:00:00Z",
"sealed_at": "2026-03-17T14:30:00Z",
"composite_hash": "sha256:def456..."
}
],
"page": 1,
"limit": 25,
"total": 12,
"has_more": false
}/v1/traces/:trace_idRetrieve a single trace with ordered event summaries.
{
"trace_id": "tr_abc123...",
"label": "Vendor Onboarding, Acme Corp",
"status": "sealed",
"event_count": 7,
"created_at": "2026-03-17T12:00:00Z",
"sealed_at": "2026-03-17T14:30:00Z",
"composite_hash": "sha256:def456...",
"seal_event_id": "evt_xyz789...",
"events": [
{
"event_id": "evt_001...",
"event_type": "document.anchored",
"payload_hash": "sha256:a3f2b1...",
"ingested_at": "2026-03-17T12:05:00Z"
}
]
}/v1/traces/:trace_id/sealInitiate sealing. The trace transitions to 'sealing' immediately (blocks new events), then a background worker computes the composite hash, signs the seal event, and transitions to 'sealed'. Returns 202 Accepted.
Sealing is permanent. Once sealed, no events can be added. The trace cannot be reopened. Poll the trace status to confirm completion.
{
"trace_id": "tr_abc123...",
"status": "sealing",
"message": "Seal initiated. Poll GET /v1/traces/:trace_id for completion."
}/v1/traces/:trace_id/proofReturns the complete proof bundle for a sealed trace. Contains all events with full payloads, hashes, signatures, composite hash, seal event, and verification results.
Only available for sealed traces. Returns 409 if trace is still open or sealing.
{
"version": "1.0",
"trace_id": "tr_abc123...",
"label": "Vendor Onboarding, Acme Corp",
"tenant_domain": "acme.com",
"status": "sealed",
"created_at": "2026-03-17T12:00:00Z",
"sealed_at": "2026-03-17T14:30:00Z",
"composite_hash": "sha256:def456...",
"event_count": 7,
"events": [
{
"event_id": "evt_001...",
"event_type": "document.anchored",
"payload": { "document_ref": "contract_v2.pdf" },
"content_hash": "sha256:a3f2b1...",
"signature": "ed25519:7b1c...a4f9",
"public_key": "ed25519_pk:9c2d...b8e1",
"ingested_at": "2026-03-17T12:05:00Z"
}
],
"seal_event": {
"event_id": "evt_xyz789...",
"event_type": "trace.sealed",
"payload": { "composite_hash": "sha256:def456...", "event_count": 7 },
"content_hash": "sha256:...",
"signature": "ed25519:...",
"public_key": "ed25519_pk:...",
"ingested_at": "2026-03-17T14:30:00Z"
}
}Anchoring items to a trace
Pass the optional trace_id field to any ingest endpoint, events, documents, or AI attestations. Each item is processed identically to its standalone counterpart (same hashing, same signing). The trace_id is a grouping reference, not part of the content hash.
{
"event_type": "approval.recorded",
"trace_id": "tr_abc123...",
"payload": { ... }
}{
"document_hash": "a94a8f...",
"trace_id": "tr_abc123...",
"document_ref": "contract.pdf"
}{
"type": "output",
"trace_id": "tr_abc123...",
"payload": { ... }
}Validation: trace must exist, belong to the same tenant, and have status "open". Returns 404 if trace not found, 409 if trace is sealed or sealing. A single trace can contain any mix of events, documents, and attestations.
Full workflow (SDK)
Create a trace, add events, documents, and attestations to it, seal it, and export the proof bundle. The key: pass trace_id when ingesting any item.
from invoance import InvoanceClient
async with InvoanceClient() as client:
# 1. Create the trace
trace = await client.traces.create(
label="Invoice Processing, Q1 2026",
metadata={"department": "finance", "quarter": "Q1"},
)
print(f"Trace created: {trace.trace_id}")
# 2. Add items to the trace (pass trace_id to any endpoint)
evt1 = await client.events.ingest(
event_type="invoice.received",
payload={"invoice_number": "INV-2026-001", "amount": 5000},
trace_id=trace.trace_id,
)
print(f"Event: {evt1.event_id}")
# Anchor a document to the same trace
doc = await client.documents.anchor_file(
file="./invoice.pdf",
document_ref="INV-2026-001",
trace_id=trace.trace_id,
)
print(f"Document: {doc.event_id}")
# Add an AI attestation to the same trace
att = await client.attestations.ingest(
type="output",
input="Summarize invoice INV-2026-001",
output="Commercial invoice for $5,000…",
model_provider="openai",
model_name="gpt-4.1",
trace_id=trace.trace_id,
)
print(f"Attestation: {att.attestation_id}")
evt2 = await client.events.ingest(
event_type="payment.authorized",
payload={"invoice_number": "INV-2026-001", "payment_id": "PAY-001"},
trace_id=trace.trace_id,
)
print(f"Event: {evt2.event_id}")
# 3. Seal the trace (async, poll for completion)
await client.traces.seal(trace.trace_id)
import asyncio
while True:
t = await client.traces.get(trace.trace_id)
if t.status == "sealed":
break
await asyncio.sleep(2)
# 4. Export the proof bundle
proof = await client.traces.proof(trace.trace_id)
print(f"Sealed: {proof.event_count} items")
print(f"Composite hash: {proof.composite_hash[:32]}…")Error codes
trace_not_foundTrace ID does not exist or does not belong to this tenant.trace_sealedTrace is already sealed. No items can be added.trace_sealingTrace is currently being sealed. Try again after seal completes.empty_traceTrace has no items. A trace must contain at least one event, document, or attestation to be sealed.invalid_labelLabel is required and must be <= 255 characters.metadata_too_largeMetadata exceeds 16 KB limit.