Filtering and Sorting
Every list query in the Refersion GraphQL API takes the same shape of arguments: some filters, a
sort, and a page size. The rules below apply to all of them, so learning them once covers the
whole API. For the arguments a specific query accepts, see the
Schema Reference.
Filters combine with AND
Pass several filters and a record must match all of them. There is no OR, and no way to widen a query beyond your own data.
Unless noted otherwise, a filter is an exact match on the field of the same name — there are no
contains, starts with, or greater-than operators. The only range filters are the date arguments
below.
{
"query": "{ conversions(status: \"APPROVED\" affiliate_id: 123456) { id total } }"
}
Dates are Unix timestamps
Every date argument takes a Unix timestamp in seconds, not an ISO 8601 string, and they come in
_from / _to pairs:
| Argument | Matches |
|---|---|
created_from | Records created strictly after the timestamp. |
created_to | Records created at or before the timestamp. |
updated_from / updated_to, last_login_from / last_login_to and last_conversion_from /
last_conversion_to behave the same way. The bounds are asymmetric: _from is exclusive, _to is
inclusive. Paging a date range by passing the previous page's last timestamp as the next _from
therefore will not repeat that record.
Date fields come back the same way — as Unix timestamps, not ISO 8601 strings:
{ "created": "1526674258" }
On the Affiliate type, a date that was never set comes back as
null rather than as a timestamp of zero.
Some arguments filter a differently-named field
A few arguments are named for the concept rather than the underlying field. They are equivalent to the field they map to, not additional filters:
| Argument | Actually filters | Notes |
|---|---|---|
order_id | The order identifier you sent when reporting the order | Identical to merchant_unique_id. |
sub_id | The subid carried on the tracking link | Note the underscore in the argument but not the field. |
payment_status | Whether the record is attached to a payment | UNPAID matches records with no payment; any other value matches records that have one. |
is_test_conversion | Whether the conversion came from test traffic | Omit it to receive both test and real conversions. |
created_from / created_to on clicks | The click's entry time | Clicks record an entry time rather than a created time. |
Sorting
sort takes a single field name and always sorts descending. There is no direction argument
and no multi-field sort.
Each type accepts its own short list of sort fields — they are listed under Sorting on every type page. Two consequences worth knowing:
- An unrecognized
sortis ignored silently. No error is returned; you get the results back in the database's own order. If a sort seems to have no effect, check the field is on that type's list. Sorting clicks bysubid, for example, usessubidand notsub_id. firstandlastoverridesort. Both act as a page size, but they also force sorting byid—firstascending,lastdescending. A query that passesfirstalongsidesortgets id-ordering, not the sort you asked for.
Page size and paging
limit caps the rows returned. Any value outside 1–200 — including a negative number, a
non-numeric value, or a number above 200 — is silently replaced by 200, which is also the default
when you pass no page size at all.
There are two ways to page:
- Offset paging with
limit(orfirst) plusoffset. Straightforward, and what Pagination walks through. - Cursor paging with
beforeandafter, which match onidrather than position:after: 500returns records with an id above 500. Because a cursor is anchored to a record rather than to a position, it does not skip or repeat rows when new records arrive mid-page — which offset paging over a growing table can do.
Records you will never see
Some records are filtered out before your arguments are applied, so no filter value will surface them:
| Query | Always excluded |
|---|---|
affiliates | Any affiliate not in ACTIVE, PENDING, DISABLED or DENIED. |
conversions | Archived conversions, and any status outside APPROVED, PENDING, DENIED, UNQUALIFIED. |
conversion_triggers | Every trigger that is not ACTIVE. |
conversion_triggers is the one that surprises people: it accepts a status argument, but only
active triggers exist as far as the API is concerned, so filtering for any other status returns an
empty list rather than an error.
payments is a special case. Cancelled payments are excluded only when the query carries at
least one argument — any argument at all, including limit. A bare payments { … } returns
cancelled payments alongside the rest, so pass a limit (which you want anyway) if you need them
filtered out.
Errors
A query that fails validation — an unknown field, a wrong argument type, malformed syntax — returns
HTTP 400 with an errors array describing what went wrong. A query that is valid but matches
nothing returns HTTP 200 and an empty list.
Related
- Schema Reference — every query, type, field and argument.
- Pagination — worked examples of paging through a large result set.
- Call Limits — request limits and response caching.