> For the complete documentation index, see [llms.txt](https://docs.empe.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.empe.io/develop/verifier/api-reference/authorization-requests.md).

# Authorization Requests

An **authorization request** is how the Verifier asks a holder to present credentials. Each request is an **OpenID4VP** request that carries its credential query inline and, once created, is tracked by a **verification session**. This page documents the two endpoints that create authorization requests: one that returns request details as JSON, and one that returns the same request encoded as a scannable **QR code**.

You build the query in your own application code and send it on every call, choosing between a **DCQL query** and a **DIF Presentation Exchange v2 definition**; the server does not store reusable request templates.

***

## Endpoints

Both endpoints live under the **`/verifiers/{verifierId}/authorization-requests`** path. The `verifierId` is the identifier of a registered verifier; it may be a DID. Every endpoint requires a valid **OIDC JWT Bearer token** (`Authorization: Bearer <token>`); no specific role is required (see [Authentication](/develop/verifier/authentication.md)).

***

## Create an Authorization Request

**`POST /verifiers/{verifierId}/authorization-requests`**

Creates an OpenID4VP authorization request and a new verification session, then returns the request URI and session identifiers as JSON.

### Request Body

Every field is optional, but **at least one** of `dcqlQuery` or `presentationDefinition` must be supplied. If neither is present, the request fails with `400 Bad Request` and the message `Either dcqlQuery or presentationDefinition must be provided.` Supply exactly one — sending both passes the service's own input validation but fails downstream for every `version` value, surfacing as a `500`.

* **`dcqlQuery`** (object) A Digital Credentials Query Language (DCQL) query describing the requested credentials and claim paths. **Required if `presentationDefinition` is not provided.**
* **`presentationDefinition`** (object) A DIF Presentation Exchange v2 definition. **Required if `dcqlQuery` is not provided.** Can only be used with `version` `v1.draft21` or `v1.draft24` — a request with `presentationDefinition` and no explicit `version` fails with an internal error (`OpenID4VP version 'v1' cannot be used with presentationExchange`).
* **`responseMode`** (string) How the holder returns the presentation. One of `direct_post`, `direct_post.jwt`, `dc_api`, `dc_api.jwt`. Defaults to **`direct_post.jwt`**.
* **`version`** (string) The OpenID4VP draft to use. One of `v1`, `v1.draft21`, `v1.draft24`. Defaults to **`v1`**, which supports only `dcqlQuery`; use `v1.draft21` or `v1.draft24` with `presentationDefinition`. `dcqlQuery` cannot be combined with `v1.draft21`.
* **`signingDid`** (string) The DID that signs the authorization request. If omitted, the `verifierId` path parameter must itself be a DID; otherwise the request fails with `400 Bad Request` and the message ``Missing signing DID. Provide a `signingDid` in the request body when the verifierId is not a DID.``
* **`authorizationResponseRedirectUri`** (string) Redirect URI to include in the authorization response.
* **`expectedOrigins`** (array of strings) Expected origins for Digital Credentials API flows (used with the `dc_api` and `dc_api.jwt` response modes).
* **`transactionData`** (array of objects) Transaction data entries to bind into the request.
* **`verifierInfo`** (array of objects) Verifier attestations to include in the request.

### Response Body

A `201 Created` response returns the request details:

* **`authorizationRequestUri`** — an `openid4vp://...` URI the wallet opens to fulfill the request.
* **`verificationSessionId`** — the session identifier used to track and observe the verification.
* **`authorizationRequestId`** — present for hosted requests.
* **`expiresAt`** — ISO timestamp when the request expires.

**Example request body (DCQL, SD-JWT VC)**

```json
{
  "responseMode": "direct_post.jwt",
  "version": "v1",
  "dcqlQuery": {
    "credentials": [
      {
        "id": "employee_badge",
        "format": "dc+sd-jwt",
        "meta": {
          "vct_values": ["https://issuer.example.com/vct/employee-badge"]
        },
        "claims": [
          { "path": ["employee_id"] },
          { "path": ["full_name"] },
          { "path": ["department"] }
        ]
      }
    ]
  }
}
```

**Example request body (Presentation Exchange v2)**

```json
{
  "responseMode": "direct_post.jwt",
  "version": "v1.draft24",
  "presentationDefinition": {
    "id": "employee-badge-check",
    "input_descriptors": [
      {
        "id": "employee_badge",
        "constraints": {
          "fields": [
            {
              "path": ["$.vct"],
              "filter": {
                "type": "string",
                "const": "https://issuer.example.com/vct/employee-badge"
              }
            },
            { "path": ["$.department"] }
          ]
        }
      }
    ]
  }
}
```

**Example response**

```json
{
  "authorizationRequestUri": "openid4vp://?request_uri=...",
  "verificationSessionId": "18b760b1-4ab8-4d38-9d42-6b4c25a4d2e0",
  "authorizationRequestId": "1b8a6a8b-2ac1-4f0b-9d9c-6b9c859b1af2",
  "expiresAt": "2026-06-22T12:34:56.789Z"
}
```

***

## Create an Authorization Request as a QR Code

**`POST /verifiers/{verifierId}/authorization-requests/qr-code`**

Takes the **same request body** as the JSON endpoint above, but instead of JSON it returns a **PNG image** of a QR code encoding the `authorizationRequestUri`. This is convenient for cross-device flows where a holder scans the code with a wallet.

### Request Body

Identical to [Create an Authorization Request](#create-an-authorization-request). The same validation rules apply, including the requirement that at least one of `dcqlQuery` or `presentationDefinition` be present.

### Response Body

The response body is the raw QR code as `image/png` (`Content-Type: image/png`). The request URI and session identifiers are returned in response headers instead of a JSON body:

* **`X-Authorization-Request-Uri`** — the `openid4vp://...` URI encoded in the QR code.
* **`X-Verification-Session-Id`** — the verification session identifier.
* **`X-Authorization-Request-Id`** — present for hosted requests.

These headers are listed in `Access-Control-Expose-Headers`, so browser-based clients can read them from a cross-origin response.

**Example request**

```bash
curl -X POST \
  "https://verifier.example.com/verifiers/did:web:verifier.example.com/authorization-requests/qr-code" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "version": "v1",
    "dcqlQuery": {
      "credentials": [
        {
          "id": "employee_badge",
          "format": "dc+sd-jwt",
          "meta": { "vct_values": ["https://issuer.example.com/vct/employee-badge"] },
          "claims": [{ "path": ["employee_id"] }, { "path": ["department"] }]
        }
      ]
    }
  }' \
  --output authorization-request.png --dump-header -
```

The downloaded `authorization-request.png` is the QR code, while the dumped headers contain `X-Authorization-Request-Uri`, `X-Verification-Session-Id`, and (for hosted requests) `X-Authorization-Request-Id`.

***

## Observing the Result

Both endpoints create a verification session as a side effect. Track its progress through the verification session endpoints:

* **`GET /verification-sessions/{sessionId}`** — read the current session state.
* **`GET /verification-sessions/{sessionId}/events`** — a **Server-Sent Events (SSE)** stream that emits a `session` event whenever the session updates, plus a `ping` heartbeat every 15 seconds.

Both endpoints require a valid Bearer token. See [Defining What Credentials to Request](/develop/verifier/server-side-vp-query.md) for guidance on building DCQL and Presentation Exchange queries.

***

## Notes

* Pass `signingDid` whenever the `verifierId` is not itself a DID; the authorization request must be signed by a DID the service controls.
* Authentication is an OIDC JWT Bearer token; the authorization-request endpoints require a valid token but no specific role.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.empe.io/develop/verifier/api-reference/authorization-requests.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
