LumiaDB LumiaDB

Developer API

API update (April 9, 2026)

  • New: HEAD support for availability checks and response headers.
  • New: OPTIONS and 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:

https://api.lumiadb.com

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/html keep the existing LumiaDB error page.
  • Programmatic clients receive a JSON body for 404 and 405 responses, which is easier to log and inspect.
  • Temporary upstream failures now return 503 with a source field such as internet_archive, cloudflare, or cloudflare-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 on 503 responses to suggest when to retry.
  • X-LumiaDB-Error-Category: Set on error responses to values such as not_found or upstream_unavailable.
  • X-LumiaDB-Error-Source: Set on upstream outage responses to indicate whether the issue came from internet_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:

https://api.lumiadb.com/RM-1085/RM-1085.zip

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.bin
  • Engineering-SBL3-Lumia-520-620-625-720-1320.bin
  • Engineering-SBL3-Lumia-810.bin
  • Engineering-SBL3-Lumia-820.bin
  • Engineering-SBL3-Lumia-822.bin
  • Engineering-SBL3-Lumia-920-928.bin
  • Engineering-SBL3-Lumia-925.bin

Example:

https://api.lumiadb.com/SBL3/Engineering-SBL3-Lumia-1020.bin

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, and productCodes from database.json.
  • List files for one model by filtering hardwareModel and mapping each firmwares[].ffuFilename into https://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.