Look up products and prices
AI agents: read /llms.txt; add .md to any page URL. This page as Markdown: /guides/products-and-catalog.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.
Read first: Products and pricing, for the kinds of product and how pricing works.
YoPrint has two sources of products:
- Your own products, which your team creates: a simple product (one item) or a variant product (one item in several sizes or colors, each a variant).
- The supplier catalog: blanks from suppliers your team has connected, such as a t-shirt style in every size and color. YoPrint reads their prices and stock from the supplier.
Both can go on a quote or sales order. See Add line items.
Your own products
Section titled “Your own products”1. List them
Section titled “1. List them”/v1/api/store/{team_slug}/product
Without status, the list has every product that isn’t deleted. Add ?status=on_sale, ?status=phased_out or ?status=deleted to narrow it.
2. Create a simple product
Section titled “2. Create a simple product”/v1/api/store/{team_slug}/product
{ "type": "simple", "title": "Embroidered cap", "brand": "Northwind", "taxable": true, "default_price": 15000}typeissimpleorvariant, andtitleis required.- A simple product needs
default_price. Send a whole number of thousandths:15000is 15.00.
3. Create a variant product
Section titled “3. Create a variant product”Send "type": "variant", with the variants in product. Then manage variants one at a time:
/v1/api/store/{team_slug}/product/{hash_id}/variant
POST Add a variant to a product /v1/api/store/{team_slug}/product/{hash_id}/variant
PUT Update a variant /v1/api/store/{team_slug}/product/{hash_id}/variant/{id}
Every size and brand name YoPrint knows, for autocomplete: your own products, and every supplier catalog YoPrint carries, not just the ones your team connected:
GET List all size names/v1/api/store/{team_slug}/get_all_product_sizes
GET List all product brands /v1/api/store/{team_slug}/get_all_product_brands
4. Stop selling a product
Section titled “4. Stop selling a product”Phasing out a product stops it being added to new quote and order lines. Lines that already use it keep working. Put it back on sale with resume.
POST Phase out a simple product/v1/api/store/{team_slug}/product/{hash_id}/phase_out
POST Put a phased-out simple product back on sale /v1/api/store/{team_slug}/product/{hash_id}/resume
Variants can be phased out and resumed the same way:
POST Phase out variants (stop selling them)/v1/api/store/{team_slug}/product/{hash_id}/variant/phase_out
Before deleting a product, ask YoPrint what deleting it would affect:
POST Check whether a product can be deleted/v1/api/store/{team_slug}/product/{hash_id}/delete_check
DELETE Delete a product /v1/api/store/{team_slug}/product/{hash_id}
5. Stock
Section titled “5. Stock”To read the stock of several products at once, optionally for one warehouse:
POST Get stock levels for products/v1/api/store/{team_slug}/product_stock
{ "warehouse_id": "3vnVzNSvE6xL6k", "product": [ { "type": "db_simple", "id": "5MnM49NNFDgB9A" }, { "type": "db_variant", "id": "GirpQnLewN2TLg" } ]}Note the type names here: db_simple for a simple product, db_variant for a variant. The stock levels in the answer are decimal strings with 8 decimal places, such as "24.00000000". Parse them as decimals. See Money and quantities.
The supplier catalog
Section titled “The supplier catalog”Catalog products have ids that start with the supplier’s code and a hyphen, such as smr-10001. Each id is one size and color of a style.
Every size and color of a style
Section titled “Every size and color of a style”Send one catalog product id of the style (db_catalog), or the style’s id (db_catalog_style). The answer is the whole style: each row of attr_data is one size and color, with its catalog product id, size_label, color_label and supplier code provider. It reads YoPrint’s copy of the catalog and doesn’t call the supplier.
/v1/api/store/{team_slug}/hydrate_product
{ "type": "db_catalog", "id": "smr-10001" }Live price and stock
Section titled “Live price and stock”Ask the supplier for current prices, stock, or both, for up to 100 catalog products at once:
POST Get live supplier pricing for catalog products/v1/api/store/{team_slug}/real_time_data_fetcher/pricing
POST Get live supplier inventory for catalog products /v1/api/store/{team_slug}/real_time_data_fetcher/inventory
POST Get live supplier pricing and inventory together /v1/api/store/{team_slug}/real_time_data_fetcher/pricing_with_inventory
{ "product": [ { "type": "db_catalog", "id": "smr-10001" }, { "type": "db_catalog", "id": "smr-10002" } ]}These calls reach the supplier, so they can be slower than other reads, and the answer depends on the supplier’s own service. Live prices come back as decimal pairs ({ "value": 425, "dp": 2 } is 4.25, so read dp every time). Inventory total_count and warehouse count are integers.
Product pictures from the supplier:
POST Get supplier images for catalog products/v1/api/store/{team_slug}/real_time_data_fetcher/images
Decoration services
Section titled “Decoration services”No public operation lists or changes decoration services. To use one on a job, take its id from a job that already has it, or set services up in the web app. Their price tables can be imported from a CSV file: see Export and import data. AI apps can list and change services: see What they can and can’t do.
Pitfalls
Section titled “Pitfalls”default_priceis in thousandths. Send a whole number of thousandths (15000is 15.00). Line item prices, by contrast, are{ value, dp }pairs. See Money and quantities.- Phase out instead of delete. Phasing out is reversible, and deleting can be refused while a product is in use. Run the delete check first.
- Phased-out products are refused on new lines, with
422. Existing lines keep working, but a draft holding one can’t be published until the line is changed (validation.unsellable_items). - One catalog id is one size and color. A style in four sizes is four ids.
- Live lookups depend on the supplier. Cache prices for a short time rather than calling for every page view.
