Overview
The ByteFLASH Tuning Data API gives authorised partners programmatic access to our vehicle tuning database. You can retrieve manufacturer lists, models, generation ranges, and detailed Stage 1 tuning figures (stock and tuned horsepower & torque, plus ECU types) to display on your own website.
https://www.byteflash.co.uk/api/v1/
JSON (UTF-8)
API key (header or query param)
All responses share this envelope structure:
{
"success": true,
"count": 42, // number of items returned (where applicable)
"data_key": [ ... ] // payload: key name varies per endpoint
}
// On error:
{
"success": false,
"error": "Human-readable error message"
}
Authentication
Every request must include your API key. There are two ways to send it; the header method is strongly preferred for server-side code, as the key will not appear in server logs or browser history.
Method 1: HTTP Header (recommended)
// Add this header to every request: X-API-Key: bf_your_key_here
Method 2: Query Parameter
https://www.byteflash.co.uk/api/v1/?action=manufacturers&api_key=bf_your_key_here
Your API key is provided by ByteFLASH. Treat it like a password; it is only sent to you once. If you ever lose it or believe it has been compromised, contact us and we will issue a replacement immediately.
Errors & Status Codes
| HTTP Code | Meaning | Common cause |
|---|---|---|
| 200 OK | Success | Normal response |
| 400 Bad Request | Missing or invalid parameter | Forgot manufacturer_id, unknown action |
| 401 Unauthorized | No key or wrong key | Missing or incorrect X-API-Key |
| 403 Forbidden | Key valid but access denied | Key suspended, or request from a domain not on your whitelist |
| 429 Too Many Requests | Rate limit exceeded | Over your hourly allowance; check the Retry-After response header |
Always check success === true before using the payload:
$data = json_decode($response, true); if (!$data['success']) { // log or display $data['error'] throw new RuntimeException('API error: ' . $data['error']); }
Rate Limiting
Your API key has a request limit per rolling hour. When that limit is exceeded the API returns HTTP 429 Too Many Requests along with a Retry-After: 3600 header. If you need a higher limit, please get in touch.
Endpoints
All endpoints are GET requests to the same base URL; the action parameter selects the operation.
GET ?action=manufacturers
Returns all vehicle manufacturers in the database, with a logo URL and model count for each.
Parameters: none beyond action.
Example response:
{
"success": true,
"count": 79,
"manufacturers": [
{ "id": 5, "name": "Audi", "logo_url": "https://www.byteflash.co.uk/images/brands/Audi.png", "model_count": 18 },
{ "id": 7, "name": "BMW", "logo_url": "https://www.byteflash.co.uk/images/brands/BMW.png", "model_count": 22 }
// ... more manufacturers
]
}
logo_url will be null for any manufacturer where we do not hold a logo image. Always check for null before rendering an <img> tag, or fall back to displaying the name as text.
GET ?action=models&manufacturer_id={id}
Returns all models for a given manufacturer.
| Parameter | Type | Required? | Description |
|---|---|---|---|
manufacturer_id | integer | Required | ID from the manufacturers endpoint |
{
"success": true,
"count": 22,
"manufacturer": { "id": 7, "name": "BMW", "logo_url": "https://..." },
"models": [
{ "id": 75, "name": "1 Series", "generation_count": 4 },
{ "id": 76, "name": "2 Series", "generation_count": 3 }
]
}
GET ?action=generations&model_id={id}
Returns all generation/year ranges for a given model.
| Parameter | Type | Required? | Description |
|---|---|---|---|
model_id | integer | Required | ID from the models endpoint |
{
"success": true,
"count": 4,
"model": { "id": 75, "name": "1 Series" },
"generations": [
{ "id": 160, "label": "E87 - 2004 - 2007", "variant_count": 12 },
{ "id": 161, "label": "E82 - 2007 - 2013", "variant_count": 9 }
]
}
GET ?action=variants&generation_id={id}
Returns all tuning variants (engine configurations) for a generation, with full performance figures.
| Parameter | Type | Required? | Description |
|---|---|---|---|
generation_id | integer | Required | ID from the generations endpoint |
{
"success": true,
"count": 12,
"variants": [
{
"id": 826, "engine_label": "118D 122hp", "fuel": "Diesel", "engine_size_cc": 1995,
"power": { "stock_hp": 122, "tuned_hp": 155, "gain_hp": 33, "stock_nm": 280, "tuned_nm": 340, "gain_nm": 60 },
"ecus": [ "Bosch EDC16C35" ]
}
// ... more variants
]
}
power may be null where figures are not available for that engine. Always null-check before doing arithmetic or display.
GET ?action=search&make={name}
Returns the complete hierarchy (manufacturers → models → generations → variants) in a single call. Useful for building a vehicle lookup widget without multiple round-trips.
| Parameter | Type | Required? | Description |
|---|---|---|---|
make | string | Required | Manufacturer name; partial match, case-insensitive. e.g. BMW or vw |
model | string | Optional | Model name filter. e.g. 3 Series |
generation | string | Optional | Generation label filter. e.g. F30 |
https://www.byteflash.co.uk/api/v1/?action=search&make=BMW&model=1+Series&api_key=bf_your_key
PHP Code Examples
All examples use PHP's built-in file_get_contents() with a stream context; no additional libraries required.
Basic request: fetch all manufacturers
<?php $api_key = 'bf_your_key_here'; $base_url = 'https://www.byteflash.co.uk/api/v1/'; $context = stream_context_create([ 'http' => [ 'header' => 'X-API-Key: ' . $api_key, 'timeout' => 10, ] ]); $url = $base_url . '?action=manufacturers'; $json = file_get_contents($url, false, $context); if ($json === false) { die('Could not reach the API.'); } $data = json_decode($json, true); if (!$data['success']) { die('API error: ' . $data['error']); } foreach ($data['manufacturers'] as $mfr) { echo $mfr['name'] . ' (' . $mfr['model_count'] . ' models)' . PHP_EOL; }
Reusable API client class
<?php class ByteFlashApi { private $api_key; private $base_url = 'https://www.byteflash.co.uk/api/v1/'; public function __construct(string $api_key) { $this->api_key = $api_key; } private function request(string $action, array $params = []): array { $params['action'] = $action; $url = $this->base_url . '?' . http_build_query($params); $context = stream_context_create(['http' => ['header' => 'X-API-Key: ' . $this->api_key, 'timeout' => 10]]); $json = file_get_contents($url, false, $context); if ($json === false) { throw new RuntimeException('ByteFlash API: network error.'); } $data = json_decode($json, true); if (!$data['success']) { throw new RuntimeException('ByteFlash API error: ' . $data['error']); } return $data; } public function getManufacturers(): array { return $this->request('manufacturers')['manufacturers']; } public function getModels(int $id): array { return $this->request('models', ['manufacturer_id' => $id])['models']; } public function getGenerations(int $id): array { return $this->request('generations', ['model_id' => $id])['generations']; } public function getVariants(int $id): array { return $this->request('variants', ['generation_id' => $id])['variants']; } } $api = new ByteFlashApi('bf_your_key_here'); $manufacturers = $api->getManufacturers(); $models = $api->getModels(7); // BMW $variants = $api->getVariants(160); // BMW 1 Series E87
Display a tuning results table
<?php $api_key = 'bf_your_key_here'; $base_url = 'https://www.byteflash.co.uk/api/v1/'; $generation_id = (int) ($_GET['gen'] ?? 0); if (!$generation_id) { die('No generation selected.'); } $context = stream_context_create(['http' => ['header' => 'X-API-Key: ' . $api_key, 'timeout' => 10]]); $data = json_decode(file_get_contents($base_url . '?action=variants&generation_id=' . $generation_id, false, $context), true); if (!$data['success']) { die(htmlspecialchars($data['error'])); } // ... render table using $data['variants']
Rendering manufacturer logos safely
<?php foreach ($manufacturers as $mfr): ?> <div class="brand-card"> <?php if ($mfr['logo_url']): ?> <img src="<?= htmlspecialchars($mfr['logo_url']) ?>" alt="<?= htmlspecialchars($mfr['name']) ?> logo" class="brand-logo"> <?php else: ?> <span class="brand-name"><?= htmlspecialchars($mfr['name']) ?></span> <?php endif; ?> </div> <?php endforeach; ?>
Caching responses (recommended)
<?php function cachedApiCall(string $url, string $api_key, int $ttl_seconds = 3600): array { $cache_file = sys_get_temp_dir() . '/' . 'bf_api_' . md5($url) . '.json'; if (file_exists($cache_file) && (time() - filemtime($cache_file)) < $ttl_seconds) { return json_decode(file_get_contents($cache_file), true); } $context = stream_context_create(['http' => ['header' => 'X-API-Key: ' . $api_key, 'timeout' => 10]]); $json = @file_get_contents($url, false, $context); if ($json === false) { if (file_exists($cache_file)) { return json_decode(file_get_contents($cache_file), true); } throw new RuntimeException('API unreachable and no cached data available.'); } $data = json_decode($json, true); if (!empty($data['success'])) { file_put_contents($cache_file, $json, LOCK_EX); } return $data; } // Cache the manufacturer list for 6 hours: $data = cachedApiCall($base_url . '?action=manufacturers', $api_key, 21600); $manufacturers = $data['manufacturers'] ?? [];
Key Security & Sharing Prevention
Your API key grants access to ByteFLASH data on your behalf. If a key is leaked, someone else could consume your request allowance.
What we enforce on our side
| Mechanism | How it works |
|---|---|
| Domain whitelisting | Your key can be locked to specific domains. Requests from other origins are rejected with HTTP 403. Contact us when setting up your account to enable this. |
| Rate limiting | Your key has a per-hour request allowance. Even if a key is accidentally shared, any misuse is automatically bounded. |
| Request logging | Every request is recorded with its IP address and origin domain. Unusual activity is monitored and may result in a key being suspended. |
| Instant revocation | If your key is ever compromised, contact us and we can suspend or replace it immediately. |
| One-way key storage | Keys are stored as a cryptographic hash. Even in the event of a database breach, the raw key values cannot be recovered. |
What you should do
- Never put your API key in client-side JavaScript. Always make API calls from server-side PHP, then pass the resulting data to the browser as HTML or your own JSON.
- Ask us to lock your key to your domain. This alone prevents almost all casual key theft.
- Store the key in a config file or environment variable outside your web root, not hardcoded in PHP files that might end up in a repository.
- Contact us immediately if you believe your key has been seen by someone who should not have it.
<script> fetch('https://www.byteflash.co.uk/api/v1/?action=manufacturers&api_key=bf_your_key') .then(r => r.json()).then(data => console.log(data)); </script>