Skip to main content

API documentation

Base URL: https://uae-fuel-prices-api.vercel.app

Need a key? Request a free API key.

Integration contract

What consumers should assume

Data is monthly and returned in AED. Latest endpoint resolves by highest year/month among active rows.

Treat all responses as dynamic API responses. Do not hardcode month labels, fuel order, or record IDs.

Use request_id in logs/support tickets for incident traceability.

Data provenance

Fuel prices are manually reviewed and published from official UAE fuel retailer sources. Reference websites: ADNOC Distribution and ENOC.

For corrections or verification requests, contact zaib@live.com.

Authentication

API key header
x-api-key: YOUR_API_KEY

Missing key → 401. Invalid/inactive key → 403.

Rate limits and quotas

Current free-tier defaults are 30 requests per minute and 1000 requests per UTC day. Limits are enforced per API key and exposed in both response body meta.rate_limit and X-RateLimit-* headers. Exceeding limits returns 429 with a Retry-After hint when applicable.

Endpoints

GET /api/v1/fuel-prices

Returns latest active calendar month.

Query parameters: ?lang=en|ar, ?format=full|minimal, ?trends=true (adds month-over-month deltas if previous month exists).

GET /api/v1/fuel-prices/history

Returns historical active months in descending order.

Query parameters: ?limit=12 (default 12, max 120), ?lang=en|ar, ?format=full|minimal.

GET /api/v1/fuel-prices/{year}/{month}
Single month, e.g. /api/v1/fuel-prices/2026/4. Returns 404 if not found or not active.

Reliability patterns (recommended)

Client behavior

Cache latest response for 5-15 minutes client-side to reduce quota burn and improve UX.

Read Retry-After on 429 and retry with exponential backoff.

For mobile/desktop apps, prefer a backend proxy so API keys are not embedded in binaries.

Use /history sparingly (e.g., startup sync), then poll only latest endpoint.

Request examples

curl: latest month
curl -s "https://uae-fuel-prices-api.vercel.app/api/v1/fuel-prices?lang=en&format=full" \
  -H "x-api-key: YOUR_API_KEY"
curl: history
curl -s "https://uae-fuel-prices-api.vercel.app/api/v1/fuel-prices/history?limit=12&format=minimal" \
  -H "x-api-key: YOUR_API_KEY"
fetch with 429 handling
const url = "https://uae-fuel-prices-api.vercel.app/api/v1/fuel-prices";
const headers = { "x-api-key": process.env.UAE_FUEL_API_KEY };

async function getLatestFuelPrices(maxRetries = 2) {
  for (let attempt = 0; attempt <= maxRetries; attempt += 1) {
    const res = await fetch(url, { headers });
    const json = await res.json();

    if (res.ok) return json;

    // Respect provider guidance for throttling.
    if (res.status === 429 && attempt < maxRetries) {
      const retryAfter = Number(res.headers.get("Retry-After") ?? "1");
      await new Promise((r) => setTimeout(r, retryAfter * 1000));
      continue;
    }

    throw new Error(`${res.status} ${json.error ?? "API error"}`);
  }

  throw new Error("Retry budget exhausted");
}

Response and error contracts

Success response shape
{
  "request_id": "550e8400-e29b-41d4-a716-446655440000",
  "meta": {
    "currency": "AED",
    "currency_labels": { "en": "UAE Dirham", "ar": "درهم إماراتي" },
    "generated_at": "2026-04-30T12:00:00.000Z",
    "rate_limit": {
      "per_minute": { "limit": 30, "remaining": 29, "reset": "..." },
      "per_day": { "limit": 1000, "remaining": 999, "reset": "..." }
    },
    "default_language": "en"
  },
  "data": {
    "period": { "month": 4, "year": 2026, "label_en": "...", "label_ar": "..." },
    "fuels": [ { "code": "super_98", "color_hex": "#2563EB", ... } ],
    "record": { "id": "...", "created_at": "..." }
  }
}
Error response shape
{
  "error": "Invalid API key",
  "request_id": "550e8400-e29b-41d4-a716-446655440000"
}

400: invalid params (for example, year-only route without month)

401: missing API key

403: invalid/revoked API key

404: no matching fuel data

429: quota exceeded

Production checklist

Use one API key per environment/client to isolate quotas and incidents.

Log request_id, status code, and endpoint on every failure.

Set network timeout and retry only for retryable statuses (429/5xx).

Guard against null prices in downstream calculations.

If public responses become empty, verify admin month status is active.