Compare devices
Submit 2-20 device identifiers to compare devices in the same supported category.
/v1/compareRequest
Run this on your server with SPECSPOOL_API_KEY set.
curl --request POST 'https://api.specspool.com/v1/compare' \
--header "x-api-key: $SPECSPOOL_API_KEY" \
--header 'Content-Type: application/json' \
--data '{"devices":["apple-iphone-16-pro-max","apple-iphone-16-pro"]}'Parameters
Required header: x-api-key. Send Content-Type: application/json with the body.
| Field | Type | Presence |
|---|---|---|
devices | union[] | Required |
- Send a JSON object with a devices array of slugs or UUIDs. Discover identifiers with Search devices.
- Comparisons consume one billable unit per submitted array entry. Comparing 20 devices uses 20 units and costs $0.60 on prepaid Standard. Admission is atomic; insufficient credit returns 402 with no debit.
- Billing includes repeated identifiers and aliases. Identical strings are deduplicated after admission, so submit each device once.
- Supported categories are phone, tablet and smartwatch. Missing spec values are represented as ---. Other categories return COMPARE_UNSUPPORTED.
- Send Content-Type: application/json. The request body is limited to 8 KiB and must be read within an absolute 5-second deadline. A timeout, malformed JSON or invalid body returns 400 validation_error before admission.
- The security budget counts distinct canonical device UUIDs across detail and compare calls and across all keys on the account. Repeated strings and slug/UUID aliases for the same device use one slot in each fixed UTC window, although billing still counts every raw array entry.
- An unresolved identifier uses a hashed missing-identifier token. Repeating the same missing identifier uses one slot; if it later resolves after publication, its canonical UUID can use a new slot.
Response
200 OK, application/json. See Response schema for device, brand, variant and search-result fields.
All customer /v1 responses use Cache-Control: private, no-store. Free device-detail responses omit image URL fields. Image URLs are optional on paid plans too; check for their presence before rendering an image.
Show an example JSON response
Illustrative data; names, counts and specifications are examples.
{
"data": {
"category": "phone",
"devices": [
{
"id": "00000000-0000-4000-8000-000000000001",
"slug": "example-phone",
"name": "Example Phone",
"brand": "Example Brand",
"brandSlug": "example-brand",
"category": "phone"
},
{
"id": "00000000-0000-4000-8000-000000000002",
"slug": "example-phone-two",
"name": "Example Phone Two",
"brand": "Example Brand",
"brandSlug": "example-brand",
"category": "phone"
}
],
"highlights": [],
"sections": [
{
"id": "display",
"title": "Display",
"specCount": 1,
"rows": [
{
"id": "size",
"label": "Size",
"cells": [
{
"primary": "6.1 in"
},
{
"primary": "6.7 in"
}
]
}
]
}
],
"meta": {
"deviceCount": 2,
"specRowCount": 1,
"leaderCount": 0,
"tieCount": 0
}
},
"revision": {
"revision": "example-revision",
"updatedAt": "2026-10-01T00:00:00.000Z"
}
}| Field | Type | Presence |
|---|---|---|
data | object | Required |
data.category | category | Required |
data.devices | object[] | Required |
data.highlights | object[] | Required |
data.sections | object[] | Required |
data.meta | object | Required |
data.meta.deviceCount | integer | Required |
data.meta.specRowCount | integer | Required |
data.meta.leaderCount | integer | Required |
data.meta.tieCount | integer | Required |
revision | Revision | Required |
Errors
Invalid supported parameters or malformed JSON can return 400 validation_error. Authentication and admission can return 401, 402, 403, 429 or 503; see authentication errors. Unexpected failures return 500 internal_error. Errors after admission remain counted.
404 DEVICES_NOT_FOUNDOne or more device identifiers could not be resolved.
422 CATEGORY_MISMATCHDevices belong to different categories.
422 COMPARE_UNSUPPORTEDThe category does not support comparison.
422 INVALID_DEVICE_COUNTFewer than two identifiers remain after identical strings are deduplicated.
413 payload_too_largeThe JSON body exceeds 8192 bytes.
{
"error": {
"code": "validation_error",
"message": "Invalid request parameters"
}
}