# Bulk Service Request

> Create a Bulk API job with one POST request: endpoint, headers, request body, payload keys per operation, examples and limits.

Source: https://docs.easyparser.com/bulk-integration/bulk-service-request

Send a POST request with a JSON array of groups to create a Bulk API job. Each group runs one operation on one marketplace for a list of input values (ASINs, keywords, URLs, seller IDs or product codes). The response returns a result `id` for every accepted input value; you fetch the parsed data later from the [Data Service](/bulk-integration/data-service-request).

## Endpoint

```http
POST https://bulk.easyparser.com/v1/bulk
```

## Headers

| Header | Required | Description |
|---|---|---|
| `api-key` | Yes | Your API key, from [Account > Plan](https://app.easyparser.com/account/plan) in the web app. |
| `Content-Type` | Yes | Must be `application/json`. |

## Request body

The body is a JSON array. Each object in the array is a group. One request can mix groups with different operations and domains.

### Group object

These fields sit at the root of each group.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `platform` | string | Yes | Target platform. Allowed: `AMZ` (Amazon). |
| `operation` | string | Yes | Operation code in upper case. Allowed: `DETAIL`, `OFFER`, `SALES_ANALYSIS_HISTORY`, `BEST_SELLERS_RANK`, `PACKAGE_DIMENSION`, `SEARCH`, `PRODUCT_LOOKUP`, `SELLER_PROFILE`, `SELLER_PRODUCTS`, `SELLER_FEEDBACK`, `SIMILAR_PRODUCTS`. |
| `domain` | string | Yes | Amazon marketplace, written with a leading dot. Example: `.com`, `.co.uk`, `.de`. Use the domain of the URLs or address you send. See [Supported Marketplaces](/essentials/supported-marketplaces). |
| `callback_url` | string | Yes | URL on your server that Easyparser notifies when a query in this group finishes. The notification carries the query record and a link to the result, not the parsed data. |
| `payload` | object | Yes | Input values and options for the operation. See the tables below. |
| `address_id` | integer | No | ID of an Active saved address for the same `domain`. `DETAIL`, `OFFER`, `SEARCH`, `SELLER_PRODUCTS`. Default: marketplace default address. |
| `operation_version` | integer | No | Response version of a versioned operation. `BEST_SELLERS_RANK`: `1` (legacy) or `2`. Send it at the root of the group; it is not read from `payload`. Default: `2`. |

For webhook retries and signature verification, see [Bulk API overview](/bulk-integration/overview). For saved addresses, see [Address Management](/essentials/address-management).

### Payload input keys

Input keys in the Bulk API are plural (`asins` instead of `asin`) and take an array of values. Each value becomes one query with its own result `id`.

| Operation | Code | Input keys |
|---|---|---|
| Detail | `DETAIL` | `asins` or `urls` (product URLs) |
| Offer | `OFFER` | `asins` |
| Sales Analysis and History | `SALES_ANALYSIS_HISTORY` | `asins` |
| Best Sellers Rank | `BEST_SELLERS_RANK` | `asins` |
| Package Dimension | `PACKAGE_DIMENSION` | `asins` |
| Similar Products | `SIMILAR_PRODUCTS` | `asins` |
| Search | `SEARCH` | `keywords` or `urls` (search URLs) |
| Product Lookup | `PRODUCT_LOOKUP` | `identifiers` and `identifier_type` |
| Seller Profile | `SELLER_PROFILE` | `seller_ids` or `urls` (seller profile URLs) |
| Seller Products | `SELLER_PRODUCTS` | `seller_ids` or `urls` (storefront URLs) |
| Seller Feedback | `SELLER_FEEDBACK` | `seller_ids` or `urls` (seller profile URLs) |

| Parameter | Type | Required | Description |
|---|---|---|---|
| `asins` | array | Conditional | Amazon product IDs: 10 upper-case letters or digits each, for example `B0CJB6V2L5`. |
| `urls` | array | Conditional | Full Amazon URLs of products, search results pages or seller pages, depending on the operation. |
| `keywords` | array | Conditional | Search terms for `SEARCH`. Maximum 255 characters each. |
| `seller_ids` | array | Conditional | Amazon seller IDs: start with `A`, 11 to 15 characters, for example `A1MCYUGJD2ILFU`. |
| `identifiers` | array | Conditional | Product codes for `PRODUCT_LOOKUP`. Maximum 18 characters each. Keep leading zeros. |
| `identifier_type` | string | Conditional | Type of every value in `identifiers`. Required with `identifiers`. One type applies to the whole group. Allowed: `ASIN`, `EAN`, `GTIN`, `ISBN`, `JAN`, `MINSAN`, `UPC`. |

Where an operation accepts two input keys, send one of them per group.

### Payload options

Options also go inside `payload`. Each one applies to every input value in the group.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `language` | string | No | Language of the returned content, as a locale code valid for the `domain`. `DETAIL`, `OFFER`, `SEARCH`, `SELLER_PROFILE`, `SELLER_PRODUCTS`. Default: marketplace default. Example: `en_US`. |
| `currency` | string | No | Currency of returned prices, as a lower-case ISO 4217 code valid for the `domain`. `DETAIL`, `OFFER`, `SEARCH`, `SELLER_PRODUCTS`. Default: marketplace default. Example: `usd`. |
| `zip_code` | string | No | Inline delivery address: zip or postal code. Join two-part codes with a comma, for example `N0E,1Y0`. Same operations as `address_id`. |
| `city` | string | No | Inline delivery address: city. Required with `zip_code` on `.com.au` and with `district` on `.ae`; send it alone on `.sa` and `.eg`. Same operations as `address_id`. |
| `district` | string | No | Inline delivery address: area within `city`. Only on `.ae`. Same operations as `address_id`. |
| `country_code` | string | No | Inline delivery address: ISO 3166 alpha-2 country code, for example `CA`. Same operations as `address_id`. |
| `associate_id` | string | No | Amazon Associates tag added to product links in the result, for example `mytag-20`. `DETAIL`, `OFFER`, `SEARCH`, `SELLER_PROFILE`, `SELLER_PRODUCTS`. |
| `parameters` | string | No | Extra Amazon URL query parameters, in the same format as the Real-Time API `parameters` field. Same operations as `associate_id`. |
| `cookie` | string | No | Cookies forwarded to Amazon in the HTTP `Cookie` header, in the same format as the Real-Time API `cookie` field. Same operations as `associate_id`. |
| `a_plus_content` | boolean | No | Include A+ content. `DETAIL`. Adds 1 credit per input value. Default: `false`. |
| `prime` | boolean | No | Only Prime offers. `OFFER`. Default: `false`. |
| `free_shipping` | boolean | No | Only offers with free shipping. `OFFER`. Default: `false`. |
| `condition_new` | boolean | No | Only new offers. `OFFER`. Default: `false`. |
| `condition_used_like_new` | boolean | No | Only used, like new offers. `OFFER`. Default: `false`. |
| `condition_used_very_good` | boolean | No | Only used, very good offers. `OFFER`. Default: `false`. |
| `condition_used_good` | boolean | No | Only used, good offers. `OFFER`. Default: `false`. |
| `condition_used_acceptable` | boolean | No | Only used, acceptable offers. `OFFER`. Default: `false`. |
| `min_quantity` | integer | No | Only offers with at least this quantity available. `OFFER`. `0` applies no filter. Default: `0`. |
| `sort_by` | string | No | Sort order of the results. `SEARCH`: default `featured`; allowed `featured`, `price-asc-rank`, `price-desc-rank`, `review-rank`, `date-desc-rank`, `exact-aware-popularity-rank`. `SELLER_PRODUCTS`: default `featured-rank`; allowed `featured-rank`, `exact-aware-popularity-rank`. |
| `exclude_sponsored` | boolean | No | Remove sponsored results. `SEARCH`. Default: `false`. |
| `exclude_refinements` | boolean | No | Do not apply Amazon's default refinements. `SEARCH`, `SELLER_PRODUCTS`. Default: `false`. |
| `page` | integer | No | Results page to fetch for each input value. `SEARCH`, `SELLER_PRODUCTS`, `SELLER_FEEDBACK`. Default: `1`. |
| `history_range` | string | No | History period in months. `SALES_ANALYSIS_HISTORY`: default `0`; allowed `0`, `3`, `6`, `9`, `12`. `SELLER_FEEDBACK`: default `all`; allowed `1`, `3`, `12`, `all`. |
| `min_rating` | integer | No | Lowest star rating to include. `SELLER_FEEDBACK`. Must be less than or equal to `max_rating`. Allowed: `1` to `5`. |
| `max_rating` | integer | No | Highest star rating to include. `SELLER_FEEDBACK`. Allowed: `1` to `5`. |
| `similar_limit` | integer | No | Number of similar products to return per ASIN. `SIMILAR_PRODUCTS`. Costs 1, 6 or 11 credits per ASIN. A string such as `"50"` is also accepted. Default: `10`. Allowed: `10`, `50`, `100`. |

The operation lists in this table match the Real-Time API. Several `OFFER` filters can be set to `true` in the same group. When you send neither `min_rating` nor `max_rating`, no rating filter is applied.

`address_id` goes at the root of the group, while `language`, `currency` and the inline address fields go inside `payload`. Inline address fields take precedence over `address_id`. Operations not listed for `address_id` (for example `SIMILAR_PRODUCTS`) do not support an address.

`BEST_SELLERS_RANK` has two versions: `1` (legacy) and `2` (Live since November 1, 2026). Set `operation_version` at the root of the group, next to `operation` (see the Best Sellers Rank example below). Inside `payload` it is not accepted. When a group does not set it, version `2` is used. See [Operation Versioning](/essentials/operation-versioning).

### Payload examples

Each example is a complete request body with one group.

#### Detail (DETAIL) by ASIN or URL

```json
[
  {
    "platform": "AMZ",
    "operation": "DETAIL",
    "domain": ".com",
    "callback_url": "https://example.com/easyparser/webhook",
    "payload": {
      "asins": ["B0CJB6V2L5", "B0DQY6J9TL"],
      "a_plus_content": true
    }
  }
]
```

To send product URLs instead, replace `asins` with `urls`:

```json
"payload": {
  "urls": ["https://www.amazon.com/dp/B0CJB6V2L5"]
}
```

#### Offer (OFFER)

```json
[
  {
    "platform": "AMZ",
    "operation": "OFFER",
    "domain": ".com",
    "callback_url": "https://example.com/easyparser/webhook",
    "payload": {
      "asins": ["B0CJB6V2L5"],
      "condition_new": true,
      "prime": true
    }
  }
]
```

#### Sales Analysis and History (SALES_ANALYSIS_HISTORY)

```json
[
  {
    "platform": "AMZ",
    "operation": "SALES_ANALYSIS_HISTORY",
    "domain": ".com",
    "callback_url": "https://example.com/easyparser/webhook",
    "payload": {
      "asins": ["B0CJB6V2L5"],
      "history_range": "3"
    }
  }
]
```

#### Best Sellers Rank (BEST_SELLERS_RANK)

```json
[
  {
    "platform": "AMZ",
    "operation": "BEST_SELLERS_RANK",
    "operation_version": 2,
    "domain": ".com",
    "callback_url": "https://example.com/easyparser/webhook",
    "payload": {
      "asins": ["B0CJB6V2L5"]
    }
  }
]
```

#### Package Dimension (PACKAGE_DIMENSION)

```json
[
  {
    "platform": "AMZ",
    "operation": "PACKAGE_DIMENSION",
    "domain": ".com",
    "callback_url": "https://example.com/easyparser/webhook",
    "payload": {
      "asins": ["B0CJB6V2L5"]
    }
  }
]
```

#### Similar Products (SIMILAR_PRODUCTS)

```json
[
  {
    "platform": "AMZ",
    "operation": "SIMILAR_PRODUCTS",
    "domain": ".com",
    "callback_url": "https://example.com/easyparser/webhook",
    "payload": {
      "asins": ["B0CJB6V2L5"],
      "similar_limit": 50
    }
  }
]
```

#### Search (SEARCH) by keyword or URL

```json
[
  {
    "platform": "AMZ",
    "operation": "SEARCH",
    "domain": ".com",
    "callback_url": "https://example.com/easyparser/webhook",
    "payload": {
      "keywords": ["wireless earbuds", "portable charger"],
      "sort_by": "price-asc-rank",
      "exclude_sponsored": true
    }
  }
]
```

To send search URLs instead, replace `keywords` with `urls`:

```json
"payload": {
  "urls": ["https://www.amazon.com/s?k=wireless+earbuds"]
}
```

#### Product Lookup (PRODUCT_LOOKUP)

```json
[
  {
    "platform": "AMZ",
    "operation": "PRODUCT_LOOKUP",
    "domain": ".com",
    "callback_url": "https://example.com/easyparser/webhook",
    "payload": {
      "identifiers": ["B0CJB6V2L5"],
      "identifier_type": "ASIN"
    }
  }
]
```

#### Seller Profile (SELLER_PROFILE)

```json
[
  {
    "platform": "AMZ",
    "operation": "SELLER_PROFILE",
    "domain": ".com",
    "callback_url": "https://example.com/easyparser/webhook",
    "payload": {
      "seller_ids": ["A1MCYUGJD2ILFU"]
    }
  }
]
```

To send seller profile URLs instead, use `"urls": ["https://www.amazon.com/sp?seller=A1MCYUGJD2ILFU"]`.

#### Seller Products (SELLER_PRODUCTS)

```json
[
  {
    "platform": "AMZ",
    "operation": "SELLER_PRODUCTS",
    "domain": ".com",
    "callback_url": "https://example.com/easyparser/webhook",
    "payload": {
      "urls": ["https://www.amazon.com/s?me=A1MCYUGJD2ILFU"],
      "sort_by": "featured-rank"
    }
  }
]
```

#### Seller Feedback (SELLER_FEEDBACK)

```json
[
  {
    "platform": "AMZ",
    "operation": "SELLER_FEEDBACK",
    "domain": ".com",
    "callback_url": "https://example.com/easyparser/webhook",
    "payload": {
      "seller_ids": ["A1MCYUGJD2ILFU"],
      "history_range": "3",
      "min_rating": 1,
      "max_rating": 5
    }
  }
]
```

## Example request

This request creates two groups: a `DETAIL` group with one ASIN and a `SEARCH` group with one keyword. It costs 2 credits when both items are accepted.

**cURL**

```bash
curl --location 'https://bulk.easyparser.com/v1/bulk' \
--header 'api-key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '[
  {
    "platform": "AMZ",
    "operation": "DETAIL",
    "domain": ".com",
    "callback_url": "https://example.com/easyparser/webhook",
    "payload": {
      "asins": ["B0CJB6V2L5"],
      "language": "en_US",
      "currency": "usd"
    }
  },
  {
    "platform": "AMZ",
    "operation": "SEARCH",
    "domain": ".com",
    "callback_url": "https://example.com/easyparser/webhook",
    "payload": {
      "keywords": ["wireless earbuds"],
      "sort_by": "featured",
      "exclude_sponsored": true
    }
  }
]'
```

**Node.js**

```javascript
// Node.js 18 or later (built-in fetch)
const body = [
  {
    platform: 'AMZ',
    operation: 'DETAIL',
    domain: '.com',
    callback_url: 'https://example.com/easyparser/webhook',
    payload: {
      asins: ['B0CJB6V2L5'],
      language: 'en_US',
      currency: 'usd',
    },
  },
  {
    platform: 'AMZ',
    operation: 'SEARCH',
    domain: '.com',
    callback_url: 'https://example.com/easyparser/webhook',
    payload: {
      keywords: ['wireless earbuds'],
      sort_by: 'featured',
      exclude_sponsored: true,
    },
  },
];

async function main() {
  const response = await fetch('https://bulk.easyparser.com/v1/bulk', {
    method: 'POST',
    headers: {
      'api-key': 'YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(body),
  });

  const data = await response.json();
  console.log(data.meta_data);

  // Store these IDs to fetch the results from the Data Service.
  for (const group of data.data?.accepted ?? []) {
    for (const result of group.results) {
      console.log(group.operation, result.id);
    }
  }
}

main().catch(console.error);
```

**Python**

```python
import requests

body = [
    {
        "platform": "AMZ",
        "operation": "DETAIL",
        "domain": ".com",
        "callback_url": "https://example.com/easyparser/webhook",
        "payload": {
            "asins": ["B0CJB6V2L5"],
            "language": "en_US",
            "currency": "usd",
        },
    },
    {
        "platform": "AMZ",
        "operation": "SEARCH",
        "domain": ".com",
        "callback_url": "https://example.com/easyparser/webhook",
        "payload": {
            "keywords": ["wireless earbuds"],
            "sort_by": "featured",
            "exclude_sponsored": True,
        },
    },
]

response = requests.post(
    "https://bulk.easyparser.com/v1/bulk",
    headers={"api-key": "YOUR_API_KEY", "Content-Type": "application/json"},
    json=body,
    timeout=60,
)
data = response.json()
print(data.get("meta_data"))

# Store these IDs to fetch the results from the Data Service.
for group in data.get("data", {}).get("accepted", []):
    for result in group["results"]:
        print(group["operation"], result["id"])
```

The response lists accepted and rejected items with their result IDs. See [Bulk Service Response](/bulk-integration/bulk-service-response).

## Limits

- One request can contain up to 5,000 input values, counted across all groups. A larger request is not rejected as a whole: 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`.
- Items count against your plan's Bulk API per-minute limit, measured in credits (`minutely_bulk_credit_limit` in the [Account API](/account/account-api)). Items above the limit are returned in `data.rate_limit_exceeded`; the rest of the request is still accepted.
- Each item is charged with the same rules as the matching Real-Time API request, and only accepted items are charged. If your credits run out, the remaining items are returned in `data.insufficient_credit`. See [Credit Consumption](/essentials/credit-consumption).
- The Bulk API uses a single `page` per input value instead of `min_page` and `max_page`.
- Results are kept for at most 24 hours and can be removed earlier. Fetch them from the Data Service soon after the webhook arrives.

> **INFO:** The webhook sent to `callback_url` does not contain the parsed data. Use each result `id` from the response, or the link in the webhook body, to fetch the result from the [Data Service](/bulk-integration/data-service-request).

## Related

- [Bulk API overview](/bulk-integration/overview)
- [Bulk Service Response](/bulk-integration/bulk-service-response)
- [Data Service Request](/bulk-integration/data-service-request)
- [Credit Consumption](/essentials/credit-consumption)
- [Address Management](/essentials/address-management)
