Querying & filtering¶
Every dataset endpoint (GET /v1/{domain}/{dataset}) supports the same query language:
filters, sorting, and field selection, combined freely with
pagination. The columns you can use are dataset-specific — find them on
the dataset's reference page, in /v1/datasets/{id}, or in /docs.
Validation is strict. An unknown column, operator, or field anywhere in the query is a 422 with a message naming the offender — never a silently ignored parameter.
Filtering¶
Plain equality is just ?column=value:
curl -H "Authorization: Bearer $API_KEY" \
"https://api.canovix.ro/v1/transport/vehicle_registry?county=CLUJ"
- Text equality is case-insensitive (
county=clujmatchesCLUJ). - Repeat a parameter for OR:
?county=CLUJ&county=SIBIUmatches either.
Everything else uses bracket operators — ?column[op]=value:
| Operator | Meaning | Example |
|---|---|---|
eq |
equal (same as no operator) | county[eq]=CLUJ |
ne |
not equal | county[ne]=CLUJ |
gt / gte |
greater than / or equal | vehicle_count[gte]=100 |
lt / lte |
less than / or equal | vehicle_count[lt]=50 |
in |
any of a comma-separated list | county[in]=CLUJ,SIBIU,BIHOR |
not_in |
none of a comma-separated list | county[not_in]=CLUJ,SIBIU |
contains |
substring match (case-insensitive) | manufacturer[contains]=volks |
starts_with |
prefix match (case-insensitive) | manufacturer[starts_with]=DA |
is_null |
null / not-null test (true/false) |
description[is_null]=true |
Values are coerced to the column's type — integers, decimals, booleans, ISO dates
(2023-12-31), and datetimes all work in comparisons. A value that can't be coerced is a
422.
Multiple filters on different columns combine with AND:
Sorting¶
?sort= takes a comma-separated list of columns; prefix with - for descending. Later
fields break ties on earlier ones.
# Largest fleets first, alphabetical manufacturer within equal counts
curl -H "Authorization: Bearer $API_KEY" \
"https://api.canovix.ro/v1/transport/vehicle_registry?sort=-vehicle_count,manufacturer"
Without ?sort=, rows come back in a stable default order (the dataset's primary key).
Sorting cannot be combined with cursor pagination.
Field selection¶
?fields= projects the response down to the columns you name — smaller payloads, less
parsing:
curl -H "Authorization: Bearer $API_KEY" \
"https://api.canovix.ro/v1/transport/vehicle_registry?fields=county,manufacturer,vehicle_count&limit=2"
{
"data": [
{ "county": "ALBA", "manufacturer": "AUDI", "vehicle_count": 4581 },
{ "county": "ALBA", "manufacturer": "BMW", "vehicle_count": 3717 }
],
"pagination": { "total": 382667, "count": 2, "limit": 2, "offset": 0, "has_next": true, "next_offset": 2 },
"meta": { "api_version": "v1", "dataset": "vehicle_registry", "domain": "transport", "last_updated": "...", "generated_at": "..." },
"links": { "self": "...", "next": "..." }
}
The projection happens in SQL, not after the fact — asking for 3 columns of a wide table genuinely reads less data.
Raw vs canonical columns¶
Some datasets carry both a raw column (exactly what the source file said) and a
canonical sibling standardized against a shared reference table — e.g.
vehicle_registry has manufacturer (raw) and manufacturer_canonical (standardized
spelling). Filter and aggregate on the canonical column when you want variants like
VW, VOLKSWAGEN, and Volkswagen AG treated as one thing; use the raw column when you
need source fidelity.