Ways in, and one that is not for customers
Surfaces
Every way to reach the same record, and one that is not a customer surface at all. The table names what each surface can do and where its limit sits.
This matrix is generated from GET /v1/surfaces in the build that produced this page.
{
"capabilities": [
{
"console": false,
"hosted_mcp": [
"afa_record_event"
],
"local_operator_tools": true,
"name": "events:write",
"rest": [
"POST /v1/chain/checkpoint",
"POST /v1/events",
"POST /v1/events/batch"
],
"sdk": true,
"summary": "Append events to your chain, singly or in batches."
},
{
"console": true,
"hosted_mcp": [
"afa_events_list",
"afa_event_get",
"afa_event_lineage"
],
"local_operator_tools": true,
"name": "events:read",
"rest": [
"GET /v1/bundles/{user_id}.authority",
"GET /v1/chain/blocks",
"GET /v1/dashboard/graph",
"GET /v1/dashboard/machines",
"GET /v1/events/lineage/{event_id}",
"GET /v1/events/stream",
"GET /v1/events/tree",
"GET /v1/events/{event_id}",
"POST /v1/events/search"
],
"sdk": false,
"summary": "Read, search and trace the events in your chain."
},
{
"console": true,
"hosted_mcp": [
"afa_grant_create",
"afa_grant_status",
"afa_grant_use",
"afa_grant_revoke",
"afa_grants_list"
],
"local_operator_tools": true,
"name": "grants",
"rest": [
"GET /v1/grants",
"GET /v1/grants/status",
"POST /v1/grants",
"POST /v1/grants/{grant_id}/revoke",
"POST /v1/grants/{grant_id}/use"
],
"sdk": true,
"summary": "Create, check, meter and revoke sub-agent grants."
},
{
"console": false,
"hosted_mcp": [
"afa_delegation_grant",
"afa_delegation_get",
"afa_delegation_list",
"afa_delegation_revoke",
"afa_service_pubkey"
],
"local_operator_tools": true,
"name": "delegation",
"rest": [
"GET /v1/delegate/grant/{grant_id}",
"GET /v1/delegate/grants",
"POST /v1/delegate/grant",
"POST /v1/delegate/grant/{grant_id}/revoke",
"POST /v1/delegate/{grant_id}/fulfill",
"POST /v1/delegations",
"POST /v1/delegations/verify"
],
"sdk": true,
"summary": "Issue and verify machine-to-machine delegation grants and order-bound tokens."
},
{
"console": true,
"hosted_mcp": [
"afa_dedup_check"
],
"local_operator_tools": true,
"name": "dedup",
"rest": [
"GET /v1/cache/{event_id}",
"GET /v1/dashboard/dedup-stats",
"GET /v1/dedup/membership/{event_id}",
"POST /v1/dedup/check"
],
"sdk": true,
"summary": "Ask whether a call already exists in your ledger, with membership proofs."
},
{
"console": true,
"hosted_mcp": [
"afa_chain_verify",
"afa_verify_envelope",
"afa_verify_checkpoint",
"aa_intent_delta",
"aa_interference_scan",
"afa_verify_scientific_campaign"
],
"local_operator_tools": true,
"name": "verify",
"rest": [
"POST /v1/chain/verify",
"POST /v1/verify/checkpoint",
"POST /v1/verify/envelope",
"POST /v1/verify/scientific-campaign"
],
"sdk": true,
"summary": "Verify exported records, settlement blocks and envelopes without storing anything."
},
{
"console": true,
"hosted_mcp": [
"afa_notifications_list"
],
"local_operator_tools": false,
"name": "notifications",
"rest": [
"GET /v1/dashboard/alerts",
"GET /v1/notifications",
"GET /v1/notifications/preferences",
"POST /v1/dashboard/alerts/{alert_id}/dismiss",
"PUT /v1/notifications/preferences"
],
"sdk": true,
"summary": "Read dispatch records and set channel preferences."
},
{
"console": false,
"hosted_mcp": [
"afa_webhook_get",
"afa_webhook_set",
"afa_webhook_delete"
],
"local_operator_tools": false,
"name": "webhooks",
"rest": [
"DELETE /v1/webhooks",
"GET /v1/webhooks",
"PUT /v1/webhooks"
],
"sdk": false,
"summary": "Register the URL that receives signed notification payloads."
},
{
"console": true,
"hosted_mcp": [
"afa_usage"
],
"local_operator_tools": false,
"name": "usage",
"rest": [
"GET /v1/dashboard/usage",
"GET /v1/usage/export",
"GET /v1/usage/summary"
],
"sdk": false,
"summary": "Read metered call counts and event aggregates for your account."
},
{
"console": true,
"hosted_mcp": [],
"local_operator_tools": false,
"name": "keys",
"rest": [
"DELETE /v1/me/api-keys/{key_id}",
"GET /v1/identity",
"GET /v1/me/api-keys",
"POST /v1/identity/register",
"POST /v1/me/api-keys",
"POST /v1/me/api-keys/{key_id}/rotate"
],
"sdk": false,
"summary": "Manage API keys and machine signing identities."
},
{
"console": false,
"hosted_mcp": [
"afa_governance_propose",
"afa_governance_list",
"afa_governance_ratify",
"afa_governance_enact"
],
"local_operator_tools": true,
"name": "governance",
"rest": [
"GET /v1/chain/checkpoint/recommend",
"GET /v1/governance/proposals",
"GET /v1/governance/proposals/{proposal_id}",
"GET /v1/heal/status",
"POST /v1/governance/proposals",
"POST /v1/governance/proposals/{proposal_id}/enact",
"POST /v1/governance/proposals/{proposal_id}/ratify",
"POST /v1/governance/proposals/{proposal_id}/reject",
"POST /v1/heal/auto/start",
"POST /v1/heal/auto/stop",
"POST /v1/heal/run",
"POST /v1/heal/scan",
"POST /v1/policy/test"
],
"sdk": false,
"summary": "Evaluate policy, heal chains and read checkpoint advice."
},
{
"console": false,
"hosted_mcp": [],
"local_operator_tools": true,
"name": "anchors",
"rest": [
"GET /v1/anchors",
"POST /v1/anchors/run"
],
"sdk": false,
"summary": "Read and run external timestamp receipts for your chain root."
},
{
"console": false,
"hosted_mcp": [
"afa_surfaces"
],
"local_operator_tools": false,
"name": "surfaces",
"rest": [
"GET /v1/surfaces"
],
"sdk": false,
"summary": "This document."
},
{
"console": false,
"hosted_mcp": [
"afa_health",
"afa_skill"
],
"local_operator_tools": false,
"name": "health",
"rest": [
"GET /v1/health",
"GET /v1/skill"
],
"sdk": true,
"summary": "Liveness, version, storage backend, and the skill text."
},
{
"console": false,
"hosted_mcp": [],
"local_operator_tools": false,
"name": "orgs",
"rest": [
"GET /v1/orgs",
"GET /v1/orgs/{org_id}",
"GET /v1/orgs/{org_id}/keys",
"GET /v1/orgs/{org_id}/members",
"POST /v1/orgs",
"POST /v1/orgs/{org_id}/accept",
"POST /v1/orgs/{org_id}/invite"
],
"sdk": false,
"summary": "The organisation and team model."
},
{
"console": false,
"hosted_mcp": [],
"local_operator_tools": false,
"name": "admin",
"rest": [
"GET /v1/admin/accounts",
"GET /v1/admin/digest-preview",
"GET /v1/admin/inquiries",
"GET /v1/admin/seats",
"GET /v1/admin/transition-requests",
"POST /v1/admin/seats",
"POST /v1/admin/transition-requests/{request_id}"
],
"sdk": false,
"summary": "The operator's own view of accounts, requests, messages and seats. Every route behind it also requires an administrator."
}
],
"excluded": [
{
"method": "GET",
"path": "/bundle.authority",
"reason": "public verification artifact"
},
{
"method": "GET",
"path": "/static/bundle.pub",
"reason": "public static assets"
},
{
"method": "GET",
"path": "/v1/billing/status",
"reason": "the account's own free period and its request for continued access"
},
{
"method": "GET",
"path": "/v1/delegations/service-pubkey",
"reason": "the published verification key; public so an offline check needs no account"
},
{
"method": "GET",
"path": "/v1/delegations/service-pubkeys",
"reason": "the published key history; public for the same reason"
},
{
"method": "GET",
"path": "/v1/legal/acceptances",
"reason": "agreement texts and acceptances, consulted before an account exists"
},
{
"method": "GET",
"path": "/v1/legal/documents",
"reason": "agreement texts and acceptances, consulted before an account exists"
},
{
"method": "GET",
"path": "/v1/legal/documents/{document_id}/text",
"reason": "agreement texts and acceptances, consulted before an account exists"
},
{
"method": "GET",
"path": "/v1/me",
"reason": "identity introspection for the signed-in session"
},
{
"method": "GET",
"path": "/v1/seats",
"reason": "how many accounts the beta will take; public"
},
{
"method": "POST",
"path": "/v1/auth/request-otp",
"reason": "sign-in, code verification and sign-out"
},
{
"method": "POST",
"path": "/v1/auth/signout",
"reason": "sign-in, code verification and sign-out"
},
{
"method": "POST",
"path": "/v1/auth/verify-otp",
"reason": "sign-in, code verification and sign-out"
},
{
"method": "POST",
"path": "/v1/billing/transition-request",
"reason": "the account's own free period and its request for continued access"
},
{
"method": "POST",
"path": "/v1/inquiries",
"reason": "a message from anybody; no account required"
},
{
"method": "POST",
"path": "/v1/internal/cron/admin-digest",
"reason": "cron invokers, gated by a shared secret rather than a customer key"
},
{
"method": "POST",
"path": "/v1/internal/cron/anchor",
"reason": "cron invokers, gated by a shared secret rather than a customer key"
},
{
"method": "POST",
"path": "/v1/internal/cron/digest",
"reason": "cron invokers, gated by a shared secret rather than a customer key"
},
{
"method": "POST",
"path": "/v1/internal/cron/grant-expiry",
"reason": "cron invokers, gated by a shared secret rather than a customer key"
},
{
"method": "POST",
"path": "/v1/internal/cron/key-expiry",
"reason": "cron invokers, gated by a shared secret rather than a customer key"
},
{
"method": "POST",
"path": "/v1/internal/cron/webhooks",
"reason": "cron invokers, gated by a shared secret rather than a customer key"
},
{
"method": "POST",
"path": "/v1/legal/accept",
"reason": "agreement texts and acceptances, consulted before an account exists"
},
{
"method": "POST",
"path": "/v1/notifications/digest/run",
"reason": "administrator only"
},
{
"method": "POST",
"path": "/v1/notifications/test",
"reason": "test send; development or administrator only"
}
],
"generated_from": "openapi+registry",
"surfaces": {
"console": {
"host": "app.afaprotocol.com",
"note": "The per-capability flag is declared from the console's own calls.",
"observed": false
},
"hosted_mcp": {
"capability_model": "per_tool",
"endpoint": "/v1/mcp",
"endpoint_capability": null,
"legacy_routes": [
"GET /v1/mcp/tools",
"POST /v1/mcp/call"
],
"note": "The endpoint itself needs no capability. Any key of the account may open a session and list the tools; a tool call is admitted only if the key holds that tool's capability, and a refusal names that capability. The per-capability rows above list which tools each capability covers.",
"observed": true,
"protocol_versions": [
"2025-06-18",
"2025-03-26"
],
"routes": [
"DELETE /v1/mcp",
"GET /v1/mcp",
"GET /v1/mcp/tools",
"POST /v1/mcp",
"POST /v1/mcp/call"
],
"tool_count": 33,
"transport": "streamable-http"
},
"local_operator_tools": {
"customer_surface": false,
"note": "The operator's own local tooling. It is not offered to customers and is not reachable through this service; the column is declared here so the matrix says where each capability lives, not to advertise it.",
"observed": false
},
"rest": {
"auth": [
"X-API-Key",
"Authorization: Bearer <api key>",
"session cookie"
],
"base": "/v1",
"observed": true,
"openapi": "/openapi.json"
},
"sdk": {
"languages": [
"python",
"typescript"
],
"note": "The per-capability flag is declared from the client sources.",
"observed": false,
"reason": "Delivery is API-only during the beta; a private client can be discussed on request.",
"status": "not_offered"
}
},
"unclassified": []
}Operator tools are not a customer surface
The local command line, the local hook and the local signing identity run on the operator's own machine and are not offered to anyone else. Everything a customer reaches goes through the hosted API. That boundary is what keeps the record's vocabulary generic.
Nothing is handed over
There is no file to fetch anywhere on this host: no archive, no client library, no local transport. Delivery is the API and the console. What the documentation describes as a file you keep, such as the local ledger, is a shape printed in full on its page for you to build.
Check: no route and no page on this host returns a signing key, a policy file or an archive; the only non-HTML file served under the documentation is the skill text itself.