Add products
A product on Flightdeck is the catalog entry a shopper browses; a variant is the thing they actually buy (a SKU with a price). A product with no variant has nothing to sell, so this guide creates both: a product and a sellable variant.
A product’s status is set at create time — create it active to make it
publicly visible (once the store is live), or draft to keep it hidden while you
finish stocking it.
Prerequisites
- A merchant key holding
manage:own_catalog. Your pre-live build key already has it — see Get your API keys. - Money is integer cents. A
$49.99price is4999.
The self-serve catalog write routes below (POST/PATCH under
/v1/merchant/catalog/...) are live HTTP endpoints but are not yet part of the
published OpenAPI document, so the typed SDK client does not cover them today —
use curl (or a raw fetch) for writes. The read route /v1/merchant/catalog
is in the SDK.
Create and stock
Create the product with its status
A product needs a slug (its stable public identity) and a name. status is
set here, at create time, and accepts only draft or active. Create it
draft to keep it hidden while you finish stocking it, or active to make it
publicly visible once the store is live.
curl -X POST https://api.ruo.pro/v1/merchant/catalog/products \
-H "Authorization: Bearer fdk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"slug": "bpc-157",
"name": "BPC-157",
"description": "Research peptide.",
"status": "draft"
}'A 201 returns { "product": { ... } } including the generated id. Catalog
writes take no Idempotency-Key header — retrying a create is safe because
it converges on 409 slug_exists (the slug is the public identity and must be
unique).
Add a sellable variant
Give the product a variant with a sku and a non-negative integer price_cents.
currency defaults to usd; label and weight_grams (a positive integer, for
shipping) are optional.
curl -X POST https://api.ruo.pro/v1/merchant/catalog/products/{productId}/variants \
-H "Authorization: Bearer fdk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"sku": "NOVA-BPC-5MG",
"label": "5mg vial",
"price_cents": 4999,
"currency": "USD",
"weight_grams": 40
}'A 201 returns { "variant": { ... } }. The SKU is immutable once set — pick it
deliberately. Like product creation, variant creation takes no Idempotency-Key;
a retried create converges on 409 sku_exists.
Make the product visible
If you created the product active, it is already visible in the public catalog
once the store is live — no further step is needed. If you created it draft,
there is one thing to know:
Product status is set only at create time. There is no self-serve
merchant route that transitions a product from draft to active after the
fact — the PATCH route updates content (name, description, and other
content fields) but never status. To publish a product you created as a
draft today, either recreate it with status: "active" (a fresh slug, or
remove the draft first), or ask the platform operator to change its status.
Plan to create products active when you intend them to sell.
You can PATCH name, description, and other content fields at any time. An
empty PATCH (no updatable fields) is a 400, not a silent no-op.
Verify it in the catalog
Read your tenant’s full catalog with the merchant credential (this read route is in the SDK and includes draft and archived products):
curl https://api.ruo.pro/v1/merchant/catalog \
-H "Authorization: Bearer fdk_your_key_here"Once the store is live, the same product also shows on the public,
unauthenticated catalog — which only ever returns active products for a live
store:
curl https://api.ruo.pro/v1/tenants/nova-peptide/catalog/products/bpc-157The public product carries its variants, price_cents per variant, and both
image_asset_ref (the raw stored ref) and image_url (the resolved, fetchable
URL, or null if unset — see Product images).
Subscription products
To make a product subscribe-and-save eligible, declare the schedule at create
time. is_subscription: true requires a valid subscription_interval
(day | week | month | year) and a positive
subscription_interval_count; subscription_price_cents is optional. A
half-specified schedule is refused (400) rather than persisted — the renewal
engine could not bill it. See Subscriptions.
Related
- API reference — the full product and variant field shapes.
- Variants and options — SKUs and per-variant pricing.
- Product images — attaching imagery.
- Organize with collections — grouping products.