---
title: "Mints an authorization code for a signed-in identity. **Internal**: admin-token gated, exactly like `/admin/*` and the website's other server-to-server calls, and never reachable from a browser."
method: POST
path: "/oauth/authorize/grant"
tags: ["oauth"]
---

# Mints an authorization code for a signed-in identity. \*\*Internal\*\*: admin-token gated, exactly like \`/admin/\*\` and the website's other server-to-server calls, and never reachable from a browser.

`POST /oauth/authorize/grant`

## Request

- Base URL: `https://api.mapmap.ai`
- URL: `https://api.mapmap.ai/oauth/authorize/grant`
- Auth: HTTP bearer

The website calls this only after (a) validating its own console
session server-side and (b) a human pressing "Allow". The identity must
already exist (the console sign-in proved it), so this endpoint never
creates one.

It DOES create a key when the identity has none: the sign-in proved
mailbox control, which is exactly the evidence `/v1/keys/verify`
accepts, so the minted key is `verified` on the standard free tier
rather than a provisional one that would expire under the user mid-use.

## Request body

- GrantRequest: Body for the internal `POST /oauth/authorize/grant`.
  - `client_id` string, required: The client the code is for: a registered UUID, or an https client-id metadata document URL (CIMD).
  - `client_kind_hint` string, nullable: Hint at the client kind (`"dcr"` / `"cimd"`); advisory only, the gateway decides from the id's own shape.
  - `code_challenge` string, required: PKCE S256 challenge (base64url, unpadded, 43 characters).
  - `identity_email` string, required: Delivery email of the signed-in identity. Server-supplied: the website reads it from its own validated console session, never from anything the browser posted.
  - `redirect_uri` string, required: Redirect URI the authorize request carried; must be one the client registered (loopback matches on any port).
  - `scope` string, nullable: Requested scope; narrowed to what this server grants.

## Response `200`

Authorization code minted

- GrantResponse: Response for the internal `POST /oauth/authorize/grant`.
  - `code` string, required: The authorization code. The website appends it, with `state` and `iss`, to the redirect; it must never be rendered or logged.
  - `expires_in` integer, required: Code lifetime in seconds.
  - `redirect_uri` string, required: The redirect URI the code is bound to (echoed so the website redirects to exactly what was validated).

## Other responses

- `400`: Bad challenge, redirect URI, or client metadata document
- `401`: Missing or wrong admin token
- `404`: Unknown client or identity
- `501`: OAuth not configured on this deployment

---

[API](https://skmtc.dev/mapmap/apis/sn-gateway.md) · [All operations](https://skmtc.dev/mapmap/apis/sn-gateway/llms.txt) · [OpenAPI document](https://skmtc.dev/mapmap/apis/sn-gateway/revisions/2293be8b4c38?raw)
