> For the complete documentation index, see [llms.txt](https://docs.corppass.gov.sg/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.corppass.gov.sg/technical-specifications/corppass-authorization-api-fapi-2.0/integration-guide/1.-pushed-authorization-request-par-endpoint.md).

# 1. Pushed Authorization Request (PAR) Endpoint

The **Pushed Authorization Request (PAR)** flow is a **mandatory** extension of the OIDC authorization code flow for FAPI 2.0, as defined in [RFC 9126](https://datatracker.ietf.org/doc/html/rfc9126).

It allows the Relying Party (RP) to register sensitive authorization request parameters directly with Corppass via a *secure back-channel `POST` request*. By "pushing" these parameters directly to the server instead of encoding them in the browser URL, this significantly reduces the risk of leaking sensitive data (e.g., `scope`, `redirect_uri`) and ensures integrity by authenticating the request before the user interaction begins.

#### Supported TLS Cipher Suites

Please ensure you are using a supported cipher suite for this endpoint. Refer to [Supported TLS Cipher Suites](/technical-specifications/corppass-authorization-api-fapi-2.0/integration-guide/supported-tls-cipher-suites.md) for the full list.

## Request

To initiate the flow, send a `POST` request to the PAR Endpoint URL obtained from the [OpenID Discovery Endpoint](/technical-specifications/corppass-authorization-api-fapi-2.0/integration-guide/0.-well-known-endpoints/openid-discovery-endpoint.md) (`pushed_authorization_request_endpoint`).

```http
POST /request
```

### Request Headers

<table><thead><tr><th width="190.41796875">Header</th><th width="114.15625">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>Content-Type</code></td><td>Yes</td><td><p>Indicates the encoding format of the request body.</p><p></p><p><strong>Validation:</strong></p><ul><li>Must be set to <code>application/x-www-form-urlencoded</code>. </li></ul></td></tr><tr><td><code>DPoP</code></td><td>Yes</td><td><p>DPoP Proof JWT. A distinct JSON Web Token (JWT) that proves the client possesses the private key corresponding to the public key used for token binding.</p><p></p><p><strong>Validation:</strong></p><ul><li>Optional only if the <code>dpop_jkt</code> parameter is provided in the request body.</li><li>Mandatory if the <code>dpop_jkt</code> parameter is missing.</li><li>If both are provided, the thumbprint derived from this header must match the <code>dpop_jkt</code> value.<br></li></ul><p><strong>Recommendation:</strong> We strongly recommend sending this Header rather than relying on the <code>dpop_jkt</code> parameter, as the <code>DPoP</code> header is mandatory for all subsequent token interactions.<br><br>Refer to the <a href="/pages/QOVgmxTpNTkdnLGQCrH6">Demonstrating Proof of Possession</a> section for more details.</p></td></tr></tbody></table>

### Request Body

<table><thead><tr><th width="193.078125">Field</th><th width="114.41796875">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>client_id</code></td><td>Yes</td><td>The unique identifier assigned to the Relying Party application during onboarding.</td></tr><tr><td><code>client_assertion</code></td><td>Yes</td><td><p>A signed JWT that identifies and authenticates the client application.</p><p></p><p><strong>Validation:</strong></p><ul><li>Must be generated afresh for each authorization session.</li><li>Must contain a unique <code>jti</code> (JWT ID) claim to prevent replay attacks.</li><li>Must be signed using the Private Key corresponding to the public key registered in your JWKS.</li></ul><p></p><p>Refer to <a href="/pages/LywRxjs8azw2UCtFr8yf">Client Assertion JWT</a> section for more details.</p></td></tr><tr><td><code>client_assertion_type</code></td><td>Yes</td><td><p>Specifies the format of the client assertion.</p><p></p><p><strong>Validation:</strong></p><ul><li>Must be set to <code>urn:ietf:params:oauth:client-assertion-type:jwt-bearer</code>, as mandated by OIDC specifications.</li></ul></td></tr><tr><td><code>code_challenge</code></td><td>Yes</td><td><p>PKCE challenge. The base64url-encoded SHA-256 hash of the client-generated <code>code_verifier</code>.</p><p></p><p>Refer to <a href="/pages/TOFgMaQYGoeEs2HmOyj3">Proof Key of Code Exchange</a> section for more details.</p></td></tr><tr><td><code>code_challenge_method</code></td><td>Yes</td><td><p>PKCE transformation method. The hashing method used to generate the <code>code_challenge</code> from the <code>code_verifier</code>.</p><p></p><p><strong>Validation:</strong></p><ul><li>Must be set to <code>S256</code>, as mandated by FAPI 2.0 specifications.</li></ul></td></tr><tr><td><code>response_type</code></td><td>Yes</td><td><p>Indicates the authorization flow to be executed.</p><p></p><p><strong>Validation:</strong></p><ul><li>Must be set to <code>code</code>, as mandated by FAPI 2.0 specifications.</li></ul></td></tr><tr><td><code>redirect_uri</code></td><td>Yes</td><td><p>The callback URL where the authorization server will redirect the user after successful authorization.<br><br><strong>Validation:</strong></p><ul><li><p>Must be <strong><code>https</code></strong> scheme</p><ul><li>Custom scheme URLs are no longer allowed. Clients are advised to use universal links for app deep-linking instead.</li></ul></li><li>Must exactly match one of the Redirect URIs pre-registered during onboarding.</li><li>Partial matches or wildcard domains are not supported.</li></ul></td></tr><tr><td><code>scope</code></td><td>Yes</td><td><p>A space-delimited list of requested scopes.</p><p></p><p>Each scope grants access to a set of <em>entity</em> or <em>acting user</em>'s attributes called claims. Once authorised, these claims are returned in the <em>ID Token</em> (via the <a href="/pages/tdw1eZJeFJxNFBu1QGx2">Token Endpoint</a>) and/or made available via the <a href="/pages/fFIrslCA8R1d2tn8SIza"><em>Userinfo Endpoint</em></a>.</p><p><br><strong>Validation:</strong></p><ul><li>Must include the <code>openid</code> scope.</li><li>Must only contain scopes authorized for your Client ID. Unrecognized scopes will result in an error.</li></ul><p></p><p>Refer to <a href="/pages/l5fLsA0Ds1G1Xbp0zFzm">Scopes</a> section for the full list of available values.</p></td></tr><tr><td><code>state</code></td><td>Yes</td><td><p>An opaque value used to maintain state between the request and callback. It serves as the primary defense against Cross-Site Request Forgery (CSRF) attacks.</p><p></p><p><strong>Validation:</strong></p><ul><li>Must be unique, non-guessable, and cryptographically random.</li><li>Must be generated afresh for each authorization session.</li><li>The Relying Party must validate that the <code>state</code> returned in the authorization request callback matches the value originally sent.</li></ul></td></tr><tr><td><code>nonce</code></td><td>Yes</td><td><p>A client-provided value used to mitigate replay attacks.</p><p></p><p><strong>Validation:</strong></p><ul><li>Must be unique, non-guessable, and cryptographically random.</li><li>Must be generated afresh for each authorization session.</li><li>The Relying Party must verify that the <code>nonce</code> returned in the ID Token strictly matches this value.</li></ul></td></tr><tr><td><code>acr_values</code></td><td>No</td><td><p>Optional. A space-delimited string indicating desired level of assurance (LoA) for the authentication session.</p><p><br>If multiple values are provided, they should be listed in descending order of preference. The authorization server will attempt to satisfy the first available or supported value.</p><p></p><p>If omitted, the authorization server defaults to the client application's configured LoA.</p><p></p><p><strong>Validation:</strong></p><ul><li>If provided, must correspond to a supported LoA.</li></ul><p></p><p><strong>Supported values:</strong></p><ul><li><code>urn:singpass:authentication:loa:2</code> - LoA 2 (High): Requires 2-Factor Authentication (2FA).</li></ul><p></p><p>Note: Additional LoA values may be introduced in the future to support different authentication standards.</p></td></tr><tr><td><code>authentication_context_type</code></td><td>Yes</td><td><p>A value from a predefined list describing the type of transaction for which the user is authenticating. This context is used by Corppass for risk assessment and anti-fraud monitoring.</p><p><br><strong>Validation:</strong></p><ul><li>Must be one of the supported types configured for your specific client application.</li><li>Values not allow-listed for your client ID will be rejected.</li><li>This parameter is applicable only for Corppass Login application. If provided for Myinfo Business application, the request will be rejected.</li></ul><p><br>Refer to <a href="/pages/AIkZjPEkVrBN3sY7KBQz">Authentication Context Parameters</a> section for more details.</p></td></tr><tr><td><code>authentication_context_message</code></td><td>No</td><td><p>Optional. A string providing context on the purpose of the authentication request.</p><p></p><p><strong>Validation:</strong></p><ul><li>Must contain only alphanumeric characters and spaces</li><li>Maximum length of 100 characters.</li><li>This parameter is applicable only for Corppass Login application. If provided for Myinfo Business application, the request will be rejected.</li></ul><p></p><p><strong>Note on usage:</strong> While currently optional, this value is slated for future enhancements where it will be displayed directly to the user during login. It is strongly advised to provide a clear, user-comprehensible message.</p></td></tr><tr><td><code>dpop_jkt</code></td><td>No</td><td><p>DPoP JWK Thumbprint. The base64url-encoded SHA-256 hash of your DPoP public key (JWK). This binds the authorization code to your specific key.<br><br><strong>Validation:</strong></p><ul><li>Optional if <code>DPoP</code> header is provided.</li><li>Mandatory if the <code>DPoP</code> header is missing.</li><li>If both are provided, the thumbprint derived from the <code>DPoP</code> header must match the <code>dpop_jkt</code> value.</li></ul><p></p><p><strong>Recommendation:</strong> We recommend relying on the <code>DPoP</code> HTTP header rather than this parameter, as the header is mandatory for all subsequent token requests.<br><br>Refer to <a href="/pages/QOVgmxTpNTkdnLGQCrH6">Demonstrating Proof of Possession</a> section for more details.</p></td></tr></tbody></table>

### Sample Request

```http
POST /request
Content-Type: application/x-www-form-urlencoded
DPoP: <signed-DPoP-JWT>

client_id=51YUlwazLASM7aqMiBNW
&client_assertion=eyJ...
&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&code_challenge=VQbq2FQzvY12kTkE-FoLmGHim5W7LRknTNYTUKuCKcE
&code_challenge_method=S256
&response_type=code
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcallback
&scope=openid%20authinfo
&state=5de6a954-a762-4975-a8f4-b692cc35b964
&nonce=4a0bb161-e3bb-4a56-9d75-ebea5de7a32c
&acr_values=urn:singpass:authentication:loa:2
&authentication_context_type=APP_AUTHENTICATION_DEFAULT
&authentication_context_message=login%20as%20corporate%20user
&dpop_jkt=boPCS...
```

## Success Response

If the request is valid, Corppass registers the provided parameters and returns a JSON response containing a `request_uri`.

### Response Body

<table><thead><tr><th width="214.66796875">Field</th><th width="136.328125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>request_uri</code></td><td>String</td><td><p>A unique URI that references the stored authorization payload.</p><p></p><p>Use the exact value as the <code>request_uri</code> query parameter when redirecting the user to the <a href="/pages/be3ILFlYmJIRS9Hv9uv3">Authorization Endpoint</a>.</p></td></tr><tr><td><code>expires_in</code></td><td>Number</td><td><p>The lifetime of the <code>request_uri</code> in seconds.</p><p></p><p>This is set to <strong>60 seconds</strong>. The client must initiate the redirect to the <a href="/pages/be3ILFlYmJIRS9Hv9uv3">Authorization Endpoint</a> within this time window, otherwise the <code>request_uri</code> will become invalid.</p></td></tr></tbody></table>

### Sample Response

```json
{
  "request_uri": "urn:ietf:params:oauth:request_uri:h8YQPVV0Dgm5MGaD_koAm",
  "expires_in": 60
}
```

## Error Response

If the request is malformed, unauthorised, or contains invalid parameters, Corppass returns a JSON response containing an error code and description.

### Response Body

<table><thead><tr><th width="214.66796875">Field</th><th width="136.328125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>error</code></td><td>String</td><td><p>A standardised error code identifying the type of error that occurred.</p><p><br>See <a href="#error-codes">Error Codes</a> below for a complete list of possible values.</p></td></tr><tr><td><code>error_description</code></td><td>String</td><td>A human-readable text description providing additional details about the error.</td></tr><tr><td><code>state</code></td><td>String</td><td>The opaque value originally provided by the client in the request body, returned unmodified.</td></tr></tbody></table>

#### Error Codes

<table><thead><tr><th width="204.31640625">Error Code</th><th width="166.359375">HTTP Status</th><th>Error Description</th></tr></thead><tbody><tr><td>invalid_request</td><td>400</td><td><p>This may be due to one of the following:</p><ul><li>A required request parameter is missing.</li><li>A request parameter is malformed or does not meet the expected format.</li><li>Unsupported parameters are included for the selected product (e.g. Corppass Login app parameters used in MyInfo Business requests).</li><li>The client’s JWKS endpoint is not reachable.</li><li>The TLS cipher suite used for the connection is not compliant with <a href="https://openid.bitbucket.io/fapi/fapi-2_0-baseline.html#section-4.2">FAPI 2.0 security requirements</a>.</li></ul><p>Please ensure that:</p><ul><li>All required parameters are provided and correctly formatted.</li><li>Only parameters applicable to the intended product are included in the request.</li><li>Your JWKS endpoint is accessible and returns a valid key set that complies with the required <a href="/pages/4HeJT56VKL5MvRg3PAsJ">specification</a>.</li></ul></td></tr><tr><td>invalid_client</td><td>400 / 401</td><td><p>This may be due to one of the following:</p><ul><li>Missing client credential</li><li>Invalid client credential</li><li>Expired client credential</li><li>Improperly formatted client credential or assertion (e.g., malformed JWT)</li><li>The client’s JWKS does not contain the required signing key</li></ul><p>Please ensure that:</p><ul><li>The client credential is present, valid, and not expired</li><li>Your JWKS endpoint is accessible and returns a valid key set that complies with the required <a href="/pages/4HeJT56VKL5MvRg3PAsJ">specification</a>.</li></ul></td></tr><tr><td>invalid_scope</td><td>400</td><td>The requested scope is invalid, unknown, malformed, or exceeds the scope granted to the client.</td></tr><tr><td>invalid_dpop_proof</td><td>401</td><td><p>This may due to the one of the following:</p><ul><li>The DPoP proof is expired.</li><li>The DPoP proof is malformed.</li><li>The DPoP proof failed signature verification.</li><li>The DPoP proof contains missing or invalid required claims.</li></ul><p>Please ensure that:</p><ul><li>The DPoP proof is correctly structured and signed using the client's private key.</li><li>The DPoP proof complies with the required <a href="/pages/QOVgmxTpNTkdnLGQCrH6">specification</a>.</li></ul></td></tr><tr><td>server_error</td><td>500</td><td>The authorization server encountered an unexpected internal error while processing the request.</td></tr><tr><td>temporarily_unavailable</td><td>503</td><td>The server is temporarily unable to handle the request due to maintenance or high load.</td></tr></tbody></table>

### Sample Response

```json
{
  "error": "invalid_client",
  "error_description": "Client authentication failed due to a missing, invalid, expired, or improperly formatted client credential or assertion.",
  "state": "5de6a954-a762-4975-a8f4-b692cc35b964"
 }
```

## Next Steps

**Redirect the User:** Upon successful retrieval of the `request_uri` from the PAR response, the next step is to redirect the user's browser to the *Authorization Endpoint*.

The `request_uri` serves as a secure reference to the parameters registered in this step and is used to construct the redirect URL, replacing the full list of query parameters typically used in legacy flows.

**Proceed to** [**2. Authorization Endpoint**](/technical-specifications/corppass-authorization-api-fapi-2.0/integration-guide/2.-authorization-endpoint.md) **to redirect the user and obtain the Authorization Code.**
