Search Target.com for a product query and return the top organic match's title, brand, price, original price, rating, TCIN, canonical product URL, and image — via the public redsky JSON aggregation API. Distinguishes real matches, spell-corrected matches, and zero-results-with-recommendation-padding outcomes. Read-only.
Automate repetitive workflows and reduce manual effort
Example: Generate reports, summarize documents, draft communications
Save 3-5 hours per week on routine tasks
Learn new skills, understand complex topics, get expert guidance
Example: Explain concepts, provide examples, suggest learning resources
Accelerate learning and skill development by 2x
Enhance output quality through reviews, suggestions, and refinements
Example: Review drafts, suggest improvements, catch errors
Improve work quality by 30-40% with less effort
Time estimate: 15-45 minutes depending on use case complexity
Prerequisites
Submit your Claude Code skill and start earning
browse install target.com/find-a-product-nn7l9gCompatible with
Supported agents
| name | find-a-product |
| title | Target.com Find Product |
| description | >- Search Target.com for a product query and return the top organic match's title, brand, price, original price, rating, TCIN, canonical product URL, and image — via the public redsky JSON aggregation API. Distinguishes real matches, spell-corrected matches, and zero-results-with-recommendation-padding outcomes. Read-only. |
| website | target.com |
| category | shopping |
| tags | - shopping - retail - target - product-search - read-only - json-api |
| source | 'browserbase: agent-runtime 2026-05-18' |
| updated | '2026-05-18' |
| recommended_method | api |
| alternative_methods | - method: browser rationale: >- Falls back to driving https://www.target.com/s?searchTerm=... in a Verified + residential-proxy session when the redsky API returns 4xx. The browser path costs ~6–8 turns and ~30–60s wall (vs ~1s for the API) and has to dismiss a Health Data Consent modal before the product grid is interactable. Use only when the API path is confirmed broken. |
| verified | false |
| proxies | false |
Given a free-text product query (e.g. "AirPods Pro 2", "tide pods", "lego star wars millennium falcon"), return the top matching Target.com product(s) with structured fields: title, brand, price, original (struck-through) price, average rating + rating count, TCIN (Target's internal product ID), canonical product URL (/p/.../-/A-<tcin>), primary image URL, and signals like spell correction or zero-results fallback. Read-only — never adds to cart, never submits an order.
target.com/s?searchTerm=... in a Verified browser — the redsky JSON API returns identical data in one ~1s HTTP request without anti-bot.Target's web search page is a Next.js SSR shell with a JS-rendered product grid; the actual data comes from a public JSON aggregation API at redsky.target.com that the browser polls on page load. The endpoint is keyed but the key is a static public token (ff457966e64d5e877fdbad070f276d18ecec4a01) embedded in Target's JS bundles, accepts unauthenticated requests, has no per-IP captcha or PerimeterX challenge, and works equally well with or without a residential proxy. Hit it directly — the browser path is a ~100× cost premium that pays for a Health Data Consent modal you have to dismiss before the grid even paints.
GET https://redsky.target.com/redsky_aggregations/v1/web/plp_search_v2
?key=ff457966e64d5e877fdbad070f276d18ecec4a01
&channel=WEB
&keyword=<URL-encoded query>
&page=%2Fs%2F<URL-encoded query>
&visitor_id=<any non-empty string, e.g. "skill-runner">
&pricing_store_id=2885
&default_purchasability_filter=true
&count=24
&offset=0
&platform=desktop
Required params (server returns HTTP 400 if any are missing): key, channel, keyword, page, visitor_id, pricing_store_id. Optional but useful: count (default 24), offset (item-level, not page-level — increment by count to paginate), default_purchasability_filter=true (hides out-of-stock), sort_by (see table below), category (scope to a category id), platform=desktop|mobile.
The page param is required and must look like a real PLP path (/s/<term>); the server validates only that it starts with /s/ — anything after is decorative. visitor_id is required but any non-empty string is accepted; the server doesn't actually validate it against a known device. pricing_store_id=2885 is the Target HQ store (Minneapolis) and yields nationwide pricing — use it as a stable default unless you specifically need store-local pricing.
sort_by value | Effect |
|---|---|
relevance (default) | Target's relevance ranking |
Featured | Featured/sponsored bias |
PriceLow | Price low → high |
PriceHigh | Price high → low |
RatingHigh | Average rating high → low |
bestselling | Best-sellers first |
newest | Newest first |
URL="https://redsky.target.com/redsky_aggregations/v1/web/plp_search_v2?key=ff457966e64d5e877fdbad070f276d18ecec4a01&channel=WEB&keyword=AirPods+Pro+2&page=%2Fs%2FAirPods+Pro+2&visitor_id=skill-runner&pricing_store_id=2885&default_purchasability_filter=true&count=24"
# Either path works — pick whatever the agent's runtime already has:
browse cloud fetch "$URL" # Browserbase Fetch API, no proxy needed
# or
curl -fsS -H 'Accept: application/json' "$URL"
A residential proxy is not required for this endpoint. Verified: same response shape, same products, same status 200, with and without --proxies. Save the proxy budget for the browser-fallback path.
.data.search.search_response |
{
total_results: .metadata.total_results,
spell_corrected: (.metadata.auto_corrected_keyword // null),
real_results: ((.facet_list // []) | length > 0),
keyword: .metadata.keyword
}
Branch on real_results:
real_results: true — Target found genuine matches for the keyword. Parse data.search.products[].real_results: false — Target found zero matches and is serving generic "recommendation" filler (typically ~200 unrelated bestsellers from books / toys / random categories). Do NOT silently return the first filler item as the match. Emit success: false, reason: "no_results" and pass through metadata.keyword so the caller can decide what to do.spell_corrected non-null — Target auto-corrected the query (e.g. "airpoods" → "airpods"). The returned products correspond to the corrected keyword. Pass the corrected term back so the caller can decide whether the correction is acceptable..data.search.products[0] |
{
tcin: .tcin, # e.g. "85978609"
title: (.item.product_description.title | @html_decode), # decode  , &, ", ™
brand: .item.primary_brand.name, # may be null
price: .price.formatted_current_price, # "$249.99" or "See price in cart"
original_price: .price.formatted_comparison_price, # null if not on sale
rating: .ratings_and_reviews.statistics.rating.average, # 0–5 float, null if no ratings
rating_count: .ratings_and_reviews.statistics.rating.count, # integer, null if no ratings
product_url: .item.enrichment.buy_url, # canonical https://www.target.com/p/.../-/A-<tcin>
image_url: .item.enrichment.image_info.primary_image.url, # scene7 CDN URL
desirability: (.desirability_cues // [] | map(.display)) # e.g. ["Bestseller"], ["5k+ bought in last month"]
}
Decode HTML entities (  → non-breaking space, & → &, " → ", ™ → ™) — Target's API returns titles with entity references intact, not pre-decoded text.
plp_search_v2 already filters most sponsored placements server-side — the field item.is_sponsored is null (not false) across all observed organic results, and sponsored slots come from a sibling aggregation (cf_sponsored_products_search_v1) the browser fetches separately. If you need to be defensive, drop any product whose __typename !== "ProductSummary".
Read-only is the rule. Do not hit the add_to_cart redsky aggregation. Do not POST to /checkout. Stop at the product summary.
If redsky.target.com ever returns 4xx (key rotation, geo-block, etc.) — drive the public site:
--proxies --verified (PerimeterX / HUMAN sensor at client.px-cloud.net/PXGWPp4wUS/main.min.js will challenge a bare session within a few requests).browse open "https://www.target.com/s?searchTerm=<URL-encoded query>" --remote.button:has-text("Continue shopping") — before snapshotting.browse wait timeout 2500 — the grid lazy-loads after consent dismissal.browse snapshot — product cards surface as link refs with TCIN-bearing hrefs.[data-test="@web/site-top-of-funnel/ProductCardWrapper"] → child [data-test="product-title"] (title), [data-test="product-price"] (price), [data-test="ratings"] (rating).The browser fallback costs ~6–8 turns and ~30–60s wall vs the API's one HTTP request. Use only when the API path is confirmed broken — not as the default.
ff457966e64d5e877fdbad070f276d18ecec4a01 has been observed in Target's web bundle continuously since at least 2021 across third-party scrapers. If it ever rotates, scan the Target SERP HTML for redsky_aggregations references and look for the key in the surrounding JS — historically it's been bundled in a global config object emitted into the SSR HTML, not behind any auth wall.key, channel, keyword, page, visitor_id, pricing_store_id flips the response to HTTP 400 with no error body. Removing default_purchasability_filter, count, offset, platform, store_ids, or sort_by is safe — those default cleanly server-side.page is path-prefix-validated, not echo'd. The server accepts any page starting with /s/. It does not compare page against keyword. You can pass page=%2Fs%2Ftest for every request regardless of the actual keyword and the response is identical to passing the real path — verified across tide+pods, airpods+pro+2, instant+pot+duo+7+in+1.xkcd12345nonexistent) returns HTTP 200 with total_results: 200 and 24 unrelated bestsellers in products[]. The reliable signal is search_response.facet_list is missing/empty for the padding case but populated for genuine results. total_results is not a reliable zero-results signal — Target pads it.products[]. When metadata.auto_corrected_keyword is non-null, the returned products are for the corrected keyword, not the typed one. The caller should be told about the correction so they can decide whether to accept it. (Example: keyword=airpoods returns auto_corrected_keyword="airpods" plus 481 AirPod-family products.)  (nbsp), & (&), " ("), ™ (™) appear verbatim. Always run titles through an HTML-entity decoder before emitting JSON to a consumer.price.formatted_current_price can be "See price in cart" for MAP-restricted items (Apple, Instant Pot RIO line, some appliances). This is a real product, just legally price-suppressed on the PLP — open the PDP via buy_url to see the actual cart price, or read price.current_retail (numeric, sometimes populated even when the formatted string is suppressed).brand is .item.primary_brand.name, but it can be null — observed null for Target-private-label staples (e.g. "up & up"), unbranded commodity items, and grocery. Fall back to extracting the leading token of the title if a brand is required downstream.rating.count is the rating count, not the review count. A separate review_count field at the top of statistics does not exist on plp_search_v2 — the field .ratings_and_reviews.statistics.rating.count is the integer you want.pricing_store_id controls store-localized pricing, not nationwide-vs-store availability. 2885 (Jersey City / NJ) is the value Target's public web bundles use by default. Other valid store IDs (1000 = Minneapolis 50th & France, 3991 = LA Westwood, etc.) are accepted. The default_purchasability_filter parameter independently controls whether out-of-stock items are hidden.client.px-cloud.net/PXGWPp4wUS/main.min.js (the HUMAN sensor) is loaded as <script id="humanSensor"> on every page. Bare sessions get challenged within ~5–10 requests; --proxies --verified is mandatory for the browser fallback. The redsky API endpoint is not behind PerimeterX — verified: 200 OK on direct curl from a datacenter IP, no challenge, no _px* cookies required.https://www.target.com/p/<slug>/-/A-<tcin> is stable — once you have the TCIN you can drop the slug entirely (/-/A-<tcin>) and Target 301s to the canonical slug.offset not page. offset is item-level (0, 24, 48, ...). The redsky endpoint also accepts &page_number=2 but it's a no-op — only offset controls pagination.store_ids filters availability, not pricing. Including store_ids=<id> scopes the result set to items in-stock at that store. Omitting it returns everything Target sells online for the keyword. They're independent dimensions from pricing_store_id.Three distinct outcome shapes:
// Success — top result is a genuine match
{
"success": true,
"query": "AirPods Pro 2",
"search_keyword": "AirPods Pro 2",
"spell_corrected_from": null,
"total_results": 259,
"product": {
"tcin": "85978609",
"title": "Apple AirPods Pro 3 Wireless Earbuds with Active Noise Cancellation",
"brand": "Apple",
"price": "$249.99",
"original_price": null,
"rating": 3.9,
"rating_count": 1441,
"product_url": "https://www.target.com/p/ap2022-true-wireless-bluetooth-headphones/-/A-85978609",
"image_url": "https://target.scene7.com/is/image/Target/GUEST_d1b8c229-751b-430b-a0fb-521d7777a784",
"desirability_cues": ["Bestseller"],
"is_sponsored": false
},
"error_reasoning": null
}
// Success with spell correction — caller should decide whether to accept
{
"success": true,
"query": "airpoods",
"search_keyword": "airpods",
"spell_corrected_from": "airpoods",
"total_results": 481,
"product": { /* ... top AirPods product ... */ },
"error_reasoning": null
}
// No real matches — Target returned recommendation filler
{
"success": false,
"query": "xkcd12345nonexistent",
"search_keyword": "xkcd12345nonexistent",
"spell_corrected_from": null,
"total_results": 200,
"product": null,
"error_reasoning": "no_results",
"note": "Target returned 200 unrelated recommendations (no facet_list in search_response — confirmed filler)."
}
// API blocked — fall back to browser path (rare)
{
"success": false,
"query": "...",
"product": null,
"error_reasoning": "api_blocked",
"http_status": 403,
"note": "redsky.target.com returned 403. Switch to the browser-fallback workflow (Health Data Consent modal + Verified session)."
}
AI-first code editor with Composer
Before installing skills in Cursor, ensure your development environment meets these requirements:
node --versionfind-a-productExecute the skills CLI command in your project's root directory to begin installation:
browse install target.com/find-a-product-nn7l9gFetches find-a-product from target.com/find-a-product-nn7l9g and configures it for Cursor.
The CLI shows a list of agents. Use arrow keys and space to select Cursor:
Confirm successful installation by checking the skill directory location:
.cursor/skills/find-a-product
Restart Cursor to activate find-a-product. Access via /find-a-productin your agent's command palette.
Learn more:View source on GitHubSkills CLI docsAbout CursorWhat are agent skills?
Steps
Common Pitfalls
✓ Do
✗ Don't
💡 Pro Tips
✓ Use when
Use when skill capabilities match your task, clear ROI on time saved, and you can validate outputs. Best for repetitive tasks, learning, and quality improvement.
✗ Avoid when
Avoid when task requires deep expertise you can't validate, involves sensitive decisions, or when learning process is more valuable than speed of completion.
check-stock
ikea.com/check-stock-sff6ln · retail · 2 shared tags
ruwangi-parfum-perempuan
ruwangi.com/ruwangi-parfum-laki-laki-ko0z5t · shopping · tag: read-only
find-product
booksmandala.com/find-product-9iiu37 · shopping · tag: read-only
get-player-stats
pro-football-reference.com/get-player-stats-5pitm4 · sports · tag: read-only
search-products
shopee.com.my/search-products-5epzg0 · marketplace · tag: read-only
find-snapshot
archive.org/find-snapshot-e3fnxh · archives · tag: read-only
find-a-product reduced setup friction for our internal harness; good balance of opinion and flexibility.
Useful defaults in find-a-product — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
find-a-product is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
find-a-product has been reliable in day-to-day use. Documentation quality is above average for community skills.
I recommend find-a-product for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
find-a-product fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.
Solid pick for teams standardizing on skills: find-a-product is focused, and the summary matches what you get after install.
We added find-a-product from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.
find-a-product has been reliable in day-to-day use. Documentation quality is above average for community skills.
find-a-product is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
showing 1-10 of 40