Filtering
Narrow list results with range, multi-value and tag filters.
🔍 Learn how to narrow down list results using query parameters on Billy's API.
List endpoints support filtering through query parameters. This page describes the filtering syntax and how to combine filters with pagination. For the exact set of filters a given endpoint accepts, see its query parameters in the API sandbox.
🔄 Filters always operate on fields that are present in the response payload — so the value you filtered on appears on every returned item. For example, filtering events by
startAtreturns events whose sessions expose astartAt, and filtering orders bystatusreturns orders that carry astatusfield. This lets you verify each result against your filter criteria client-side.
Range filters
Some fields support range filtering using dot-notation suffixes, following Stripe's convention. Each suffix maps to a comparison operator:
| Suffix | Operator | Meaning |
|---|---|---|
.gt | Strictly greater than | Return results where the field is strictly after (or greater than) the value. |
.gte | Greater than or equal | Return results where the field is at or after (or greater than or equal to) the value. |
.lt | Strictly less than | Return results where the field is strictly before (or less than) the value. |
.lte | Less than or equal | Return results where the field is at or before (or less than or equal to) the value. |
For example, updatedAt.gte returns results updated at or after the given value, while updatedAt.lt returns results updated strictly before it.
🕒 Datetime format — For datetime fields, use ISO 8601 format with a timezone offset. Example:
2026-03-01T00:00:00+02:00. Always include an offset to avoid ambiguity.
Only a subset of operators is exposed per field. Suffixes not exposed for a given field are ignored.
Multi-value filters
Some fields accept multiple values as a comma-separated list. Values are combined with OR semantics — a result matches if it equals any of the supplied values. Each list is limited to 10 values.
This pattern is already in use today: eventIds and sessionIds on the orders and tickets endpoints both accept comma-separated IDs, and tags on the events endpoint accepts comma-separated tags (see Filtering by tags).
?eventIds=331704d8-50bf-4e99-8d82-95c4974bxxxx,168c36ec-2e28-4312-be93-8893f0ccxxxxNegation
Some fields support negation through the .ne suffix, returning results that do not match the given value. As with multi-value filters, .ne accepts a comma-separated list (max 10) and excludes results matching any of the listed values.
For example, tags.ne=sport,football returns results tagged with neither sport nor football.
🚧 Planned — The
.nesuffix is not yet available on any field.tags(see below) is expected to be the first field to support it, and it may be extended to other fields later.
Examples
Filter by a date range
Bound a datetime field on both sides to get a time window. This returns events with at least one session starting within March 2026:
curl "https://platform.billyapp.live/v1/events?startAt.gte=2026-03-01T00:00:00%2B02:00&startAt.lte=2026-03-31T23:59:59%2B02:00" \
-H "Authorization: Bearer billy:o:1234567891234567:xxxxxxxxxxxxxxxxx"Filter by an exact value
Some fields accept a single value. This returns only fulfilled orders:
curl "https://platform.billyapp.live/v1/orders?status=FULFILLED" \
-H "Authorization: Bearer billy:o:1234567891234567:xxxxxxxxxxxxxxxxx"Filter by multiple values
Multi-value filters scope results to specific resources. This returns tickets belonging to either of two events:
curl "https://platform.billyapp.live/v1/tickets?eventIds=331704d8-50bf-4e99-8d82-95c4974bxxxx,168c36ec-2e28-4312-be93-8893f0ccxxxx" \
-H "Authorization: Bearer billy:o:1234567891234567:xxxxxxxxxxxxxxxxx"Filtering by tags
The events endpoint supports filtering by tags, following the multi-value convention described above:
| Parameter | Example | Behavior |
|---|---|---|
tags | tags=sport,football | Return events having any of the given tags (OR semantics, max 10). |
Tag matching is normalization-aware: values are compared case-insensitively, with surrounding and repeated whitespace collapsed, and accents preserved (Café ≠ Cafe). tags=Rap%20Music therefore matches events tagged rap music. Matching is scoped to your organization's tags.
curl "https://platform.billyapp.live/v1/events?tags=rap%20music,jazz" \
-H "Authorization: Bearer billy:o:1234567891234567:xxxxxxxxxxxxxxxxx"An empty tag value (tags= or a stray comma, e.g. tags=sport,) returns a 400 Bad Request.
🚧 Planned — Negation (
tags.ne=sport, see Negation) is not available yet. Once released, both will compose:tags=sport,football&tags.ne=indoorwill return sport-or-football events that are not also taggedindoor.
Combining filters
Multiple filters are combined with AND semantics — only results matching every supplied filter are returned. Range, multi-value, and negation filters compose freely with each other and with pagination parameters (page, perPage).
When both bounds of a range are supplied (e.g. updatedAt.gte and updatedAt.lte), the result is the inclusive window between them.
curl "https://platform.billyapp.live/v1/orders?status=FULFILLED&updatedAt.gte=2026-01-01T00:00:00%2B00:00&updatedAt.lte=2026-01-31T23:59:59%2B00:00&page=1&perPage=50" \
-H "Authorization: Bearer billy:o:1234567891234567:xxxxxxxxxxxxxxxxx"Validation errors
Invalid filter values return a 400 Bad Request with a JSON body describing the problem:
{
"detail": "Invalid request parameters",
"errors": [
{
"loc": "query.status",
"input": "PAID",
"ctx": "Invalid status. Expected one of ('PENDING', 'FULFILLED', 'CANCELLED')"
}
]
}Common validation errors include an invalid status value, more than 10 values in a multi-value list (eventIds, sessionIds, tags), an empty tag value, and malformed datetimes.
ℹ️ When a requested page is out of range, the API returns a 204 No Content with an empty body — see Pagination.