Create a product
AI agents: read /llms.txt; add .md to any page URL. This page as Markdown: /reference/products/v1-products-store.md. Index of every page and the rules for every call: /llms.txt. Guides and concepts in one file: /llms-full.txt. OpenAPI: /openapi.json.
POST/
Creates one of your own products and returns it.
- A simple product (
type: simple) is one item with one price: a mug, a setup fee you sell as a product. On sales order lines it is auser_simpleline. - A variant product (
type: variant) comes in sizes, colors or both (variant_type). Send the option lists (size_data,color_data) and one entry inproductfor each size and color combination you sell. Each combination becomes a variant with its own price; on sales order lines it is adb_variantline that names the variant id.
Creating a product creates no stock. Amounts here use thousandths, an older encoding: 12500 is 12.50. Usually a whole number; an amount finer than a thousandth comes back as a number with a fraction (1234.5 is 1.2345), or as a string ("1234.5") when you send X-Yoprint-Decimal-Format: exact-v1. See Money and quantities.
Business rules
- Send prices as a whole number of thousandths:
12500is 12.50. - A variant product needs
variant_typeand at least one entry inproduct; each entry needsdefault_price, plussize_idandsize_labelfor sizes andcolor_id,color_labelandcolor_hexfor colors. - On create, the entries in
productare not checked against each other or againstsize_dataandcolor_data: send each combination once, with the ids and names your lists use. Adding variants later (Add a variant) does check both. - Titles need not be unique.
dimension_x,dimension_yanddimension_zare saved but not returned by this answer or the products list.
Path parameters
Your team slug, shown as Team ID next to your API key in Profile.
- Example
your-team
- Example
Request body
application/json, required.
What kind of product?
Send one of these 2 bodies. Picked by type.
simple- Simple product
variant- Variant product
Simple product
One item with one price.
- Always
"simple"
- Always
Required. Send a whole number of thousandths:
12500is 12.50.Required on create. The product name shown on orders.
barcodestringThe product's barcode. Saved as sent.
brandstringThe product's brand.
descriptionstringA description of the product.
dimension_xnumberdimension_ynumberdimension_znumberprice_datamap of objectsPrices for pricing groups, keyed by pricing group id:
{"<pricing group id>": {"price": 11000}}. A line priced with that group uses this price instead ofdefault_price. Send a whole number of thousandths:11000is 11.00.Fields of each item (1)
Send a whole number of thousandths:
11000is 11.00.
supplier_idstringThe supplier's code for the product.
taxablebooleanWhether sales tax applies to it.
vendor_idstringThe vendor you buy it from.
weightnumberThe product's weight. Simple products only.
Example request
curl -X POST 'https://secure.yoprint.com/v1/api/store/your-team/product' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Accept: application/json' \ -H 'X-Yoprint-Decimal-Format: exact-v1' \ -H 'Content-Type: application/json' \ -d '{ "brand": "Northwind", "default_price": 12500, "supplier_id": "MUG-11", "taxable": true, "title": "Enamel mug", "type": "simple" }'Variant product
Sizes, colors or both, one variant per combination.
- Always
"variant"
- Always
One entry per size and color combination you sell.
- At least 1 item
Fields of each item (13)
Required. This variant's selling price. Send a whole number of thousandths:
9000is 9.00.barcodestringSaved as sent; not checked.
color_hexstringFor products with colors, such as
#1F2937.color_idstringFor products with colors: your id for the color. The rule depends on the case:
- When creating a product: use an id from
color_data. - When adding a variant to a color-only product: send a new id to add a color. Reusing an existing id is a duplicate (422).
- When adding a variant to a size-and-color product: reuse an id from
color_datato add a new size in an existing color, or send a new id to add a color.
- When creating a product: use an id from
color_labelstringFor products with colors. For a color the product already has, its current name is kept.
enablebooleanSaved as sent (default true); returned as
enable. Nothing enforces it: phase a variant out to stop selling it.price_datamap of objectsPrices for pricing groups, keyed by pricing group id:
{"<pricing group id>": {"price": 11000}}. A line priced with that group uses this price instead ofdefault_price. Send a whole number of thousandths:11000is 11.00.Fields of each item (1)
Send a whole number of thousandths:
11000is 11.00.
size_idstringFor products with sizes: your id for the size. The rule depends on the case:
- When creating a product: use an id from
size_data. - When adding a variant to a size-only product: send a new id to add a size. Reusing an existing id is a duplicate (422).
- When adding a variant to a size-and-color product: reuse an id from
size_datato add a new color for an existing size, or send a new id to add a size.
- When creating a product: use an id from
size_labelstringFor products with sizes. For a size the product already has, its current name is kept.
supplier_idstringThe supplier's code for this variant.
track_inventorybooleanSaved as sent (default true); not checked.
vendor_idstringweightnumberThe variant's weight.
Required on create. The product name shown on orders.
Which options the product has.
- One of:
"size","color","size_color"
- One of:
barcodestringThe product's barcode. Saved as sent.
brandstringThe product's brand.
color_dataarray of objectsRequired for
colorandsize_color: the colors.descriptionstringA description of the product.
dimension_xnumberdimension_ynumberdimension_znumbersize_dataarray of objectsRequired for
sizeandsize_color: the sizes, in display order.supplier_idstringThe supplier's code for the product.
taxablebooleanWhether sales tax applies to it.
vendor_idstringThe vendor you buy it from.
weightnumberThe product's weight. Simple products only.
Example request
curl -X POST 'https://secure.yoprint.com/v1/api/store/your-team/product' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Accept: application/json' \ -H 'X-Yoprint-Decimal-Format: exact-v1' \ -H 'Content-Type: application/json' \ -d '{ "brand": "Northwind", "color_data": [ { "hex": "#000000", "id": "black", "label": "Black" } ], "product": [ { "color_hex": "#000000", "color_id": "black", "color_label": "Black", "default_price": 9000, "size_id": "S", "size_label": "S" }, { "color_hex": "#000000", "color_id": "black", "color_label": "Black", "default_price": 9000, "size_id": "M", "size_label": "M" } ], "size_data": [ { "id": "S", "label": "S" }, { "id": "M", "label": "M" } ], "title": "Classic Tee", "type": "variant", "variant_type": "size_color" }'Response
200Successful response.
One of, picked by
type:Simple product
simple- Always
"simple"
- Always
The selling price. Null when not set. Thousandths, an older encoding:
12500is 12.50. Usually a whole number; an amount finer than a thousandth comes back as a number with a fraction (1234.5is 1.2345), or as a string ("1234.5") when you sendX-Yoprint-Decimal-Format: exact-v1. See Money and quantities.barcodestring | nullbrandstring | nullcolor_dataarray of anydeleted_atstring (date-time) | nulldeleted_byobject | nullWho did it, as
{id, name}; null when on sale or nobody was recorded.descriptionstring | nullenablebooleanphased_out_atstring (date-time) | nullphased_out_byobject | nullWho did it, as
{id, name}; null when on sale or nobody was recorded.price_dataobject | arrayPrices for pricing groups, as saved: keyed by the pricing group's internal number (not its hash id), each
{"price": <thousandths>}. An empty list[]when there are none.size_dataarray of anysupplier_idstring | nulltaxablebooleantrack_inventorybooleanvariant_countnullvendor_idstring | nullweightnumber | string | null
Variant product
variant- Always
"variant"
- Always
- One of:
"size","color","size_color"
- One of:
brandstring | nulldefault_priceinteger | number | string | nullNot used for variant products: each variant has its own. Null when not set. Thousandths, an older encoding:
12500is 12.50. Usually a whole number; an amount finer than a thousandth comes back as a number with a fraction (1234.5is 1.2345), or as a string ("1234.5") when you sendX-Yoprint-Decimal-Format: exact-v1. See Money and quantities.descriptionstring | nullenablebooleansupplier_idstring | nulltaxablebooleanvendor_idstring | null
Errors
401The API key is missing or wrong (
unauthenticated).403You are not allowed to do this.
api_access_not_in_plan: your team's plan doesn't include API access (Pro and above, with an active subscription or trial), so every request answers this until the team upgrades. When your role lacks the permission the operation needs, the body is only{"message": "Insufficient Permission"}. Other refusals use the error envelope, withunauthorizedoruser_is_not_authorized.- When
- Your role cannot create products. This 403 has a short body,
{"message": "Insufficient Permission"}, with nosuccessorerror. - Fix
- Ask a team owner to set Manage Products to "Users CAN view, update and create products".
404Not found.
page_not_found: the team slug is unknown, you are not a member of the team, or an id in the path is not one of this team's.code: null, with a message that starts "No query results for": there is no record with that id.422The request was refused and changed nothing.
validation_failedlists what to fix inerror.fields; other codes name a business rule, explained inerror.message. A few checks answer with only{"message": "..."}. An operation that calls another service (a payment provider, a carrier, an accounting app) can answerconnect_timeout("Please retry again") when that service does not answer in time: the change may or may not have happened there, so read the record back before you retry.- When
typeortitleis missing, a simple product has nodefault_price, a variant product is missingvariant_type, its option lists orproduct, or a price is not a number.error.codeisvalidation_failed.- Fix
- Fix each field named in
error.fields; its keys are field paths such ascontact.0.phone.
500A business rule refused the request (see the operation's errors), or something failed inside YoPrint. Refusals use the error envelope with a code such as
action_not_allowed; an unexpected failure answers{"message": "Server Error"}. Repeating a refusal gets the same answer; after an unexpected failure, read the record back before you retry a change.- When
- A price is not a whole number of thousandths, such as
12.5. - Fix
- Send whole numbers:
12500for 12.50.
Related
- POSTAdd a variant to a product
/v1/ api/ store/ {team_slug}/ product/ {hash_id}/ variant - PATCHUpdate a product (PATCH)
/v1/ api/ store/ {team_slug}/ product/ {hash_id} - POSTAdd a line item to a sales order or quote
/v2/ api/ store/ {team_slug}/ v2/ sales_order/ {order_unique_key}/ order_item
