TL;DR: You can build a working device comparison tool in under 100 lines of code using the MobileAPI.dev specifications API. Search 27,805+ devices with fuzzy matching, fetch structured specs for any two devices, and render a side-by-side comparison table -- all with a free API key that gives you 200 requests per month.

By MobileAPI Team | Last updated: March 2026


Table of Contents

  1. What You Will Build
  2. Get Your API Key
  3. Search for Devices with Autocomplete
  4. Fetch Full Device Specifications
  5. Fetch Individual Spec Categories
  6. Build the Comparison Table
  7. Add Device Images
  8. Handle Errors and Rate Limits
  9. Full Working Example
  10. FAQ
  11. Key Takeaways

What You Will Build

A device comparison tool that lets users search for any two devices and see their specs side by side. The tool covers display, battery, platform, camera, and body specs -- the data points that matter most when someone is choosing between two phones, tablets, or laptops.

The architecture is straightforward: a search interface backed by autocomplete, two API calls to fetch device details, and a rendered comparison table. No database required. The API handles all the device data.


Get Your API Key

Sign up at mobileapi.dev/signup for a free account. You get 200 API requests per month, which is enough to build and test a comparison tool. Each endpoint call costs 1 credit.

Once registered, copy your API key from the dashboard. You will use it in every request via the Authorization header:

Authorization: Token YOUR_API_KEY

You can also pass it as a query parameter (?key=YOUR_API_KEY), but the header method is preferred for security.


Search for Devices with Autocomplete

The comparison tool needs a search box. The autocomplete endpoint returns suggestions as the user types, with results appearing after just 3 characters.

Python

import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.mobileapi.dev"
HEADERS = {"Authorization": f"Token {API_KEY}"}

def autocomplete(query, limit=10):
    response = requests.get(
        f"{BASE_URL}/devices/autocomplete/",
        headers=HEADERS,
        params={"q": query, "limit": limit}
    )
    response.raise_for_status()
    return response.json()

# User types "sam"
results = autocomplete("sam", limit=5)
for device in results["devices"]:
    print(f"{device['name']} ({device['manufacturer_name']})")

JavaScript

const API_KEY = "YOUR_API_KEY";
const BASE_URL = "https://api.mobileapi.dev";

async function autocomplete(query, limit = 10) {
  const response = await fetch(
    `${BASE_URL}/devices/autocomplete/?q=${encodeURIComponent(query)}&limit=${limit}`,
    { headers: { "Authorization": `Token ${API_KEY}` } }
  );
  if (!response.ok) throw new Error(`API error: ${response.status}`);
  return response.json();
}

// User types "sam"
const results = await autocomplete("sam", 5);
results.devices.forEach(device => {
  console.log(`${device.name} (${device.manufacturer_name})`);
});

For more precise lookups, use the search endpoint with fuzzy matching. It returns a match_certainty score so you can filter weak results:

def search_device(name):
    response = requests.get(
        f"{BASE_URL}/devices/search/",
        headers=HEADERS,
        params={"name": name}
    )
    response.raise_for_status()
    data = response.json()
    # Filter to matches above 70% certainty
    return [d for d in data["devices"]
            if float(d["match_certainty"].strip("%")) >= 70]

results = search_device("iPhone 17 Pro")
# Returns:
# {
#   "id": 43,
#   "match_certainty": "100.00%",
#   "match_type": "exact_model",
#   "name": "iPhone 17 Pro",
#   "manufacturer_name": "Apple",
#   "device_type": "phone",
#   "screen_resolution": "6.3\", 1206x2622 pixels",
#   "weight": "206g"
# }

The match_type field tells you how the result was found: exact_model, partial_model, or device_name. A 100% match_certainty means an exact hit. Anything between 70-99% is a fuzzy match -- still useful, but worth flagging to the user.


Fetch Full Device Specifications

Once the user selects two devices from search results, fetch their full specs using the device ID.

Python

def get_device(device_id):
    response = requests.get(
        f"{BASE_URL}/devices/{device_id}/",
        headers=HEADERS
    )
    response.raise_for_status()
    return response.json()

device_a = get_device(43)   # iPhone 17 Pro
device_b = get_device(1205) # Samsung Galaxy S26 Ultra

print(device_a["name"])  # "iPhone 17 Pro"
print(device_b["name"])  # "Samsung Galaxy S26 Ultra"

JavaScript

async function getDevice(deviceId) {
  const response = await fetch(
    `${BASE_URL}/devices/${deviceId}/`,
    { headers: { "Authorization": `Token ${API_KEY}` } }
  );
  if (!response.ok) throw new Error(`API error: ${response.status}`);
  return response.json();
}

const [deviceA, deviceB] = await Promise.all([
  getDevice(43),   // iPhone 17 Pro
  getDevice(1205)  // Samsung Galaxy S26 Ultra
]);

The device response includes the full specifications object, a base64 thumbnail in main_image_b64 (100x100 pixels), and metadata like manufacturer, device type, and release year.


Fetch Individual Spec Categories

For a comparison tool, you often want specific spec categories rather than the entire payload. The API provides sub-endpoints for each category: display, battery, platform, cameras, body, memory, network, sound, communications, features, and miscellaneous.

This approach costs 1 credit per sub-endpoint call, but gives you cleaner data structures to work with.

Python

def get_spec(device_id, category):
    response = requests.get(
        f"{BASE_URL}/devices/{device_id}/{category}/",
        headers=HEADERS
    )
    response.raise_for_status()
    return response.json()

# Fetch display specs for both devices
display_a = get_spec(43, "display")
display_b = get_spec(1205, "display")

# Fetch battery specs for both devices
battery_a = get_spec(43, "battery")
battery_b = get_spec(1205, "battery")

# Fetch platform specs for both devices
platform_a = get_spec(43, "platform")
platform_b = get_spec(1205, "platform")

JavaScript

async function getSpec(deviceId, category) {
  const response = await fetch(
    `${BASE_URL}/devices/${deviceId}/${category}/`,
    { headers: { "Authorization": `Token ${API_KEY}` } }
  );
  if (!response.ok) throw new Error(`API error: ${response.status}`);
  return response.json();
}

// Fetch multiple spec categories in parallel
const [displayA, displayB, batteryA, batteryB] = await Promise.all([
  getSpec(43, "display"),
  getSpec(1205, "display"),
  getSpec(43, "battery"),
  getSpec(1205, "battery")
]);

Using Promise.all in JavaScript (or asyncio.gather in Python) lets you fetch specs for both devices in parallel, cutting your wait time roughly in half.


Build the Comparison Table

Now bring it together. Fetch two devices and render their specs side by side.

Python

def compare_devices(id_a, id_b):
    device_a = get_device(id_a)
    device_b = get_device(id_b)

    specs_to_compare = [
        ("Name", "name"),
        ("Manufacturer", "manufacturer_name"),
        ("Type", "device_type"),
        ("Screen", "screen_resolution"),
        ("Weight", "weight"),
    ]

    # Print header
    print(f"{'Spec':<20} {'Device A':<30} {'Device B':<30}")
    print("-" * 80)

    for label, key in specs_to_compare:
        val_a = device_a.get(key, "N/A")
        val_b = device_b.get(key, "N/A")
        print(f"{label:<20} {str(val_a):<30} {str(val_b):<30}")

compare_devices(43, 1205)

Output:

Spec                 Device A                       Device B
--------------------------------------------------------------------------------
Name                 iPhone 17 Pro                  Samsung Galaxy S26 Ultra
Manufacturer         Apple                          Samsung
Type                 phone                          phone
Screen               6.3", 1206x2622 pixels         6.9", 1440x3120 pixels
Weight               206g                           218g

JavaScript (HTML Table)

async function renderComparison(idA, idB) {
  const [deviceA, deviceB] = await Promise.all([
    getDevice(idA),
    getDevice(idB)
  ]);

  const specs = [
    { label: "Name", key: "name" },
    { label: "Manufacturer", key: "manufacturer_name" },
    { label: "Type", key: "device_type" },
    { label: "Screen", key: "screen_resolution" },
    { label: "Weight", key: "weight" },
  ];

  let html = "<table><thead><tr>";
  html += "<th>Spec</th>";
  html += `<th>${deviceA.name}</th>`;
  html += `<th>${deviceB.name}</th>`;
  html += "</tr></thead><tbody>";

  for (const spec of specs) {
    html += "<tr>";
    html += `<td>${spec.label}</td>`;
    html += `<td>${deviceA[spec.key] || "N/A"}</td>`;
    html += `<td>${deviceB[spec.key] || "N/A"}</td>`;
    html += "</tr>";
  }

  html += "</tbody></table>";
  document.getElementById("comparison").innerHTML = html;
}

renderComparison(43, 1205);

For a richer comparison, combine the full device response with individual spec endpoints. The full device call gets you the top-level fields (name, weight, screen resolution), while the sub-endpoints give you granular details like display protection glass, battery charging wattage, and chipset model.


Add Device Images

Each device listing includes a main_image_b64 field -- a 100x100 base64-encoded thumbnail. This works well for the comparison table header.

For full-resolution images, use the images endpoint:

Python

def get_device_images(device_id):
    response = requests.get(
        f"{BASE_URL}/devices/{device_id}/images/",
        headers=HEADERS
    )
    response.raise_for_status()
    return response.json()

images = get_device_images(43)
# Returns metadata for available images

# Fetch a full-resolution image (costs 1 image credit)
def get_image(image_id):
    response = requests.get(
        f"{BASE_URL}/images/{image_id}/",
        headers=HEADERS
    )
    response.raise_for_status()
    return response.content  # Binary image data

JavaScript

async function getDeviceImages(deviceId) {
  const response = await fetch(
    `${BASE_URL}/devices/${deviceId}/images/`,
    { headers: { "Authorization": `Token ${API_KEY}` } }
  );
  return response.json();
}

// Use the base64 thumbnail for quick rendering
function renderThumbnail(device) {
  const img = document.createElement("img");
  img.src = `data:image/jpeg;base64,${device.main_image_b64}`;
  img.alt = device.name;
  img.width = 100;
  return img;
}

The base64 thumbnail is included in every device response at no extra cost. Full-resolution images from the /images/ endpoint each consume 1 image credit. For a comparison tool, thumbnails are usually sufficient.


Handle Errors and Rate Limits

Production comparison tools need to handle API errors gracefully. The API returns standard HTTP status codes and includes rate limit headers in every response.

Python

import time

def safe_api_call(url, max_retries=3):
    for attempt in range(max_retries):
        response = requests.get(url, headers=HEADERS)

        if response.status_code == 200:
            return response.json()

        if response.status_code == 429:
            # Rate limited -- check reset header and wait
            reset_time = int(response.headers.get("X-RateLimit-Reset", 60))
            print(f"Rate limited. Waiting {reset_time}s...")
            time.sleep(reset_time)
            continue

        if response.status_code == 401:
            raise Exception("Invalid API key. Check your credentials.")

        if response.status_code == 204:
            return None  # Device not found

        response.raise_for_status()

    raise Exception(f"Failed after {max_retries} retries")

JavaScript

async function safeApiCall(url, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, {
      headers: { "Authorization": `Token ${API_KEY}` }
    });

    if (response.ok) return response.json();

    if (response.status === 429) {
      const resetTime = parseInt(
        response.headers.get("X-RateLimit-Reset") || "60"
      );
      console.warn(`Rate limited. Waiting ${resetTime}s...`);
      await new Promise(resolve => setTimeout(resolve, resetTime * 1000));
      continue;
    }

    if (response.status === 401) {
      throw new Error("Invalid API key. Check your credentials.");
    }

    if (response.status === 204) return null;

    throw new Error(`API error: ${response.status}`);
  }
  throw new Error(`Failed after ${maxRetries} retries`);
}

Key rate limits to keep in mind: the Free plan allows 5 requests per minute, Pro allows 10 per second, and Enterprise plans go up to 100 per second. Monitor the X-RateLimit-Remaining header to track your usage in real time.

A comparison of two devices using the full device endpoint costs just 2 credits. If you also fetch 3 spec sub-endpoints per device, that is 8 credits total. On the Free plan (200 requests/month), you can run 25 full comparisons per month -- enough for development and testing.


Full Working Example

Here is a complete Python script that ties everything together: search, compare, and display.

import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.mobileapi.dev"
HEADERS = {"Authorization": f"Token {API_KEY}"}


def search(query):
    resp = requests.get(
        f"{BASE_URL}/devices/search/",
        headers=HEADERS,
        params={"name": query}
    )
    resp.raise_for_status()
    devices = resp.json().get("devices", [])
    return [d for d in devices
            if float(d["match_certainty"].strip("%")) >= 70]


def get_device(device_id):
    resp = requests.get(
        f"{BASE_URL}/devices/{device_id}/",
        headers=HEADERS
    )
    resp.raise_for_status()
    return resp.json()


def compare(name_a, name_b):
    results_a = search(name_a)
    results_b = search(name_b)

    if not results_a:
        print(f"No results found for '{name_a}'")
        return
    if not results_b:
        print(f"No results found for '{name_b}'")
        return

    device_a = get_device(results_a[0]["id"])
    device_b = get_device(results_b[0]["id"])

    fields = [
        ("Name", "name"),
        ("Manufacturer", "manufacturer_name"),
        ("Type", "device_type"),
        ("Screen", "screen_resolution"),
        ("Weight", "weight"),
    ]

    print(f"\n{'Spec':<20} {device_a['name']:<30} {device_b['name']:<30}")
    print("=" * 80)
    for label, key in fields:
        a = str(device_a.get(key, "N/A"))
        b = str(device_b.get(key, "N/A"))
        print(f"{label:<20} {a:<30} {b:<30}")


if __name__ == "__main__":
    compare("iPhone 17 Pro", "Samsung Galaxy S26 Ultra")

This script uses 4 API credits per comparison (2 search calls + 2 device calls). Swap in the autocomplete endpoint if you are building a web UI where users type to search.


FAQ

How many API credits does a single comparison use?

A minimal comparison uses 4 credits: 2 for searching both devices and 2 for fetching their full specs. If you add individual spec sub-endpoints (display, battery, platform), each one costs 1 additional credit. A comparison with 3 extra spec categories per device totals 10 credits.

Can I compare more than two devices at once?

Yes. The API does not limit how many devices you fetch. Add a third or fourth device by making additional calls to /devices/{id}/. Each extra device costs 1 credit for its full specs. A 4-device comparison table costs 8 credits (4 search + 4 device lookups).

Does the API support tablets, laptops, and wearables?

It does. The database covers 27,805+ devices across 5 categories: phones, tablets, laptops, wearables, and other. Filter by type using the /devices/by-type/ endpoint, or check the device_type field in any device response.

What happens when I hit my monthly request limit?

The API returns a 429 status code. You will receive email alerts at 80% and 100% of your quota. On the Free plan (200 requests/month), upgrading to Pro at $15/month gives you 10,000 requests -- enough for roughly 2,500 comparisons.

Can I cache API responses to reduce credit usage?

Caching is a good practice. Device specs do not change frequently -- new devices are added weekly on Pro and daily on Enterprise, but existing specs are stable. Cache responses locally with a 24-hour TTL to minimize redundant API calls during development.


Key Takeaways

  • A device comparison tool needs just 3 endpoints: search (or autocomplete), device details, and optionally spec sub-endpoints.
  • Each comparison costs 4-10 API credits depending on how many spec categories you fetch separately.
  • The Free plan (200 requests/month) is sufficient for building and testing. Upgrade to Pro for production workloads.
  • Use match_certainty from the search endpoint to filter weak fuzzy matches below 70%.
  • Handle rate limits by reading X-RateLimit-Remaining and X-RateLimit-Reset headers.
  • Cache device responses to reduce credit usage -- specs rarely change for existing devices.
  • Base64 thumbnails (main_image_b64) are included in every device response at no extra image credit cost.

Start Building

Get your free API key at mobileapi.dev/signup and start making comparison requests in minutes. The API documentation covers every endpoint, parameter, and response field. With 200 free requests per month, you can have a working comparison prototype running today.