Catalog Import & Export — Vendor
Vendor-scoped mirror of the product import pipeline and product export, locked to the session vendor so a supplier can bring their own catalog in and take it back out.
Vendor-scoped mirror of the product import pipeline and product export, locked to the session vendor so a supplier can bring their own catalog in and take it back out. The full format reference, pipeline stages, mapping-profile model and image-migration behaviour are documented once in admin/catalog-io.md — this page covers only what differs.
Source:
api-modules/catalog-io/src/controllers/vendor-product-import.controller.ts,api-modules/catalog-io/src/controllers/vendor-product-export.controller.ts.
Authentication and scoping
All endpoints require a Better-Auth vendor session (BetterAuthGuard). There is no permission check beyond the session — a vendor's access to their own catalog is implied by the session itself.
Every read and write is locked to resolveActiveVendorId(session):
- Batches and exports created here carry that
vendorId; the list endpoints only ever return the caller's own rows. - Another tenant's id returns
404, never403. A403would confirm the row exists and let one supplier probe for another's imports. - The
vendor_slugandvendorcolumns are ignored on this surface. Every imported product belongs to the session seller regardless of what the spreadsheet says.
Because the vendor is fixed, the MISSING_VENDOR and VENDOR_NOT_FOUND row errors that the admin surface can raise never occur here.
Endpoints
The paths mirror the admin surface under vendor/catalog/ instead of admin/catalog/:
| Method | Path |
|---|---|
POST | /vendor/catalog/imports/upload-url |
POST | /vendor/catalog/imports |
GET | /vendor/catalog/imports |
GET | /vendor/catalog/imports/:id |
GET | /vendor/catalog/imports/:id/profiling |
PUT | /vendor/catalog/imports/:id/mapping |
POST | /vendor/catalog/imports/:id/validate |
GET | /vendor/catalog/imports/:id/preview |
GET | /vendor/catalog/imports/:id/rows |
GET | /vendor/catalog/imports/:id/errors.csv |
POST | /vendor/catalog/imports/:id/apply |
POST | /vendor/catalog/imports/:id/cancel |
POST | /vendor/catalog/exports |
GET | /vendor/catalog/exports |
GET | /vendor/catalog/exports/template |
GET | /vendor/catalog/exports/:id |
GET | /vendor/catalog/exports/:id/download |
Request and response shapes are identical to the admin surface.
Exports
An export requested here is filtered to the session vendor's products. Any vendorId in the request body is ignored — the session wins.
Taxonomy creation
createMissing behaves as it does on the admin surface, but note that brands, categories, tags and ingredients are platform-wide, not per-vendor. A vendor import with createMissing: true can therefore introduce taxonomy rows visible to every vendor. Operators who want a curated taxonomy should have suppliers import with createMissing: false, which turns an unrecognised name into a row error instead.
Approval
This surface writes products directly through the same ProductService path as the admin import; it does not route through the vendor catalog-request approval workflow. Products land in whatever status the file specifies (default draft).
Cart Module — Vendor surface
Vendor-facing HTTP endpoints for browsing carts that contain the vendor's own products and for vendor-scoped cart funnel analytics. There are no write operations: a vendor cannot…
Catalog Module — Vendor surface
Vendor-facing CRUD over the vendor's own products, variants, options, and tabs, plus the vendor-side "request a new taxonomy entry" workflow (new brand, category, tag, or…