Saved Filters
Save any filter combination set on the /requests page — provider, model, status, date range, and more — under a name, then restore the entire state in one click on future visits. Useful for recurring debug queries or shared team views.
How to use
- Go to /requests and configure your filters — provider, model, status, date range, etc.
- Click Save as filter on the right side of the filter bar.
- Enter a name (1–80 characters) and click Save.
- On future visits, select the saved name from the Saved filters dropdown in the filter bar to restore all filters at once.
Scope and isolation
Saved filters are per-user. Filters created by other members in the same organization are not visible, and only your own filters appear in the dropdown. This isolation is enforced at the database level via Row Level Security (RLS).
API
All endpoints require JWT authentication (authJwt middleware). Include Authorization: Bearer <supabase_access_token> in the request header.
List
GET /api/v1/saved-filters
# Response: array sorted newest first
# [
# {
# "id": "sf_xxxxxxxx",
# "name": "GPT-4o errors only",
# "filters": { "provider": "openai", "model": "gpt-4o", "status": "5xx" },
# "created_at": "2026-05-15T09:00:00.000Z"
# },
# ...
# ]bashSave
POST /api/v1/saved-filters
Content-Type: application/json
{
"name": "GPT-4o errors only",
"filters": {
"provider": "openai",
"model": "gpt-4o",
"status": "5xx"
}
}
# 201 Created
# {
# "id": "sf_xxxxxxxx",
# "name": "GPT-4o errors only",
# "filters": { "provider": "openai", "model": "gpt-4o", "status": "5xx" },
# "created_at": "2026-05-15T09:00:00.000Z"
# }bashDelete
DELETE /api/v1/saved-filters/:id
# 204 No ContentbashRequest / response schema
| Field | Type | Description |
|---|---|---|
name | string | 1–80 characters. Must be unique per user — returns 409 on duplicate. |
filters | object | Free-form JSON object containing the filter values. Stored as JSONB without server-side parsing — the UI reads and writes it in its own format. |
id | string | Server-assigned identifier. |
created_at | string (ISO 8601) | Creation timestamp. The list is sorted by this value descending. |
Error codes
| HTTP status | Cause |
|---|---|
400 | name missing or too long, or filters is absent |
401 | JWT token missing or expired |
404 | Delete target ID does not exist or does not belong to the current user |
409 | A filter with the same name already exists for this user |
curl examples
# List saved filters
curl https://spanlens-server.vercel.app/api/v1/saved-filters \
-H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN"
# Save a filter
curl -X POST https://spanlens-server.vercel.app/api/v1/saved-filters \
-H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Anthropic 429 errors","filters":{"provider":"anthropic","status":"4xx"}}'
# Delete a filter
curl -X DELETE https://spanlens-server.vercel.app/api/v1/saved-filters/sf_xxxxxxxx \
-H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN"bashLimitations
- No organization-wide sharing. Saved filters are private to the creating user. Shared team filters are on the roadmap.
- No filter validation. The server stores the
filtersobject as-is without validating keys or values. An invalid filter value will be saved without error but may be ignored when the /requests UI applies it. - 100 filters per user maximum. Delete old filters before creating new ones if you hit this limit.