Job Status & Polling
When POST /api/map can't resolve an identifier within its 8-second synchronous window, it hands back a jobId instead of blocking further. Poll this endpoint with that ID to retrieve
the result once the background worker finishes.
Request Specification
GET /api/jobs/641a5293-91de-41bb-a019-db228c58f04e
Authorization: Bearer pm_live_xxxxxxxxxxxxxxxxxxxxxxxx
# No request body. Same auth as POST /api/map - see the callout below
# for what happens if you poll a jobId that isn't yours./api/map - a personal API key or a signed-in session - is
required, or the request gets a 401. Beyond that, this endpoint also checks
that you're the one who submitted the job: polling someone else's jobId gets back the same { "status": "processing" } shape as a job that's
still running, rather than a distinguishable "forbidden" response - so a caller can't tell
"not yours" apart from "not done yet." A completed job's result is deleted from the queue
automatically after 10 minutes either way.Still Processing
The default response while the job hasn't finished yet.
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "processing",
"message": "Job is still in progress"
}Completed
data is the exact same payload shape POST /api/map returns synchronously on a direct 200 - see that page for the full field reference.
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "completed",
"data": {
"identifierType": "UPC",
"identifierValue": "079361039905",
"marketplace": "amazon",
"marketplaceId": "B01NAL48FU",
"amazonMarketplaceLabel": "US",
"timestamp": 1787503535096,
"listingDetails": {
"asin": "B01NAL48FU",
"title": "Nike Air Zoom Pegasus 36 Men's Running Shoes",
"brand": "Nike",
"manufacturer": "Nike Inc.",
"description": "Lightweight breathable mesh upper. Foam midsole for responsive cushioning. Rubber outsole for durable traction.",
"imageUrl": "https://m.media-amazon.com/images/I/71xyz.jpg",
"price": 119.95,
"formattedPrice": "$119.95",
"listPrice": 129.95,
"offerCount": 6,
"offerCountFba": 4,
"offerCountMerchant": 2,
"isBuyBoxWinner": true,
"salesRank": 1420,
"category": "Athletic Shoes",
"categoryGroup": "Sporting Goods",
"packageQuantity": 1,
"link": "https://www.amazon.com/dp/B01NAL48FU",
"isActive": true,
"identifiers": { "upc": "079361039905", "asin": "B01NAL48FU" },
"marketplaceId": "ATVPDKIKX0DER",
"marketplaceLabel": "US"
}
}
}Failed / Not Found
The identifier has no match in Amazon's catalog.
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "failed",
"error": "NOT_FOUND"
}Polling Multiple Jobs at Once
Tracking several in-flight lookups? GET /api/jobs?ids= checks many job IDs
in a single request instead of one poll per job - same auth, same response shape per job
as the single-job endpoint above, keyed by job ID. Up to 100 IDs per request; more than
that returns 400.
GET /api/jobs?ids=641a5293-91de-41bb-a019-db228c58f04e,7c2e1d90-33aa-4f11-9c05-1a2b3c4d5e6f
Authorization: Bearer pm_live_xxxxxxxxxxxxxxxxxxxxxxxx
# Comma-separated job IDs, up to 100 per request.HTTP/1.1 200 OK
Content-Type: application/json
{
"jobs": {
"641a5293-91de-41bb-a019-db228c58f04e": { "status": "processing" },
"7c2e1d90-33aa-4f11-9c05-1a2b3c4d5e6f": {
"status": "completed",
"data": { "...": "same shape as the single-job Completed response above" }
}
}
}Sample Poll Loop
# Recommended: poll every ~1.5s, stop once status is "completed" or
# "failed". A job that never resolves is still safe to keep polling -
# /api/jobs/{id} just keeps returning "processing" until a background
# worker eventually finishes it or you decide to give up client-side.
async function pollJob(jobId, attempt = 0) {
const res = await fetch(`/api/jobs/${jobId}`);
const json = await res.json();
if (json.status === 'completed') return json.data;
if (json.status === 'failed') throw new Error(json.error);
await new Promise((r) => setTimeout(r, 1500));
return pollJob(jobId, attempt + 1);
}