API reference
Exports
The verifier key, the sealed bundle when it is built, and a per-account JSON export of stored events.
GET /bundle.authority
The sealed bundle
Streams the sealed bundle bytes to a signed-in caller when the artifact is built.
On the hosted deployment this route may answer 503 bundle_not_built; the artifact is not part of the current launch.
Parameters
None.
Request body
None.
Example request
curl
curl -sS -X GET "https://api.afaprotocol.com/bundle.authority" \
-H "X-API-Key: afa-beta-EXAMPLE-e4qs"
Python
import requests
API = "https://api.afaprotocol.com"
headers = {"X-API-Key": "afa-beta-EXAMPLE-e4qs"}
r = requests.get(f"{API}/bundle.authority", headers=headers, timeout=30)
r.raise_for_status()
open("download.bin", "wb").write(r.content)
Example response
HTTP 200, a file body. The sealed bundle bytes, Cache-Control private, no-store.
Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | missing_token / invalid_or_expired_api_key | No credential, an expired session, or a revoked or expired key. |
| 503 | bundle_not_built | No artifact on disk; an empty body is never served instead. |
What would show this is false
A 503 names bundle_not_built rather than returning an empty body, and a 200 carries Cache-Control private, no-store.
GET /static/bundle.pub
The bundle verifier key
Serves the 32-byte Ed25519 public key that verifies the sealed bundle.
Parameters
None.
Request body
None.
Example request
curl
curl -sS -X GET "https://api.afaprotocol.com/static/bundle.pub"
Python
import requests
API = "https://api.afaprotocol.com"
r = requests.get(f"{API}/static/bundle.pub", timeout=30)
r.raise_for_status()
open("download.bin", "wb").write(r.content)
Example response
HTTP 200, a file body. The body is the raw 32-byte key, Content-Type application/octet-stream.
Errors
| Status | Code | Meaning |
|---|---|---|
| 503 | verifier_key_unavailable | The deployment has no key file; nothing is served in its place. |
What would show this is false
The body is exactly 32 bytes.
GET /v1/bundles/{user_id}.authority
Export one account's events
Returns a JSON envelope of the account's stored events, for the account itself or an administrator.
The envelope is plain JSON of the stored events, served as an attachment. Signatures on events are the client's own and verify against the registered keys; the export adds none.
Parameters
user_idpath, string required- No description in the schema.
Request body
None.
Example request
curl
curl -sS -X GET "https://api.afaprotocol.com/v1/bundles/2f6e1a0c-9b4d-4e8a-8c31-5d7f0a2b9c14.authority" \
-H "X-API-Key: afa-beta-EXAMPLE-e4qs"
Python
import requests
API = "https://api.afaprotocol.com"
headers = {"X-API-Key": "afa-beta-EXAMPLE-e4qs"}
r = requests.get(f"{API}/v1/bundles/2f6e1a0c-9b4d-4e8a-8c31-5d7f0a2b9c14.authority", headers=headers, timeout=30)
r.raise_for_status()
print(r.json())
Example response
HTTP 200
{
"event_count": 2,
"events": [
{
"decision": "allow",
"event_id": "evt-2b3c4d5e6f708192",
"event_type": "tool_result",
"machine_id": "worker-1",
"payload_hash": "sha256:772e64d4f2db3ca9cedf4cf77d19cc66ba30a2fa8263bb0077a1f391c4ffc0da",
"prev_hash": "sha256:74f696b9d0babf1685dc161c2f83a88c8822f940e54d3876568800d1d3c51ab6",
"sequence": 1,
"tool": "deploy"
},
{
"decision": "allow",
"event_id": "evt-1a2b3c4d5e6f7081",
"event_type": "tool_call",
"machine_id": "worker-1",
"payload_hash": "sha256:74f696b9d0babf1685dc161c2f83a88c8822f940e54d3876568800d1d3c51ab6",
"prev_hash": null,
"sequence": 0,
"tool": "deploy"
}
],
"exported_at": "2026-09-01T15:10:00+00:00",
"exported_by": "2f6e1a0c-9b4d-4e8a-8c31-5d7f0a2b9c14",
"schema": "afaprotocol.user_bundle.v1",
"user_id": "2f6e1a0c-9b4d-4e8a-8c31-5d7f0a2b9c14"
}
Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | missing_token / invalid_or_expired_api_key | No credential, an expired session, or a revoked or expired key. |
| 403 | scope_missing | A key limited by scopes lacks events:read; the body names it. |
| 422 | validation error | A required field is missing or a value has the wrong type. |
| 403 | forbidden | The caller is neither this account nor an administrator. |
| 404 | user_not_found | No such account. |
What would show this is false
Ask for another account's id without the administrator role: 403 forbidden and no envelope.