{"openapi":"3.1.0","info":{"title":"3D Print House quote API for AI agents","version":"1","description":"Instant price and delivery date for FDM 3D printing of your model, 1 to 5000 pieces, shipped in the EU. Print quotes only: a print order is always placed by a person through order_url. Get a key with POST /agent/keys and send it as a Bearer token. The shop part (/shop/prices, /shop/quote, /shop/orders, /shop/request) needs no key: fixed prices of ready-made organizers, cart total, orders and company requests for larger orders. Catalogue: https://3dprinthouse.eu/obchod.json and https://3dprinthouse.eu/obchod.md."},"servers":[{"url":"https://api.3dprinthouse.eu"}],"components":{"securitySchemes":{"key":{"type":"http","scheme":"bearer"}},"schemas":{"ShopCart":{"type":"object","required":["items"],"properties":{"items":{"type":"array","minItems":1,"maxItems":20,"description":"Duplicate key and colour lines are merged","items":{"type":"object","required":["key","qty"],"properties":{"key":{"type":"string","description":"Key from GET /shop/prices (product or set), e.g. m2-extender, servisny-stol"},"qty":{"type":"integer","minimum":1,"maximum":500,"description":"Packs. Price per pack falls at 10, 50 and 100 packs of the same item (see tiers in GET /shop/prices)"},"custom_text":{"type":"string","maxLength":12,"default":"","description":"Optional text printed on the item. Only for keys listed in GET /shop/prices custom_text.keys, only when the cart has at least custom_text.from_qty packs of that item. Letters, digits, space and hyphen. One fixed setup surcharge per line with text (custom_text.setup_gross incl. VAT); it does not count towards free delivery."},"color":{"type":"string","default":"black","enum":["black","white","grey","yellow","red","blue"],"description":"Price does not depend on colour; a set has one colour"}}}},"country":{"type":"string","default":"SK","maxLength":2},"lang":{"type":"string","default":"sk","enum":["sk","cs","hu","pl","de","en"],"description":"Language of line names"}}}}},"paths":{"/agent/keys":{"post":{"summary":"Send an API key to an e-mail address (one per address per day)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"}}}}}},"responses":{"200":{"description":"Key sent if the address is valid"}}}},"/options":{"get":{"summary":"Materials, qualities, infills, countries, max quantity, minimum order","responses":{"200":{"description":"Options"}}}},"/agent/quotes":{"post":{"summary":"Upload a model and get a quote. Status queued or running means poll GET /agent/quotes/{id} after retry_after_s.","security":[{"key":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"STL, 3MF, OBJ or STEP, up to 50 MB"},"material":{"type":"string","default":"PLA","enum":["PLA","PETG","ASA","ABS","PETG-CF","PLA-CF"]},"quality":{"type":"string","default":"standard","enum":["standard","detail"]},"infill":{"type":"string","default":"standard","enum":["light","standard","strong"]},"quantity":{"type":"integer","default":1,"minimum":1,"maximum":5000},"country":{"type":"string","default":"SK","description":"EU delivery country, ISO 3166-1 alpha-2"},"lang":{"type":"string","default":"en","enum":["sk","cs","hu","pl","de","en"],"description":"Language of order_url"},"scale":{"type":"number","default":100,"description":"Scale in percent"}}}}}},"responses":{"200":{"description":"Quote or its status"},"401":{"description":"Missing key"},"429":{"description":"Daily limit of new models"}}}},"/agent/quotes/{id}":{"get":{"summary":"Quote status, or the same model priced for another quantity or country without re-slicing","security":[{"key":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"quantity","in":"query","schema":{"type":"integer","default":1}},{"name":"country","in":"query","schema":{"type":"string","default":"SK"}},{"name":"lang","in":"query","schema":{"type":"string","default":"en"}}],"responses":{"200":{"description":"Quote: price, delivery, grams_per_piece, warnings, better_quantity, order_url"}}}},"/shop/prices":{"get":{"summary":"Fixed prices of the shop (ready-made organizers and sets) for a delivery country. Amounts are EUR including 23 % VAT.","parameters":[{"name":"country","in":"query","schema":{"type":"string","default":"SK","maxLength":2},"description":"ISO 3166-1 alpha-2, case insensitive. Unsupported country: 400."}],"responses":{"200":{"description":"Delivery price and free-delivery threshold of the zone, price of every item and set","content":{"application/json":{"schema":{"type":"object","properties":{"country":{"type":"string"},"delivery":{"type":"number","description":"Delivery price once per order, EUR incl. VAT"},"free_from":{"type":["number","null"],"description":"Goods total from which delivery is free; null when the zone has no free delivery"},"custom_text":{"type":"object","description":"Rules for optional custom text on labels and tags","properties":{"keys":{"type":"array","items":{"type":"string"}},"from_qty":{"type":"integer","description":"Minimum packs of the same item"},"max_chars":{"type":"integer"},"setup_net":{"type":"number","description":"One-off surcharge per line with text, EUR excl. VAT"},"setup_gross":{"type":"number","description":"The same incl. VAT"}}},"items":{"type":"object","additionalProperties":{"type":"object","properties":{"base":{"type":"number"},"tiers":{"type":"object","description":"From N packs of the item: price per pack incl. VAT","additionalProperties":{"type":"number"}}}}},"sets":{"type":"object","additionalProperties":{"type":"object","properties":{"base":{"type":"number"},"contents":{"type":"array","items":{"type":"string"}}}}}}}}}},"400":{"description":"Country not served"},"429":{"description":"Rate limit: 300 requests per hour per IP on prices and quote"}}}},"/shop/quote":{"post":{"summary":"Price a cart: lines, goods total, delivery (once per order, free above the zone threshold), total with and without VAT. Prices in the request are never read.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShopCart"}}}},"responses":{"200":{"description":"Priced cart","content":{"application/json":{"schema":{"type":"object","properties":{"lines":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"color":{"type":"string"},"name":{"type":"string"},"qty":{"type":"integer"},"unit":{"type":"number"},"total":{"type":"number"},"tier":{"type":"integer"},"custom_text":{"type":"string"},"setup":{"type":"number","description":"Setup surcharge of a line with custom text, incl. VAT"}}}},"setup_gross":{"type":"number","description":"Present only when the cart has custom text: sum of setup surcharges incl. VAT, included in total_gross"},"goods_gross":{"type":"number"},"delivery":{"type":"number","description":"0 when free"},"free_from":{"type":["number","null"]},"missing_to_free":{"type":"number","description":"How much more goods are needed for free delivery"},"total_gross":{"type":"number"},"total_net":{"type":"number"},"vat":{"type":"number"},"reverse_charge":{"type":"boolean","description":"Always false in a quote; decided when ordering"}}}}}},"400":{"description":"Short sentence in detail: invalid field, unknown item, more than 500 packs of one item, custom text not allowed for the item or below the minimum packs"},"429":{"description":"Rate limit"}}}},"/shop/request":{"post":{"summary":"Company request for a quote on a larger order (tens to hundreds of packs) or on custom text or a logo. Stores the request and notifies the shop, who reply by e-mail with price and delivery date. Place it only for the customer, with the customer's own details. Not an order and not a price.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["company","email","quantity"],"properties":{"kind":{"type":"string","enum":["b2b"],"default":"b2b"},"company":{"type":"string","minLength":2,"maxLength":200},"email":{"type":"string","format":"email","maxLength":200},"product":{"type":"string","maxLength":80,"description":"Key from GET /shop/prices, or other, or custom-part"},"quantity":{"type":"integer","minimum":1,"maximum":100000,"description":"Packs or pieces"},"custom":{"type":"boolean","default":false,"description":"True when company text or a logo is needed"},"message":{"type":"string","maxLength":1000},"lang":{"type":"string","default":"sk","enum":["sk","cs","hu","pl","de","en"]},"website":{"type":"string","description":"Honeypot, leave empty"}}}}}},"responses":{"200":{"description":"Stored","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"id":{"type":["string","null"],"description":"Request number, for example B-00012"}}}}}},"400":{"description":"Validation error as a short sentence"},"429":{"description":"More than 5 requests per hour from one IP"}}}},"/shop/orders":{"post":{"summary":"Place an order for a cart. Place it only when the customer explicitly asks, with the customer's own contact details. The server recomputes the price; payment is by bank transfer.","requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ShopCart"},{"type":"object","required":["contact"],"properties":{"note":{"type":"string","maxLength":1000},"contact":{"type":"object","required":["email","street","zip","city","phone"],"properties":{"kind":{"type":"string","enum":["firm","person"],"default":"firm"},"email":{"type":"string","format":"email","maxLength":200},"company":{"type":"string","maxLength":200},"ico":{"type":"string","maxLength":30},"vat":{"type":"string","maxLength":20,"description":"EU VAT ID; a valid one from another country than SK means no VAT is charged"},"name":{"type":"string","maxLength":200},"street":{"type":"string","minLength":2,"maxLength":200},"zip":{"type":"string","minLength":3,"maxLength":12},"city":{"type":"string","minLength":2,"maxLength":100},"phone":{"type":"string","minLength":6,"maxLength":30}}}}}]}}}},"responses":{"200":{"description":"Order created; the customer also gets an e-mail with the proforma invoice and payment QR","content":{"application/json":{"schema":{"type":"object","properties":{"number":{"type":"string"},"deadline_check":{"type":"boolean"},"total":{"type":"number","description":"What the customer pays (net when reverse_charge)"},"reverse_charge":{"type":"boolean"},"status_token":{"type":"string"},"qr_kind":{"type":"string","enum":["paybysquare","spd","epc"]},"qr":{"type":"string","description":"Payload to render as a QR code"},"iban":{"type":"string"},"vs":{"type":"string"},"due":{"type":"string","format":"date"}}}}}},"400":{"description":"Validation error as a short sentence"},"429":{"description":"More than 10 shop orders per hour from one IP"}}}}}}