PetrolPrice.xyz API
Free during beta · Live petrol & diesel prices · JSON · CORS-enabled · Edge-cached
The PetrolPrice.xyz API exposes the same normalized fuel-price snapshots that power our dashboards. Every endpoint is read-only JSON over HTTPS, served from the Vercel edge with a 5-minute shared cache and a 10-minute stale-while-revalidate window. No authentication is required during the beta.
Base URL
Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/prices | Latest petrol & diesel snapshot for every supported country. |
| GET | /api/v1/prices?country=XX | Same as above filtered to one country (ISO 3166-1 alpha-2, case-insensitive). |
| GET | /api/v1/countries | Registry of every supported country with its name, ISO 2 code, and ISO 4217 currency. |
| GET | /api/v1/geo | ISO 3166-1 alpha-2 country for the caller IP (from edge headers on Vercel; country_code may be null locally). |
GET /api/v1/prices
Returns the latest publishable snapshot for every country we cover, aggregated to a single national-level price per fuel grade.
Example requestcurl https://petrolprice.xyz/api/v1/prices
Example response (200 · truncated)
{
"updated_at": "2026-05-21",
"data": [
{
"country": "Malaysia",
"country_code": "MY",
"currency": "MYR",
"updated_at": "2026-05-21",
"prices": {
"RON95": 4.07,
"RON97": 4.85,
"diesel": 4.97
}
},
{
"country": "Singapore",
"country_code": "SG",
"currency": "SGD",
"updated_at": "2026-05-20",
"prices": {
"RON95": 2.83,
"RON97": 3.41,
"diesel": 2.65
}
}
]
}
GET /api/v1/prices?country=XX
Filters the response to a single country by ISO 3166-1 alpha-2 code. The code is case-insensitive. Returns 404 with {"error":"country not found"} for unsupported codes.
Example requestcurl https://petrolprice.xyz/api/v1/prices?country=MY
Example response (200)
{
"updated_at": "2026-05-21",
"data": [
{
"country": "Malaysia",
"country_code": "MY",
"currency": "MYR",
"updated_at": "2026-05-21",
"prices": {
"RON95": 4.07,
"RON97": 4.85,
"diesel": 4.97
}
}
]
}
GET /api/v1/geo
Returns the request country as ISO 3166-1 alpha-2. On Vercel this uses the platform IP country header; responses are not cached. The dashboard uses this to suggest a default country filter.
Example requestcurl https://petrolprice.xyz/api/v1/geo
Example response (200)
{
"country_code": "MY"
}
GET /api/v1/countries
Static registry of every country the API can serve. Useful for populating dropdowns or validating country_code input before calling /api/v1/prices.
Example requestcurl https://petrolprice.xyz/api/v1/countries
Example response (200 · truncated)
{
"data": [
{ "country": "Malaysia", "country_code": "MY", "currency": "MYR" },
{ "country": "Singapore", "country_code": "SG", "currency": "SGD" },
{ "country": "Brunei", "country_code": "BN", "currency": "BND" }
]
}
Conventions
Units. Prices are per litre in the country's local currency (no FX conversion). The US sheet is published in USD per gallon and is converted to USD per litre on output so the unit is consistent across the API.
Aggregation. For countries with regional or per-station sheets (US states, Canadian provinces, Mexican states, Indonesian cities, Vietnamese areas, Lao provinces, Burmese regions, Indian regions, and the Singapore / Hong Kong per-provider feeds) we take the most recent publishable date and return the arithmetic mean across all rows on that date. National sheets are returned as-is from the latest row.
Freshness. The updated_at field on each country is the UTC date of its latest source row. The top-level updated_at on /api/v1/prices is the most recent date across all countries.
Missing grades. If a country does not publish a particular fuel grade (e.g. Israel only publishes RON95), the corresponding key is omitted from the prices object rather than set to null.
Fuel key mapping
The public RON95 / RON97 / diesel keys are a stable contract. They alias the closest equivalent grade from each upstream feed:
| ISO | RON95 ← source | RON97 ← source | diesel ← source |
|---|---|---|---|
| MY | ron95 | ron97 | diesel (peninsular) |
| SG, BN, CN, TW, JP, KR, ID*, MM, AE, KW, BH, OM | RON95 | RON98 | diesel |
| HK | standard petrol | premium petrol | diesel |
| US, CA, MX | regular | premium | diesel |
| TH | gasohol 95 | E20 | diesel |
| VN | RON 95 (III) | RON 95 (V) | diesel euro 5 |
| PH, IL, JO, LB, IQ, IR, SA, QA, KW, BH, OM | RON95 / gasoline 95 / super 95 / premium 95 | RON98 / gasoline 98 / super 98 / ultra 98 (when published) | diesel (when published) |
| KH, MN, PK, BD, LK, NP, MV, AF, KZ, UZ, KG, TJ, TM, YE, TL | RON92 / A92 / AI92 / petrol (only grade published) | — (omitted) | diesel |
| BT, IN | RON91 (only grade published) | — (omitted) | diesel |
* For Indonesia, RON95 aliases Pertamax 92 (the most widely sold regular grade), RON97 aliases Pertamax Turbo 98, and diesel aliases Dexlite (falling back to Pertamina Dex).
HTTP headers
Successful responses include:
Content-Type: application/json; charset=utf-8
Cache-Control: public, s-maxage=300, stale-while-revalidate=600
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, OPTIONS
Access-Control-Allow-Headers: Content-Type
X-PetrolPrice-Api: v1
CORS pre-flight (OPTIONS) is handled and returns 204 No Content.
Errors
# Unknown country code
HTTP/1.1 404 Not Found
{ "error": "country not found" }
# Wrong HTTP method
HTTP/1.1 405 Method Not Allowed
{ "error": "method not allowed" }
Feedback & contact
Found a bug, want a country added, or planning to ship something on top of the API? Drop us a line at hello@petrolprice.xyz.