Skip to main content

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 typeOperators
TextEQUALS, NOT_EQUALS, IN, NOT_IN, CONTAINS, NOT_CONTAINS, STARTS_WITH, ENDS_WITH, IS_NULL, IS_NOT_NULL
Numbers, dates and timesEQUALS, NOT_EQUALS, IN, NOT_IN, GT, GTE, LT, LTE, BETWEEN, IS_NULL, IS_NOT_NULL
True/falseEQUALS, NOT_EQUALS, IS_NULL, IS_NOT_NULL
  • IS_NULL and IS_NOT_NULL take no value. All other operators need one.
  • IN and NOT_IN take a list, for example value: [0, 3].
  • BETWEEN takes 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_WITH and ENDS_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_size is 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_page is false.

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 }
}
}
  • page is 1 by default. page_size is 100 by default, and at most 1000.
  • To get the next page, run the same query with page increased by one, until page equals total_pages.
  • total_records is 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 records instead.

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 200 with an errors list 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.