Security & data
No player PII to third-party apps
A user token's sub is a per-app pairwise identifier: stable for one player inside one
app, different in every other app. Your app never receives a player's real account ID, e-mail,
date of birth, exact location or balance. GET /me returns only sub and a chosen
display_name, and only with profile.basic.read consent.
Consent, not implicit trust
Every user-authorised capability requires an explicit, scoped consent on africaone.io, with a
recorded receipt (scopes granted, consent-text version). A player can withdraw it at any time;
every token issued under a revoked consent answers 403 CONSENT_REVOKED on its next use.
Regulated features are off and fail closed
Regulated asset types exist in the schema and are switched off (Global Directive #8). A policy
check that cannot positively confirm a feature is enabled refuses the request
(503 FEATURE_DISABLED) rather than defaulting to allow. Commerce, entitlements and regulated
assets are not reachable through this API today, in sandbox or production.
Secrets
Client secrets, webhook endpoint secrets and signing keys are never generated client-side and
never logged. Endpoint secrets are derived (HMAC(master, "ao-webhook/v1/" + endpoint + "/" + key_version)), not stored directly, so rotation never requires reading a secret out of
storage. Keep your client secret and webhook endpoint secret on your server only.
Transport and headers
Every response carries an opaque request_id, X-AfricaOne-API-Version and
Cache-Control: no-store. Refusals are application/problem+json (see Errors).
Every mutating API call requires an Idempotency-Key header once production is enabled (Global
Directive #4); the sandbox contract mock does not yet enforce it, but integrations should send
it from day one.
Reporting a concern
This preview does not yet publish a public security contact. Until it does, do not submit real credentials, real player data or production traffic to any sandbox endpoint described here.