API reference
Lineage and tree
Two read-only views over the parent linkage: the subtree beneath an event and the ancestry above it. Both are scoped to your own account.
GET /v1/events/lineage/{event_id}
Ancestry up to genesis
Walks parent_id upward from an event and returns the chain, event first, genesis last.
Parameters
event_idpath, string required- No description in the schema.
Request body
None.
Example request
curl
curl -sS -X GET "https://api.afaprotocol.com/v1/events/lineage/evt-5e6f708192a3b4c5" \
-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/events/lineage/evt-5e6f708192a3b4c5", headers=headers, timeout=30)
r.raise_for_status()
print(r.json())
Example response
HTTP 200
{
"depth": 2,
"event_id": "evt-5e6f708192a3b4c5",
"genesis_event_id": "env-7d3c1a9e5b2f4068",
"lineage": [
{
"decision": "allow",
"event_id": "evt-5e6f708192a3b4c5",
"event_type": "tool_call",
"sequence": 4,
"ts": "2026-09-01T14:10:21+00:00"
},
{
"decision": "allow",
"event_id": "env-7d3c1a9e5b2f4068",
"event_type": "intent_envelope",
"sequence": 3,
"ts": "2026-09-01T14:10:00+00:00"
}
],
"reached_genesis": true,
"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. |
| 404 | event_not_found | No such event on this account. |
What would show this is false
An event whose parent_id names something outside your account stops the walk there: reached_genesis is false, not silently true.
GET /v1/events/tree
Subtree beneath an event
Returns the events whose parent_id linkage descends from a root, to a depth you choose.
Parameters
depthquery, integer- levels of descendants below the root Default
25. rootquery, string required- root event_id
Request body
None.
Example request
curl
curl -sS -X GET "https://api.afaprotocol.com/v1/events/tree?root=env-7d3c1a9e5b2f4068&depth=3" \
-H "X-API-Key: afa-beta-EXAMPLE-e4qs"
Python
import requests
API = "https://api.afaprotocol.com"
headers = {"X-API-Key": "afa-beta-EXAMPLE-e4qs"}
params = {
"depth": "3",
"root": "env-7d3c1a9e5b2f4068"
}
r = requests.get(f"{API}/v1/events/tree", headers=headers, params=params, timeout=30)
r.raise_for_status()
print(r.json())
Example response
HTTP 200
{
"depth": 3,
"descendant_count": 2,
"node_count": 3,
"root": "env-7d3c1a9e5b2f4068",
"tree": {
"children": [
{
"children": [],
"decision": "allow",
"event_id": "evt-5e6f708192a3b4c5",
"event_type": "tool_call",
"sequence": 4,
"ts": "2026-09-01T14:10:21+00:00"
},
{
"children": [],
"decision": "allow",
"event_id": "evt-4d5e6f708192a3b4",
"event_type": "tool_call",
"sequence": 2,
"ts": "2026-09-01T14:09:58+00:00"
}
],
"decision": "allow",
"event_id": "env-7d3c1a9e5b2f4068",
"event_type": "intent_envelope",
"sequence": 3,
"ts": "2026-09-01T14:10:00+00:00"
},
"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. |
| 404 | event_not_found | The root is not on this account. |
What would show this is false
Set depth=0: node_count is 1 and children is empty. The count follows the depth you asked for, not the data.