# OAuth authorization endpoint (authorization code)

Backend step after the iClosed consent UI (`https://app.iclosed.io/oauth/authorize`): validates client, redirect URI, and scopes, requires an authenticated resource owner session (Bearer session JWT from login — not an API key or OAuth access token), then redirects to `redirect_uri` with `code` and optional `state`. Third-party OAuth clients start the flow in the browser at the consent URL; they do not call this endpoint directly.

Endpoint: GET /v1/oauth/authorize
Version: 1.0.0

## Query parameters:

  - `response_type` (string, required)
    OAuth response type. Must be "code".

  - `client_id` (string, required)
    OAuth client identifier.

  - `redirect_uri` (string, required)
    Redirect URI registered for the client. Must use https://, or http:// on localhost.

  - `scope` (string)
    Space-delimited scopes requested by the client. Defaults to the full client-allowed scope set.

  - `state` (string)
    Opaque value returned unchanged to prevent CSRF in client-side state handling.

  - `code_challenge` (string)
    PKCE code challenge. Required together with code_challenge_method for public clients and for every client registered through anonymous dynamic client registration; optional for account-owned confidential clients.

  - `code_challenge_method` (string)
    PKCE method; required when code_challenge is present. Only S256 is supported.

## Response 302:

  - `302` (unknown)
    Redirect to the validated redirect_uri with code/state query params

## Response 400:

  - `400` (unknown)
    OAuth request validation failed

## Response 400 fields (application/json):

  - `error` (string, required)

  - `error_description` (string)

## Response 401:

  - `401` (unknown)
    Resource owner not authenticated or invalid OAuth client credentials

## Response 401 fields (application/json):

  - `error` (string, required)

  - `error_description` (string)

## Response 429:

  - `429` (unknown)
    Account rate limit exceeded

