PetrolPrice.xyz API

Free during beta · Live petrol & diesel prices · JSON · CORS-enabled · Edge-cached

FREE BETA · v1 JSON CORS · GET EDGE

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

Base https://petrolprice.xyz/api/v1

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

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 request
curl 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

GET /api/v1/prices?country=MY

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 request
curl 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

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 request
curl https://petrolprice.xyz/api/v1/geo
Example response (200)
{
  "country_code": "MY"
}

GET /api/v1/countries

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 request
curl 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
MYron95ron97diesel (peninsular)
SG, BN, CN, TW, JP, KR, ID*, MM, AE, KW, BH, OMRON95RON98diesel
HKstandard petrolpremium petroldiesel
US, CA, MXregularpremiumdiesel
THgasohol 95E20diesel
VNRON 95 (III)RON 95 (V)diesel euro 5
PH, IL, JO, LB, IQ, IR, SA, QA, KW, BH, OMRON95 / gasoline 95 / super 95 / premium 95RON98 / 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, TLRON92 / A92 / AI92 / petrol (only grade published)— (omitted)diesel
BT, INRON91 (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" }
Auth: No API key is required during the beta. We expect to introduce authenticated tiers (with higher rate limits and historical endpoints) in a future major version. Existing v1 routes will keep working unchanged.

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.