Who this is for: Developers integrating SWT3 via HTTP (any language), DevOps engineers configuring webhook pipelines, and compliance architects evaluating API capabilities. Assumes familiarity with REST APIs and Bearer token authentication.
1. Introduction
| Base URL | https://sovereign.tenova.io |
| API Prefix | /api/v1/ |
| Transport | HTTPS only (TLS 1.3). HTTP requests are redirected. |
| Content-Type | application/json for all request and response bodies |
| Character Encoding | UTF-8 |
All timestamps are ISO 8601 UTC. Fingerprint timestamps use millisecond-precision Unix epoch.
2. Authentication
The API supports three authentication modes depending on the caller:
| Mode | Used By | Header / Mechanism | Scope |
|---|---|---|---|
| Bearer Token | SDKs, CI/CD, scripts | Authorization: Bearer axm_live_... |
Tenant-scoped. All witness and export endpoints. |
| Session Cookie | Dashboard UI | httpOnly cookie (set at login) |
User-scoped. Dashboard routes and admin endpoints. |
| Audit Token | External assessors | Token in URL path: /api/v1/audit/{token}/... |
Read-only. Scoped to one assessment engagement. |
Getting an API Key
- Sign up at
https://sovereign.tenova.io/signupor log in to the dashboard. - Go to Settings > API Keys.
- Click Create Key. The key is shown once -- copy it immediately.
- Keys start with
axm_live_(production) oraxm_trial_(trial). - Keys are stored as SHA-256 hashes. Lost keys cannot be recovered -- create a new one.
Example: Bearer Token
curl -X POST https://sovereign.tenova.io/api/v1/witness \ -H "Authorization: Bearer axm_live_abc123def456..." \ -H "Content-Type: application/json" \ -d '{"procedure_id":"AI-INF.1","factor_a":1,"factor_b":1,"factor_c":0,...}'
SWT3_API_KEY) or a secret manager. Keys have tenant-level access -- treat them like database credentials.
3. Rate Limits and Quotas
Per-Tenant Rate Limits (Witness Ingestion)
| Tier | Requests / Second | Monthly Anchor Limit | Batch Size |
|---|---|---|---|
| OPEN (Free) | 10 | 100 | Up to 500 |
| PRO ($499/mo) | 50 | Unlimited | Up to 500 |
| ENCLAVE ($9,500/mo) | 200 | Unlimited | Up to 500 |
| SOVEREIGN | 500 | Unlimited | Up to 500 |
Rate limits use a token bucket algorithm that refills continuously. With 2 PM2 instances, effective throughput is approximately double.
Public Endpoint Rate Limits (Per IP)
| Endpoint | Limit |
|---|---|
GET /api/v1/verify/public | 60 requests / minute |
POST /api/v1/passport/verify | 10 requests / minute |
GET /api/v1/passport/status/:id | 60 requests / minute |
When You Hit a Limit
The API returns HTTP 429 with a Retry-After header (in seconds). Best practice: exponential backoff starting at 1 second, capped at 30 seconds.
// Example 429 response
HTTP/1.1 429 Too Many Requests
Retry-After: 2
Content-Type: application/json
{
"error": "Rate limit exceeded. Retry after 2s.",
"retry_after_seconds": 2
}
4. Error Codes
All error responses follow the shape:
{
"error": "Human-readable message",
"reference": "AXM-4821" // Server-side correlation ID (502/503 only)
}
| Status | Meaning | Retryable | Common Causes |
|---|---|---|---|
400 | Validation Error | No | Missing required field, invalid procedure_id, clearing_level out of range (0-3), timestamp out of bounds, malformed JSON |
401 | Authentication Failed | No | Missing Authorization: Bearer header, key does not start with axm_, key not found in database |
403 | Forbidden | No | Insufficient tier (e.g., webhooks require Enclave+), assessor attempting write operation, revoked agent |
404 | Not Found | No | Resource does not exist, invalid audit token |
409 | Conflict | No | Duplicate entity (tenant, webhook subscription, API key) |
429 | Rate Limit Exceeded | Yes | Per-second or monthly limit reached. Check Retry-After header. |
502 | Upstream Error | Yes | Database write failed, external service timeout. Includes AXM-XXXX reference code. |
503 | Service Degraded | Yes | Maintenance window, dependency unavailable. Retry after 30 seconds. |
506 | Agent Revoked | No | Agent ID has been revoked via AI-REV.1. Re-register or use a different agent. |
reference field (e.g., AXM-4821). Include this code when contacting support@tenovaai.com for faster resolution. Non-admin callers receive sanitized error messages; admin/Bearer callers receive full diagnostics.
5. SWT3 Anchor Format
Every witness receipt includes a SWT3 Witness Anchor -- a structured token that encodes the attestation metadata:
SWT3-E-VULTR-AI-AI-INF.1-PASS-1773316622-96b7d56c0245 | | | | | | | | | | | | | | | +-- Fingerprint (SHA-256, 12 hex chars) | | | | | | +-------------- Epoch (Unix seconds) | | | | | +------------------- Verdict (PASS or FAIL) | | | | +---------------------------- Procedure ID | | | +------------------------------- UCT Domain (AI) | | +-------------------------------------- Provider (VULTR, AWS, AZURE, GCP, HYBRID) | +----------------------------------------- Tier (E=Enclave, S=SaaS, H=Hybrid) +--------------------------------------------- Protocol prefix
Fingerprint Formula
The 12-character fingerprint is derived from:
SHA256("WITNESS:{tenant_id}:{procedure_id}:{factor_a}:{factor_b}:{factor_c}:{fingerprint_timestamp_ms}").hex()[:12]
You can verify any anchor using a terminal:
echo -n "WITNESS:DEMO_TENANT:AI-INF.1:1:1:0:1774800000000" | sha256sum | cut -c1-12
# Output: 2e16e2fe92dd
This formula is locked across all 9 SDKs (Python, TypeScript, Rust, C#, Ruby, Swift, Kotlin, MCP, K8s). Cross-language parity is verified against published test vectors.
6. Health
Lightweight health check. No authentication required. Use for uptime monitoring.
Response (200)
{
"status": "healthy",
"version": "5.42.0",
"uptime": 1234567,
"checks": {
"supabase": true,
"timestamp": "2026-08-13T12:00:00.000Z"
}
}
Response (503 -- Degraded)
{
"status": "degraded",
"checks": { "supabase": false }
}
Curl
curl -s https://sovereign.tenova.io/api/v1/health | jq .
Tip: Point your monitoring tool (Datadog, UptimeRobot, Pingdom) at this endpoint. Alert on non-200 status or supabase: false.
7. Witness Ingestion
The core of SWT3. The SDK pre-clears evidence factors and mints a fingerprint locally, then sends the factors to this endpoint. At Clearing Level 1 and above, raw prompts and responses never leave your infrastructure.
Ingest a single witness payload. The server re-derives the fingerprint, evaluates the verdict deterministically, writes to the ledger, and returns a receipt.
Request Body
procedure_id: string REQUIRED -- AI procedure (e.g., "AI-INF.1"). See UCT Registry for all 113.factor_a: number REQUIRED -- Primary factor (meaning varies by procedure)factor_b: number REQUIRED -- Secondary factorfactor_c: number REQUIRED -- Tertiary factorclearing_level: number REQUIRED -- 0 (Analytics), 1 (Standard), 2 (Sensitive), 3 (Classified)anchor_fingerprint: string REQUIRED -- SDK-computed 12-char hex fingerprintanchor_epoch: number REQUIRED -- Unix epoch in secondsfingerprint_timestamp_ms: number REQUIRED -- Millisecond-precision timestamp used in fingerprintAI Metadata (presence depends on clearing level):
ai_model_id: string optional -- Model identifier (e.g., "gpt-4o", "claude-sonnet-4-20250514")ai_prompt_hash: string optional -- SHA-256 of prompt (first 16 hex chars)ai_response_hash: string optional -- SHA-256 of response (first 16 hex chars)ai_system_prompt_hash: string optional -- SHA-256 of system promptai_latency_ms: number optional -- Inference latency in millisecondsai_input_tokens: number optional -- Input token countai_output_tokens: number optional -- Output token countAgent Identity and Governance:
agent_id: string optional -- Agent identifier (AI-ID.1, survives all clearing levels)cycle_id: string optional -- Multi-agent chain link (survives all clearing levels)tool_name: string optional -- Tool invoked (AI-TOOL.1)tool_call_id: string optional -- Unique tool call identifierauthorization_id: string optional -- Pre-inference gate receipt (AI-GRD.3)Signing (Payload Integrity):
payload_signature: string optional -- HMAC-SHA256 hex signaturesigning_key_id: string optional -- Key identifier for server-side validationsigning_key_version: number optional -- Monotonic key version for rotation auditingLifecycle Chains (v6.0):
lifecycle_chain_id: string optional -- Format: LC- + 16 hex charslifecycle_parent: string optional -- Fingerprint of previous anchor (12 hex chars)lifecycle_stage: string optional -- One of: initiated, checkpoint, escalated, resolved, abandoned, supersededescalation_chain_id: string optional -- Cross-procedure linkingCJT Fields (Jurisdictional Context):
jurisdiction: string optional -- ISO 3166-1 alpha-2 (e.g., "US", "DE")legal_basis: string optional -- GDPR legal basis (e.g., "Art. 6(1)(f)")purpose_class: string optional -- Processing purpose (e.g., "fraud_detection")Revocation (AI-REV.1):
revocation_target: string optional -- Fingerprint of anchor being revokedrevocation_reason: string optional -- Reason code (0-6)
Response (200)
{
"procedure_id": "AI-INF.1",
"verdict": "PASS",
"swt3_anchor": "SWT3-E-VULTR-AI-AI-INF.1-PASS-1773316622-2e16e2fe92dd",
"clearing_level": 1,
"witnessed_at": "2026-08-13T12:00:00.000Z",
"verification_url": "/api/v1/attest/verify?token=SWT3-E-VULTR-AI-AI-INF.1-PASS-1773316622-2e16e2fe92dd",
"signature_verified": true
}
Validation Rules
- Timestamp bounds:
fingerprint_timestamp_msmust be within the last 24 hours and no more than 5 minutes in the future. - Fingerprint integrity: The server re-derives
SHA256("WITNESS:{tenant}:{proc}:{fa}:{fb}:{fc}:{ts_ms}")and compares the first 12 hex chars. If they differ, the request is rejected (factors tampered in transit). - Clearing level: Must be 0, 1, 2, or 3.
- Procedure ID: Must be one of the 113 recognized AI procedures. Unknown IDs return 400 with the full list.
- Lifecycle chain ID: If provided, must match
LC-[0-9a-f]{16}. - Lifecycle stage: If provided, must be one of: initiated, checkpoint, escalated, resolved, abandoned, superseded.
Error Responses
| Status | Error Message | Fix |
|---|---|---|
| 401 | "Missing Authorization: Bearer <token> header" | Add Authorization: Bearer axm_... header |
| 401 | "Invalid API key format" | Key must start with axm_ |
| 401 | "Invalid or revoked API key" | Key not found. Generate a new one at Settings > API Keys |
| 400 | "Unknown AI procedure: AI-FOO.1" | Check UCT Registry for valid procedure IDs |
| 400 | "clearing_level must be 0-3" | Use integer 0, 1, 2, or 3 |
| 400 | "Anchor timestamp out of bounds" | Timestamp must be within last 24h and no more than 5 min in the future. Check system clock sync (NTP). |
| 400 | "Anchor fingerprint validation failed" | Factors were modified between SDK minting and server receipt. Verify no middleware is altering the request body. |
| 400 | "Payload signature validation failed" | HMAC does not match any registered signing key. Verify key ID and secret. |
| 429 | "Rate limit exceeded" | Back off per Retry-After header, or upgrade tier |
| 429 | "Monthly anchor limit reached (100)" | OPEN tier limit. Upgrade to Pro for unlimited anchors. |
| 506 | "Agent revoked" | Agent ID was revoked via AI-REV.1. Re-register or use a different agent. |
Examples
curl -X POST https://sovereign.tenova.io/api/v1/witness \
-H "Authorization: Bearer $SWT3_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"procedure_id": "AI-INF.1",
"factor_a": 1,
"factor_b": 1,
"factor_c": 0,
"clearing_level": 1,
"anchor_fingerprint": "2e16e2fe92dd",
"anchor_epoch": 1774800000,
"fingerprint_timestamp_ms": 1774800000000,
"ai_model_id": "gpt-4o"
}'
# The SDK handles fingerprint minting, clearing, and flushing. # You never need to call the API directly. from swt3_ai import Witness witness = Witness( api_key="axm_live_...", tenant_id="YOUR_TENANT", clearing_level=1 ) # Wrap your OpenAI client -- all inferences are witnessed automatically import openai client = witness.wrap(openai.OpenAI()) response = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": "Hello"}] ) # Anchor minted, cleared, and queued for flush. Zero blocking.
// The SDK handles fingerprint minting, clearing, and flushing. import { Witness } from "@tenova/swt3-ai"; import OpenAI from "openai"; const witness = new Witness({ apiKey: "axm_live_...", tenantId: "YOUR_TENANT", clearingLevel: 1 }); const client = witness.wrapTool(new OpenAI()); const response = await client.chat.completions.create({ model: "gpt-4o", messages: [{ role: "user", content: "Hello" }] }); // Anchor minted, cleared, and queued for flush.
Ingest up to 500 witness payloads in a single request. Each payload is validated independently -- partial success is possible.
Request Body
{
"witnesses": [
{ "procedure_id": "AI-INF.1", "factor_a": 1, ... },
{ "procedure_id": "AI-GRD.1", "factor_a": 2, ... }
]
}
Response (200)
{
"results": [
{ "procedure_id": "AI-INF.1", "verdict": "PASS", "swt3_anchor": "SWT3-..." },
{ "procedure_id": "AI-GRD.1", "verdict": "PASS", "swt3_anchor": "SWT3-..." }
],
"accepted": 2,
"rejected": 0
}
Limits
- Maximum 500 payloads per batch request.
- Each payload counts against your per-second rate limit.
- Rejected payloads include an
errorfield in the results array.
Retrieve all anchors in a lifecycle chain. Used for forensic reconstruction of multi-step processes (emergency overrides, champion-challenger assessments).
Response (200)
{
"chain_id": "LC-a1b2c3d4e5f67890",
"anchors": [
{ "stage": "initiated", "procedure_id": "AI-EMRG.1", "verdict": "PASS", ... },
{ "stage": "escalated", "procedure_id": "AI-EMRG.1", "verdict": "PASS", ... },
{ "stage": "resolved", "procedure_id": "AI-EMRG.1", "verdict": "PASS", ... }
],
"integrity": "verified"
}
8. Verification
All verification endpoints are public -- no authentication required. Auditors can independently verify any anchor using only the token string and SHA-256.
Structural validation of a SWT3 Witness Anchor. Decomposes the token and verifies format integrity.
Response (200)
{
"valid": true,
"tier": "E",
"tier_label": "Enclave",
"provider": "VULTR",
"uct": "AI",
"procedure_id": "AI-INF.1",
"verdict": "PASS",
"timestamp": "2026-08-13T12:00:00.000Z",
"fingerprint": "2e16e2fe92dd"
}
Curl
curl "https://sovereign.tenova.io/api/v1/verify/public?token=SWT3-E-VULTR-AI-AI-INF.1-PASS-1773316622-2e16e2fe92dd"
Verify an HMAC-signed Compliance Passport or a W3C Verifiable Credential.
Request (HMAC Passport)
{ "passport": "<base64-encoded HMAC-signed passport>" }
Request (W3C Verifiable Credential)
{ "credential": { "@context": [...], "type": [...], "proof": {...} } }
Response (200)
{
"valid": true,
"signature_valid": true,
"expired": false,
"passport_id": "PSP-a1b2c3d4",
"format": "vc",
"cryptosuite": "eddsa-jcs-2022"
}
Check the revocation status of a Verifiable Credential.
Response (200)
{
"status": "active", // "active", "revoked", or "unknown"
"passport_id": "PSP-a1b2c3d4"
}
9. Compliance Passport
Export a vendor compliance summary in one of three formats, gated by subscription tier.
| Format | Minimum Tier | Content-Type | Description |
|---|---|---|---|
?format=html | Pro | text/html | Self-contained HTML report for auditors |
?format=json | Pro | application/json | HMAC-SHA256 signed JSON for machine consumption |
?format=vc | Enclave | application/vc+ld+json | W3C Verifiable Credential (Ed25519, eddsa-jcs-2022) |
10. Webhooks
Outbound HMAC-signed compliance events for SIEM, GRC, and notification pipelines. Requires Enclave tier or above.
Event Types
| Event | Fires When |
|---|---|
verdict.issued | A PASS verdict is recorded |
verdict.failed | A FAIL verdict is recorded |
drift.detected | A control changes from PASS to FAIL |
attestation.lapsed | A manual attestation expires |
score.threshold | Sovereign Score drops below configured threshold |
hw.attestation.stale | Hardware attestation exceeds staleness window |
hw.drift.detected | Hardware configuration drift detected |
ping | Test event (via test endpoint) |
Webhook Payload
{
"event": "verdict.failed",
"tenant_id": "YOUR_TENANT",
"timestamp": "2026-08-13T12:00:00.000Z",
"data": {
"procedure_id": "AI-GRD.1",
"verdict": "FAIL",
"swt3_anchor": "SWT3-E-VULTR-AI-AI-GRD.1-FAIL-...",
"factor_a": 2,
"factor_b": 0,
"factor_c": 0,
"clearing_level": 1,
"ai_model_id": "gpt-4o",
"verification_url": "/api/v1/attest/verify?token=SWT3-..."
}
}
HMAC Signature Verification
Every webhook delivery includes an X-SWT3-Signature header containing the HMAC-SHA256 signature of the raw request body, using your webhook secret as the key.
import hmac, hashlib
def verify_webhook(body: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(), body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
import { createHmac, timingSafeEqual } from "crypto";
function verifyWebhook(body: string, signature: string, secret: string): boolean {
const expected = createHmac("sha256", secret).update(body).digest("hex");
return timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}
Create a webhook subscription. Maximum 10 subscriptions per tenant.
Request Body
{
"url": "https://your-server.com/webhook",
"event_types": ["verdict.failed", "drift.detected"],
"description": "Slack alert pipeline"
}
Response (200)
{
"id": "wh_abc123",
"secret": "whsec_...", // Shown once. Store securely.
"is_active": true
}
List all webhook subscriptions. Secrets are masked.
Send a test ping event to verify your endpoint receives and processes webhooks correctly. Returns the delivery result.
View delivery history for a webhook subscription. Includes HTTP status codes, response bodies, and retry status.
Update a subscription (URL, event types, active status).
Delete a webhook subscription. Existing delivery history is retained.
11. AI Witness Analytics
AI witness posture summary: total anchors, procedure coverage, model inventory with drift status.
Auditor-ready JSON export of all AI witness evidence. Suitable for import into assessment tools.
12. Merkle Proofs
Compute the daily Merkle root for your tenant. Domain-separated hashing (SWT3:LEAF: and SWT3:NODE: prefixes).
Request Body (optional)
{ "date": "2026-08-13" } // defaults to today
Response (200)
{
"merkle_root": "a1b2c3d4e5f6...",
"date": "2026-08-13",
"anchor_count": 47
}
List Merkle rollups for the last N days (default 30).
Get an inclusion proof for a specific anchor fingerprint. Returns the Merkle path for independent verification.
Response (200)
{
"proof": [
{ "hash": "abc123...", "direction": "L" },
{ "hash": "def456...", "direction": "R" }
],
"root": "a1b2c3d4e5f6...",
"verified": true
}
13. OSCAL Exports
All OSCAL exports are validated against NIST oscal-cli v3.1.0 before delivery. Zero errors, zero warnings.
System Security Plan in OSCAL JSON format.
Plan of Action and Milestones. Includes risk-level mapping, milestone dates, and overdue flags.
Assessment Results. Findings, objective coverage, and procedures exercised.
Complete package: SSP + POA&M + AR + cross-validation report. Signed ZIP.
14. API Key Management
List all API keys for your tenant. Keys are masked (only prefix shown). Maximum 5 active keys per tenant.
Response (200)
{
"keys": [
{
"key_id": "k_abc123",
"key_prefix": "axm_live_7f3a...",
"created_at": "2026-08-01T00:00:00Z",
"last_used": "2026-08-13T11:30:00Z"
}
]
}
Create a new API key. The raw key is returned exactly once in the response. Store it securely.
Response (200)
{
"key": "axm_live_7f3a9b2c4d5e6f7890abcdef12345678", // shown once
"key_id": "k_abc123"
}
Revoke an API key. Immediate effect. Existing anchors are not affected. Action is logged to the audit trail.
15. Agents
Register and manage AI agents (AI-ID.1). Each agent has a charter defining authorized tools, scopes, and constraints.
Register an agent with a charter (tool authorization and scope limits).
Request Body
{
"agent_id": "fraud-detector-v2",
"agent_type": "llm",
"charter": {
"tools": ["search_transactions", "flag_suspicious"],
"scopes": ["read:transactions"],
"constraints": { "max_actions_per_minute": 100 }
}
}
List all registered agents with status and charter hash.
Revoke an agent. Mints an AI-REV.1 anchor. Subsequent witness ingestion attempts by this agent return 506.
Request Body
{ "agent_id": "fraud-detector-v2", "reason": "policy_violation" }
16. Crosswalks
Resolve a procedure ID across regulatory frameworks (e.g., NIST 800-53 to CMMC to EU AI Act).
Request Body
{
"source_framework": "NIST-800-53",
"source_control_id": "AC-2",
"target_framework": "CMMC"
}
Response (200)
{
"mappings": [
{ "target_control_id": "AC.L2-3.1.1", "mapping_type": "1:1", "confidence": 0.95 }
]
}
Full mapping matrix between two frameworks. 1,057 crosswalk rows across 36 frameworks.
17. Audit Portal
Token-based access for external assessors. No dashboard login required. All access is read-only.
Retrieve audit session metadata (tenant scope, frameworks, status).
Cryptographic proof chain for every verdict in the assessment scope. Includes Merkle proofs for independent verification.
Assessor submits a finding (severity, control_id, description). Does not modify verdicts.
Export the conformity evidence package (SWT3 Spec v1.0.1 format). Self-contained HTML or JSON.