> ## Documentation Index
> Fetch the complete documentation index at: https://docs.perflo-api.proofof.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Call Perflo from a browser

> Register a browser origin and use authorization code, PKCE, DPoP, and exact CORS checks.

Perflo supports registered public browser clients with authorization code, Proof Key for Code Exchange (PKCE), and Demonstrating Proof of Possession (DPoP). A confidential backend-for-frontend remains the recommended architecture when you can operate one.

## Register the browser client

Register the public browser profile with exact Hypertext Transfer Protocol Secure (HTTPS) redirect URIs and exact browser origins. Local development may use Hypertext Transfer Protocol (HTTP) on a literal loopback host.

The redirect URI and browser origin are separate values. An origin contains a scheme, host, and optional port, with no path, query, fragment, wildcard, or credentials.

See [Prepare a client for registration](/oauth/client-registration) for the complete validation rules.

## Start authorization with a browser navigation

Create a direct authorization-code request with these values:

* `response_type=code`
* A registered `client_id` and exact `redirect_uri`
* A PKCE `S256` challenge
* `dpop_jkt` for the grant’s DPoP key
* The exact environment `resource`
* Optional `openid` with a required `nonce`

The authorization endpoint does not enable cross-origin resource sharing (CORS). Navigate the browser to the discovered authorization endpoint instead of calling it with `fetch`.

Perflo accepts `query` and `form_post` response modes. It rejects fragment mode, implicit responses, arbitrary request objects, and unissued request URIs.

## Exchange the code from the registered origin

The token endpoint accepts a cross-origin request from an exact origin registered to an enabled public browser client. Send the same `client_id`, the PKCE verifier, the code, the exact redirect URI, and a DPoP proof.

Perflo does not set `Access-Control-Allow-Credentials`. The interaction cookie is host-only and never authenticates a token or API request.

Pushed Authorization Requests (PAR), confidential-client revocation, introspection, and client administration do not enable browser CORS. A public client’s resource owner revokes its grant from the host-only account page.

## Send protected requests from the same client

For a protected application programming interface (API) operation, send the DPoP access token and a new proof as described in [Use DPoP with Perflo tokens](/oauth/dpop). The request origin must belong to the enabled client identified by the validated token.

An accepted preflight does not authenticate the later request. Perflo rechecks the actual client, origin, token, proof, grant, and scope.

Dynamic CORS responses echo the exact accepted origin and never use `*`.

## Use only the allowed browser headers

Browser preflights may request these headers when the target route uses them:

* `Authorization`
* `DPoP`
* `Idempotency-Key`
* `X-Request-Id`
* `Content-Type`

Perflo may expose `DPoP-Nonce`, `Idempotent-Replayed`, `Retry-After`, `X-Request-Id`, and `WWW-Authenticate`. It rejects `Origin: null`, unregistered origins, wildcard matches, and a disabled or mismatched client.

## Keep account actions on the issuer origin

Consent, the account page, logout, and provider disconnect use server-rendered pages at the issuer origin. They do not enable CORS.

Unsafe account and interaction submissions require the host-only cookie, exact issuer origin, and a synchronizer token against cross-site request forgery (CSRF). Grant revocation and provider disconnect also require authentication from the previous 10 minutes. Browser scripts never receive provider credentials, provider device identifiers, email, wallet identity, or session cookies.

See [Manage connected clients](/oauth/account-access) for consent, grant revocation, logout, and provider disconnect behavior.
