API Reference
All endpoints are JSON over HTTP.
Authentication
All requests require an API key in the Authorization header.
Authorization: Bearer <your-api-key>
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
Bad Request
Invalid request body or missing required fields.
Unauthorized
Missing or invalid API key.
Forbidden
API key does not have permission for this operation.
Too Many Requests
Rate limit exceeded. Wait and retry.
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, include an explicit intent flag:
{
"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"
}
Public Artifact Metadata
Public artifacts include:
publication_timestamporiginating_org_iddisclosure_intentflag
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"
Verify Chain Integrity (Python)
import requests
response = requests.post(
"https://api.chainoffact.com/api/verify/chain",
headers={"Authorization": "Bearer YOUR_API_KEY"}
)
result = response.json()
print(f"State: {result['state']}")
print(f"Event count: {result['event_count']}")
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"
Generate Evidence Bundle (Python)
import requests
response = requests.post(
"https://api.chainoffact.com/api/bundles/evidence",
headers={"Authorization": "Bearer YOUR_API_KEY"}
)
result = response.json()
print(f"Bundle ID: {result['bundle_id']}")
print(f"Download: {result['download_path']}")