Filtering & Search
Filtering & Searchlink
Filter API responses to retrieve exactly the data you need. Almost all endpoints accept optional parameters which can be passed as HTTP query string parameters to filter, limit and sort the data in an API response. We call these parameters JQL.
Common Filter Parameterslink
Different endpoints may support different filters. These are the common patterns:
| Parameter | Type | Description |
|---|---|---|
date_min_<field> |
string | Filter for a minimum date field. E.g.: ?date_min_approved_date=2020-08-03T10:59:00. |
date_max_<field> |
string | Filter for a maximum date field. E.g.: ?date_max_started_date=2020-08-03T10:59:00. |
expanded |
string | This parameter allows to include resource relations. E.g.: ?expanded=relation1,relation2. For more information, see the Expanding Relationships section. |
limit |
integer | Limit the number of results. E.g.: ?limit=200. For more information, see the Pagination section. |
sort |
string | Sort by a field in ascending order. E.g.: ?sort=name. For more information, see the Sorting section. |
s_<field> |
string | Search field for a given value. E.g.: ?s_code=ABC123. |
s_<field>_in |
string | Search field where the value is present in specified list. E.g.: ?s_category_id_in=777,888,999. |
s_<field>_notin |
string | Search field where the value is not present in specified list. E.g.: ?s_category_id_notin=111,222,333. |
s_<field>_like |
string | Search field that contains a given value. E.g.: ?s_name_like=john. The search is case insensitive. |
s_<relation>-<field>[_in,_notin,_like] |
string | Search field that belongs to a relation for a given value. E.g.: ?s_work-cost_center_id_notin=null (work is a relation and cost_center_id is an attribute of it). |
Note: For the "filtering" parameters (e.g.:
date_min_*,date_max_*,s_*), each resource has its own "searchable" fields defined on the endpoint description, in the "Query Parameters" section.
Status-Based Endpointslink
Some resources offer pre-filtered endpoints for common queries:
# All failures (any status)
curl "https://api.infraspeak.com/v3/failures" \
-H "Authorization: Bearer YOUR_TOKEN"
# Only open failures (not completed or archived)
curl "https://api.infraspeak.com/v3/failures/open" \
-H "Authorization: Bearer YOUR_TOKEN"
# Only closed failures (completed or archived)
curl "https://api.infraspeak.com/v3/failures/closed" \
-H "Authorization: Bearer YOUR_TOKEN"
Such endpoints are also documented in the API Reference.
Date Range Filteringlink
Filter by date ranges where supported:
# Failures created after a specific date-time
curl "https://api.infraspeak.com/v3/failures?date_min_created_at=2026-01-01T00:00:00" \
-H "Authorization: Bearer YOUR_TOKEN"
# Failures created within a date range
curl "https://api.infraspeak.com/v3/failures?date_min_created_at=2026-01-01T00:00:00&date_max_created_at=2026-01-31T23:59:59" \
-H "Authorization: Bearer YOUR_TOKEN"
Note the use of the parameter prefix (date_min_, date_max_) along with the attribute to filter for (created_at in this case).
Filtering Best Practiceslink
Filter Server-Side, Not Client-Sidelink
# Good - filter on the server
response = requests.get(url, params={"s_state": "WAITING_RESOLUTION"})
open_failures = response.json()["data"]
# Bad - fetch all, filter client-side
response = requests.get(url)
all_failures = response.json()["data"]
open_failures = [f for f in all_failures if f["attributes"]["state"] == "WAITING_RESOLUTION"]
Combine Filters for Performancelink
# Efficient - specific query
response = requests.get(
"https://api.infraspeak.com/v3/failures/open",
params={
"s_local_id": 12345,
"s_priority": 4,
"limit": 200
}
)
# Less efficient - broad query with client filtering
response = requests.get(
"https://api.infraspeak.com/v3/failures",
params={"limit": 200}
)
# Then filtering 1500 results (multiple pages) client-side...
Use Indexed Fieldslink
Filter on indexed fields for best performance:
- IDs (
local_id,category_id,client_id) - States and statuses
- Codes (unique identifiers)
Empty Resultslink
When no records match your filters, the API returns an empty array:
{
"data": [],
"meta": {
"pagination": {
"total": 0,
"count": 0,
"per_page": 200,
"current_page": 1,
"total_pages": 2
}
}
}
Handle empty results gracefully:
data = response.json()
if not data["data"]:
print("No matching records found")
else:
for item in data["data"]:
process(item)