Developer API
API update (April 9, 2026)
- New:
HEADsupport for availability checks and response headers. - New:
OPTIONSand CORS support for browser-based apps. - New: JSON error responses for API clients, while browsers still keep the HTML error page.
Existing direct download URLs still use the same path format:
GET /<model>/<filename> for FFU files,
GET /<model>/<model>.zip for emergency packages, and
GET /SBL3/<filename> for SBL3 files.
If you want to integrate LumiaDB into your applications, you've come to the right place. Our firmware collection is hosted on the Internet Archive, but the files are scattered across multiple Archive items. The LumiaDB API simplifies this by providing a stable endpoint that searches across all these locations for you.
This allows you to build tools, such as an app that automatically downloads and flashes firmware, without worrying about where the files are stored or if the direct links change. The API uses the exact same logic as the direct download buttons on this website.
API Endpoint
All API requests should be made to the following base URL:
The download endpoint is intentionally path-based: you provide the exact file path, and LumiaDB resolves
it across the archive mirrors. The path format below is unchanged. Successful requests still return the
requested file, while newer clients can also use HEAD for lightweight checks and
OPTIONS for browser preflight requests. For searching devices or listing available files,
use database.json as the catalog layer described below.
Response Codes
| Status | Description |
|---|---|
| 200 OK | Success. The request was successful and the file
was found. A standard GET request will return the file body. |
| 204 No Content | Returned for OPTIONS preflight requests from browser
applications. |
| 206 Partial Content | Returned when the upstream mirror honors a Range
request, allowing resumable or partial downloads. |
| 304 Not Modified | Returned when conditional headers such as
If-None-Match or If-Modified-Since match the upstream file. |
| 404 Not Found | The requested file or model could not be found on any mirror. Browser requests still receive the familiar HTML error page, while API clients receive a JSON error response. |
| 405 Method Not Allowed | Only GET, HEAD, and OPTIONS
are supported. |
| 500 Error | Reserved for unexpected worker-side failures. This should be rare. |
| 503 Service Unavailable | Returned when the file path may be valid but the request failed because Internet Archive was unavailable, Cloudflare could not reach the mirrors, or both. |
Request Methods
GET: The original download behavior. Existing integrations can keep using this exactly as before.HEAD: Performs the same mirror lookup without downloading the response body. This is useful for availability checks, header inspection, and cache validation.OPTIONS: Supports browser CORS preflight, which allows web apps to call the API directly from the client side.
Common request headers such as Range, If-None-Match,
If-Modified-Since, and related conditional headers are forwarded to the upstream mirror
when available.
Error Format
The request path format is unchanged. What changed is how missing files are reported depending on the client:
- Browser requests that prefer
text/htmlkeep the existing LumiaDB error page. - Programmatic clients receive a JSON body for
404and405responses, which is easier to log and inspect. - Temporary upstream failures now return
503with asourcefield such asinternet_archive,cloudflare, orcloudflare-and-internet-archive.
{
"error": "Service Unavailable",
"category": "upstream_unavailable",
"source": "internet_archive",
"message": "This error came from the Internet Archive mirrors backing LumiaDB, not from a missing file path.",
"path": "/RM-1085/example.ffu",
"failures": [
{
"name": "db1",
"collection": "lumiadb",
"status": "Server unavailable"
}
]
}
Response Headers
Successful responses now include a few optional diagnostic headers that can help with logging and support cases:
X-LumiaDB-Mirror: The mirror that ultimately served the file.X-LumiaDB-Collection: The Internet Archive collection used for the successful response.X-LumiaDB-Attempts: How many mirrors were tried before the request succeeded.Retry-After: Included on503responses to suggest when to retry.X-LumiaDB-Error-Category: Set on error responses to values such asnot_foundorupstream_unavailable.X-LumiaDB-Error-Source: Set on upstream outage responses to indicate whether the issue came frominternet_archive,cloudflare, or both.
Usage & Endpoints
The URL structure below is unchanged, so older integrations can continue to use the same paths.
1. FFU Files
To get a download link for a specific firmware (FFU) file, use the following structure:
/<model>/<filename>
<model>: The device model, e.g.,RM-1085.<filename>: The exact firmware filename.
Example:
https://api.lumiadb.com/RM-1085/RM1085_1078.0053.10586.13169.12742.034EE8_retail_prod_signed.ffu
2. Emergency Files
Emergency files for a specific model are bundled into a single .zip archive. The filename is
the model name itself, with a .zip extension.
/<model>/<model>.zip
Example:
3. Engineering SBL3 Files
Engineering SBL3 files are located under the /SBL3/ path. The filename specifies the
compatible model(s).
/SBL3/<sbl3-filename>
Available Files:
Engineering-SBL3-Lumia-1020.binEngineering-SBL3-Lumia-520-620-625-720-1320.binEngineering-SBL3-Lumia-810.binEngineering-SBL3-Lumia-820.binEngineering-SBL3-Lumia-822.binEngineering-SBL3-Lumia-920-928.binEngineering-SBL3-Lumia-925.bin
Example:
4. Full Database Access (JSON)
The download API does not expose a dedicated search endpoint, but developers can parse our raw database file to discover available firmware. This file is a comprehensive JSON dataset containing device information, product codes, and filenames.
File URL: https://lumiadb.com/database.json
File Structure
The database is structured as a JSON array. Below is an example of a single object representing one device variant:
{
"manufacturer": "Microsoft",
"hardwareModel": "RM-1109",
"phoneModel": "Lumia 640 Dual SIM DTV",
"variant": "Brazil",
"image": "/images/lumia640.png",
"productCodes": [
"059X150",
"059X207"
],
"specs": {
"released": "March 2015",
"SoC": "Snapdragon 400",
"GPU": "Adreno 305",
"RAM": "1GB",
"storage": "8GB",
"display": "5.0\" IPS LCD (720x1280)",
"camera": "8MP rear + 1MP front",
"battery": "2500 mAh",
"dimensions": "141.3 x 72.2 x 8.8 mm"
},
"firmwares": [
{
"packageTitle": "RM-1109 VAR LTA BR CV",
"firmware": "02166.00000.15103.05001",
"os": "Windows Phone 8.1 Update 2 - 8.10.15148",
"productCode": "059X150",
"ffuFilename": "RM1109_02177.00000.15184.36002_RETAIL_prod_signed_1000_0247E9_000-BR.ffu"
}
]
}
Key Information Provided
| Field Name | Description |
|---|---|
| hardwareModel | The technical model identifier (e.g., RM-1109). Used as the first parameter in API calls. |
| phoneModel | The commercial name of the device (e.g., Lumia 640 Dual SIM DTV). |
| firmwares | An array containing all available firmware versions for this specific variant. |
| firmwares[].ffuFilename | The exact filename of the FFU. This is the value required for the API download link. |
| firmwares[].productCode | The unique 7-character product code (e.g., 059X150). Essential for matching specific variants. |
Searching Devices & Listing Files
The direct download endpoint is optimized for fetching a file when you already know the path. For
discovery tasks such as device search, product code lookup, or listing every downloadable file for a
model, use https://lumiadb.com/database.json as the source of truth and build a small
lookup layer on top of it.
Recommended approach
- Search devices by indexing fields such as
hardwareModel,phoneModel,manufacturer,variant, andproductCodesfromdatabase.json. - List files for one model by filtering
hardwareModeland mapping eachfirmwares[].ffuFilenameintohttps://api.lumiadb.com/<model>/<filename>. - This keeps discovery flexible while leaving the current direct download URLs untouched.
const database = await fetch('https://lumiadb.com/database.json').then(response => response.json());
function searchDevices(query) {
const normalizedQuery = query.trim().toLowerCase();
return database.filter(device => {
const fields = [
device.hardwareModel,
device.phoneModel,
device.manufacturer,
device.variant,
...(device.productCodes || [])
];
return fields.some(value => String(value || '').toLowerCase().includes(normalizedQuery));
});
}
function listDownloadsForModel(model) {
return database
.filter(device => device.hardwareModel === model)
.flatMap(device => [
...(device.firmwares || []).map(firmware => ({
type: 'ffu',
productCode: firmware.productCode,
url: `https://api.lumiadb.com/${device.hardwareModel}/${firmware.ffuFilename}`
})),
{
type: 'emergency',
url: `https://api.lumiadb.com/${device.hardwareModel}/${device.hardwareModel}.zip`
}
]);
}
Important Note on Availability
We do not have files for every single product code. If a specific product code is missing in the
database,
we recommend implementing a fallback strategy in your application. For example, you
can fallback
to a "Global" firmware variant or select any other available firmware for the same
hardwareModel
to ensure the device can still be flashed.
Integration Example
The following JavaScript snippet demonstrates how to fetch the database, find the correct FFU file for a given Product Code, and construct the final download URL. This flow is unchanged and remains the recommended approach for existing integrations.
// 1. Define your target device and product code
const targetProductCode = '059X150';
// 2. Fetch the database
fetch('https://lumiadb.com/database.json')
.then(response => response.json())
.then(data => {
// 3. Find the device entry that contains this product code
const device = data.find(item =>
item.firmwares && item.firmwares.some(fw => fw.productCode === targetProductCode)
);
if (device) {
// 4. Extract the specific firmware details
const firmware = device.firmwares.find(fw => fw.productCode === targetProductCode);
// 5. Construct the download URL: https://api.lumiadb.com/{model}/{filename}
const downloadUrl = `https://api.lumiadb.com/${device.hardwareModel}/${firmware.ffuFilename}`;
console.log('Download URL found:', downloadUrl);
} else {
console.error('Product code not found. Attempting fallback...');
// Implement fallback logic here (e.g., search by hardwareModel only)
}
})
.catch(err => console.error('Error fetching database:', err));
Rate Limiting & Fair Use
Currently, there are no strict rate limits on the API. However, we ask that you use it fairly and
responsibly. Please implement caching in your application where appropriate and avoid making an
excessive number of requests in a short period. If you only need to check whether a file exists or read
response headers, prefer HEAD over repeatedly downloading the full file. We reserve the
right to block any IP address or application that abuses the service.
Disclaimer
This API is provided "as is" without warranty of any kind. LumiaDB is not responsible for how you use the files obtained through this service. Flashing firmware carries inherent risks, and you assume full responsibility for any potential damage to your device.