Last updated: Jun 08, 2026

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)