A lightweight PHP client for the UK Government Fuel Finder API.
The lack of any proper documentation drove me round the bend, support were unhelpful at best so here's a working example for you to play with.
If you're just interested in the endpoints:
- Generate token : https://www.fuel-finder.service.gov.uk/api/v1/oauth/generate_access_token
- Regenerate a token : https://www.fuel-finder.service.gov.uk/api/v1/oauth/regenerate_access_token
- Filling Station prices: https://www.fuel-finder.service.gov.uk/api/v1/pfs/fuel-prices
- Filling station info : https://www.fuel-finder.service.gov.uk/api/v1//pfs
This client handles:
- OAuth 2.0 authentication
- Access token caching
- Refresh token regeneration
- API request throttling
- Single concurrent request protection
- Batch pagination
- Fuel price retrieval
- Forecourt/station data retrieval
- PHP 8.1+
- PHP cURL extension enabled
fuel-finder/
├── config.php
├── FuelFinderClient.php
├── example.php
├── token.json # Created automatically
└── fuel-finder.lock # Created automatically
Create a config.php file:
<?php
return [
'client_id' => 'YOUR_CLIENT_ID',
'client_secret' => 'YOUR_CLIENT_SECRET',
'scope' => 'fuelfinder.read',
// OAuth endpoints
'oauth_url' =>
'https://www.fuel-finder.service.gov.uk/api/v1/oauth/generate_access_token',
'refresh_url' =>
'https://www.fuel-finder.service.gov.uk/api/v1/oauth/regenerate_access_token',
// Base API URL
'api_base' =>
'https://www.fuel-finder.service.gov.uk/api/v1',
// API paths
'fuel_price_path' =>
'/pfs/fuel-prices',
// Detailed station information
'stations_path' =>
'/pfs',
// Local token storage
'token_cache' =>
__DIR__ . '/token.json'
];The client uses OAuth 2.0 client credentials authentication.
The initial token request is:
POST https://www.fuel-finder.service.gov.uk/api/v1/oauth/generate_access_token
The request body is JSON:
{
"grant_type": "client_credentials",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"scope": "fuelfinder.read"
}A successful response returns the token inside the data object:
{
"success": true,
"data": {
"access_token": "...",
"expires_in": 3600,
"refresh_token": "...",
"refresh_token_expires_in": 172800
}
}The client stores:
- Access token
- Access token expiry
- Refresh token
- Refresh token expiry
When the access token expires, the client uses:
POST https://www.fuel-finder.service.gov.uk/api/v1/oauth/regenerate_access_token
to request a new access token.
All API requests are made against:
https://www.fuel-finder.service.gov.uk/api/v1
Authenticated requests use:
Authorization: Bearer ACCESS_TOKEN
The Fuel Finder API applies:
- 100 requests per minute per client
- 1 concurrent request per client
The client implements:
- 600ms minimum delay between requests
- File locking to prevent simultaneous requests from multiple PHP processes
The client creates:
fuel-finder.lock
This file is intentionally not deleted, it's used as a persistent lock target.
Request flow:
- Open lock file
- Acquire exclusive lock
- Perform API request
- Release lock
Fuel Finder returns data in batches.
Rules:
- Maximum 500 rows per response
- Batch numbering starts at 1
- Batches are retrieved sequentially
Example:
GET /pfs/fuel-prices?batch-number=1
GET /pfs/fuel-prices?batch-number=2
GET /pfs/fuel-prices?batch-number=3
The client automatically retrieves all batches using:
getAll()Example:
<?php
require __DIR__ . '/FuelFinderClient.php';
$config = require __DIR__ . '/config.php';
$client = new FuelFinderClient($config);
try {
foreach ($client->getAll($config['fuel_price_path']) as $station) {
echo $station['trading_name'] . PHP_EOL;
foreach ($station['fuel_prices'] as $fuel) {
echo $fuel['fuel_type'];
echo ': ';
echo $fuel['price'];
echo "p";
echo PHP_EOL;
}
echo PHP_EOL;
}
} catch (Exception $e) {
echo "ERROR: " . $e->getMessage() . PHP_EOL;
}Example output:
Clock Service Station
E5: 174.9p
E10: 157.9p
B7_STANDARD: 177.9p
B7_PREMIUM: 194.9p
Example record:
{
"node_id": "5d432546f4d997e10bd607e91619ed4b6953e4cd8e71bf47a968966b1e1fe1bf",
"public_phone_number": "+441217253764",
"trading_name": "Clock Service Station",
"fuel_prices": [
{
"fuel_type": "E5",
"price": 174.9,
"price_last_updated": "2026-07-29T10:18:45.000Z",
"price_change_effective_timestamp": "2026-07-29T10:18:45.000Z"
}
]
}Detailed station information is available from:
GET /pfs
Example:
$stations = $client->getAll($config['stations_path']);Authentication data is stored locally:
token.json
Example:
{
"access_token": "...",
"expires_at": 1785326400,
"refresh_token": "...",
"refresh_token_expires_at": 1785412800
}API errors are returned as exceptions.
Example:
try {
$prices = $client->get(
$config['fuel_price_path'],
[
"batch-number" => 1
]
);
} catch (Exception $e) {
echo $e->getMessage();
}Official Fuel Finder information:
-
GOV.UK Fuel Finder API guidance
https://www.gov.uk/guidance/access-the-latest-fuel-prices-and-forecourt-data-via-api-or-email -
Fuel Finder developer authentication documentation
https://www.developer.fuel-finder.service.gov.uk/fuel-finder/api-authentication