Bath & Body Works product data
The Bath & Body Works endpoints are paused for maintenance, so none of them runs right now. This page shows what they return; meanwhile, search Bath & Body Works products with product search from your agent.
Search
Bath & Body Works (US) keyword search (https://www.bathandbodyworks.com/search?q=<words>): the first main-grid page only, up to 48 products, limit 1-48; no pagination. Name, scent, form, literal size, current base price, list and sale price in the page's currency (USD), online orderability and promotion callouts. Promotion prices are conditional (codes) and never the checkout price; no stock quantities.
- ID
bathandbodyworks.search_items- Version
1- Price
- 5 credits / page
- State
- Paused for maintenance
- Typical time
- About 30 s (estimate)
What it does
Reads one search results page (or up to the page limit) and returns one record per product card, in page order. Works on bathandbodyworks.com; other hosts are rejected before anything runs.
Input
One page URL per request, shaped like https://www.bathandbodyworks.com/search?q=vanilla, plus these bounded parameters.
| Parameter | Type | Allowed | Default | Set in /v1/requests |
|---|---|---|---|---|
limit | integer | 1–48 | 48 | POST /v1/jobs only |
Price
5 credits / page. Failed requests are free; a page that loaded but had nothing on it still costs credits. Set max_credits to refuse anything dearer before it runs.
Output
The default, "format": "structured". Every shop answers in the same fields, mapped from the page to the product_summary@1 schema. Fields are null when the page doesn't show them, and a record that can't be mapped is read best-effort from its raw fields. Products are in products, up to 50 a page; follow next_cursor with GET /v1/requests/{id} (MCP: get_results).
| Field | Type | Description |
|---|---|---|
product_id | string or null | Opaque id. Pass it to get_product (or capability "product") to read the product again. |
title | string | Product title as the shop shows it. |
url | string or null | The product page on the shop. |
shop | string or null | The shop’s hostname, without www. |
price | object or null | amount (number), currency (ISO 4217, or null when the shop doesn’t say) and text (the shop’s own wording when it is the same amount, else null). |
original_price | object or null | The price before a discount, in the same shape as price. |
rating | number or null | Average rating, on the shop’s own scale. |
review_count | integer or null | Number of reviews or ratings. |
image_url | string or null | Main product image. |
availability | string or null | in_stock, out_of_stock, or the shop’s own stock wording. |
sponsored | boolean or null | true for an ad the shop marks as sponsored; null when the page doesn’t say. |
{
"request_id": "string",
"status": "done",
"products": [
{
"product_id": "string or null",
"title": "string",
"url": "string or null",
"shop": "string or null",
"price": {
"amount": "number",
"currency": "string or null",
"text": "string or null"
},
"original_price": {
"amount": "number",
"currency": "string or null",
"text": "string or null"
},
"rating": "number or null",
"review_count": "integer or null",
"image_url": "string or null",
"availability": "string or null",
"sponsored": "boolean or null"
}
],
"next_cursor": "string or null",
"meta": {
"as_of": "date-time",
"country": "string",
"credits_used": "integer",
"credits_left": "integer"
}
}Over the Jobs API, GET /v1/jobs/{id}/results?format=structured returns the full product_summary@1 records.
With "format": "raw", the answer keeps the structured fields and adds raw: this endpoint's own records, unchanged, one per item, in the schema below. It is the data the endpoint extracted from the page, not the page's HTML. Same price as structured.
| Field | Type | Description |
|---|---|---|
id | string required | Pattern ^[0-9]{4,20}$ |
url | string (uri) required | — |
name | string required | — |
scent | string or null required | — |
form | string or null required | — |
size | string or null required | — |
bundle_quantity | null required | — |
price | string required | Pattern ^[0-9]{1,9}\.[0-9]{2}$ |
currency | string required | Pattern ^[A-Z]{3}$ |
regular_price | string or null required | Pattern ^[0-9]{1,9}\.[0-9]{2}$ |
source_sale_price | string or null required | Pattern ^[0-9]{1,9}\.[0-9]{2}$ |
source_price_per_unit | string or null required | Pattern ^[0-9]{1,9}\.[0-9]{2}$ |
normalized_price_per_volume | null required | — |
min_order_quantity | integer or null required | Minimum 0 |
order_step_quantity | integer or null required | Minimum 0 |
web_orderable | boolean or null required | — |
stock_quantity | null required | — |
promotions | array required | — |
position | integer required | Minimum 1 |
page | 1 required | — |
{
"id": "string",
"url": "string (uri)",
"name": "string",
"scent": "string or null",
"form": "string or null",
"size": "string or null",
"bundle_quantity": null,
"price": "string",
"currency": "string",
"regular_price": "string or null",
"source_sale_price": "string or null",
"source_price_per_unit": "string or null",
"normalized_price_per_volume": null,
"min_order_quantity": "integer or null",
"order_step_quantity": "integer or null",
"web_orderable": "boolean or null",
"stock_quantity": null,
"promotions": "array",
"position": "integer",
"page": 1
}Raw needs this endpoint: a search with format: "raw" doesn't fall back to shopping search, and answers raw_unavailable where no endpoint can run. Over the Jobs API, results are raw by default; format=both gives each raw record with its structured form.
Request
Run exactly this endpoint with capability: "endpoint"; there is no fallback, and a failed run is free. Set format to "raw" for the raw records too. For a keyword instead of a URL, search_products with this shop as site builds the search URL, tries the shop's endpoint first and then shopping search.
curl https://api.datawebot.com/v1/requests \
-H "Authorization: Bearer $DATAWEBOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"capability":"endpoint","endpoint":"bathandbodyworks.search_items","url":"https://www.bathandbodyworks.com/search?q=vanilla","format":"structured"}'submit_job {
"endpoint": "bathandbodyworks.search_items",
"url": "https://www.bathandbodyworks.com/search?q=vanilla",
"format": "structured"
}If the answer says "status": "working", read it again with GET /v1/requests/{id} (MCP: get_results) after check_after_seconds.
Limits
- One page URL per request, on bathandbodyworks.com only; other hosts are rejected before anything runs.
- Prices and stock are read when the request runs (
meta.as_of); datawebot keeps no price history, so schedule and store repeat reads yourself. - Fields the page doesn't show come back null; nothing is filled in or guessed.
- Up to 30 requests a minute per account.
- Paused for maintenance: search.
Questions about the Bath & Body Works scraper API
Does Bath & Body Works have an official API?
datawebot does not use one. It reads Bath & Body Works's pages and returns them as structured JSON, so you need no Bath & Body Works developer account or partner key. Whether Bath & Body Works offers its own API, and on what terms, is for Bath & Body Works to say.
Can I scrape Bath & Body Works with Python?
Yes. Send the POST /v1/requests call shown on this page from Python with any HTTP client, such as requests or httpx: the same JSON body, with your API key in the Authorization header. The products come back in the answer's products field (product for a product page).
Is it legal to scrape Bath & Body Works?
It depends on where you are, Bath & Body Works's terms and what you do with the data. You stay responsible for how you use what datawebot returns. This is not legal advice; read our guide to robots.txt and legal considerations, and ask a lawyer about your case.
What does a Bath & Body Works scraper API call cost?
The current price is in find_endpoints and GET /v1/job-blueprints. Failed requests are free; a page that loaded but had nothing on it still costs credits. Every account starts with 200 free credits, and credit packs start at 10,000 credits for $10, with no subscription.
Start with 200 free credits
Connect your agent with one setup prompt, or create an API key, and run Bath & Body Works requests right away. No card and no subscription.
Connect your agent See pricing