filtering
rest

Filtering

Query syntax: ?column=operator.value

Operators

OperatorExample
eq?rating=eq.PG
neq?rating=neq.R
gt?length=gt.90
gte?rental_rate=gte.2.99
lt?length=lt.60
lte?rental_rate=lte.0.99
like?title=like.ACE%25
ilike?title=ilike.%25dinosaur%25
in?rating=in.(PG,G,PG-13)
notin?rating=notin.(NC-17,R)
is?return_date=is.null
not?return_date=not.is.null
haskey?metadata=haskey.preferences
jsoncontains?tags=jsoncontains.{"genre":"action"}
arraycontains?categories=arraycontains.{Drama}

Multiple filters (AND)

# Films rated PG, shorter than 90 minutes, rental ≤ $2.99
GET /api/v1/film?rating=eq.PG&length=lt.90&rental_rate=lte.2.99

OR conditions

GET /api/v1/film?or=(rating.eq.G,rating.eq.PG)

Select specific columns

GET /api/v1/film?select=title,rental_rate,length

Sorting

GET /api/v1/film?orderBy=rental_rate&orderDirection=asc

Pagination

# Offset
GET /api/v1/film?limit=20&offset=40

# Cursor
GET /api/v1/film?first=20&after=eyJmaWxtX2lkIjo0MH0=

Response includes pagination metadata:

# Add Prefer header to include exact total count
GET /api/v1/film?limit=20&offset=40
Prefer: count=exact
{
  "data": [...],
  "pagination": {
    "total": 1000,
    "offset": 40,
    "limit": 20,
    "hasMore": true
  }
}

Note: pagination.total is only included when the request sends the Prefer: count=exact header. Without it, the response omits total to avoid expensive COUNT(*) queries on large tables.