Getting started
Afixo answers one question for an API client: which version of this person may I see, for this stated reason? This page takes an integrator from zero to a disclosure decision.
-
Sign in at afixo.io. Subjects authenticate with GitHub. The browser never holds a token: the session is a sealed cookie set by the edge (see the session boundary).
-
Register an API client. Dashboard → API clients → Register. You receive a
client_idand aclient_secret. The secret is shown once; the server keeps only a SHA-256 hash. If it is lost, Rotate secret issues a new one without changing theclient_id, so rules that name the client keep working. -
Get a rule from the subject. Nothing is disclosed until the subject writes a rule that matches your client and/or the purpose you declare (Dashboard → Policies). Without one, every call is a
403 deny. -
Get a bearer token with the OAuth 2.0 client-credentials grant. Tokens are opaque and valid for one hour; there is no refresh token — request a new one.
Terminal window curl -s https://api.afixo.io/oauth/token \-u "$CLIENT_ID:$CLIENT_SECRET" \-d grant_type=client_credentialsTerminal window curl -s https://api.afixo.io/oauth/token \-d grant_type=client_credentials \-d client_id="$CLIENT_ID" \-d client_secret="$CLIENT_SECRET"{ "access_token": "…", "token_type": "Bearer", "expires_in": 3600 }Wrong credentials are
401 invalid_client; a grant type other thanclient_credentialsis400 unsupported_grant_type. Token responses areCache-Control: no-store. -
Request a disclosure. Name the subject by handle and declare one of the seven purposes. The
purposequery parameter is required.Terminal window curl -s "https://api.afixo.io/v1/disclose/alice?purpose=shipping" \-H "Authorization: Bearer $ACCESS_TOKEN"If a rule matches, you get exactly one persona, filtered by the rule’s ceiling and allow-list. Withheld fields are reported by key name only:
{"decision": "allow","decision_id": "019…","persona": "legal","fields": { "full_name": "Alice Example", "postal_address": "1 Example Street, Example Town" },"withheld": ["dob"]}If nothing matches — no rule, an unknown handle, or a persona the subject has since deleted — the answer is the same
403every time:{ "decision": "deny", "decision_id": "019…", "reason": "no_matching_rule" }Other answers:
400 invalid_purposefor a name outside the vocabulary,401 invalid_tokenfor a missing or expired bearer,403 wrong_principalfor a subject token on this host, and503 upstream_unavailablewhen the audit service is down — a disclosure that cannot be recorded is refused, never served. -
Keep the
decision_id. Every decision, allow or deny, is written to the subject’s audit log before the answer is sent, and thedecision_idis that row’s id: a subject can find exactly the call you quote.
- Machine API reference — every route on
api.afixo.iowith full examples - Disclosure rules — what the subject controls, and how specificity is ranked
- Explorer — the dashboard panel that makes these same calls from the browser