# ChainOfFact API Reference All endpoints are JSON over HTTP. ## Authentication All requests require an API key in the Authorization header. Authorization: Bearer API keys are issued during onboarding. Contact hello@chainoffact.com to request access. ## Rate Limits Default rate limits apply per API key: - POST /api/events: 1,000 requests per minute - GET /api/events/:id: 500 requests per minute - POST /api/verify/*: 100 requests per minute - POST /api/bundles/evidence: 10 requests per minute Higher limits available on request for production deployments. ## Error Codes 400 - Bad Request: Invalid request body or missing required fields. 401 - Unauthorized: Missing or invalid API key. 403 - Forbidden: API key does not have permission for this operation. 429 - Too Many Requests: Rate limit exceeded. Wait and retry. 500 - Internal Server Error: Unexpected error. Contact support if persistent. ## POST /api/events Records a new event. Request: { "event_type": "string", "subject": "string (optional)", "actor": "string (optional)", "inputs_hash": "string (optional)", "outputs_hash": "string (optional)", "policy_id": "string (optional)", "policy_version": "string (optional)", "metadata": { "key": "value" } } Response: { "event_id": "uuid", "event_hash": "sha256", "timestamp_utc": "ISO-8601" } The event is immutable once recorded. ## GET /api/events/:event_id Retrieves a previously recorded event. Response: - Event object if found - { "state": "UNKNOWN" } if not found ## POST /api/verify/event Verifies the integrity of a single event by ID. Request: { "event_id": "uuid" } Response: { "state": "MATCH | MISMATCH | UNKNOWN" } ## POST /api/verify/chain Verifies the integrity of the full ledger. Response: { "state": "MATCH | MISMATCH | ABSTAIN | UNKNOWN", "event_count": number } ## POST /api/bundles/evidence Generates a sealed evidence bundle. ### Public Disclosure Warning This endpoint may generate a publicly accessible, immutable verification artifact. Once created: - The artifact cannot be modified or revoked - The artifact may be accessed by third parties - The artifact may be retained indefinitely ChainOfFact does not evaluate whether publication is appropriate, safe, lawful, or advisable. You are responsible for determining whether public disclosure is intended. Request (for public disclosure): { "intent": "public_disclosure" } This flag must be explicit and is documented as irreversible. Response: { "bundle_id": "uuid", "created_utc": "ISO-8601", "chain_state": "MATCH | MISMATCH | ABSTAIN | UNKNOWN", "download_path": "string" } ## GET /api/bundles/download/:filename Downloads an evidence bundle ZIP. ## GET /api/health Health and ledger status. Response: { "ok": true, "ledger_head": "sha256 | null", "mode": "append-only" } ## Examples ### Record an Event (curl) curl -X POST https://api.chainoffact.com/api/events \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "event_type": "model_inference", "subject": "user-123", "actor": "gpt-4-turbo", "inputs_hash": "sha256:abc123...", "outputs_hash": "sha256:def456...", "metadata": {"session_id": "sess-789"} }' ### Record an Event (Python) import requests response = requests.post( "https://api.chainoffact.com/api/events", headers={ "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" }, json={ "event_type": "model_inference", "subject": "user-123", "actor": "gpt-4-turbo", "inputs_hash": "sha256:abc123...", "outputs_hash": "sha256:def456...", "metadata": {"session_id": "sess-789"} } ) result = response.json() print(f"Event ID: {result['event_id']}") print(f"Hash: {result['event_hash']}") ### Verify Chain Integrity (curl) curl -X POST https://api.chainoffact.com/api/verify/chain \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" ### Generate Evidence Bundle (curl) curl -X POST https://api.chainoffact.com/api/bundles/evidence \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" --- Canonical URL: https://chainoffact.com/docs/api