# Submit a PDP by Amazon ASIN

`PUT /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](/api/product-details/upsertPdpByGtin), 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](/api/product-details/getPdpByAsin)
(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.

## Request Body

### application/json

- **object** — Optional context for an ASIN ingestion. The body may be omitted
entirely; in that case the request is treated as `{ "region": "us" }`.

  - `region` (string) — Amazon storefront region (e.g., `us`, `uk`, `de`, `ca`). Combined
with `amazon` server-side to resolve the storefront. Unknown
values return `400 INVALID_REGION`.


## Responses

### 202 — PDP accepted for processing

**application/json**

- **object**
  - `asin` (string, required)
  - `region` (string, required) — Echoed back from the request (defaulted to `us` when omitted).
  - `pdp_id` (string, required) — Internal identifier for the PDP (useful for support diagnostics).
  - `status` (enum: "processing", required) — Always `"processing"` — poll GET for the eventual status.
  - `score_url` (string, required) — Relative path to poll for scoring results. Includes the `region`
query parameter so callers do not have to reconstruct it.


### 400 — Validation error. `error_code` values:
  - INVALID_ASIN — ASIN is not 10 uppercase alphanumeric characters
  - INVALID_REGION — `region` is not a supported Amazon storefront
  - CATEGORY_NOT_IN_ORG_ICP — scraped category is outside the caller org's ICP
  - NO_VALID_CATEGORY — retailer returned no usable category data


**application/json**

- **object** — Standardized error format for all `/v1/*` endpoints. `error_code` is a
stable SCREAMING_SNAKE_CASE identifier clients can switch on.

  - `detail` (string) — Human-readable error message
  - `status_code` (integer) — HTTP status code
  - `error_code` (string) — Stable machine-readable error code
  - `request_id` (any) — Request identifier for correlation
  - `extra` (any) — Endpoint-specific additional context. For example,
IMAGE_DOWNLOAD_FAILED populates extra.failed_urls with per-URL
failure reasons so clients can triage bulk submissions.

  - `timestamp` (string)

### 401 — Missing or invalid Bearer token

### 404 — Resource not found. `error_code` values:
  - ASIN_NOT_FOUND_AT_RETAILER — the ASIN could not be resolved on the storefront
  - PDP_NOT_FOUND — the caller's organization has no default portfolio configured


**application/json**

- **object** — Standardized error format for all `/v1/*` endpoints. `error_code` is a
stable SCREAMING_SNAKE_CASE identifier clients can switch on.

  - `detail` (string) — Human-readable error message
  - `status_code` (integer) — HTTP status code
  - `error_code` (string) — Stable machine-readable error code
  - `request_id` (any) — Request identifier for correlation
  - `extra` (any) — Endpoint-specific additional context. For example,
IMAGE_DOWNLOAD_FAILED populates extra.failed_urls with per-URL
failure reasons so clients can triage bulk submissions.

  - `timestamp` (string)

### 429 — Rate limit exceeded for this organization

### 502 — Retailer scrape failed after retries
(`error_code`: `SCRAPE_UPSTREAM_ERROR`).


**application/json**

- **object** — Standardized error format for all `/v1/*` endpoints. `error_code` is a
stable SCREAMING_SNAKE_CASE identifier clients can switch on.

  - `detail` (string) — Human-readable error message
  - `status_code` (integer) — HTTP status code
  - `error_code` (string) — Stable machine-readable error code
  - `request_id` (any) — Request identifier for correlation
  - `extra` (any) — Endpoint-specific additional context. For example,
IMAGE_DOWNLOAD_FAILED populates extra.failed_urls with per-URL
failure reasons so clients can triage bulk submissions.

  - `timestamp` (string)

### 504 — Retailer scrape timed out after retries
(`error_code`: `SCRAPE_TIMEOUT`).


**application/json**

- **object** — Standardized error format for all `/v1/*` endpoints. `error_code` is a
stable SCREAMING_SNAKE_CASE identifier clients can switch on.

  - `detail` (string) — Human-readable error message
  - `status_code` (integer) — HTTP status code
  - `error_code` (string) — Stable machine-readable error code
  - `request_id` (any) — Request identifier for correlation
  - `extra` (any) — Endpoint-specific additional context. For example,
IMAGE_DOWNLOAD_FAILED populates extra.failed_urls with per-URL
failure reasons so clients can triage bulk submissions.

  - `timestamp` (string)
