Query options
A deliberately small slice of OData v4, supported identically on all four datasets.
| Option | Supported | Notes |
|---|---|---|
$select | yes | Name the columns you load. The most important option here. |
$filter | yes | Standard OData predicates. |
$orderby | yes | Note that it changes the paging order, see Paging. |
$count | yes | $count=true scans the whole dataset. |
$top / $skip | yes | $top is capped at 1000. Prefer next links over $skip. |
$skiptoken | yes | Server-generated. Follow it, do not construct it. |
$expand | no | The datasets are flat and have no navigation properties. Join in your warehouse instead. |
$apply | no | No server-side aggregation. Aggregate in your warehouse. |
$search | no | Use $filter with contains(). |
$select
?$select=TicketInternalId,FaireventName,TicketGrossPrice,CurrencyShort
Projecting is not only about response size. The underlying datasets are assembled from several sources, and asking for fewer columns lets the database skip work it would otherwise do. It shortens every page you fetch.
$filter
Standard OData v4 syntax. The operators you will use:
| Operator | Example |
|---|---|
eq, ne | SaleIsTest eq false |
gt, ge, lt, le | TicketGrossPrice gt 0 |
and, or, not | FaireventYear eq 2026 and SaleIsTest eq false |
contains(), startswith(), endswith() | contains(ArticleName,'Day') |
null comparison | TicketCancelledOn eq null |
Literal syntax that trips people up:
| Type | How to write it |
|---|---|
| String | single quotes: 'Trade Fair'; escape an inner quote by doubling it: 'O''Brien' |
| Boolean | true / false, unquoted |
| Number | unquoted: 42, 25.00 |
| Date and time | ISO 8601, unquoted: 2026-01-01T00:00:00Z |
| Guid | unquoted: 4f1e... |
Filtering a status column
Status-like columns — TicketStatusType, SaleStatus, ArticleType and the rest — are plain strings holding UPPER_SNAKE_CASE tokens, not OData enum types. Filter them with an ordinary quoted string:
?$filter=SalePaymentStatus eq 'PAID'
?$filter=ArticleType eq 'TICKET' and TicketStatusType ne 'BLOCKED'
Most of these columns have a closed, documented value set — Datasets → Column values lists every one. Do not guess a token; a misspelt one is not an error, it simply matches nothing.
Three filters worth knowing before you write any others:
?$filter=SaleIsTest eq false
?$filter=FaireventName eq 'Trade Fair' and FaireventYear eq 2026
?$filter=FaireventInternalId eq 42
SaleIsTest eq falseexcludes test sales. Apply it unless you specifically want them.- Match event names with
eq, nevercontains, and filter the year separately. - Filtering by event is the effective way to split a very large extract into chunks that parallelise.
Property names are matched case-insensitively; token values are not — they are uppercase.
Why there is no by-key endpoint
Tickets(MandatorInternalId=1,TicketInternalId=2) answers 404, deliberately. This surface exists for bulk extraction, and single-record lookup during a transaction is what the operational APIs are for. The keys are declared in the model because they are what turns paging into a cheap keyset walk.