Documentation

Docs

Use the official Node/TypeScript SDK, Python SDK, CLI, or raw HTTP API to capture provenance for AI generations, verify outputs, and move from local to production without changing your evidence contract.

AuthenChain is infrastructure for verifiable AI outputs. Official SDKs are available for Node.js, TypeScript, and Python. Use raw HTTP only when a supported SDK does not fit the customer runtime.
AuthenChain provides technical evidence for AI output provenance, integrity, traceability, audit, chain of custody, verification, and dispute workflows. AuthenChain does not provide legal advice and does not determine legal compliance.
Buyers reviewing regulatory posture can use the public Regulatory Coverage page for the current framework map, status legend, and customer-owned boundaries.
Recommended path

Use @authenchain/node for Node.js/TypeScript backends and authenchain from sdks/python for Python AI services, data pipelines, and model-serving workloads.

Auth

Use API keys in Authorization: Bearer ac_test_example_... or x-api-key. Keep keys server-side only.

Never expose AuthenChain keys in browser bundles, screenshots, support tickets, or chat transcripts.

Base URL

Production examples use https://authenchain.com. Local development may use http://localhost:3000. Set AUTHENCHAIN_BASE_URL explicitly so environment intent is clear.

On this page
The SDK examples below map directly to the current SIGN, VERIFY, Evidence Pack export, and public Evidence Pack verification endpoints. Public production verification is available at https://authenchain.com/verify. No backend refactor is required.

What AuthenChain is for

  • Sign AI outputs at generation time.
  • Verify origin and integrity later in your pipeline.
  • Attach review-ready provenance to agents, orchestrators, and regulated workflows.

AuthenChain verifies origin and integrity properties when content was signed at creation time. It does not judge truthfulness or detect AI on its own.

Official SDKs

Choose the SDK that matches the customer server runtime. All official SDKs preserve the same AuthenChain evidence contract: server-side API key, final output boundary, signed metadata, trace ID, signature, public key ID, verification, Evidence Pack export, and customer-owned legal interpretation.

RuntimePackage / pathUse forMain methods
Node.js / TypeScript@authenchain/node, sdks/node/Next.js, Express, workers, LLM orchestration, agent backends.sign, verify, captureGeneration, wrapGeneration, captureRegulatedOutput, verifyRegulatoryEvidence, exportEvidencePack, verifyEvidencePack.
Pythonauthenchain, sdks/python/FastAPI, Flask, Celery, notebooks, model-serving, data science pipelines.sign, verify, capture_regulated_output, verify_regulatory_evidence, export_evidence_pack, verify_evidence_pack, validate_regulatory_metadata.
Any backend runtimeRaw HTTPS APIJava, Go, Ruby, PHP, .NET, or private runtimes without an official SDK.POST /api/provenance/sign, POST /api/provenance/verify, GET /api/provenance/evidence-pack, POST /api/public/evidence/verify.

There is no official Java, Go, Ruby, PHP, or .NET SDK in this repository today. Those runtimes should use the HTTP API contract shown below until an official SDK is shipped.

Customer server implementation

A production integration should live entirely in the customer backend. The customer stores raw prompts, inputs, outputs, and workflow records locally, while AuthenChain signs hashes and minimized metadata for later technical verification.

  1. 1. Create a server-side API key with least-privilege scopes.
  2. 2. Add AuthenChain environment variables to the customer backend.
  3. 3. Choose the final output boundary after guardrails and formatting.
  4. 4. Store raw input and output in the customer system, preferably encrypted.
  5. 5. Calculate input/output hashes with authenchain.content.v1.
  6. 6. Send content_hash, contentEvidence, and regulatory metadata to /api/provenance/sign.
  7. 7. Store trace_id, signature, public_key_id, signed_at, and contentEvidence.
  8. 8. Recalculate hashes during disputes, audits, or export to detect any changed input/output.
  9. 9. Export an Evidence Pack by trace ID or time window when review evidence is needed.
  10. 10. Verify the Evidence Pack through the dashboard, API, or public verifier.
Example
env: customer backend
AUTHENCHAIN_ENABLED=1
AUTHENCHAIN_BASE_URL=https://authenchain.com
AUTHENCHAIN_API_KEY=ac_live_...
AUTHENCHAIN_TIMEOUT_SEC=8
AUTHENCHAIN_SIGN_MODE=best_effort
AUTHENCHAIN_POLICY_VERSION=customer-ai-output-policy-v1

Recommended scopes for a production AI backend are provenance:sign, provenance:verify, provenance:events, and audit:export. Add webhooks:read and webhooks:write only for automation keys that manage webhooks.

Example
SQL: local evidence table
CREATE TABLE ai_regulatory_evidence (
  id TEXT PRIMARY KEY,
  created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
  request_id TEXT,
  user_ref TEXT,
  action TEXT NOT NULL,
  model_provider TEXT,
  model_name TEXT,
  risk_context TEXT,
  input_hash TEXT NOT NULL,
  output_hash TEXT NOT NULL,
  content_canonicalization TEXT NOT NULL DEFAULT 'authenchain.content.v1',
  evidence_hash TEXT NOT NULL UNIQUE,
  input_payload JSONB NOT NULL DEFAULT '{}'::jsonb,
  output_payload JSONB NOT NULL DEFAULT '{}'::jsonb,
  regulatory_payload JSONB NOT NULL DEFAULT '{}'::jsonb,
  authenchain_trace_id TEXT,
  authenchain_content_hash TEXT,
  authenchain_signature TEXT,
  authenchain_public_key_id TEXT,
  authenchain_signed_at TEXT,
  authenchain_status TEXT NOT NULL DEFAULT 'pending',
  authenchain_payload JSONB NOT NULL DEFAULT '{}'::jsonb
);
Example
HTTP: sign regulated output
curl -X POST "$AUTHENCHAIN_BASE_URL/api/provenance/sign" \
  -H "Authorization: Bearer $AUTHENCHAIN_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: req_123:evidence_hash" \
  -H "X-Request-Id: req_123" \
  -d '{
    "content_hash": "64_hex_chars_for_regulatory_evidence_envelope",
    "contentEvidence": {
      "captureMode": "hash_only",
      "input": {
        "content_hash": "64_hex_chars_from_authenchain_content_v1",
        "rawContentStored": false
      },
      "output": {
        "content_hash": "64_hex_chars_from_authenchain_content_v1",
        "rawContentStored": false
      }
    },
    "metadata": {
      "issuer": "customer-ai-backend",
      "content_type": "text",
      "created_at": "2026-05-28T16:00:00.000Z",
      "nonce": "nonce-1234567890abcd",
      "trace_id": "00000000-0000-4000-8000-000000000000",
      "model": "gpt-5.1",
      "regulatory": {
        "schema_version": "regulatory.v1",
        "ai_generated": true,
        "jurisdiction": "BR",
        "risk_context": "high",
        "human_reviewed": false,
        "human_oversight_required": true,
        "disclosure_required": true,
        "disclosure_applied": true,
        "policy_version": "customer-ai-output-policy-v1"
      }
    }
  }'

The full repository guide is docs/customer-server-implementation-guide.md. It includes Node.js, Python, Evidence Pack, public verifier, webhook, anchor/publication, retry, and acceptance-test examples.

10-minute Quickstart

  1. 1. Create an API key in the dashboard.
  2. 2. Install the SDK for the customer backend runtime.
  3. 3. Capture provenance when your model or agent produces an output.
  4. 4. Persist the returned signature, trace ID, and public key ID with the generated artifact.
  5. 5. Verify the output later anywhere in your backend pipeline.
Example
bash: install the Node/TypeScript SDK
npm install @authenchain/node
Example
bash: install the Python SDK from this repository
cd sdks/python
python -m pip install -e .
Example
TypeScript: first integration
import { AuthenChain } from '@authenchain/node'

const ac = new AuthenChain({
  apiKey: process.env.AUTHENCHAIN_API_KEY!,
  baseUrl: process.env.AUTHENCHAIN_BASE_URL,
  timeoutMs: 10_000,
})

const captured = await ac.captureGeneration({
  output: 'final answer generated by the agent',
  issuer: 'customer-support-agent',
  model: 'gpt-5.1',
  generateMetadataDefaults: true,
  extra: {
    source: 'support-orchestrator',
    prompt_id: 'prompt_123',
  },
})

const verification = await ac.verify({
  content: captured.output,
  provenance: captured.provenance,
})
Example
Python: first integration
import os

from authenchain import AuthenChain

client = AuthenChain(
    api_key=os.environ["AUTHENCHAIN_API_KEY"],
    base_url=os.getenv("AUTHENCHAIN_BASE_URL", "https://authenchain.com"),
    timeout=10.0,
)

signed = client.sign(
    content="final answer generated by the agent",
    metadata={
        "issuer": "customer-support-agent",
        "content_type": "text",
        "model": "gpt-5.1",
    },
    generate_metadata_defaults=True,
)

verification = client.verify(
    content="final answer generated by the agent",
    provenance=signed,
)

Capture generation

Use captureGeneration when your application already has the final output and you want AuthenChain to sign it immediately with generation metadata.

Example
TypeScript: capture a text generation
const captured = await ac.captureGeneration({
  output: completion.text,
  issuer: 'research-agent',
  model: completion.model,
  user_ref: 'user_42',
  trace_id: workflowTraceId,
  generateMetadataDefaults: true,
  extra: {
    source: 'batch-evaluator',
    model_version: '2026-03-01',
    pipeline: 'claims-review-v2',
  },
})

console.log(captured.provenance.traceId)
console.log(captured.provenance.signature)
console.log(captured.provenance.publicKeyId)
Example
TypeScript: capture a structured JSON output
const captured = await ac.captureGeneration({
  output: {
    verdict: 'approved',
    confidence: 0.98,
  },
  issuer: 'underwriting-agent',
  model: 'gpt-5.1-mini',
  generateMetadataDefaults: true,
  serializeOutput: (value) => JSON.stringify(value),
})

Wrap generation

Use wrapGeneration when you want the SDK to run your generation function and return the result plus its provenance in one step.

Example
TypeScript: wrap an LLM call
const run = await ac.wrapGeneration({
  issuer: 'ops-agent',
  model: 'gpt-5.1',
  run: async () => {
    const response = await llm.responses.create({
      model: 'gpt-5.1',
      input: 'Summarize incident INC-204',
    })

    return {
      raw: response,
      text: response.output_text,
    }
  },
  mapOutput: (result) => result.text,
})

console.log(run.result.raw.id)
console.log(run.output)
console.log(run.provenance.traceId)

Python SDK

Use the Python SDK for AI services written in Python, model-serving APIs, batch jobs, notebooks, and data science pipelines. Python method names use snake_case; JSON wire fields returned by AuthenChain keep the same API keys used by the HTTP API and Evidence Packs.

Example
Python: regulated output capture
import os

from authenchain import AuthenChain

client = AuthenChain(
    api_key=os.environ["AUTHENCHAIN_API_KEY"],
    base_url=os.getenv("AUTHENCHAIN_BASE_URL", "https://authenchain.com"),
    timeout=10.0,
    max_retries=2,
)

regulatory = {
    "schema_version": "regulatory.v1",
    "ai_generated": True,
    "jurisdiction": "BR",
    "regulatory_context": ["customer_regulated_output"],
    "content_type": "text",
    "model_provider": "openai",
    "model_name": "gpt-5.1",
    "system_purpose": "customer_support_response",
    "risk_context": "limited",
    "human_reviewed": False,
    "disclosure_required": True,
    "disclosure_applied": True,
    "label_type": "human_visible",
    "policy_version": "ai-disclosure-policy-v1",
}

captured = client.capture_regulated_output(
    output="Final AI answer shown to the user.",
    issuer="support-answer-service",
    content_type="text",
    model="gpt-5.1",
    user_ref="ticket_123",
    regulatory=regulatory,
    extra={"source": "python-backend"},
    generate_metadata_defaults=True,
    idempotency_key="ticket_123:final_answer_v1",
    request_id="req_123",
    correlation_id="req_123",
)

print(captured["provenance"]["traceId"])
print(captured["regulatory"]["legalCompliance"])
Example
Python: verify provenance and Evidence Pack
verification = client.verify_regulatory_evidence(
    content="Final AI answer shown to the user.",
    provenance=captured["provenance"],
)

pack = client.export_evidence_pack(
    trace_id=captured["provenance"]["traceId"],
)

pack_verification = client.verify_evidence_pack(evidence_pack=pack)

combined = client.verify_regulatory_evidence(
    content="Final AI answer shown to the user.",
    provenance=captured["provenance"],
    evidence_pack=pack,
    verification_scope="combined",
)

print(verification["provenanceVerified"])
print(pack_verification["trustedStatus"])
print(combined["regulatoryEvidenceStatus"])
print(combined["legalCompliance"])
Example
Python: mock mode for tests and demos only
from authenchain import AuthenChain

client = AuthenChain(mock=True)

signed = client.sign(
    content="local test output",
    metadata={
        "issuer": "local-test",
        "content_type": "text",
    },
    generate_metadata_defaults=True,
)

verification = client.verify(content="local test output", provenance=signed)
print(verification["environment"])

Python mock mode is useful for examples, tests, local CI, and sales engineering demos. It must not be presented as externally trustworthy evidence. For production, use a live API key and server-side environment variables.

Official examples

Use the official examples in sdks/node/examples/ and sdks/python/examples/ when you need a partner-ready starting point for a real provider, agent runtime, backend route, or Python AI service.

  • openai-basic: OpenAI Responses API with wrapGeneration and immediate verification.
  • langchain-basic: LangChain chat integration with AuthenChain provenance attached to the final output.
  • agent-runtime-basic: multi-step orchestration example showing where AuthenChain fits in agent flows.
  • next-route-example: Next.js route handler pattern for server-side generation plus provenance.
  • sign-basic and verify-basic: low-level reference flows for direct signing and validation.
  • sdks/python/examples/regulated-text-output: minimal Python regulated output capture and verification.
  • sdks/python/examples/credit-decision-audit and sdks/python/examples/medical-ai-traceability: Python regulated workflow examples with tamper checks.
  • sdks/python/examples/evidence-pack-export-verify: Python Evidence Pack export and public verification flow.

Partner PoC kit

The repository also includes a partner-ready PoC kit in poc/. These flows are designed for solution demos, buyer conversations, and governance reviews where you need to show business risk and evidence, not just API usage.

For partner architecture, integration, and commercial positioning guidance, see docs/partners.md.

  • clinical-ai-assistant: clinically relevant summary, later altered, with original verification and tampered failure.
  • claim-analysis-ai: insurance claim rationale changed after generation, then independently audited.
  • credit-decision-ai: risk-support recommendation challenged after generation in a fintech-style workflow.

Low-level sign / verify

Use these methods when you want explicit control over content vs. pre-computed hashes, or when you are integrating AuthenChain below your generation layer.

Example
TypeScript: sign
const provenance = await ac.sign({
  content: 'hello world',
  metadata: {
    issuer: 'agent-router',
    content_type: 'text',
    created_at: new Date().toISOString(),
    nonce: 'nonce-1234567890abcd',
    trace_id: '00000000-0000-4000-8000-000000000000',
  },
})
Example
TypeScript: verify from a stored provenance record
const verification = await ac.verify({
  content: 'hello world',
  provenance,
})

Regulated content evidence

Regulated integrations can keep raw prompts, inputs, and outputs inside the customer system while sending AuthenChain hash-only evidence. When you send pre-computed input/output hashes, calculate them with the authenchain.content.v1 canonicalization contract shown below. Do not send a plain sha256(raw_text) value and label it as AuthenChain content evidence.

Example
TypeScript: contentEvidence hash contract
import { createHash } from 'node:crypto'

function canonicalJson(value: unknown): string {
  if (value === null) return 'null'
  if (typeof value === 'string') return JSON.stringify(value)
  if (typeof value === 'boolean') return value ? 'true' : 'false'
  if (typeof value === 'number') {
    if (!Number.isFinite(value)) throw new Error('non_finite_number')
    return JSON.stringify(value)
  }
  if (Array.isArray(value)) return '[' + value.map(canonicalJson).join(',') + ']'
  if (typeof value === 'object' && value) {
    const row = value as Record<string, unknown>
    return '{' + Object.keys(row)
      .sort()
      .map((key) => JSON.stringify(key) + ':' + canonicalJson(row[key]))
      .join(',') + '}'
  }
  throw new Error('unsupported_json_value')
}

function authenchainContentHash(content: string) {
  const canonicalBody = canonicalJson({
    canonicalization: 'authenchain.content.v1',
    content,
    encoding: 'utf8',
  })
  return createHash('sha256').update(canonicalBody, 'utf8').digest('hex')
}

const canonicalInputJson = canonicalJson({ messages: [{ role: 'user', content: 'Question' }] })
const inputHash = authenchainContentHash(canonicalInputJson)
const outputHash = authenchainContentHash(finalAiOutputText)

For structured input, first create a deterministic JSON string for the official input boundary, then pass that string as content. For output, use the exact final text or artifact body delivered to the user after guardrails and formatting.

Example
cURL: sign with hash-only input/output evidence
curl -X POST https://authenchain.com/api/provenance/sign \
  -H "Authorization: Bearer ac_test_example_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: regulated-output-0001" \
  -d '{
    "content_hash": "64_hex_chars_for_regulatory_envelope",
    "contentEvidence": {
      "captureMode": "hash_only",
      "input": {
        "content_hash": "64_hex_chars_from_authenchain_content_v1",
        "rawContentStored": false
      },
      "output": {
        "content_hash": "64_hex_chars_from_authenchain_content_v1",
        "rawContentStored": false
      }
    },
    "metadata": {
      "issuer": "customer-ai-backend",
      "content_type": "text",
      "created_at": "2026-05-28T00:00:00.000Z",
      "nonce": "nonce-1234567890abcd",
      "trace_id": "00000000-0000-4000-8000-000000000000",
      "regulatory": {
        "schema_version": "regulatory.v1",
        "ai_generated": true,
        "jurisdiction": "BR",
        "risk_context": "high",
        "policy_version": "customer-ai-output-policy-v1"
      }
    }
  }'

The signed provenance payload stores these hashes as contentEvidence.input.contentHash and contentEvidence.output.contentHash, both with canonicalization: authenchain.content.v1. Any later one-character change in the official input or output produces a different hash during verification.

HTTP API reference

These endpoints are what the SDK calls under the hood. They remain stable and compatible with the current backend.

Example
cURL: sign
curl -X POST https://authenchain.com/api/provenance/sign \
  -H "Authorization: Bearer ac_test_example_..." \
  -H "Content-Type: application/json" \
  -d '{
    "content": "hello world",
    "metadata": {
      "issuer": "acme-inc",
      "content_type": "text",
      "created_at": "2026-03-06T00:00:00.000Z",
      "nonce": "nonce-1234567890abcd",
      "trace_id": "00000000-0000-4000-8000-000000000000"
    }
  }'
Example
JSON: sign response
{
  "trace_id": "...",
  "content_hash": "...",
  "metadata": { ... },
  "signature": "...",
  "public_key_id": "...",
  "kid": "...",
  "algorithm": "Ed25519",
  "signed_at": "..."
}
Example
cURL: verify
curl -X POST https://authenchain.com/api/provenance/verify \
  -H "Authorization: Bearer ac_test_example_..." \
  -H "Content-Type: application/json" \
  -d '{
    "content": "hello world",
    "metadata": {
      "issuer": "acme-inc",
      "content_type": "text",
      "created_at": "2026-03-06T00:00:00.000Z",
      "nonce": "nonce-1234567890abcd",
      "trace_id": "00000000-0000-4000-8000-000000000000",
      "schema_version": "1.0"
    },
    "signature": "...",
    "public_key_id": "..."
  }'
Example
JSON: verify response
{
  "trace_id": "...",
  "verified": true,
  "reason": null,
  "content_hash": "...",
  "origin_verified": true,
  "integrity": "intact",
  "issuer_verified": true,
  "reason_codes": [],
  "verified_at": "..."
}

Events API

Retrieve review-ready provenance events by trace ID or paginate recent events for the current API key.

Example
HTTP: list events
GET /api/provenance/events?trace_id=TRACE_ID
GET /api/provenance/events?limit=50&cursor=EVENT_ID

Webhooks

Receive provenance.signed and provenance.verified events in downstream systems.

Example
HTTP: create webhook endpoint
POST /api/webhooks

Request body:
{ "url": "https://example.com/webhooks" }

Runtime headers today:
X-AITL-Signature: v1=<hex_hmac>
X-AITL-Timestamp: <unix_ms>
X-AITL-Event-Id: <event_id>

Preferred header names:
X-AuthenChain-Signature: v1=<hex_hmac>
X-AuthenChain-Timestamp: <unix_ms>
X-AuthenChain-Event-Id: <event_id>
Example
Node: webhook verification
function verifySignature(secret, headers, rawBody) {
  const signatureHeader =
    headers["x-authenchain-signature"] || headers["x-aitl-signature"];
  const timestamp =
    headers["x-authenchain-timestamp"] || headers["x-aitl-timestamp"];
  if (!signatureHeader || !timestamp) return false;

  const [version, received] = String(signatureHeader).split("=");
  if (version !== "v1" || !received) return false;

  const base = "v1." + timestamp + "." + rawBody;
  const expected = require("crypto")
    .createHmac("sha256", secret)
    .update(base, "utf8")
    .digest("hex");

  return expected === received;
}

Rate limits & errors

Verification mismatches are not transport errors. The API returns 200 with verified: false and reason codes for content or signature mismatches. Malformed requests still return 4xx.

Example
Common error codes
401: INVALID_API_KEY | KEY_REVOKED | KEY_EXPIRED
403: INVALID_KEY_OWNERSHIP
402: BILLING_INACTIVE
429: RATE_LIMITED | MONTHLY_QUOTA_EXCEEDED
413: PAYLOAD_TOO_LARGE
400: INVALID_JSON | INVALID_PAYLOAD
503: RATE_LIMIT_BACKEND_UNAVAILABLE

Protected responses may include x-trace-id, x-quota-limit, x-quota-remaining, x-quota-reset-at, and Retry-After.

Operational notes

  • Sign at generation time whenever possible. Provenance added later proves handling, not original creation.
  • Store trace_id, signature, and public_key_id with every signed artifact.
  • Use stable nonces and workflow trace IDs to correlate retries, jobs, and downstream verification.
  • Handle 429 with backoff and respect Retry-After.

Security notes

AuthenChain stores hashes and signed metadata, not raw text or media, unless your deployment adds that separately.

Do not place PII or secrets in metadata. If you must associate sensitive data, tokenize or encrypt it before submission.

For regulated workflows, keep raw prompts, raw outputs, and protected records in the customer system when possible, then send contentEvidence hashes and minimized regulatory metadata to AuthenChain.

Documentation | AuthenChain - AuthenChain