Products
Create, read, list, update and archive products from your server.
Create the products you sell from code, and get back each product's public page. Every endpoint here takes an API token, and also works for the dashboard. Products you create from the API show up in Store → Products like any other.
With the SDK: jami.products.create, .get, .list, .update and
.archive.
The product object
Every response returns the product, its price and its public url:
{
"product": {
"_id": "6710c2e8b1a2f0012ab34c01",
"checkoutToken": "p_x7Kf3mQz9aBc",
"title": "Ge’ez Calligraphy Course",
"description": "Six live classes, Saturdays in Bole.",
"pricingModel": "fixed",
"productType": "one_time",
"status": "published",
"media": [],
"metadata": { "sku": "CAL-06" },
"createdAt": "2026-10-16T09:00:00.000Z",
"updatedAt": "2026-10-16T09:00:00.000Z"
},
"price": { "type": "fixed", "amount": 250000, "currency": "ETB" },
"url": "https://jami.bio/jamidev/p_x7Kf3mQz9aBc"
}Prop
Type
Create a product
POST /api/jamidev/productscurl https://jami.bio/api/jamidev/products \
-H "Authorization: Bearer $JAMI_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Ge’ez Calligraphy Course",
"pricingModel": "fixed",
"price": { "amount": 250000 },
"status": "published"
}'Prop
Type
Returns 201 with the product object. Only one-time products are available; productType
other than one_time returns 400.
Get a product
GET /api/jamidev/products/{id}{id} is the product id or its p_… token. Returns the product object, or 404 if it
isn't in your organization.
List products
GET /api/jamidev/products?page=1&limit=20&status=publishedNewest first. limit is 1 to 100 (default 20); status filters by draft, published or
archived. Each item is the product with price and url inlined:
{ "items": [{ "_id": "…", "checkoutToken": "p_…", "title": "…", "price": { … }, "url": "https://jami.bio/jamidev/p_…" }], "total": 1, "page": 1, "limit": 20 }Update a product
PATCH /api/jamidev/products/{id}Send only what changes: title, description, media, metadata, status (draft,
published or archived), and price. In price, change amount on a fixed product, or
minimumAmount and defaultAmount on a flexible one.
curl -X PATCH https://jami.bio/api/jamidev/products/p_x7Kf3mQz9aBc \
-H "Authorization: Bearer $JAMI_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "price": { "amount": 300000 } }'Checkouts already open keep the price they started with; new ones use the new price.
Archive a product
DELETE /api/jamidev/products/{id}Sets status to archived. It stops selling, and its page shows "not available". Orders
and sessions keep pointing at it. Returns { product, url }.
Errors
| Status | When |
|---|---|
400 | Missing or too-long title (over 120), description over 5,000, an unknown pricingModel, a missing price.amount (fixed) or price.minimumAmount (pwyw), defaultAmount below the minimum, a non-ETB currency, or a bad status |
401 | Bad token |
403 | No token and no dashboard session |
404 | Not found in your organization |
422 | Changing a locked field: pricingModel, productType, billingInterval, intervalCount, price.type, or price.amount on a non-fixed product |
Next
- Charge for it from your server: Checkout, with
productIdset to thep_…token. - Benefits and checkout fields are still set in the dashboard: Products & Benefits.
