Install
openclaw skills install target-shoppingSearch Target.com, look up products, check per-store stock and pickup ETAs near a ZIP, and build a deep link that pre-populates a guest cart. Read-only browsing plus an unauthenticated guest-cart builder; no login, no checkout.
openclaw skills install target-shoppingBrowse Target.com from the assistant. Wraps a handful of Target's public-facing JSON endpoints (the same ones target.com itself loads) and one local URL builder that pre-populates a guest cart in the user's browser.
Unofficial. Not affiliated with, endorsed by, or sponsored by Target Corporation. "Target" and the Target bullseye are trademarks of Target Brands, Inc.; they are used here only to describe the service this skill talks to.
Public web endpoints, not a stable API. The skill calls Target's
public-facing web API (the same JSON endpoints target.com itself loads in
your browser) and carts.target.com. These are not a documented public API.
Field shapes, auth keys, throttling, and even endpoint availability can
change without notice; expect breakage and pin the version you tested against.
No warranty on prices, stock, or pickup ETAs. Results are point-in-time
snapshots of what the API returned. Prices and availability change
constantly and may differ from what the user actually sees at checkout.
Always direct the user to buy_url for the source of truth before they
commit to a purchase.
Personal / light use only. Single-shot lookups for a real shopping
task, not bulk scraping, competitive price monitoring, or inventory
mirroring. The in-script throttle (TARGET_MIN_INTERVAL, default 1s) is
the floor — do not lower it. See references/tos-and-etiquette.md.
The cart-link feature creates a real server-side guest cart. It mints
a 24-hour anonymous bearer token against gsp.target.com and POSTs TCINs
to carts.target.com. Treat the resulting URL like a one-time share link:
it grants ~24h of cart-write access to whoever holds it. No login, payment
info, or shipping address is ever transmitted.
No checkout, payment, or auth. Checkout, returns, saved carts, Circle deals tied to an account, and order history are out of scope and will stay out of scope. If you need any of those, open target.com in a browser.
references/tos-and-etiquette.md.The skill ships as a uv project under its own directory. From the skill
root (~/.openclaw/workspace/skills/target-com-shopper/ at runtime):
uv sync
That's it — runtime is stdlib-only; uv is just used for the venv and to
run scripts reproducibly.
store_id shapes every product/price/fulfillment response. Ask the user
for their ZIP code (or city) before calling product endpoints, then look
up nearby stores:
uv run python -m scripts.stores 55403 --limit 5
Pick a store_id from the results and pass it as --store-id to
search, pdp, and summary. (Or set TARGET_DEFAULT_STORE_ID in the
environment for the session.) If the user truly doesn't care about
location, the default store (2281, San Jose Central) is fine for
keyword search and PDP, but not for accurate "in stock today" answers.
uv run python -m scripts.search "wireless earbuds" --count 10 --store-id 1375
uv run python -m scripts.search --category 5xteg --count 10
uv run python -m scripts.search "chicken breast" --category 4tgi7 # keyword AND category
--raw returns the full API payload. Default trims to tcin, title,
brand, price, rating, buy_url, image.
Fresh-grocery searches: generic keyword search drowns fresh items in shelf-stable hits (e.g. "chicken breast" returns canned chicken first). Combine the keyword with a category N-ID to scope — see references/categories.md for the curated list of common N-IDs (Fresh Chicken, Fresh Produce, Herbs & Spices, etc.).
Building a multi-item shopping list? The skill has no batched search
endpoint — plp_search_v2 accepts one query at a time. Fire individual
scripts.search calls in parallel from the agent runtime; the in-script
TARGET_MIN_INTERVAL throttle (default 1s) protects the upstream. For a
6-item list expect ~6 seconds wall time. Do not lower TARGET_MIN_INTERVAL
below 0.5s — see references/tos-and-etiquette.md.
uv run python -m scripts.pdp 89827259 --store-id 1375
Returns title, brand, price, bullets, images, promotions, variant TCINs.
For a shortlist (e.g. comparing 3–5 candidates) use summary instead of
calling pdp N times — one round trip:
uv run python -m scripts.summary 89827259 94783927 --zip 55403 --store-id 1375
Note: summary does not return price. Combine with pdp if needed.
uv run python -m scripts.fulfillment 89827259 --zip 55403 --radius 25 --only-available
uv run python -m scripts.stores "Minneapolis, MN" --limit 5
uv run python -m scripts.stores 55403 --within 25
This actually pre-populates the recipient's cart. Behind the scenes the
script mints a 24h anonymous guest token (gsp.target.com), creates a
real server-side cart by POSTing each TCIN to carts.target.com, writes
a local HTML redirect file, and tries to launch the user's default
browser at:
https://www.target.com/cart?access_token=<TOKEN>
When the browser opens it, target.com merges the items into the session
cart and lands on /cart. No login required.
uv run python -m scripts.cart_link 89827259 94783927 --quantities 1 2
uv run python -m scripts.cart_link 89827259 # qty defaults to 1
uv run python -m scripts.cart_link 111 222 333 --quantities 2 # qty=2 for all
uv run python -m scripts.cart_link 89827259 --refresh-token # force new token
uv run python -m scripts.cart_link 89827259 --no-open # just write the file
uv run python -m scripts.cart_link 89827259 --cart-file ~/Downloads/cart.html
CRITICAL — DO NOT inline the
urlfield into your chat reply. The token is ~600 characters. Most chat UIs truncate URLs of that length, which silently breaks the cart handoff (the recipient lands on/cartwith an invalidaccess_tokenand an empty basket). Always hand off via:
auto_opened: true— the script already launched the user's browser; just confirm in the reply.cart_file— short local path (e.g./tmp/target-com-shopper/cart-XXX.html). Tell the user to open that file if the browser didn't launch.shopping_list_markdown— clickable per-item PDP links as a fallback, in case the auto-merge fails. Each link is short and click-safe.The skill emits
url_preview(truncated for logging) andurl_lengthso you can see at a glance how oversized the raw URL is. The fullurlstays in the output for programmatic callers, but treat it as private.
Treat the URL like a one-time share link. It contains a bearer token
that grants ~24h of cart-write access. Do not commit it, do not paste it
into long-lived chat history. The skill caches the token under
$TMPDIR/target-com-shopper/anonymous-token.json (mode 0600) and reuses it
across calls until ~10 min before expiry.
Output JSON includes cart_file, auto_opened, cart_id, guest_id,
total_cart_item_quantity, items_added (with per-item title,
unit_price, current_price), items_failed, shopping_list_markdown,
shopping_list_text, token_expires_in_hours, url_length,
url_preview, url_warning, and url. If any TCIN fails to add, it
appears under items_failed and the script exits 2.
uv run python -m scripts.reviews 89827259
Returns the review count and average rating only. Full review text is
not exposed by product_review_v1 — point the user at buy_url to read
reviews on target.com.
| Var | Default | Purpose |
|---|---|---|
TARGET_API_KEY | baked-in public key | Override if Target rotates the public web key. Not a secret. |
TARGET_DEFAULT_STORE_ID | 2281 | Fallback store when --store-id is omitted. |
TARGET_USER_AGENT | target-com-shopper-skill/0.1 ... | UA string sent on every request. |
TARGET_HTTP_TIMEOUT | 10 | Seconds. |
TARGET_MIN_INTERVAL | 1.0 | Minimum seconds between requests (politeness throttle). |
TARGET_LIVE_TESTS | unset | Set to 1 to enable live-network tests. |
uv run pytest # offline only (default)
TARGET_LIVE_TESTS=1 uv run pytest -m live -v # hit the real API
references/endpoints.md — every API operation used, required params,
field-path gotchas.references/categories.md — curated Target category N-IDs (grocery,
fresh meat, produce, spices, etc.) for use with scripts.search --category.references/status-codes.md — what 206/400/410/429/5xx mean here.references/tos-and-etiquette.md — be a polite client.