Container Store Scraper API
Fetch Container Store product pages and store-scoped inventory data through managed, store-bound sessions
The Container Store API fetches a containerstore.com product or inventory URL through a warm, managed session and returns the upstream response verbatim — HTML for product pages, JSON for inventory endpoints. Pass a storeid and the session is bound to that physical store, so store-scoped inventory responses answer for it. No cookies, no session state, and no store-association calls to manage on your side.
curl "https://api.scrape.do/plugin/containerstore/store?token=$TOKEN&url=https%3A%2F%2Fwww.containerstore.com%2Fv1%2Finventory%2Fpickup%2Foptions%3FskuId%3D10062529%26searchInput%3D80021"Credit Usage: Each successful request costs 10 credits. Failed responses are not charged.
Key Features
- Store-bound sessions: pass
storeidand the request is served by a session associated with that store, so store-scoped inventory endpoints reflect it. - Verbatim upstream response: you get Container Store's own body and content type back — JSON from
/v1/inventory/…endpoints, full HTML from/s/…product and category pages. - Method and body forwarding:
GETandPOST(and other methods) pass through, so both read endpoints likepickup/optionsand bodied endpoints likebatch/sku-availabilitywork on the same route. - Zero session management: session cookies, headers, and store association are handled server-side. Every call is independent from your side.
- Automatic retries: transient upstream failures are retried internally before an error is returned.
- No render fee: requests are served without headless browsing charges.
Endpoint
GET https://api.scrape.do/plugin/containerstore/storeAll HTTP methods are accepted (GET, POST, …) — the method and request body are forwarded to the target url.
Basic Example
curl --location --request GET 'https://api.scrape.do/plugin/containerstore/store?token=<SDO-token>&url=https%3A%2F%2Fwww.containerstore.com%2Fv1%2Finventory%2Fpickup%2Foptions%3FskuId%3D10062529%26searchInput%3D80021'import requests
import json
import urllib.parse
token = "<SDO-token>"
target = urllib.parse.quote_plus(
"https://www.containerstore.com/v1/inventory/pickup/options?skuId=10062529&searchInput=80021"
)
url = f"https://api.scrape.do/plugin/containerstore/store?token={token}&url={target}"
response = requests.request("GET", url)
print(json.dumps(response.json(), indent=2))const axios = require('axios');
const token = "<SDO-token>";
const target = encodeURIComponent(
"https://www.containerstore.com/v1/inventory/pickup/options?skuId=10062529&searchInput=80021"
);
const url = `https://api.scrape.do/plugin/containerstore/store?token=${token}&url=${target}`;
axios.get(url)
.then(response => {
console.log(JSON.stringify(response.data, null, 2));
})
.catch(error => {
console.error(error);
});package main
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
)
func main() {
token := "<SDO-token>"
target := url.QueryEscape(
"https://www.containerstore.com/v1/inventory/pickup/options?skuId=10062529&searchInput=80021",
)
apiURL := fmt.Sprintf(
"https://api.scrape.do/plugin/containerstore/store?token=%s&url=%s",
token, target,
)
resp, err := http.Get(apiURL)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}require 'net/http'
require 'json'
require 'cgi'
token = "<SDO-token>"
target = CGI.escape("https://www.containerstore.com/v1/inventory/pickup/options?skuId=10062529&searchInput=80021")
url = URI("https://api.scrape.do/plugin/containerstore/store?token=#{token}&url=#{target}")
response = Net::HTTP.get(url)
puts JSON.pretty_generate(JSON.parse(response))import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class ContainerStoreStore {
public static void main(String[] args) throws Exception {
String token = "<SDO-token>";
String target = URLEncoder.encode(
"https://www.containerstore.com/v1/inventory/pickup/options?skuId=10062529&searchInput=80021",
StandardCharsets.UTF_8
);
String url = String.format(
"https://api.scrape.do/plugin/containerstore/store?token=%s&url=%s",
token, target
);
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setRequestMethod("GET");
BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream())
);
String line;
StringBuilder response = new StringBuilder();
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
System.out.println(response.toString());
}
}using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
string token = "<SDO-token>";
string target = Uri.EscapeDataString(
"https://www.containerstore.com/v1/inventory/pickup/options?skuId=10062529&searchInput=80021"
);
string url = $"https://api.scrape.do/plugin/containerstore/store?token={token}&url={target}";
using HttpClient client = new HttpClient();
string response = await client.GetStringAsync(url);
Console.WriteLine(response);
}
}<?php
$token = "<SDO-token>";
$target = urlencode("https://www.containerstore.com/v1/inventory/pickup/options?skuId=10062529&searchInput=80021");
$url = "https://api.scrape.do/plugin/containerstore/store?token={$token}&url={$target}";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo json_encode(json_decode($response), JSON_PRETTY_PRINT);
?>curl "https://api.scrape.do/plugin/containerstore/store?token=$TOKEN&url=https%3A%2F%2Fwww.containerstore.com%2Fv1%2Finventory%2Fpickup%2Foptions%3FskuId%3D10062529%26searchInput%3D80021"Request Parameters
Required
| Parameter | Type | Description |
|---|---|---|
token | string | Your Scrape.do API authentication token |
url | string | Full www.containerstore.com URL to fetch. Must be a product/category page (/s/…) or an inventory endpoint (/v1/inventory/…). Must be URL-encoded because it contains its own query string. |
Optional
| Parameter | Type | Default | Description |
|---|---|---|---|
storeid | integer | — | Container Store store id. When provided, the request is served by a session bound to that store, so store-scoped inventory responses reflect it. Omit for endpoints that don't depend on a store selection. |
timeout | integer | system max | Per-request timeout in milliseconds. |
Supported URLs
Only these www.containerstore.com paths can be fetched:
| Path | Returns | Examples |
|---|---|---|
/v1/inventory/… | JSON | pickup/options, shipping-and-pickup/availability, batch/sku-availability |
/s/… | HTML | Product detail and category pages |
Any other path is rejected with 400. Store association is managed internally through the storeid parameter and cannot be called directly.
Example Requests
# Pickup options for a SKU near a ZIP code
curl --get "https://api.scrape.do/plugin/containerstore/store" \
--data-urlencode "url=https://www.containerstore.com/v1/inventory/pickup/options?skuId=10062529&searchInput=80021" \
--data-urlencode "token=$TOKEN"
# Same lookup, answered by a session bound to store 114
curl --get "https://api.scrape.do/plugin/containerstore/store" \
--data-urlencode "url=https://www.containerstore.com/v1/inventory/pickup/options?skuId=10062529&searchInput=80021" \
--data-urlencode "storeid=114" \
--data-urlencode "token=$TOKEN"
# Product detail page (HTML) — no store binding needed
curl --get "https://api.scrape.do/plugin/containerstore/store" \
--data-urlencode "url=https://www.containerstore.com/s/kitchen/food-storage/oxo-good-grips-pop-square-canisters/12d?productId=11010872" \
--data-urlencode "token=$TOKEN"
# POST endpoint with a JSON body (method and body are forwarded)
curl -X POST "https://api.scrape.do/plugin/containerstore/store?token=$TOKEN&storeid=114&url=https%3A%2F%2Fwww.containerstore.com%2Fv1%2Finventory%2Fbatch%2Fsku-availability" \
-H "Content-Type: application/json" \
-d '{"skuIds":["10062529","10075145"]}'Response
The response is Container Store's own body and content type, returned verbatim:
- Inventory endpoints (
/v1/inventory/…) return JSON — pickup options, store availability, shipping estimates, exactly as the site's own frontend receives them. - Product and category pages (
/s/…) return full HTML. Product pages embed the SKU catalog inside a<script id="__NEXT_DATA__">block, including SKUs, prices, variants, and the defaultselectedSkuId.
There is no wrapper envelope — what the site returns is what you get, so existing parsers built against Container Store responses work unchanged.
Store Binding
Some Container Store inventory endpoints answer relative to the store the session is associated with, not just the parameters in the URL. The storeid parameter controls this:
- With
storeid: the request is served by a session bound to that store. Store-scoped availability, pickup, and shipping responses reflect that store's inventory. - Without
storeid: the request is served by a plain warm session with no particular store selected. Endpoints that take their location from the URL itself (likepickup/optionswith asearchInputZIP code) work fine this way.
The first request for a store you haven't used recently may take noticeably longer while the store binding is set up; subsequent requests for the same store are fast.
Notes
- US only. Container Store inventory and store pickup apply to US stores.
storeidvalues are not validated against the store directory — a non-existent id falls back to the site's default store behavior. Use ids from Container Store's own store locator.- For
POSTrequests, send your payload with the matchingContent-Typeheader; both are forwarded to the target endpoint. Request bodies are limited to 250 KB. - Transient upstream failures are retried automatically before an error is returned. Use
timeoutto bound the total time spent on a request.
Error Responses
| Status | Body | Cause |
|---|---|---|
400 | { "error": "token is required" } | Missing token parameter |
400 | { "error": "invalid url provided" } | url parameter missing or malformed |
400 | { "error": "unsupported url", "message": "..." } | URL is not a supported www.containerstore.com product (/s/…) or inventory (/v1/inventory/…) endpoint |
400 | { "error": "invalid storeid provided", "message": "storeid must be numeric" } | storeid is present but not numeric |
400 | { "error": "timeout is invalid" } | timeout is not an integer |
403 | { "error": "endpoint not allowed", "message": "..." } | The URL targets the store-association endpoint, which is managed internally via storeid |
502 | { "error": "containerstore-store plugin failure.", "message": "..." } | All internal attempts were exhausted; retry, and contact support if it persists |

