Pushed Authorization Requests
Overview
Pushed Authorization Requests (PAR, RFC 9126) allow the client to send authorization parameters to the authorization server via a back-channel POST request, instead of including them in the authorization URL query string. This provides:
- Parameter confidentiality — Authorization parameters are not exposed in the browser address bar or HTTP referer headers
- Request integrity — Parameters cannot be tampered with during the redirect
- Large parameter support — No URL length limitations
- Required by FAPI 2.0 — Mandatory for financial-grade API compliance
The PAR API is available at client.par.
How PAR Works
sequenceDiagram
participant App
participant SDK
participant AS as Auth Server
App->>SDK: Login
SDK->>AS: POST /par (all params)
AS->>SDK: request_uri
SDK-->>AS: Redirect with request_uri only
- The SDK sends all authorization parameters to the PAR endpoint via POST
- The server returns a
request_uri(an opaque reference to the stored parameters) - The authorization URL contains only the
request_uriandclient_id— no sensitive parameters
Usage
Checking Availability
// Check if PAR endpoint is availableconst available = await client.par.isAvailable();
// Check if the server requires PARconst required = await client.par.isRequired();Pushing Authorization Parameters
Send authorization parameters to the PAR endpoint:
const parResult = await client.par.push({ redirectUri: 'https://myapp.com/callback', scope: 'openid profile email',});
console.log(parResult.requestUri); // urn:ietf:params:oauth:request_uri:...console.log(parResult.expiresAt); // Epoch secondsPARResult
| Property | Type | Description |
|---|---|---|
requestUri | string | Opaque reference to the stored authorization request |
expiresAt | number | When the request URI expires (epoch seconds) |
Building the Authorization URL
After pushing, build the authorization URL with just the request_uri:
const url = await client.par.buildAuthorizationUrl(parResult.requestUri);
// Redirect the userwindow.location.href = url;The generated URL contains only client_id and request_uri — all other parameters are stored server-side.
Complete Flow
// 1. Push parametersconst parResult = await client.par.push({ redirectUri: 'https://myapp.com/callback', scope: 'openid profile email',});
// 2. Build URL with request_uriconst url = await client.par.buildAuthorizationUrl(parResult.requestUri);
// 3. Redirectwindow.location.href = url;
// 4. Handle callback (same as standard Authorization Code Flow)const tokens = await client.handleCallback(window.location.href);Using PAR with buildAuthorizationUrl
You can also use PAR transparently through buildAuthorizationUrl() by setting usePar: true:
const { url } = await client.buildAuthorizationUrl({ redirectUri: 'https://myapp.com/callback', scope: 'openid profile email', usePar: true,});
// The SDK automatically pushes parameters via PAR// and builds the URL with the request_uriwindow.location.href = url;API Reference
Push Options
The push() method accepts the same options as buildAuthorizationUrl():
| Parameter | Type | Default | Description |
|---|---|---|---|
redirectUri | string | Required | Redirect URI |
scope | string | 'openid profile' | Requested scopes |
responseType | 'code' | 'none' | 'code' | Response type |
prompt | string | — | Prompt behavior |
loginHint | string | — | Login hint |
acrValues | string | — | Authentication context |
extraParams | Record<string, string> | — | Additional parameters |
Error Handling
| Error Code | Description | Recovery |
|---|---|---|
par_error | PAR request failed | Check parameters, retry |
par_required | Server requires PAR but it wasn’t used | Use usePar: true or call par.push() |
no_par_endpoint | PAR endpoint not found in discovery | Server doesn’t support PAR |
try { const parResult = await client.par.push({ redirectUri: 'https://myapp.com/callback', });} catch (error) { if (error.code === 'no_par_endpoint') { // Fall back to standard authorization URL const { url } = await client.buildAuthorizationUrl({ redirectUri: 'https://myapp.com/callback', }); window.location.href = url; }}References
- RFC 9126 — OAuth 2.0 Pushed Authorization Requests
- PAR feature overview — Server-side PAR documentation
Next Steps
- JAR & JARM — Signed authorization requests and responses
- DPoP — Bind tokens to cryptographic keys
- Authorization Code Flow — Standard login flow