Submit a PDP by Amazon ASIN
Trigger Vizit's scrape-and-score pipeline for an Amazon ASIN.
/v1/pdps/asin/{asin}Submitting an ASIN runs Vizit's standard Amazon scrape-and-score pipeline server-side: ASIN lookup and validation, category inference with ICP check, retailer scrape, image ingest, and scoring. Unlike Submit a PDP by GTIN, the caller does not supply images or a category — both are derived from the scrape.
Upsert semantics. If a PDP already exists for this ASIN in your
organization (and region), this call refreshes it — same behavior as
the in-product "refresh" action. The previous scores remain visible
alongside status: processing until the new scores land.
The response returns immediately with status: processing and a
score_url. Use
Retrieve PDP scores by ASIN
(with the same region) to watch the scores come in. Score
availability is bounded by the scrape and scoring pipeline — expect
tens of seconds for typical Amazon ASINs.
Common errors. INVALID_ASIN if the path parameter is not 10
uppercase alphanumeric characters; ASIN_NOT_FOUND_AT_RETAILER if
Amazon does not return the listing; CATEGORY_NOT_IN_ORG_ICP if the
scraped category is outside your organization's ICP;
NO_VALID_CATEGORY if the retailer returned no usable category
data.
Authorization
bearerAuth Short-lived access token issued by Create a token.
Send it on every request as Authorization: Bearer <token>.
In: header
Path Parameters
Amazon Standard Identification Number — 10 characters, uppercase
letters and digits only. Validated at the router; a mismatch
returns 400 INVALID_ASIN before any retailer call is made.
^[A-Z0-9]{10}$Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Amazon storefront region (e.g., us, uk, de, ca). Combined
with amazon server-side to resolve the storefront. Unknown
values return 400 INVALID_REGION.
"us"Response Body
application/json
application/json
application/json
application/json
application/json
curl -X PUT "https://ext.vizit.com/v1/pdps/asin/B07XVTRJKX" \ -H "Content-Type: application/json" \ -d '{}'{ "asin": "B07XVTRJKX", "region": "us", "pdp_id": "2ed2d86b-85b6-49b8-bfaf-11ce19f11301", "status": "processing", "score_url": "/v1/pdps/asin/B07XVTRJKX?region=us"}{ "detail": "string", "status_code": 0, "error_code": "INVALID_GTIN", "request_id": "266ea41d-adf5-480b-af50-15b940c2b846", "extra": { "failed_urls": [ { "url": "https://cdn.example.com/broken.jpg", "reason": "IMAGE_DOWNLOAD_TIMEOUT" }, { "url": "https://cdn.example.com/icon.svg", "reason": "UNSUPPORTED_IMAGE_FORMAT" } ] }, "timestamp": "2019-08-24T14:15:22Z"}{ "detail": "string", "status_code": 0, "error_code": "INVALID_GTIN", "request_id": "266ea41d-adf5-480b-af50-15b940c2b846", "extra": { "failed_urls": [ { "url": "https://cdn.example.com/broken.jpg", "reason": "IMAGE_DOWNLOAD_TIMEOUT" }, { "url": "https://cdn.example.com/icon.svg", "reason": "UNSUPPORTED_IMAGE_FORMAT" } ] }, "timestamp": "2019-08-24T14:15:22Z"}{ "detail": "string", "status_code": 0, "error_code": "INVALID_GTIN", "request_id": "266ea41d-adf5-480b-af50-15b940c2b846", "extra": { "failed_urls": [ { "url": "https://cdn.example.com/broken.jpg", "reason": "IMAGE_DOWNLOAD_TIMEOUT" }, { "url": "https://cdn.example.com/icon.svg", "reason": "UNSUPPORTED_IMAGE_FORMAT" } ] }, "timestamp": "2019-08-24T14:15:22Z"}{ "detail": "string", "status_code": 0, "error_code": "INVALID_GTIN", "request_id": "266ea41d-adf5-480b-af50-15b940c2b846", "extra": { "failed_urls": [ { "url": "https://cdn.example.com/broken.jpg", "reason": "IMAGE_DOWNLOAD_TIMEOUT" }, { "url": "https://cdn.example.com/icon.svg", "reason": "UNSUPPORTED_IMAGE_FORMAT" } ] }, "timestamp": "2019-08-24T14:15:22Z"}GETRetrieve PDP scores by ASIN
Returns the current scores and processing state for a PDP submitted via [Submit a PDP by ASIN](/api/product-details/upsertPdpByAsin). Poll until `status` moves from `processing` to `scored`. During a refresh, previously computed scores remain visible alongside `status: processing` and the prior `scored_at` timestamp, so clients can keep showing the last known result while a new one is computed. Use the optional `region` query parameter to disambiguate between regional storefronts when the same ASIN has been ingested under multiple regions in your organization. The `score_url` returned by the PUT response already includes this parameter.
POSTCreate a bulk export job
Queues an asynchronous bulk export for the caller's organization. The response returns immediately with `status: PENDING` and a `status_url` pointing at [Retrieve an export](/api/exports/getExport); poll there until `status` reaches `COMPLETED` to obtain the short-lived presigned download URL. Org scope is enforced by the access token; the optional `filters` block narrows within the org. Each caller is limited to one in-flight `PENDING`/`PROCESSING` export at a time — additional submissions return `409 EXPORT_CONCURRENCY_LIMIT`. ## CSV format Exports are CSV in v1 (JSONL and Parquet deferred to v2). The header row is fixed per `subject`; carousel rows in `subject=images` exports emit empty values for hero-only columns so partners can rely on a stable column set. ### `subject=pdps` column set | Column | Type | Notes | | --- | --- | --- | | `pdp_id` | uuid | PDP identifier; stable across refreshes | | `portfolio_id` | uuid | Owning portfolio | | `retailer_region` | string | e.g. `amazon_us`, `walmart_us` | | `item_id` | string | ASIN or GTIN, depending on retailer | | `name` | string \| null | PDP display name | | `brand` | string \| null | | | `category_id` | uuid \| null | Vizit category identifier | | `category` | string \| null | Category display name | | `listing_score` | int \| null | 0–100, resolved per org | | `raw_listing_score` | float \| null | Pre-blend, pre-penalty | | `listing_score_blended` | int \| null | 0–100, pre-penalty | | `score_penalty` | bool \| null | True if any penalty applied | | `image_count_penalty` | float \| null | | | `image_mix_penalty` | float \| null | | | `image_order_penalty` | float \| null | | | `high_scoring_asset_count` | int \| null | | | `is_ideal_content_mix` | bool \| null | | | `images_matching_ideal_mix` | int \| null | | | `score_status` | string | `CREATED`, `PROCESSING`, `SCORED`, or `CATEGORY_NOT_FOUND` | | `created_at` | date-time | | | `updated_at` | date-time | | | `last_refreshed` | date-time \| null | Last successful scrape + score | ### `subject=images` column set Hero-score and mobile-readiness columns are populated only for hero rows; carousel rows emit empty values in those columns. | Column | Type | Notes | | --- | --- | --- | | `image_id` | uuid | | | `pdp_id` | uuid | Parent PDP | | `portfolio_id` | uuid | Denormalized from PDP for row-standalone exports | | `retailer_region` | string | | | `item_id` | string | ASIN or GTIN of the parent PDP | | `image_type` | string | `hero` or `carousel` | | `image_url` | string | | | `position` | int | 1-based position within the PDP (matches `CarouselImageResponse.position`) | | `source` | string \| null | e.g. `scraped` | | `vizit_score` | int \| null | 0–100, resolved per org | | `raw_score` | float \| null | | | `hero_score` | int \| null | 0–100; null for carousel rows. The `hero_score_breakdown` sub-scores (heroism, category_edge, technical_integrity, local_support) are intentionally omitted from v1 — the hero formula is in flight | | `mobile_ready` | bool \| null | All five clarity scores ≥ 80. Null for carousel | | `mobile_brand_clarity` | float \| null | Null for carousel | | `mobile_product_type_clarity` | float \| null | Null for carousel | | `mobile_variant_clarity` | float \| null | Null for carousel | | `mobile_count_clarity` | float \| null | Null for carousel | | `mobile_size_clarity` | float \| null | Null for carousel | | `mobile_scored_model` | string \| null | Null for carousel | | `classification` | string \| null | e.g. `Lifestyle`, `Packshot` | | `classification_confidence` | float \| null | 0–1 | | `classification_high_confidence` | bool \| null | | | `created_at` | date-time | | | `updated_at` | date-time | | | `scored_at` | date-time \| null | Last successful score |