Filter Registration API
The Filter Registration endpoints allow you to define how user context (access rules, ownership scope, and session filters) maps to metadata filters on each nexset. Once registered, the Agentic RAG endpoint automatically resolves these schemas at query time, converting the caller's user_context into per-nexset access control and pre-retrieval filters.
Base path: /v2/nexsets/{nexset_id}/filters
Authentication
All endpoints require an Authorization header. See the GenAI RAG API overview for full details.
Access is role-gated against the target nexset via the Nexla Admin API:
- Read endpoints (GET) require at least
collaboratorrole on the nexset - Write endpoints (POST, PATCH, DELETE, refresh) require at least
operatorrole on the nexset
Concepts
Filter Types
Each filter entry belongs to one of three layers, which determines how the value is sourced from user_context at query time:
| Type | Source at Query Time | Applied As | Description |
|---|---|---|---|
access_rules | user_context.access_rules | ACL filter | Policy-level gates (e.g., "can this user access confidential docs?") |
access_scope | user_context.access_scope | ACL filter | Data ownership scope (e.g., "only docs from this tenant"). Values use IN semantics |
filters | user_context.filters | Pre-retrieval filter | Page or session context (e.g., "only docs from this project") |
Filters can never expand access beyond what access_rules and access_scope permit. If a key appears in both access_scope and filters, Nexla applies the intersection — filters only narrow, never broaden.
Filter Operators
| Operator | Value Type | Description |
|---|---|---|
EQ | single value | Equals |
NEQ | single value | Not equals |
IN | array | Value is in the provided list |
NOT_IN | array | Value is not in the provided list |
GT | single value | Greater than |
GTE | single value | Greater than or equal |
LT | single value | Less than |
LTE | single value | Less than or equal |
CONTAINS | single value | Field contains the value (substring match) |
NOT_CONTAINS | single value | Field does not contain the value |
EXISTS | (ignored) | Field exists and is not null |
NOT_EXISTS | (ignored) | Field does not exist or is null |
BETWEEN | array of two values [min, max] | Value is within the inclusive range |
Filter Registration Entry
Used in the request body for POST /v2/nexsets/{nexset_id}/filters:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
key | string | Yes | — | Metadata field name to filter on. Must match ^[\w\-\.]{1,255}$ |
type | string | Yes | — | Filter type: "access_rules", "access_scope", or "filters" |
operator | string | No | "EQ" | Default comparison operator for this filter |
description | string or null | No | null | Human-readable description |
nexset_field | string or null | No | null | Backend field name, if it differs from key. When set, key is used to look up the value in user_context and nexset_field is the actual metadata field or column consulted by the backend |
nexset_field allows decoupling the user_context key name from the actual backend metadata field. For example, you might register key: "tenant_id" with nexset_field: "org_tenant" so that callers use "tenant_id" in user_context while the backend filters on the "org_tenant" column.
Filter Entry Object
All endpoints that return filter data use this object shape:
| Field | Type | Description |
|---|---|---|
id | integer | Unique identifier for this filter entry |
nexset_id | string | The nexset this filter belongs to |
key | string | The metadata field name |
type | string | Filter layer: "access_rules", "access_scope", or "filters" |
operator | string | The comparison operator applied at query time |
description | string or null | Human-readable description |
nexset_field | string or null | Backend field override, if any |
created_at | string | ISO-8601 timestamp of creation |
updated_at | string | ISO-8601 timestamp of last update |
Endpoints
Register Filter Schema
POST /v2/nexsets/{nexset_id}/filters
Register or replace the full filter schema for a nexset. This replaces all existing filters for the nexset.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
nexset_id | string | The nexset identifier. Must match ^[\w\-\.]{1,255}$ |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
filters | array of FilterRegistrationEntry | Yes | The filter entries to register |
Response
Status: 200 OK
{
"nexset_id": "10000",
"filters": [
{
"id": 1,
"nexset_id": "10000",
"key": "tenant_id",
"type": "access_scope",
"operator": "IN",
"description": "Restrict results to the user's tenant",
"nexset_field": null,
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z"
},
{
"id": 2,
"nexset_id": "10000",
"key": "classification",
"type": "access_rules",
"operator": "EQ",
"description": "Document classification level",
"nexset_field": null,
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z"
}
]
}
Get Filter Schema
GET /v2/nexsets/{nexset_id}/filters
Retrieve the current filter schema for a nexset.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
nexset_id | string | The nexset identifier. Must match ^[\w\-\.]{1,255}$ |
Response
Status: 200 OK
Returns the same envelope as the register endpoint. The filters array is empty when no schema has been registered for the nexset.
Update a Filter Key
PATCH /v2/nexsets/{nexset_id}/filters/{key}?type={type}
Update a single filter key. The type query parameter identifies which filter entry to update when the same key exists under multiple types.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
nexset_id | string | The nexset identifier. Must match ^[\w\-\.]{1,255}$ |
key | string | The filter key name. Must match ^[\w\-\.]{1,255}$ |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | Yes | The current filter type of the entry to update: "access_rules", "access_scope", or "filters" |
Request Body
All fields are optional. Include only the fields you want to change. At least one must be present.
| Field | Type | Required | Description |
|---|---|---|---|
type | string | No | Move this filter to a different type |
operator | string | No | Update the comparison operator |
description | string | No | Update the description |
nexset_field | string | No | Update the backend field override |
Response
Status: 200 OK
Returns the updated Filter Entry Object.
{
"id": 1,
"nexset_id": "10000",
"key": "tenant_id",
"type": "access_rules",
"operator": "EQ",
"description": "Updated description",
"nexset_field": null,
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-16T14:00:00Z"
}
Delete a Filter Key
DELETE /v2/nexsets/{nexset_id}/filters/{key}?type={type}
Remove a single filter key from a nexset.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
nexset_id | string | The nexset identifier. Must match ^[\w\-\.]{1,255}$ |
key | string | The filter key name. Must match ^[\w\-\.]{1,255}$ |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | Yes | The filter type to delete: "access_rules", "access_scope", or "filters" |
Response
Status: 204 No Content
No response body.
Refresh Filter Cache
POST /v2/nexsets/{nexset_id}/filters/refresh
Invalidates the Redis-backed filter schema cache for the nexset. The next V2 query that needs this nexset's registered filter keys reloads them from Supabase and writes the refreshed schema back to cache.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
nexset_id | string | The nexset identifier. Must match ^[\w\-\.]{1,255}$ |
Response
Status: 200 OK
{
"status": "ok",
"nexset_id": "10000"
}