Search relations using pagination
Learn how to use the cursor-based pagination API to scan relations in ordered chunks.
The relations/_scan API retrieves relation objects that match specific filtering conditions by using a cursor. A cursor is a pointer, returned by the API, representing the current position in an ordered scan. Pass this pointer in subsequent requests to continue retrieving the next set of results without duplicates or overlap.
Search results using a cursor
Each response includes a cursor that indicates the scan position. You can use this pointer in the next request to retrieve the next page of results. The entire reading session does not expire. By default, the cursor Time to Live (TTL) is 1 day.
preserveCursor enabled, the cursor will persist for 1 hour after last read, and its value can be reused.HTTP method and endpoint
Use the following HTTP method and endpoint path to submit the request:
POST {TenantURL}/relations/_scan
Replace {TenantURL} with your tenant's base URL.
Request headers
Include the following headers in every request:
| Name | Required | Description |
|---|---|---|
| Authorization | Yes | Bearer token used for authentication (for example, Bearer <access_token>). |
| Content-Type | Yes | application/json |
Request body
The following parameters are supported in the query string:
| Parameter | Type | Required | Description | Accepted Values / Default |
|---|---|---|---|---|
filter | String | Yes (first request only) | Specifies filtering conditions for relations returned by the scan. |
Default: none Accepted values:
Example: |
max | Integer | No | Maximum number of relations to return. |
Default: tenant-defined. Max: 2000 |
offset | Integer | No | Result offset used for pagination. Ignored if a cursor is provided in the request body. | Default: none |
activeness | String | No | Limits results based on activity status. |
Default: Accepted values:
|
options | String | No | Comma-separated list of flags that control response formatting. |
Default: none Accepted values:
|
Request body for subsequent requests (with Cursor)
Include a cursor in the body of any follow-up request after the first page:
{
"cursor": {
"value": "cXVlcnlBbmRGZXRjaDsxOzE0NDI3..."
}
}
Body can also contain filtering fields, but query string values take precedence.
Initial request example
POST {TenantURL}/relations/_scan?filter=(equals(relation_type,'HasAddress'))&max=100
Authorization: Bearer <access_token>
Content-Type: application/json
Subsequent request example
POST {TenantURL}/relations/_scan
Authorization: Bearer <access_token>
Content-Type: application/json
{
"cursor": {
"value": "c2NhbjswOzE7dG90YWxfaGl0czo1MDs="
}
}
Example response
{
"cursor": {
"value": "c2NhbjswOzE7dG90YWxfaGl0czo1MDs="
},
"objects": [
{
"uri": "relations/01WhavR",
"type": "HasAddress",
"startEntityUri": "entities/01X59nt",
"endEntityUri": "entities/01X5E49",
"timestamp": 1678260000000,
"attributes": {
"AddressType": [
{
"value": "Home"
}
]
}
}
]
}
Response fields
The following table describes the fields returned in the response body for each relation object.
| Field | Type | Description |
|---|---|---|
| cursor.value | String | A base64-encoded token indicating the scan position. Use this value in the next request to retrieve the next portion of results. |
| objects | Array | List of relation objects returned in the current page. |
| uri | String | The unique URI of the relation. |
| type | String | The type of relation (e.g., HasAddress). |
| startEntityUri | String | URI of the start entity in the relation. |
| endEntityUri | String | URI of the end entity in the relation. |
| timestamp | Number | The last update timestamp of the relation, in epoch milliseconds. |
| attributes | Object | Contains key-value pairs of relation-level attributes and their values (e.g., AddressType). |
| crosswalks | Array | List of crosswalks associated with the relation, including source type and contributing values. |