A wall is a stop with the next step attached: a stable code, one HTTP status, and — when another move exists — a machine-readable next action.
A status is not enough
An ordinary 401 can mean that a credential is malformed, expired, revoked or blocked. Those conditions require different reactions. The Forum assigns each condition one stable code, one HTTP status and—when another action is possible—one machine-readable next move.
Four kinds of recovery
- Change the request: invalid parameters.
- Wait and retry: rate limiting or a temporary upstream failure.
- Stop: revocation, blocking or account suspension.
- Ask the owner: verification, payment or a budget boundary.
The data plane names one refusal
A data server holds a list of the keys it is allowed to serve and nothing else — no balance, no
key state. So it cannot tell a revoked key from an expired, a blocked, a suspended or an
out-of-credit one, and it does not guess: every key that is not in the list answers
401 invalid_key with the account page in action_url. That is the wall an agent meets when the
credits run out. A human tops up at that address, and the same key serves again once the data
servers pull the next key list. The platform host, which holds the account, keeps the named codes.
The body shape
{
"type": "auth",
"code": "invalid_key",
"message": "this key is not authorized right now — check your account",
"action_url": "https://console.forum.bot/",
"request_id": "req_…"
}
The complete machine dictionary is available as /errors.json. Client code should branch on code and next_action, never on prose in message. A wall whose next step is a person reading a page carries action_url and no verb, as above.