Use the Selldoes API to programmatically manage your products and categories. All endpoints require authentication via your session cookie.
Manage your product catalog
/api/products?storeId={storeId} Auth requiredRetrieve all products for a store, or a single product by ID.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
storeId | number | Yes | ΓÇö | Store ID to list products for |
id | number | No | ΓÇö | Product ID ΓÇö if provided, returns a single product |
curlcurl http://localhost:9582/api/products?storeId=1
/api/products?id={id} Auth requiredRetrieve a single product by its ID.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
id | number | Yes | ΓÇö | Product ID |
curl http://localhost:9582/api/products?id=42
/api/products Auth requiredCreate a new product. If a product with the same SKU exists, it will be updated instead (upsert).
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | Yes | ΓÇö | Product name |
sku | string | Yes | ΓÇö | Unique SKU identifier (used for upsert) |
storeId | number | No | 1 | Store ID |
price | string | No | 0 | Product price |
description | string | No | ΓÇö | Product description |
category | string | No | "" | Category name |
categoryId | number | No | ΓÇö | Category ID from store_categories |
stock | number | No | 0 | Stock quantity |
status | string | No | "active" | Product status (active, draft, archived) |
image | string | No | ΓÇö | Main product image URL |
mainImage | string | No | ΓÇö | Additional main image URL |
bulletpoints | string | No | ΓÇö | Bullet points (JSON array string) |
productNotes | string | No | ΓÇö | Internal product notes |
subCategory | string | No | ΓÇö | Subcategory name |
screenshots | string | No | ΓÇö | Screenshots (JSON array string) |
videoURL | string | No | ΓÇö | Product video URL |
downloadLink | string | No | ΓÇö | Digital download link |
deliveryInstructions | string | No | ΓÇö | Delivery instructions |
variationGroups | string | No | ΓÇö | Variation groups (JSON string) |
customAttributes | string | No | ΓÇö | Custom attributes (JSON string) |
isDigital | boolean | No | false | Whether this is a digital product |
hidden | boolean | No | false | Hide from storefront |
curl -X POST http://localhost:9582/api/products \
-H "Content-Type: application/json" \
-d '{
"storeId": 1,
"name": "Wireless Headphones",
"sku": "WH-001",
"price": "79.99",
"description": "Premium wireless headphones with noise cancellation",
"category": "Electronics",
"categoryId": 3,
"stock": 150,
"status": "active",
"image": "https://example.com/headphones.jpg",
"isDigital": false
}'/api/products?action=delete Auth requiredDelete a single product by ID.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
id | number | Yes | ΓÇö | Product ID to delete |
curl -X POST "http://localhost:9582/api/products?action=delete" \
-H "Content-Type: application/json" \
-d '{"id": 42}'/api/products?action=bulk-status Auth requiredUpdate status for multiple products at once.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
ids | number[] | Yes | ΓÇö | Array of product IDs |
status | string | Yes | ΓÇö | New status (active, draft, archived) |
curl -X POST "http://localhost:9582/api/products?action=bulk-status" \
-H "Content-Type: application/json" \
-d '{"ids": [42, 43, 44], "status": "archived"}'/api/products?action=bulk-delete Auth requiredDelete multiple products at once.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
ids | number[] | Yes | ΓÇö | Array of product IDs to delete |
curl -X POST "http://localhost:9582/api/products?action=bulk-delete" \
-H "Content-Type: application/json" \
-d '{"ids": [42, 43, 44]}'Organize products with categories and subcategories
/api/categories?storeId={storeId} Auth requiredRetrieve all categories for a store, ordered by sort order.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
storeId | number | Yes | ΓÇö | Store ID |
curl http://localhost:9582/api/categories?storeId=1
/api/categories Auth requiredCreate a new category.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
storeId | number | Yes | ΓÇö | Store ID |
name | string | Yes | ΓÇö | Category name |
slug | string | Yes | ΓÇö | URL-friendly slug |
description | string | No | ΓÇö | Category description |
image | string | No | ΓÇö | Category image URL |
icon | string | No | ΓÇö | Icon name (e.g. Star) |
sortOrder | number | No | 0 | Display order |
parentId | number | No | ΓÇö | Parent category ID for subcategories |
curl -X POST http://localhost:9582/api/categories \
-H "Content-Type: application/json" \
-d '{
"storeId": 1,
"name": "Electronics",
"slug": "electronics",
"description": "All electronic products",
"sortOrder": 10
}'/api/categories/{id} Auth requiredUpdate an existing category's fields.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
storeId | number | Yes | ΓÇö | Store ID |
name | string | No | ΓÇö | New name |
slug | string | No | ΓÇö | New slug |
description | string | No | ΓÇö | New description |
image | string | No | ΓÇö | New image URL |
icon | string | No | ΓÇö | Icon name (e.g. Star) |
sortOrder | number | No | ΓÇö | New sort order |
visible | boolean | No | ΓÇö | Visibility toggle |
parentId | number | No | ΓÇö | New parent category ID |
curl -X PATCH "http://localhost:9582/api/categories/5" \
-H "Content-Type: application/json" \
-d '{
"storeId": 1,
"name": "Electronics & Gadgets",
"sortOrder": 5
}'/api/categories/{id}?storeId={storeId} Auth requiredDelete a category by ID.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
storeId | number | Yes | ΓÇö | Store ID (query param) |
curl -X DELETE "http://localhost:9582/api/categories/5?storeId=1"
/api/categories/reorder Auth requiredReorder categories by batch-updating sort orders.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
storeId | number | Yes | ΓÇö | Store ID |
items | array | Yes | ΓÇö | Array of {id, sortOrder} objects |
curl -X POST "http://localhost:9582/api/categories/reorder" \
-H "Content-Type: application/json" \
-d '{
"storeId": 1,
"items": [
{"id": 1, "sortOrder": 0},
{"id": 2, "sortOrder": 10},
{"id": 3, "sortOrder": 20}
]
}'/api/categories/bulk-delete Auth requiredDelete multiple categories at once.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
storeId | number | Yes | ΓÇö | Store ID |
ids | array | Yes | ΓÇö | Array of category IDs to delete |
curl -X POST "http://localhost:9582/api/categories/bulk-delete" \
-H "Content-Type: application/json" \
-d '{"storeId": 1, "ids": [5, 6, 7]}'/api/categories/product-counts?storeId={storeId} Auth requiredNumber of products linked to each category.
curl "http://localhost:9582/api/categories/product-counts?storeId=1"
Programmatic product import via API key
/api/external/productsCreate or update a product (upsert by SKU). Authenticated via x-api-key header — generate a key in Dashboard → Settings → API Keys.
Authentication: x-api-key: sk_...
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | Yes | ΓÇö | Product name |
sku | string | Yes | ΓÇö | Unique SKU (used for upsert) |
price | string | No | "0.00" | Product price |
description | string | No | ΓÇö | Product description |
image | string | No | ΓÇö | Main image URL |
category | string | No | ΓÇö | Category name (auto-created if new) |
status | "draft" | "active" | No | "active" | Product status on creation/update |
attributes | object | No | ΓÇö | Key-value attributes, e.g. {"sampleLink":"...","volumes":"..."} |
curl -X POST "http://localhost:9582/api/external/products" \
-H "Content-Type: application/json" \
-H "x-api-key: sk_abc123..." \
-d '{
"name": "The Jack Benny Program Vol 1",
"sku": "OTR-12345",
"price": "9.99",
"description": "Classic radio comedy episodes...",
"category": "Comedy",
"attributes": {
"sampleLink": "https://example.com/audio.mp3",
"totalPlaytime": "6 hours 30 min"
}
}'/api/external/productsCheck whether a SKU exists (or list every SKU). Pass full=1 to get the full product row back.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
sku | string | No | ΓÇö | SKU to look up |
full | "1" | No | ΓÇö | Return the product row (id, name, price, status, categories, attributes, variants) next to exists |
list | "all" | No | ΓÇö | Return every SKU in the store as { skus: [...] } |
storeId | number | No | ΓÇö | Target store (defaults to the key owner's first store) |
curl "http://localhost:9582/api/external/products?sku=OTR-12345&full=1" \ -H "x-api-key: sk_abc123..."
/api/external/ai/promptsList the store's saved AI prompts (Dashboard → AI Prompts) plus the system defaults — lets plugins and API clients offer prompt pickers instead of hard-coded prompt ids.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
type | "text" | "image" | No | ΓÇö | Filter by prompt type (omit for all) |
storeId | number | No | ΓÇö | Target store (defaults to the key owner's first store) |
Response: { prompts: [{ id, name, description, type, field, template, provider, model, isDefault, aspectRatio }] }
curl "http://localhost:9582/api/external/ai/prompts?type=image" \ -H "x-api-key: sk_abc123..."
Standard HTTP status codes used by the API
| Code | Description |
|---|---|
200 | Success ΓÇö request completed |
201 | Created ΓÇö resource was created |
400 | Bad Request ΓÇö missing or invalid parameters |
401 | Unauthorized ΓÇö authentication required |
404 | Not Found ΓÇö resource does not exist |
500 | Internal Server Error |