Service stations
GET /v1 returns one resource per station with all selected fuel prices.
GET /v1
All six filters also accept filter[...] names. Query parsing, aliases and combination limits are described in Filtering.
The example uses brand 32, suburb PERTH AIRPORT and surrounding=no to obtain a small, complete response. No station records or attributes were removed. Omitting product selects all seven fuels; Costco Perth Airport returned prices for products 1, 6 and 11 in this capture.
Expanded response with enrichment
The same selection with expand=all includes named reference objects, opening hours and Google Maps provenance. enrichment.fields identifies the provider's contribution; the phone number and opening hours are also present, but were supplied by FuelWatch in this example. See source priority and attribution.
All references expanded, with enrichment
Captured 2026-09-30T11:42:42.891+08:00 (AWST) · HTTP 200. Historical snapshot; repeat the request for current data.
curl 'https://fuelwatch.oss.bhodges.me/v1?brand=32&suburb=PERTH%20AIRPORT&surrounding=no&expand=all' \
-H 'Accept: application/vnd.api+json'{
"jsonapi": {
"version": "1.1"
},
"meta": {
"source": "fuelwatch.wa.gov.au",
"products": [
1,
2,
4,
5,
6,
10,
11
],
"sourceDate": "2026-09-30",
"fetchedAt": "2026-09-30T11:00:52.278+08:00",
"validFrom": "2026-09-30T06:00:00.000+08:00",
"validUntil": "2026-10-01T06:00:00.000+08:00",
"publicationStatus": "available",
"copyright": "Copyright 2025 Department of Local Government, Industry Regulation and Safety (source data); Copyright 2026 Bradley Hodges (api). All rights reserved.",
"documentation": "https://docs.fuelwatch.oss.bhodges.me",
"issues": "https://github.com/bradleyhodges/fuelwatch-api/issues",
"version": "4.30.1"
},
"data": [
{
"type": "serviceStation",
"id": "2026-09-30:dca78516464d85042c12eab0fd45d71665adc32b578908bc8444f29201d02ba7",
"attributes": {
"name": "Costco Perth Airport",
"tradingName": "Costco Perth Airport",
"brand": {
"code": 32,
"name": "Costco",
"logo": "/static/image/brand/costco.svg"
},
"price": {
"asAt": "2026-09-30T06:00:00.000+08:00",
"products": {
"1": 218.7,
"6": 242.7,
"11": 264.7
}
},
"address": {
"street": "142 Dunreath Dr",
"suburb": "PERTH AIRPORT",
"state": "WA",
"postcode": "6105"
},
"is24Hours": false,
"phone": "+61893114700",
"latitude": -31.940377,
"longitude": 115.951869,
"siteFeatures": [
{
"code": 8,
"name": "EFTPOS"
},
{
"code": 1,
"name": "Credit Cards"
},
{
"code": 2,
"name": "Debit Cards"
}
],
"restrictions": [
{
"code": 3,
"name": "Membership Required"
}
],
"enrichment": {
"provider": "Google Maps",
"placeId": "ChIJw1UkrSm5MioRiEMGrwrsOUI",
"fetchedAt": "2026-09-29T18:36:18.295+08:00",
"stale": false,
"fields": [
"address.postcode",
"siteFeatures"
],
"googleMapsUri": "https://www.google.com/maps/search/?api=1&query=Costco%20Perth%20Airport&query_place_id=ChIJw1UkrSm5MioRiEMGrwrsOUI",
"attributions": []
},
"openHours": {
"Monday": "06:00-21:30",
"Tuesday": "06:00-21:30",
"Wednesday": "06:00-21:30",
"Thursday": "06:00-21:30",
"Friday": "06:00-21:30",
"Saturday": "06:00-19:30",
"Sunday": "07:00-19:00"
}
}
}
]
}Collection behavior
The response contains jsonapi, meta and data. A station selling multiple selected fuels appears once. price.products contains only its available selected products. A single-product query uses the same grouped shape.
Resource type is always serviceStation. The id combines sourceDate with a SHA-256 digest of normalized station identity. It is stable across product selections, expansion, price corrections and enrichment changes, but not across source dates. Treat it as opaque; there is no /v1/{id} endpoint. A moved or otherwise reidentified station can receive a different identity.
Ordering is deterministic for a selection but is not a global cheapest-station ranking across fuels. Sort locally for the product you are comparing. Do not persist row indexes as station identifiers.
Completeness and bounds
Every required source request must validate before the API publishes success. Conflicting quotes, invalid dates/prices/coordinates, unsafe XML and excessive input reject the selection. Individual source responses are bounded to 4 MiB and 5,000 stations; combined selections are limited to 10,000 input quotes. Source-filtered combined input is also bounded to 16 MiB.
An empty data array is a valid 200 result. A missing product at a station is unavailable, not zero-priced. Unknown phone/postcode/schedule values remain null or omitted as specified.
HEAD and OPTIONS
HEAD /v1 uses the same query, validation, status, ETag and cache semantics as GET, then omits the body. A matching If-None-Match gives 304. OPTIONS /v1 provides public CORS preflight; it does not read prices.
See HTTP behavior, caching and the error catalogue.