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) and receives a request_uri, a short reference 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 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 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, a one-time secret that protects the sign-in code) 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.