Skip to content

Overview

The Bulk API processes many Amazon inputs asynchronously. You submit one POST request with groups of inputs, Easyparser processes each input in the background, notifies your callback_url, and you fetch the parsed results from the Data Service.

How it works

  1. Submit a bulk job

    Send a POST request to the Bulk Service with a JSON array of groups. Each group sets the platform, operation, domain, callback_url and a payload with the input values (for example asins, keywords or urls).

  2. Store the result IDs

    The response returns immediately. For every accepted input value it contains a result id in data.accepted[].results[]. Processing continues in the background.

  3. Receive the webhook

    When a query finishes, Easyparser sends a POST request to the group's callback_url. The body is the query record with a links array that points to the parsed result. It does not contain the parsed data.

  4. Fetch the results

    Call the Data Service with each result id (or follow the result link from the webhook) to get the parsed JSON. You can also open each result in the web app: on the Bulk Requests page, open the job and select the result icon of an item.

When to use the Bulk API

  • Collect data for thousands of ASINs, keywords or sellers in one submission.
  • Run scheduled jobs such as daily price, offer or ranking snapshots.
  • Process inputs where you do not need the answer in the same HTTP response.

To get data immediately in a single synchronous call, use the Real-Time API.

Endpoints and authentication

ServiceMethod and URLPurpose
Bulk ServicePOST https://bulk.easyparser.com/v1/bulkSubmit a bulk job
Data ServiceGET https://data.easyparser.com/v1/queries/{id}Get the query record, including its status
Data ServiceGET https://data.easyparser.com/v1/queries/{id}/results?format=jsonGet the query record with the parsed JSON result (no raw HTML)

Both services authenticate with your API key in the api-key header. The Authorization: Bearer header is not supported. Send Content-Type: application/json when you submit a job.

You find your API key in the web app under Account > Plan at https://app.easyparser.com/account/plan. New accounts get 100 free credits per month, with no credit card required. For a visual walkthrough, see Getting Started.

Identifiers

A bulk job returns three kinds of IDs. Only the result id is used to fetch data.

IdentifierWhere it appearsWhat it identifies
bulk_request_idmeta_data.bulk_request_idThe whole submission. Use it to find the job on the Bulk Requests page of the web app.
group_iddata.accepted[].group_idOne group (one object in the request array).
iddata.accepted[].results[].idOne query (one input value). Pass it to the Data Service.

Example flow

Submit the job

This request runs the Search operation (SEARCH) on .ca for two search result URLs.

Terminal window
curl --location 'https://bulk.easyparser.com/v1/bulk' \
--header 'api-key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '[
{
"platform": "AMZ",
"operation": "SEARCH",
"domain": ".ca",
"callback_url": "https://example.com/webhook",
"payload": {
"urls": [
"https://www.amazon.ca/s?k=mouse",
"https://www.amazon.ca/s?k=table+tennis"
]
}
}
]'

Read the result IDs

The response lists one result id per accepted input value (abbreviated):

{
"success": true,
"meta_data": {
"bulk_request_id": "01a0341d-c6a8-722b-9189-2f2ee09608ef",
"total_count": 2,
"accepted_count": 2,
"invalid_count": 0,
"insufficient_credit_count": 0,
"failed_count": 0,
"rate_limit_exceeded_count": 0
},
"data": {
"accepted": [
{
"platform": "AMZ",
"operation": "SEARCH",
"domain": ".ca",
"callback_url": "https://example.com/webhook",
"group_id": "01a0341d-c6be-7ccb-b916-49e17627b560",
"results": [
{ "url": "https://www.amazon.ca/s?k=mouse", "id": "250f8e2a-7614-40b3-9a40-def192b74810", "credit": 1 },
{ "url": "https://www.amazon.ca/s?k=table+tennis", "id": "cd4b5677-c8a7-47e1-91a1-966bc448e0e8", "credit": 1 }
]
}
]
}
}

Wait for the webhook

Easyparser sends a webhook to https://example.com/webhook for each query when it finishes. See Webhooks.

Fetch each result

Terminal window
curl --location 'https://data.easyparser.com/v1/queries/250f8e2a-7614-40b3-9a40-def192b74810/results?format=json' \
--header 'api-key: YOUR_API_KEY'

format supports only json. To check whether a query is still pending or has ended as success or failure, call GET https://data.easyparser.com/v1/queries/{id} instead. The result structure for each operation is described in Data Service Response.

Webhooks

Delivery and retries

  • Easyparser sends one webhook per query (result id), not one per job, to the callback_url of the query's group.
  • The body is the query record. Its links array contains the URL of the parsed result, so you can follow that link instead of building the URL from the id.
  • Your endpoint must respond with HTTP 200 within 3 seconds. Otherwise the delivery is retried once, 5 minutes later. If the second attempt also fails, Easyparser stops trying. In the webhook logs the second attempt shows retry_count 2.
  • If 10 or more deliveries fail within one hour, Easyparser notifies you by e-mail so you can check that your endpoint is reachable.
  • You can resend failed webhooks, one at a time or all failed ones of a job, from the job's webhook logs on the Bulk Requests page of the web app. A manual resend is a single attempt with no automatic retry.

The webhook is a notification only. Queries are processed whether or not the webhook is delivered, so you can always fetch results with the IDs from the submit response.

Verify the signature

Each webhook includes an X-Easyparser-Signature header: a hex-encoded HMAC-SHA256 of the raw request body, keyed with your API key. Verification is optional, but recommended for production endpoints.

  1. Take the raw request body exactly as received.
  2. Compute an HMAC-SHA256 of it with your API key as the secret, as a hex string.
  3. Compare the result with the X-Easyparser-Signature header using a constant-time comparison. If they match, the request came from Easyparser.
import hmac
import hashlib
def verify_signature(raw_body: bytes, signature_header: str, api_key: str) -> bool:
# raw_body must be the exact bytes received, not a re-serialized dict
expected = hmac.new(
api_key.encode("utf-8"),
raw_body,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature_header or "")

Limits and data retention

  • A single bulk request accepts up to 5,000 input values, counted across all groups. If you send more, the values that fit are processed and the rest are returned in data.invalid.
  • Each query has a processing timeout of 5 minutes. A query that does not finish in time ends with status failure.
  • Inputs count against your plan's Bulk API per-minute limit, measured in credits (minutely_bulk_credit_limit in the Account API). Inputs above the limit are not accepted and are returned in data.rate_limit_exceeded; the rest of the request is still accepted.
  • Only supported platforms and operations are accepted. Input values that fail validation are returned in data.invalid with a message. See Bulk Service Response.
  • Data Service retrieval is limited to your plan's per-minute Bulk limit plus 20% (for example, a 1,000 per minute Bulk limit allows 1,200 result retrievals per minute).

Credits

Each input value is charged with the same rules as the matching Real-Time API request, and only accepted inputs are charged. The Bulk API uses a single page per input value instead of min_page and max_page, so SEARCH, SELLER_PRODUCTS and SELLER_FEEDBACK inputs cost 1 credit per input value. Each accepted result carries its cost in credit. When your credits run out, inputs are accepted in order until the balance is used up and the rest are returned in data.insufficient_credit. See Credit Consumption.