Filtering and paging
This page describes how to filter and page through data in Analytics API v1.4.13. For a first query and the API key, see How to use the API.
Query shape
In /clean/graphql and /core/graphql, every table is a query field and every column is a field, with the same names as in the Analytics database (Endpoints), for example records and en_GB.
{
records {
id
status
updated_at
}
}
The result is a list of every row that matches, with no paging and no fixed order. Always filter large tables, see below.
Filtering
Filters are given in the filters argument, one condition per column:
{
records(filters: {
status: { operator: EQUALS, value: 3 },
updated_at: { operator: GTE, value: "2026-09-01T00:00:00Z" },
deleted_at: { operator: IS_NULL }
}) {
id
status
en_GB
updated_at
}
}
Conditions on different columns must all match (AND). There is one condition per column. To match several values in one column, use IN, NOT_IN or BETWEEN.
Operators
| Column type | Operators |
|---|---|
| Text | EQUALS, NOT_EQUALS, IN, NOT_IN, CONTAINS, NOT_CONTAINS, STARTS_WITH, ENDS_WITH, IS_NULL, IS_NOT_NULL |
| Numbers, dates and times | EQUALS, NOT_EQUALS, IN, NOT_IN, GT, GTE, LT, LTE, BETWEEN, IS_NULL, IS_NOT_NULL |
| True/false | EQUALS, NOT_EQUALS, IS_NULL, IS_NOT_NULL |
IS_NULLandIS_NOT_NULLtake novalue. All other operators need one.INandNOT_INtake a list, for examplevalue: [0, 3].BETWEENtakes a list of exactly two values, and includes both ends.- Dates and times are given in ISO 8601, for example
"2026-09-01"or"2026-09-01T00:00:00Z". All timestamps are in UTC. - In
CONTAINS,STARTS_WITHandENDS_WITH, the characters%and_work as wildcards.
A second example: ongoing or completed records created in January 2026.
{
records(filters: {
status: { operator: IN, value: [0, 3] },
created_at: { operator: BETWEEN, value: ["2026-01-01", "2026-01-31T23:59:59Z"] }
}) {
id
created_at
}
}
Paging
Clean and Core
Clean and Core tables are not paged. To read a large table, split it into windows with filters and run one query per window, for example one month at a time with updated_at and GTE/LT, or ranges of id with BETWEEN.
Serve: records
The records field in /serve/graphql is paged with a cursor, and ordered by the time the record was last updated:
{
records(
filters: { updated_from: { value: "2026-09-01T00:00:00Z" } }
paging: { page_size: 500 }
) {
paging_info { page_size has_next_page next_cursor }
items { record_id record_updated_at }
}
}
page_sizeis 100 by default, and at most 1000.- To get the next page, run the same query with
paging: { page_size: 500, after: "<next_cursor>" }. - Repeat until
has_next_pageisfalse.
See Serve Table Descriptions for the fields.
Serve: main_report
The main_report field in /serve/graphql is built for the Main Report in EWA Insight, see Configuration. It is paged by page number, and ordered by record_id:
{
main_report(
filters: { start_date: { value: "2026-09-01T00:00:00Z" } }
paging: { page: 1, page_size: 500 }
) {
paging_info { page page_size total_pages total_records }
items { record_id organization_name station_name }
}
}
pageis 1 by default.page_sizeis 100 by default, and at most 1000.- To get the next page, run the same query with
pageincreased by one, untilpageequalstotal_pages. total_recordsis the number of records that match the filters.- Rows added or changed while you page can move between pages. To read all records consistently, use
recordsinstead.
Lookups
Most lookup lists are paged by page number, with paging: { page: 1, page_size: 100 }, and return paging_info { page page_size total_pages total_records } and items. See Lookups.
Language (locale)
The Serve records field returns English (en_GB) names, and the Lookups return names as stored in EWA.
Tables with names in several languages have one column per language, for example name_en_GB and name_nb_NO in mission types, or en_GB and nb_NO in record status, so you can choose the column you need.
Errors and limits
- A missing or wrong API key returns HTTP
401. - Other errors, for example an unknown field or a wrong operator, return HTTP
200with anerrorslist in the response. The message usually says what is wrong. - Request one field per query. Two or more fields in one query is not supported, and returns an error, but the API keeps running.
- Whole numbers are returned as GraphQL
Int, which is limited to 2 147 483 647. - Large unfiltered queries can be slow and put load on the Analytics database. Filter, and request only the fields you need.