# /query Endpoint

ESS supports an [authorization mechanism based on Access Requests and Grants](https://docs.inrupt.com/security/authorization/access-requests-grants).

ESS serializes the Access Requests and Grants as [Verifiable Credentials (VCs)](https://docs.inrupt.com/reference/glossary#verifiable-credential) The query endpoint provides an optimized mechanism to search and filter these VCs.

## /query Endpoint

The ESS [Access Grant Service](https://docs.inrupt.com/ess/latest/services/service-access-grant) provides an endpoint with the following URL:

```jsdoc
https://vc.<ESS DOMAIN>/query
```

{% hint style="info" %}
**Note**\
Access to the **`/query`** endpoint requires users to be authenticated. The endpoint supports the use of either [Solid-OpenID Connect (OIDC) access token](https://docs.inrupt.com/ess/latest/services/service-oidc) or [UMA token](https://docs.inrupt.com/ess/latest/services/service-uma).
{% endhint %}

To query for Access Requests or Grants, clients can send a request to the endpoint:

<table data-header-hidden><thead><tr><th width="162.37005615234375"></th><th></th></tr></thead><tbody><tr><td>Method</td><td><strong><code>GET</code></strong></td></tr><tr><td>Endpoint</td><td><strong><code>https://vc.&#x3C;ESS DOMAIN>/query</code></strong></td></tr><tr><td>Query Parameters</td><td>Parameters that control which results are returned. See <a href="#input-query-parameters">Input: Query Parameters</a> for details.</td></tr></tbody></table>

### Behavior

The ESS **`/query`** endpoint adds support for retrieving access credentials based on a defined set of filters. Please see [Input: Query Parameters](#input-query-parameters) for details.

The results are be available via a pageable interface. Clients can use **`Link`** headers in the response to navigate through the result pages. The query result body consists of a JSON object that lists access credentials formatted as VCs . Please see [Output: Query Response](#output-query-response) for details.

## Input: Query Parameters

<table data-header-hidden><thead><tr><th width="169.46881103515625"></th><th></th></tr></thead><tbody><tr><td><strong><code>type</code></strong></td><td>One of <strong><code>SolidAccessRequest</code></strong>, <strong><code>SolidAccessGrant</code></strong>, <strong><code>SolidAccessDenial</code></strong></td></tr><tr><td><strong><code>status</code></strong></td><td>One of <strong><code>Pending</code></strong>, <strong><code>Denied</code></strong>, <strong><code>Granted</code></strong>, <strong><code>Canceled</code></strong>, <strong><code>Expired</code></strong>, <strong><code>Active</code></strong>, <strong><code>Revoked</code></strong>. Please see <a href="#status-values">Status values</a> for details.</td></tr><tr><td><strong><code>fromAgent</code></strong></td><td>The WebID of the creator of the access credential.</td></tr><tr><td><strong><code>toAgent</code></strong></td><td>The WebID of the recipient of the access credential.</td></tr><tr><td><strong><code>resource</code></strong></td><td>The URL of a storage location specified in the access credential.</td></tr><tr><td><strong><code>purpose</code></strong></td><td>The URL of a purpose identifier specified in the access credential.</td></tr><tr><td><strong><code>issuedWithin</code></strong></td><td>One of <strong><code>P1D</code></strong> (one day), <strong><code>P7D</code></strong> (one week) <strong><code>P1M</code></strong> (one month) or <strong><code>P3M</code></strong> (three months).<br>This parameter will limit the results to those that were issued within the specified time period.</td></tr><tr><td><strong><code>revokedWithin</code></strong></td><td>One of <strong><code>P1D</code></strong> (one day), <strong><code>P7D</code></strong> (one week) <strong><code>P1M</code></strong> (one month) or <strong><code>P3M</code></strong> (three months).<br>This parameter is only relevant when <strong><code>status</code></strong> is <strong><code>Revoked</code></strong> or <strong><code>Canceled</code></strong>. This will limit the results to those that were revoked within the specified time period.</td></tr><tr><td><strong><code>pageSize</code></strong></td><td>This controls the maximum number of results in a page of results. By default, this value is 20. It may not exceed 100.</td></tr><tr><td><strong><code>page</code></strong></td><td>This value is an opaque cursor used to navigate through result pages. A client should make use of this value when consuming <strong><code>Link</code></strong> headers in a response but should not need to set this value independently.</td></tr></tbody></table>

### Status values

**`Active`**

This status value will list Access Grants that have not expired and have not been revoked. This value is only relevant when **`type`** is **`SolidAccessGrant`** .

**`Expired`**

This status value will list Access Grants that have expired. This value is only relevant when **`type`** is **`SolidAccessGrant`** .

**`Revoked`**

This status value will list Access Grants that have been revoked. This value is only relevant when **`type`** is **`SolidAccessGrant`** .

**`Pending`**

This status value will list Access Requests that do not have a corresponding Access Grant or Access Denial. This value is only relevant when **`type`** is **`SolidAccessRequest`** .

**`Granted`**

This status value will list Access Requests that have a corresponding Access Grant. This value is only relevant when **`type`** is **`SolidAccessRequest`** .

**`Denied`**

This status value will list Access Requests that have a corresponding Access Denial. This also can be used with Access Denial types. This value is relevant when the **`type`** is either **`SolidAccessRequest`** or **`SolidAccessDenial`** .

**`Canceled`**

This status value will list Access Requests that have been revoked (i.e. canceled). This value is only relevant when **`type`** is **`SolidAccessRequest`** .

## Output: Query Response

The **`/query`** endpoint returns a JSON object containing an individual page of results as part of a pageable interface. By default, each page of results will contain up to 20 items.

{% hint style="warning" %}
The **`/query`** endpoint operates in a **dynamic environment** where access credentials can be created, expired, or revoked at any time. This has several important implications:

* Results represent a point-in-time snapshot that may change between queries
* The total count can go up or down accordingly as credentials change
* Page content and availability can change during pagination
* A “next” page that was available in a previous query might return empty results in a subsequent query
* Clients should be designed to handle these dynamic aspects gracefully
  {% endhint %}

The response includes a summary section with the total count of access credentials matching the query filters at the time the query was submitted.

```json
{
  "items": [
    { // Matching access credential VC },
    { // Matching access credential VC },
    ...
  ],
  "summary": {
    "total": 100
  }
}
```

When there are multiple pages of results, **`Link`** headers will point to the **`first`** , **`last`** , **`prev`** and **`next`** page, as appropriate. The first page, for example, will not include a **`prev`** link.

Example **`Link`** headers are included below:

```none
Link: </query?type=SolidAccessGrant&status=Active&page=323904ad>; rel="first"
Link: </query?type=SolidAccessGrant&status=Active&page=3d224607>; rel="prev"
Link: </query?type=SolidAccessGrant&status=Active&page=6af7d740>; rel="next"
Link: </query?type=SolidAccessGrant&status=Active&page=35faea55>; rel="last"
```

The **`page`** parameter is used to navigate through an ordered list of pages. Client applications should treat this value as opaque.

#### Total Count Field

{% hint style="success" %}
Added in version 2.5.
{% endhint %}

The response includes a **`summary`** object with a **`total`** field that provides the total count of access credentials matching the query filters at the time the query was submitted, regardless of pagination. This value represents a point-in-time snapshot and may change in subsequent queries as credentials are created, expired, or revoked. Clients can use this field to:

* Display the total count with appropriate context (e.g., “Found 100 matching access credentials”)
* Calculate the number of pages for custom pagination UI (being aware that the total may change in next request)
* Determine if there are any results before proceeding with operations

The count is always included in the response, even when there are no matching results (where the total will be 0). This field maintains backward compatibility with existing clients as it is an addition to the response structure.

## Examples

These examples describe some common queries that application developers may use. In each example, the URL is formatted across multiple lines to improve readability. Please note that all URI parameters are URL-encoded; this is especially important for URIs that contain hash fragments, i.e. sections beginning with the character **`#`** .

{% hint style="info" %}
When implementing clients that consume the query API, consider the following best practices to handle the dynamic nature of the system:

* Avoid making assumptions about data stability between requests
* Implement robust error handling for pagination that gracefully handles when pages become unavailable or return empty results
* Consider adding retry logic with appropriate backoff strategies
* When displaying total counts, include context that indicates it represents a point-in-time value that may have changed
* Design UIs that can gracefully handle changes in result availability
  {% endhint %}

### Example 1

The following query searches for all pending Access Requests from the last week, targeting a particular user, such as the current user of an application. The results of this query may represent the list of outstanding requests that a user should either approve or reject.

```none
/query?type=SolidAccessRequest
    &status=Pending
    &issuedWithin=P7D
    &toAgent=https%3A%2F%2Fid.example%2Fusername
```

### Example 2

The following query searches for all Access Grants that a particular user has issued in the last month. This might allow a user to understand who has been granted access to their Storage to decide if access needs to be changed for anyone.

```none
/query?type=SolidAccessGrant
    &status=Active
    &issuedWithin=P1M
    &fromAgent=https%3A%2F%2Fid.example%2Fusername
```

### Example 3

The following query searches for all Access Requests made by a particular user in the last three months that have been denied.

```none
/query?type=SolidAccessRequest
    &status=Denied
    &issuedWithin=P3M
    &fromAgent=https%3A%2F%2Fid.example%2Fusername
```

### Example 4

The following query searches for all Access Grants that a user has received from others.

```
/query?type=SolidAccessGrant
    &status=Active
    &toAgent=https%3A%2F%2Fid.example%2Fusername
```
