Pushed Authorization Requests (PAR)
With a pushed authorization request (PAR) the client POSTs the authorization parameters to a back-channel endpoint first (server to server, with client authentication). It receives a request_uri, a short reference that it then uses in the browser redirect. This avoids URL-length limits, keeps sensitive parameters out of the browser, and prevents tampering. Use it whenever the request carries something that you do not want visible or editable in the address bar. It is mandatory for FAPI 2.0 clients (the high-security profile for banking-grade APIs).
POST /orgs/{orgId}/api/v1/oauth/par
PAR is required for FAPI 2.0 clients. Use it for any flow involving sensitive parameters (e.g., claims, acr_values, or large scope strings).
PAR Request
Submit all authorization parameters to the PAR endpoint using client authentication. The request body is application/x-www-form-urlencoded.
| Parameter | Required | Description |
|---|---|---|
response_type | ✅ | e.g., code |
client_id | ✅ | Your client ID |
redirect_uri | ✅ | Pre-registered redirect URI |
scope | ✅ | Requested scopes |
state | recommended | CSRF protection value |
code_challenge | PKCE | S256 code challenge |
code_challenge_method | PKCE | S256 |
response_mode | optional | query, fragment, form_post or a JARM mode (jwt, query.jwt, …) — see Signed responses (JARM) |
request | optional | A signed request object (JAR: the authorization parameters carried as a signed JWT). Its claims take precedence over the other form fields; the outer client_id must match iss. See Signed request objects (JAR). |
resource | optional | Identifier of the API that the token is for (may be repeated). Validated now and stored with the request; see Resource indicators. |
| Any other authorization parameter | nonce, prompt, max_age, claims, etc. |
request_uri is not accepted in a PAR body (the PAR standard forbids it) and returns invalid_request. A request object that fails verification returns invalid_request_object (or request_not_supported for encrypted objects).
PKCE (Proof Key for Code Exchange) is a one-time secret that protects the sign-in code. It requires the client to generate a random code verifier and send a hash of it when starting the flow, then the verifier itself when exchanging the code. See PKCE.
curl -X POST https://app.lumoauth.dev/orgs/acme-corp/api/v1/oauth/par \
-u "your_client_id:your_client_secret" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "response_type=code" \
-d "client_id=your_client_id" \
-d "redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback" \
-d "scope=openid+profile+email" \
-d "state=abc123" \
-d "code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM" \
-d "code_challenge_method=S256"
PAR Response
{
"request_uri": "urn:ietf:params:oauth:request_uri:6esc_11ACC5bwc014ltc14eY22c",
"expires_in": 600
}
| Field | Description |
|---|---|
request_uri | Opaque URI referencing the pushed request. Single-use and short-lived. |
expires_in | Seconds until request_uri expires (600, the FAPI 2.0 maximum) |
Using the request_uri
Pass the request_uri to the Authorization Endpoint instead of inline parameters:
GET https://app.lumoauth.dev/orgs/acme-corp/api/v1/oauth/authorize?
client_id=your_client_id&
request_uri=urn%3Aietf%3Aparams%3Aoauth%3Arequest_uri%3A6esc_11ACC5bwc014ltc14eY22c
Do not include other authorization parameters alongside request_uri — they will be ignored (or rejected for FAPI 2.0 clients).
Errors
| HTTP | error | Cause |
|---|---|---|
| 400 | invalid_request | response_type is not code, redirect_uri is missing or not registered, or request_uri was sent |
| 400 | invalid_target | A resource value is malformed or not registered for the client |
| 400 | invalid_request_object / request_not_supported | The signed request object failed verification, or it was encrypted |
| 401 | invalid_client | Client authentication failed, or the client is disabled |
| 429 | too_many_requests | More than 60 pushed requests per minute from one client |
A DPoP proof sent with the PAR request binds the resulting authorization code to that key (see DPoP).
Related
- FAPI 2.0 — profile where PAR is mandatory
- Authorization endpoint — including signed request objects (JAR) and signed responses (JARM)
- PKCE
Standards used on this page
| Plain name | Standard |
|---|---|
| Pushed authorization requests (PAR) | RFC 9126 |
| Financial-grade API (FAPI) 2.0 | FAPI 2.0 Security Profile |
| Proof Key for Code Exchange (PKCE) | RFC 7636 |
| Signed authorization responses (JARM) | OpenID JWT Secured Authorization Response Mode |
| Signed authorization requests (JAR) | RFC 9101 |
| Resource indicators | RFC 8707 |
| Sender-constrained tokens (DPoP) | RFC 9449 |
See the standards reference for what each one covers and how LumoAuth uses it.