Products
CRUD for the product catalog.
The admin product object extends the public one with internal fields
(costPrice, soft-delete deletedAt, etc.).
Product object (admin view)
{
"id": "f3a7e9b8-...",
"slug": "kurti-emerald",
"name": "Emerald Kurti",
"description": "Hand-block printed cotton kurti.",
"price": "1490.00",
"comparePrice": "1990.00",
"costPrice": "780.00",
"stock": 12,
"sku": "KRT-EM-M",
"tags": ["new", "summer"],
"categoryIds": ["c1d2e3f4-..."],
"isActive": true,
"isFeatured": false,
"deletedAt": null,
"createdAt": "2026-05-20T08:00:00.000Z",
"updatedAt": "2026-05-26T14:30:00.000Z"
}List products
GET /api/v1/admin/productsScope: products:read
Query parameters
| Name | Type | Notes |
|---|---|---|
limit | integer (1–100) | Default 20. |
cursor | string | Opaque cursor. |
q | string | Substring match on name and SKU. |
categoryId | uuid | Filter by category. |
isActive | "true" | "false" | Filter by active status. |
Example
curl "https://api.sellvik.app/api/v1/admin/products?limit=50&isActive=true" \
-H "Authorization: Bearer <admin-key>"Create a product
POST /api/v1/admin/productsScope: products:write
Request body
{
"name": "Emerald Kurti",
"slug": "kurti-emerald",
"description": "Hand-block printed cotton kurti.",
"price": "1490.00",
"comparePrice": "1990.00",
"costPrice": "780.00",
"stock": 12,
"sku": "KRT-EM-M",
"tags": ["new", "summer"],
"categoryIds": ["c1d2e3f4-..."],
"isActive": true,
"isFeatured": false,
"features": ["100% cotton", "Block-printed"],
"specifications": { "fabric": "cotton", "fit": "regular" },
"metaTitle": "Emerald Kurti — Hand-block printed",
"metaDescription": "Lightweight cotton kurti for summer."
}| Field | Required | Notes |
|---|---|---|
name | yes | 1–200 chars. |
slug | no | Lowercase, hyphenated. Auto-generated from name if omitted. |
price | yes | Money string. See Money and numbers. |
comparePrice | no | Original / strike-through price. Money string. |
costPrice | no | For margin reports. Never returned in store API. |
stock | no | Default 0. |
categoryIds | no | Array of category UUIDs. |
isActive | no | Default true. |
Response
201 Created with the new product.
Errors
| Status | Code | When |
|---|---|---|
| 400 | invalid_body | Validation failed. |
| 409 | duplicate_slug | Slug already exists in this shop. |
Get a product
GET /api/v1/admin/products/{id}Scope: products:read
404 not_found if the product doesn't exist or belongs to another shop.
Update a product
PATCH /api/v1/admin/products/{id}Scope: products:write
Request body
Any subset of the create-time fields. Pass only what you're changing.
curl -X PATCH "https://api.sellvik.app/api/v1/admin/products/f3a7..." \
-H "Authorization: Bearer <admin-key>" \
-H "Content-Type: application/json" \
-d '{ "stock": 18 }'Response
200 with the updated product.
Soft-delete a product
DELETE /api/v1/admin/products/{id}Scope: products:write
Sets deletedAt to the current timestamp. The product disappears from the
public storefront immediately, but the row is retained for order-history
integrity (a customer's old order still references the product).
Hard-delete is not exposed via the API. If you need it for GDPR-style erasure, mail us.
Response
204 No Content.