Create a bulk export job
Start an asynchronous export of PDP or image scores.
/v1/exportsQueues 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; 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 |
Authorization
bearerAuth Short-lived access token issued by Create a token.
Send it on every request as Authorization: Bearer <token>.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Which dataset to export. pdps returns PDP-level scores; images
returns image-level scores. CSV column layout per subject is
documented in the createExport endpoint description.
"pdps" | "images"Optional filters narrowing the export. Org scope is always enforced
by the access token; these filters refine within the caller's org.
Unknown filter keys are rejected with INVALID_FILTER.
Response Body
application/json
application/json
application/json
application/json
curl -X POST "https://ext.vizit.com/v1/exports" \ -H "Content-Type: application/json" \ -d '{ "subject": "pdps" }'{ "export_id": "a9a55f8d-48b1-4a5b-a88e-c41b0cd75102", "subject": "pdps", "status": "PENDING", "status_url": "/v1/exports/4f1a2b3c-5d6e-7f8a-9b0c-1d2e3f4a5b6c", "requested_at": "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"}PUTSubmit a PDP by Amazon 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.
GETRetrieve an export
Returns the current status of an export job. When `status` is `COMPLETED` and the artifact has not yet expired, `download_url` is populated with a path to [Download an export artifact](/api/exports/downloadExport). Authenticate that follow-up GET with the same Bearer token used for this endpoint — the URL itself does not carry embedded credentials. Lifecycle: - `PENDING` / `PROCESSING` → `download_url` is `null`, no `error_code` - `COMPLETED` (within retention) → `download_url` populated - `COMPLETED` (past 7-day retention) → `download_url` is `null`, `error_code: EXPORT_EXPIRED` - `ERROR` → `download_url` is `null`, `error_code: EXPORT_FAILED` Cross-org access is intentionally indistinguishable from "not found"; foreign `export_id`s return `404 EXPORT_NOT_FOUND`.