Products
Concepts, endpoints, and media model for managing your catalog.
A product in Mobiari is a sellable thing in your store. Every product has one or more variants — even a "single" product has a hidden default variant under the hood, so pricing and stock are always carried on the variant, never on the product itself.
Mental model
product ← title, description, brand, SEO
├── variants[] ← sku, price_cents, stock, fulfillment_mode
│ ├── option_values[] ← e.g. size=M, color=blue
│ └── shipping_box ← physical box for freight calc
├── product_images[] ← gallery items (images and videos)
│ └── image_variants[] ← srcset sizes (thumbnail/small/medium/large)
├── highlight_video ← one short video → bottom-left widget on PDP
├── product_specs[] ← long-form specs (key/value, grouped)
└── reviews[]A few terms that matter:
- product_type —
"single"(one configuration) or"variable"(multiple variants with options). Drives the admin UI. - fulfillment_mode on the variant —
stocked,on_demand, orstocked_or_on_demand. Decides whether availability is computed from inventory or always treated as "in stock". - media_type on a gallery row —
"image"(default) or"video". Image rows go through the resize pipeline; video rows skip it and point straight at the URL.
Endpoints
All paths below are relative to https://api.mobiari.com/v1/stores/{store_id}.
| Method | Path | Purpose |
|---|---|---|
GET | /products | List, paginated. See Listing. |
POST | /products | Create. Returns the new id, title and slug. |
GET | /products/{id} | Single product with variants and stock. |
PUT | /products/{id} | Update. Fields you leave out are left alone. |
DELETE | /products/{id} | Hard delete. Cascades to variants and gallery. |
GET | /products/{id}/images | Full gallery with variants (sizes). |
POST | /products/{id}/images | Upload an image (multipart). |
POST | /products/{id}/images/associate | Attach an existing library file. |
POST | /products/{id}/videos | Attach a video by URL (next section). |
PATCH | /products/{id}/images/{img_id} | Reorder, set primary, swap alt text. |
DELETE | /products/{id}/images/{img_id} | Remove a gallery item. |
Create a product
curl -X POST "https://api.mobiari.com/v1/stores/$STORE_ID/products" \
-H "Authorization: Bearer $BP_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"title": "Iced Matcha",
"description": "Stone-ground ceremonial grade.",
"product_type": "single",
"default_price_cents": 1890
}'Single products get a hidden "Default" variant created in the same
transaction when you pass default_price_cents. For variable products,
omit default_price_cents and create each variant with
POST /v1/product-variants, passing product_id, sku, title and
price_cents in the body.
Send an Idempotency-Key on creates so a retried request can't create
the product twice. See Idempotency.
Attach a highlight video
A product can have one highlight video — a short clip that the storefront renders as a small floating widget at the bottom-left of the product page. Click it to expand to fullscreen with sound.
Set it on the product itself, not the gallery:
curl -X PUT "https://api.mobiari.com/v1/stores/$STORE_ID/products/$PRODUCT_ID" \
-H "Authorization: Bearer $BP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"highlight_video_url": "https://youtu.be/abc123",
"highlight_video_poster_url": "https://files.example.com/poster.jpg"
}'The provider (youtube, vimeo, upload, external) is auto-detected
from the URL — you can override by setting highlight_video_provider
explicitly.
Add a gallery video
Gallery videos sit next to gallery images and are useful for product tours, "how it's made", or fit/sizing demos. Unlike the highlight video, they're click-to-play inside the gallery instead of an autoplay widget.
curl -X POST "https://api.mobiari.com/v1/stores/$STORE_ID/products/$PRODUCT_ID/videos" \
-H "Authorization: Bearer $BP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://files.example.com/video.mp4",
"poster_url": "https://files.example.com/poster.jpg",
"position": 2
}'If you set product_variant_id on the request, the video only appears
when that variant is selected on the product page — same rule as
variant-scoped images.
Listing
Products are sorted by priority (ascending), then most recently updated
first. Filters:
| Query parameter | Meaning |
|---|---|
search | Case-insensitive substring of the title or sku_prefix. |
status | Only products in this status. |
include_drafts | Drafts are hidden unless true (or unless you filter by status). |
limit, offset | Paging. limit is 1 to 200, default 50. |
curl "https://api.mobiari.com/v1/stores/$STORE_ID/products?search=matcha" \
-H "Authorization: Bearer $BP_TOKEN"Moving to the Page envelope
The products list is being moved to the standard
Page response (data, has_more,
next_cursor) with cursor paging. Until Products appears in the
API reference, it answers
{"products": [...], "total": ..., "page": ...}.
Permission cheatsheet
| Action | Permission |
|---|---|
| List, get | products.read |
| Create | products.write |
| Update, attach media | products.edit |
| Delete | products.delete |
| Publish (status → live) | products.publish |