{"components":{"schemas":{"Bend":{"additionalProperties":false,"description":"A straight fold across the whole part, on the line through start_in\nand end_in ([x, y] in the item's frame; any two points on the line).\nangle_deg is how far it folds: 90 is a square bend. direction is up (a\nmountain fold seen from above) or down (a valley fold); it does not\nchange the price.","properties":{"angle_deg":{"default":90.0,"exclusiveMinimum":0,"maximum":180,"title":"Angle Deg","type":"number"},"direction":{"default":"up","enum":["up","down"],"title":"Direction","type":"string"},"end_in":{"maxItems":2,"minItems":2,"prefixItems":[{"maximum":120,"minimum":0,"type":"number"},{"maximum":120,"minimum":0,"type":"number"}],"title":"End In","type":"array"},"start_in":{"maxItems":2,"minItems":2,"prefixItems":[{"maximum":120,"minimum":0,"type":"number"},{"maximum":120,"minimum":0,"type":"number"}],"title":"Start In","type":"array"}},"required":["start_in","end_in"],"title":"Bend","type":"object"},"BoltCircleHoles":{"additionalProperties":false,"description":"count round holes spaced evenly on a circle bolt_circle_diameter_in\nacross, centred on (center_x_in, center_y_in). The first hole sits at\nstart_angle_deg, counter-clockwise from +x.","properties":{"bolt_circle_diameter_in":{"exclusiveMinimum":0,"maximum":120,"title":"Bolt Circle Diameter In","type":"number"},"center_x_in":{"maximum":120,"minimum":0,"title":"Center X In","type":"number"},"center_y_in":{"maximum":120,"minimum":0,"title":"Center Y In","type":"number"},"count":{"maximum":100,"minimum":2,"title":"Count","type":"integer"},"diameter_in":{"exclusiveMinimum":0,"maximum":120,"title":"Diameter In","type":"number"},"kind":{"const":"bolt_circle","title":"Kind","type":"string"},"start_angle_deg":{"default":0.0,"maximum":360,"minimum":-360,"title":"Start Angle Deg","type":"number"}},"required":["kind","center_x_in","center_y_in","count","bolt_circle_diameter_in","diameter_in"],"title":"BoltCircleHoles","type":"object"},"CircleOutline":{"additionalProperties":false,"description":"A round plate diameter_in across. The origin is the lower-left\ncorner of the square around it, so the centre is at\n(diameter_in / 2, diameter_in / 2).","properties":{"diameter_in":{"exclusiveMinimum":0,"maximum":120,"title":"Diameter In","type":"number"},"kind":{"const":"circle","title":"Kind","type":"string"}},"required":["kind","diameter_in"],"title":"CircleOutline","type":"object"},"Delivery":{"additionalProperties":false,"description":"How an item reaches the person. quoted_after_order: Steady Steel\nquotes the freight once the order is in, and it is not in this quote.\npriced_at_checkout: the order page prices delivery from the address,\nor the person picks it up. not_applicable: nothing ships (a\ndownload).","properties":{"note":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Note"},"status":{"enum":["quoted_after_order","priced_at_checkout","not_applicable"],"title":"Status","type":"string"}},"required":["status"],"title":"Delivery","type":"object"},"DimensionSpan":{"additionalProperties":false,"description":"The smallest and largest value one dimension takes, in inches.","properties":{"max_in":{"title":"Max In","type":"number"},"min_in":{"title":"Min In","type":"number"}},"required":["min_in","max_in"],"title":"DimensionSpan","type":"object"},"ErrorBody":{"additionalProperties":false,"description":"What went wrong. Branch on type, then code; message is for people.\nrequest_id matches the X-Request-Id header: quote it when you ask us\nabout a request.","properties":{"code":{"title":"Code","type":"string"},"details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"default":null,"title":"Details"},"doc_url":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Doc Url"},"message":{"title":"Message","type":"string"},"param":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Param"},"request_id":{"title":"Request Id","type":"string"},"retryable":{"default":false,"title":"Retryable","type":"boolean"},"type":{"enum":["invalid_request_error","not_found_error","conflict_error","rate_limit_error","api_error"],"title":"Type","type":"string"}},"required":["type","code","message","request_id"],"title":"ErrorBody","type":"object"},"ErrorEnvelope":{"additionalProperties":false,"description":"The one error shape. Every non-2xx answer from /api/v1 is this.","properties":{"error":{"$ref":"#/components/schemas/ErrorBody"}},"required":["error"],"title":"ErrorEnvelope","type":"object"},"GridHoles":{"additionalProperties":false,"description":"A grid of round holes, columns across and rows up, centred on\n(center_x_in, center_y_in). The spacings are centre to centre, and\nrotation_deg turns the whole grid about its centre, counter-clockwise.","properties":{"center_x_in":{"maximum":120,"minimum":0,"title":"Center X In","type":"number"},"center_y_in":{"maximum":120,"minimum":0,"title":"Center Y In","type":"number"},"columns":{"maximum":50,"minimum":1,"title":"Columns","type":"integer"},"diameter_in":{"exclusiveMinimum":0,"maximum":120,"title":"Diameter In","type":"number"},"kind":{"const":"grid","title":"Kind","type":"string"},"rotation_deg":{"default":0.0,"maximum":360,"minimum":-360,"title":"Rotation Deg","type":"number"},"rows":{"maximum":50,"minimum":1,"title":"Rows","type":"integer"},"x_spacing_in":{"exclusiveMinimum":0,"maximum":120,"title":"X Spacing In","type":"number"},"y_spacing_in":{"exclusiveMinimum":0,"maximum":120,"title":"Y Spacing In","type":"number"}},"required":["kind","center_x_in","center_y_in","columns","rows","x_spacing_in","y_spacing_in","diameter_in"],"title":"GridHoles","type":"object"},"Handoff":{"additionalProperties":false,"description":"A link to give the person. It opens one page on steadysteel.org that\nshows what was quoted, and each item's button takes them to the page\nthat sells it, where they check it and order. Nothing is paid through\nthis API. The link works until expires_at, when the last of its quotes\nexpires. Anyone holding url can open the page, so give it only to the\nperson it is for.","properties":{"expires_at":{"format":"date-time","title":"Expires At","type":"string"},"id":{"title":"Id","type":"string"},"items":{"items":{"$ref":"#/components/schemas/HandoffItem"},"title":"Items","type":"array"},"object":{"const":"handoff","default":"handoff","title":"Object","type":"string"},"url":{"title":"Url","type":"string"}},"required":["id","url","expires_at","items"],"title":"Handoff","type":"object"},"HandoffItem":{"additionalProperties":false,"description":"One item on the page the link opens, in the order the quotes list\nthem. action says what its button does there.","properties":{"action":{"title":"Action","type":"string"},"description":{"title":"Description","type":"string"},"index":{"title":"Index","type":"integer"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Label"},"quote_id":{"title":"Quote Id","type":"string"}},"required":["quote_id","index","description","action"],"title":"HandoffItem","type":"object"},"HandoffRequest":{"additionalProperties":false,"description":"The quotes to hand to the person: one to ten ids from POST /quotes,\neach ready and unexpired, with ten items at most across them.","properties":{"quote_ids":{"items":{"maxLength":64,"minLength":1,"type":"string"},"maxItems":10,"minItems":1,"title":"Quote Ids","type":"array"}},"required":["quote_ids"],"title":"HandoffRequest","type":"object"},"Issue":{"additionalProperties":false,"description":"Something to know about a quote or one of its items. A blocking\nissue stops the quote: act on its message and ask for a new quote.\nparam names the request field it is about.","properties":{"code":{"title":"Code","type":"string"},"message":{"title":"Message","type":"string"},"param":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Param"},"severity":{"enum":["blocking","warning","info"],"title":"Severity","type":"string"}},"required":["code","severity","message"],"title":"Issue","type":"object"},"LeadTime":{"additionalProperties":false,"description":"How long, in days from the order. note says which days they are\n(business days for cut plate) and what the span includes.","properties":{"days_max":{"title":"Days Max","type":"integer"},"days_min":{"title":"Days Min","type":"integer"},"note":{"title":"Note","type":"string"}},"required":["days_min","days_max","note"],"title":"LeadTime","type":"object"},"LinearHoles":{"additionalProperties":false,"description":"count round holes in a row. The first is centred at\n(start_x_in, start_y_in) and each one after it is spacing_in further\nalong angle_deg: 0 runs right, 90 runs up.","properties":{"angle_deg":{"default":0.0,"maximum":360,"minimum":-360,"title":"Angle Deg","type":"number"},"count":{"maximum":100,"minimum":1,"title":"Count","type":"integer"},"diameter_in":{"exclusiveMinimum":0,"maximum":120,"title":"Diameter In","type":"number"},"kind":{"const":"linear","title":"Kind","type":"string"},"spacing_in":{"exclusiveMinimum":0,"maximum":120,"title":"Spacing In","type":"number"},"start_x_in":{"maximum":120,"minimum":0,"title":"Start X In","type":"number"},"start_y_in":{"maximum":120,"minimum":0,"title":"Start Y In","type":"number"}},"required":["kind","start_x_in","start_y_in","count","spacing_in","diameter_in"],"title":"LinearHoles","type":"object"},"ListEnvelope_Material_":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Material"},"title":"Data","type":"array"},"has_more":{"default":false,"title":"Has More","type":"boolean"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Next Cursor"},"object":{"const":"list","default":"list","title":"Object","type":"string"}},"required":["data"],"title":"ListEnvelope[Material]","type":"object"},"ListEnvelope_Product_":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Product"},"title":"Data","type":"array"},"has_more":{"default":false,"title":"Has More","type":"boolean"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Next Cursor"},"object":{"const":"list","default":"list","title":"Object","type":"string"}},"required":["data"],"title":"ListEnvelope[Product]","type":"object"},"ListEnvelope_Profile_":{"additionalProperties":false,"properties":{"data":{"items":{"$ref":"#/components/schemas/Profile"},"title":"Data","type":"array"},"has_more":{"default":false,"title":"Has More","type":"boolean"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Next Cursor"},"object":{"const":"list","default":"list","title":"Object","type":"string"}},"required":["data"],"title":"ListEnvelope[Profile]","type":"object"},"Material":{"additionalProperties":false,"description":"A plate material we laser cut, with every thickness we sell in it.\nNothing thicker than max_laser_thickness_in is cut in this material.\nid is the value a plate quote takes as its material.","properties":{"id":{"title":"Id","type":"string"},"max_laser_thickness_in":{"title":"Max Laser Thickness In","type":"number"},"name":{"title":"Name","type":"string"},"object":{"const":"material","default":"material","title":"Object","type":"string"},"thicknesses":{"items":{"$ref":"#/components/schemas/ThicknessOffer"},"title":"Thicknesses","type":"array"}},"required":["id","name","max_laser_thickness_in","thicknesses"],"title":"Material","type":"object"},"OpenApiDocument":{"additionalProperties":true,"description":"This API described in OpenAPI 3.1: every endpoint, what it takes and\nwhat it answers.","properties":{"components":{"additionalProperties":true,"title":"Components","type":"object"},"info":{"additionalProperties":true,"title":"Info","type":"object"},"openapi":{"const":"3.1.0","title":"Openapi","type":"string"},"paths":{"additionalProperties":true,"title":"Paths","type":"object"},"servers":{"items":{"additionalProperties":true,"type":"object"},"title":"Servers","type":"array"}},"required":["openapi","info","servers","paths","components"],"title":"OpenApiDocument","type":"object"},"PlateItem":{"additionalProperties":false,"description":"A flat plate, laser cut and bent if asked, priced by the engine\nbehind the plate quoter on steadysteel.org. material is a material id\nand thickness_in one of its thicknesses, exactly as GET /materials lists\nthem. Every length is inches, +x right and +y up. For a rectangle,\ncircle or ring the origin is the lower-left corner of the square or\nrectangle around the part; a polygon's corners set the frame, and holes\nand bends use the same one. holes takes up to 200 entries and 500\ncutouts in all, counting every hole in a pattern; each must sit inside\nthe material with material all round it. bends takes up to 10.\nquantity is how many (1 to 999), and quantity_options prices up to five\nother quantities beside it. label works as on a product item.","properties":{"bends":{"items":{"$ref":"#/components/schemas/Bend"},"maxItems":10,"title":"Bends","type":"array"},"holes":{"items":{"discriminator":{"mapping":{"bolt_circle":"#/components/schemas/BoltCircleHoles","grid":"#/components/schemas/GridHoles","linear":"#/components/schemas/LinearHoles","single":"#/components/schemas/SingleHole","slot":"#/components/schemas/SlotHole"},"propertyName":"kind"},"oneOf":[{"$ref":"#/components/schemas/SingleHole"},{"$ref":"#/components/schemas/LinearHoles"},{"$ref":"#/components/schemas/GridHoles"},{"$ref":"#/components/schemas/BoltCircleHoles"},{"$ref":"#/components/schemas/SlotHole"}]},"maxItems":200,"title":"Holes","type":"array"},"kind":{"const":"plate","title":"Kind","type":"string"},"label":{"anyOf":[{"maxLength":60,"type":"string"},{"type":"null"}],"default":null,"title":"Label"},"material":{"enum":["mild_steel","stainless_304","stainless_316","aluminum_6061"],"title":"Material","type":"string"},"outline":{"discriminator":{"mapping":{"circle":"#/components/schemas/CircleOutline","polygon":"#/components/schemas/PolygonOutline","rectangle":"#/components/schemas/RectangleOutline","ring":"#/components/schemas/RingOutline"},"propertyName":"kind"},"oneOf":[{"$ref":"#/components/schemas/RectangleOutline"},{"$ref":"#/components/schemas/CircleOutline"},{"$ref":"#/components/schemas/RingOutline"},{"$ref":"#/components/schemas/PolygonOutline"}],"title":"Outline"},"quantity":{"default":1,"maximum":999,"minimum":1,"title":"Quantity","type":"integer"},"quantity_options":{"items":{"maximum":999,"minimum":1,"type":"integer"},"maxItems":5,"title":"Quantity Options","type":"array"},"thickness_in":{"exclusiveMinimum":0,"maximum":4,"title":"Thickness In","type":"number"}},"required":["kind","material","thickness_in","outline"],"title":"PlateItem","type":"object"},"PolygonOutline":{"additionalProperties":false,"description":"A straight-sided outline: its corners in order around the part,\neither way round, each [x, y] in inches, 3 to 200 of them. The outline\ncloses itself; a last corner that repeats the first is dropped. The\ncorners set the frame, and the item's holes and bends use it too.","properties":{"kind":{"const":"polygon","title":"Kind","type":"string"},"points_in":{"items":{"maxItems":2,"minItems":2,"prefixItems":[{"maximum":120,"minimum":0,"type":"number"},{"maximum":120,"minimum":0,"type":"number"}],"type":"array"},"maxItems":200,"minItems":3,"title":"Points In","type":"array"}},"required":["kind","points_in"],"title":"PolygonOutline","type":"object"},"Product":{"additionalProperties":false,"description":"A pre-designed product from the Steady Steel catalog. Tier prices\nare firm and before HST. Freight on a kit or a welded unit is quoted by\nSteady Steel after the order.","properties":{"blurb":{"title":"Blurb","type":"string"},"certification_note":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Certification Note"},"division":{"title":"Division","type":"string"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Image Url"},"name":{"title":"Name","type":"string"},"object":{"const":"product","default":"product","title":"Object","type":"string"},"product_url":{"title":"Product Url","type":"string"},"slug":{"title":"Slug","type":"string"},"tiers":{"items":{"$ref":"#/components/schemas/ProductTier"},"title":"Tiers","type":"array"}},"required":["slug","name","division","blurb","product_url","tiers"],"title":"Product","type":"object"},"ProductItem":{"additionalProperties":false,"description":"A catalog product to price, by the slug and a tier from\nGET /products; only a tier marked orderable can be quoted. quantity is\nhow many (1 to 50). quantity_options prices up to five other quantities\nbeside it. A design package is bought once, so its quantity is 1, it\ntakes no quantity_options, and a quote names it once. label is your own\nshort name for the item, shown back on the quote: up to 60 letters,\ndigits, spaces and - _ # . , ( ) / ' \". Any other label, or one that\nreads as a link, a web or email address or a phone number, is left off:\nthe item is still priced and carries a label_dropped warning.","properties":{"kind":{"const":"product","title":"Kind","type":"string"},"label":{"anyOf":[{"maxLength":60,"type":"string"},{"type":"null"}],"default":null,"title":"Label"},"quantity":{"default":1,"maximum":50,"minimum":1,"title":"Quantity","type":"integer"},"quantity_options":{"items":{"maximum":50,"minimum":1,"type":"integer"},"maxItems":5,"title":"Quantity Options","type":"array"},"slug":{"maxLength":80,"pattern":"^[A-Za-z0-9_-]{1,80}$","title":"Slug","type":"string"},"tier":{"enum":["kit","welded","design"],"title":"Tier","type":"string"}},"required":["kind","slug","tier"],"title":"ProductItem","type":"object"},"ProductTier":{"additionalProperties":false,"description":"One way to buy a product: design (the drawing package), kit (the\nsteel cut to the drawings) or welded (built in our shop).\nunit_amount_cents is before HST, and null when the price is given on\nrequest. orderable means it can be ordered on steadysteel.org today.","properties":{"includes":{"items":{"type":"string"},"title":"Includes","type":"array"},"kind":{"enum":["design","kit","welded"],"title":"Kind","type":"string"},"label":{"title":"Label","type":"string"},"lead_time_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"title":"Lead Time Days"},"orderable":{"title":"Orderable","type":"boolean"},"unit_amount_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"title":"Unit Amount Cents"}},"required":["kind","label","includes","orderable"],"title":"ProductTier","type":"object"},"Profile":{"additionalProperties":false,"description":"A structural section an assembly estimate can use. W shapes (I_BEAM)\nand C shapes (CHANNEL) go by designation and carry their weight per\nfoot in steel. Tube, angle and bar are sized instead: send every key in\ndimensions, in inches, each inside its span; note gives any rule\nbetween them.","properties":{"designation":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Designation"},"dimensions":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/DimensionSpan"},"type":"object"},{"type":"null"}],"default":null,"title":"Dimensions"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Note"},"object":{"const":"profile","default":"profile","title":"Object","type":"string"},"profile_type":{"enum":["I_BEAM","CHANNEL","HSS_SQUARE","HSS_RECT","ANGLE","FLAT_BAR","ROUND_BAR"],"title":"Profile Type","type":"string"},"weight_lb_per_ft":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null,"title":"Weight Lb Per Ft"}},"required":["profile_type"],"title":"Profile","type":"object"},"ProfileQuery":{"additionalProperties":false,"description":"Filters for the profile list. search matches designations and section\nnames, ignoring case and spaces. cursor is next_cursor from the page\nbefore.","properties":{"cursor":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"title":"Cursor"},"limit":{"default":20,"maximum":50,"minimum":1,"title":"Limit","type":"integer"},"profile_type":{"anyOf":[{"enum":["I_BEAM","CHANNEL","HSS_SQUARE","HSS_RECT","ANGLE","FLAT_BAR","ROUND_BAR"],"type":"string"},{"type":"null"}],"default":null,"title":"Profile Type"},"search":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"title":"Search"}},"title":"ProfileQuery","type":"object"},"QuantityOption":{"additionalProperties":false,"description":"The same item priced at another quantity, in CAD cents before HST.","properties":{"amount_cents":{"title":"Amount Cents","type":"integer"},"quantity":{"title":"Quantity","type":"integer"},"unit_amount_cents":{"title":"Unit Amount Cents","type":"integer"}},"required":["quantity","unit_amount_cents","amount_cents"],"title":"QuantityOption","type":"object"},"Quote":{"additionalProperties":false,"description":"A priced quote. It never changes: to change anything, ask for a new\none. status is ready when every item is priced, blocked when an issue\nstops it, and expired once it is past expires_at. A blocked quote's\nthree totals are null, and so are a blocked item's amounts; an item\nthat is ready still shows its amounts. price_type is firm when every price is one we sell at\ntoday, and estimate when any part is an estimate (then beta is true and\nnotice says what that means). The page the person orders on prices the\norder again, so a price can move if ours changes first. Amounts are CAD\ncents, with HST as its own figure.","properties":{"amount_subtotal_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"title":"Amount Subtotal Cents"},"amount_tax_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"title":"Amount Tax Cents"},"amount_total_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"title":"Amount Total Cents"},"beta":{"title":"Beta","type":"boolean"},"created_at":{"format":"date-time","title":"Created At","type":"string"},"currency":{"const":"cad","default":"cad","title":"Currency","type":"string"},"expires_at":{"format":"date-time","title":"Expires At","type":"string"},"id":{"title":"Id","type":"string"},"issues":{"items":{"$ref":"#/components/schemas/Issue"},"title":"Issues","type":"array"},"items":{"items":{"$ref":"#/components/schemas/QuotedItem"},"title":"Items","type":"array"},"notice":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Notice"},"object":{"const":"quote","default":"quote","title":"Object","type":"string"},"price_type":{"enum":["firm","estimate"],"title":"Price Type","type":"string"},"status":{"enum":["ready","blocked","expired"],"title":"Status","type":"string"},"tax_note":{"title":"Tax Note","type":"string"}},"required":["id","status","price_type","beta","items","tax_note","issues","created_at","expires_at"],"title":"Quote","type":"object"},"QuoteRequest":{"additionalProperties":false,"description":"What to price: one to ten items, each a catalog product or a\nplate.","properties":{"items":{"items":{"discriminator":{"mapping":{"plate":"#/components/schemas/PlateItem","product":"#/components/schemas/ProductItem"},"propertyName":"kind"},"oneOf":[{"$ref":"#/components/schemas/ProductItem"},{"$ref":"#/components/schemas/PlateItem"}]},"maxItems":10,"minItems":1,"title":"Items","type":"array"}},"required":["items"],"title":"QuoteRequest","type":"object"},"QuotedItem":{"additionalProperties":false,"description":"One priced item, in the order the request listed it. description is\nours; label is yours, as sent. Amounts are CAD cents before HST. A\nproduct's amount_cents is unit_amount_cents times quantity. A plate is\npriced as one job at its quantity, so its unit_amount_cents is\namount_cents divided by the quantity, to the nearest cent. lead_time is\nfor the quantity asked; it is null when Steady Steel confirms it after\nthe order (an info issue then gives the figure for one) or has none to\nstate.","properties":{"amount_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"title":"Amount Cents"},"delivery":{"$ref":"#/components/schemas/Delivery"},"description":{"title":"Description","type":"string"},"includes":{"items":{"type":"string"},"title":"Includes","type":"array"},"index":{"title":"Index","type":"integer"},"issues":{"items":{"$ref":"#/components/schemas/Issue"},"title":"Issues","type":"array"},"kind":{"enum":["product","plate"],"title":"Kind","type":"string"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Label"},"lead_time":{"anyOf":[{"$ref":"#/components/schemas/LeadTime"},{"type":"null"}],"default":null},"plate":{"anyOf":[{"$ref":"#/components/schemas/QuotedPlate"},{"type":"null"}],"default":null},"price_type":{"enum":["firm","estimate"],"title":"Price Type","type":"string"},"product":{"anyOf":[{"$ref":"#/components/schemas/QuotedProduct"},{"type":"null"}],"default":null},"quantity":{"title":"Quantity","type":"integer"},"quantity_options":{"items":{"$ref":"#/components/schemas/QuantityOption"},"title":"Quantity Options","type":"array"},"status":{"enum":["ready","blocked"],"title":"Status","type":"string"},"unit_amount_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"title":"Unit Amount Cents"}},"required":["index","kind","description","status","price_type","quantity","quantity_options","includes","delivery","issues"],"title":"QuotedItem","type":"object"},"QuotedPlate":{"additionalProperties":false,"description":"The plate as we read it. width_in and height_in are the outline's\nextent in the item's frame. weight_lb and cut_length_in are for one\npiece; they are null when the plate is blocked before it is priced.\npreview_url is a drawing of the part as priced, in SVG: the outline,\nevery hole and slot, and each bend as a dashed line. Show it to the\nperson before they order. It is null when the plate is blocked.","properties":{"bend_count":{"title":"Bend Count","type":"integer"},"cut_length_in":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null,"title":"Cut Length In"},"height_in":{"title":"Height In","type":"number"},"hole_count":{"title":"Hole Count","type":"integer"},"material":{"enum":["mild_steel","stainless_304","stainless_316","aluminum_6061"],"title":"Material","type":"string"},"preview_url":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"title":"Preview Url"},"slot_count":{"title":"Slot Count","type":"integer"},"thickness_in":{"title":"Thickness In","type":"number"},"weight_lb":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null,"title":"Weight Lb"},"width_in":{"title":"Width In","type":"number"}},"required":["material","thickness_in","width_in","height_in","hole_count","slot_count","bend_count"],"title":"QuotedPlate","type":"object"},"QuotedProduct":{"additionalProperties":false,"description":"The catalog product a product item prices, and the page that sells\nit.","properties":{"product_url":{"title":"Product Url","type":"string"},"slug":{"title":"Slug","type":"string"},"tier":{"enum":["kit","welded","design"],"title":"Tier","type":"string"}},"required":["slug","tier","product_url"],"title":"QuotedProduct","type":"object"},"RectangleOutline":{"additionalProperties":false,"description":"A rectangle width_in across and height_in up, its lower-left corner\non the origin.","properties":{"height_in":{"exclusiveMinimum":0,"maximum":120,"title":"Height In","type":"number"},"kind":{"const":"rectangle","title":"Kind","type":"string"},"width_in":{"exclusiveMinimum":0,"maximum":120,"title":"Width In","type":"number"}},"required":["kind","width_in","height_in"],"title":"RectangleOutline","type":"object"},"RfqLink":{"additionalProperties":false,"description":"A link to Steady Steel's quote request form with the job filled in.\nThe person reads it over, adds their own name and contact details and\nsends it, and Steady Steel gets back to them with a price. The link\nworks until expires_at, 30 days. Anyone holding url can open the form\nwith the job in it, so give it only to the person it is for.","properties":{"expires_at":{"format":"date-time","title":"Expires At","type":"string"},"id":{"title":"Id","type":"string"},"object":{"const":"rfq_link","default":"rfq_link","title":"Object","type":"string"},"url":{"title":"Url","type":"string"}},"required":["id","url","expires_at"],"title":"RfqLink","type":"object"},"RfqLinkRequest":{"additionalProperties":false,"description":"A job POST /quotes cannot price, for Steady Steel to quote: a part\nfrom a drawing, a weldment, a repair, plate past the laser. description\nsays what the person wants made, in plain words: sizes, material,\nfinish, how many, when it is needed. material, thickness_in and\nquantity are optional. Send nothing about the person: no name, email,\nphone number or link. They give their own on our form, and a\ndescription or material carrying one is refused.","properties":{"description":{"maxLength":2000,"minLength":1,"title":"Description","type":"string"},"material":{"anyOf":[{"maxLength":60,"type":"string"},{"type":"null"}],"default":null,"title":"Material"},"quantity":{"anyOf":[{"maximum":100000,"minimum":1,"type":"integer"},{"type":"null"}],"default":null,"title":"Quantity"},"thickness_in":{"anyOf":[{"exclusiveMinimum":0,"maximum":12,"type":"number"},{"type":"null"}],"default":null,"title":"Thickness In"}},"required":["description"],"title":"RfqLinkRequest","type":"object"},"RingOutline":{"additionalProperties":false,"description":"A washer: a round plate with a round bore on the same centre. The\norigin is the lower-left corner of the square around it. The wall,\nhalf the difference of the two diameters, must be at least 1/8 in.","properties":{"inner_diameter_in":{"exclusiveMinimum":0,"maximum":120,"title":"Inner Diameter In","type":"number"},"kind":{"const":"ring","title":"Kind","type":"string"},"outer_diameter_in":{"exclusiveMinimum":0,"maximum":120,"title":"Outer Diameter In","type":"number"}},"required":["kind","outer_diameter_in","inner_diameter_in"],"title":"RingOutline","type":"object"},"SingleHole":{"additionalProperties":false,"description":"One round hole diameter_in across, centred at (x_in, y_in).","properties":{"diameter_in":{"exclusiveMinimum":0,"maximum":120,"title":"Diameter In","type":"number"},"kind":{"const":"single","title":"Kind","type":"string"},"x_in":{"maximum":120,"minimum":0,"title":"X In","type":"number"},"y_in":{"maximum":120,"minimum":0,"title":"Y In","type":"number"}},"required":["kind","x_in","y_in","diameter_in"],"title":"SingleHole","type":"object"},"SlotHole":{"additionalProperties":false,"description":"A slot with round ends, width_in across and length_in from tip to\ntip, centred on (center_x_in, center_y_in). angle_deg turns its long\naxis counter-clockwise from +x.","properties":{"angle_deg":{"default":0.0,"maximum":360,"minimum":-360,"title":"Angle Deg","type":"number"},"center_x_in":{"maximum":120,"minimum":0,"title":"Center X In","type":"number"},"center_y_in":{"maximum":120,"minimum":0,"title":"Center Y In","type":"number"},"kind":{"const":"slot","title":"Kind","type":"string"},"length_in":{"exclusiveMinimum":0,"maximum":120,"title":"Length In","type":"number"},"width_in":{"exclusiveMinimum":0,"maximum":120,"title":"Width In","type":"number"}},"required":["kind","center_x_in","center_y_in","width_in","length_in"],"title":"SlotHole","type":"object"},"Status":{"additionalProperties":false,"properties":{"api":{"const":"v1","default":"v1","title":"Api","type":"string"},"docs_url":{"title":"Docs Url","type":"string"},"object":{"const":"status","default":"status","title":"Object","type":"string"},"ok":{"title":"Ok","type":"boolean"}},"required":["ok","docs_url"],"title":"Status","type":"object"},"ThicknessOffer":{"additionalProperties":false,"description":"One plate thickness we sell. Quote with thickness_in exactly as\ngiven. carried means we stock the size; a size we do not stock is still\nsold, and its lead_time includes bringing the plate in. lead_time is\nnull when we cannot say.","properties":{"carried":{"title":"Carried","type":"boolean"},"label":{"title":"Label","type":"string"},"lead_time":{"anyOf":[{"$ref":"#/components/schemas/LeadTime"},{"type":"null"}],"default":null},"thickness_in":{"title":"Thickness In","type":"number"}},"required":["thickness_in","label","carried"],"title":"ThicknessOffer","type":"object"}}},"externalDocs":{"description":"How to use this API, in words, with the guide for AI agents","url":"https://www.steadysteel.org/docs/api"},"info":{"contact":{"name":"Steady Steel Inc.","url":"https://www.steadysteel.org"},"description":"Steady Steel Inc., steel fabrication in Newmarket, Ontario. For AI agents and other software; no key needed. Amounts are whole CAD cents (fields ending _cents), lengths inches (_in), weights pounds (_lb). Every error is one envelope: {\"error\": {\"type\", \"code\", \"message\", \"param\", \"request_id\", ...}}.","title":"Steady Steel API","version":"v1"},"openapi":"3.1.0","paths":{"/handoffs":{"post":{"description":"Takes one to ten quote ids from POST /quotes, each ready and unexpired, with ten items at most across them. The link opens one page on steadysteel.org that shows what was quoted, with a button for each item: a plate opens in Forgelet, our plate quoter, to check and buy; a product goes to its order page. The person orders and pays there, and that page prices the order again. Give the person url. 404 quote_not_found for an id we never gave out; 409 quote_expired or quote_not_ready for a quote past expires_at or blocked; 503 storage_unavailable, worth a retry, when a plate design could not be stored.","operationId":"create_handoff","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandoffRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Handoff"}}},"description":"Make a link the person orders from on steadysteel.org"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Any error, in the one error envelope."}},"summary":"Make a link the person orders from on steadysteel.org","tags":["handoffs"]}},"/materials":{"get":{"description":"Every plate material the laser cuts, with each thickness we sell, whether we stock it, and a lead time in business days. Empty while online plate orders are switched off.","operationId":"list_materials","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListEnvelope_Material_"}}},"description":"List the plate materials and thicknesses we laser cut"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Any error, in the one error envelope."}},"summary":"List the plate materials and thicknesses we laser cut","tags":["catalog"]}},"/openapi.json":{"get":{"operationId":"openapi_document","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenApiDocument"}}},"description":"This API, described in OpenAPI 3.1"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Any error, in the one error envelope."}},"summary":"This API, described in OpenAPI 3.1","tags":["meta"]}},"/products":{"get":{"description":"Every published catalog product and the ways to buy it. Prices are firm, in CAD cents before HST.","operationId":"list_products","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListEnvelope_Product_"}}},"description":"List the pre-designed products we sell"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Any error, in the one error envelope."}},"summary":"List the pre-designed products we sell","tags":["catalog"]}},"/products/{slug}":{"get":{"description":"One published product. 404 product_not_found when no published product has the slug.","operationId":"get_product","parameters":[{"in":"path","name":"slug","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}},"description":"Get one product by its slug"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Any error, in the one error envelope."}},"summary":"Get one product by its slug","tags":["catalog"]}},"/profiles":{"get":{"description":"Tube, angle and bar with the dimensions to send and their ranges, then W shapes and C shapes by designation with their weight per foot. Paged: when has_more is true, send next_cursor back as cursor with the same filters.","operationId":"list_profiles","parameters":[{"in":"query","name":"search","required":false,"schema":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"title":"Search"}},{"in":"query","name":"profile_type","required":false,"schema":{"anyOf":[{"enum":["I_BEAM","CHANNEL","HSS_SQUARE","HSS_RECT","ANGLE","FLAT_BAR","ROUND_BAR"],"type":"string"},{"type":"null"}],"default":null,"title":"Profile Type"}},{"in":"query","name":"limit","required":false,"schema":{"default":20,"maximum":50,"minimum":1,"title":"Limit","type":"integer"}},{"in":"query","name":"cursor","required":false,"schema":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"title":"Cursor"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListEnvelope_Profile_"}}},"description":"List the structural sections an assembly estimate takes"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Any error, in the one error envelope."}},"summary":"List the structural sections an assembly estimate takes","tags":["catalog"]}},"/quotes":{"post":{"description":"Prices one to ten items, with HST as its own figure: catalog products at a tier the product page sells today, and flat plate laser cut, holed and bent to your outline in a material and thickness from GET /materials. A plate we cannot make as asked (past the laser, a hole outside the part) comes back blocked, with an issue saying why. The quote is kept: GET /quotes/{id} returns it exactly as sent here until 30 days after it expires. Asking again makes a new quote. 422 when a slug, tier, material, thickness or quantity is outside what GET /products and GET /materials list.","operationId":"create_quote","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quote"}}},"description":"Price catalog products and cut plate"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Any error, in the one error envelope."}},"summary":"Price catalog products and cut plate","tags":["quotes"]}},"/quotes/{public_id}":{"get":{"description":"The quote exactly as it was first sent, with status expired once it is past expires_at. 404 quote_not_found for an id we never gave out or one already removed.","operationId":"get_quote","parameters":[{"in":"path","name":"public_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quote"}}},"description":"Get a quote by its id"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Any error, in the one error envelope."}},"summary":"Get a quote by its id","tags":["quotes"]}},"/quotes/{public_id}/items/{index}/preview.svg":{"get":{"description":"A drawing of one plate item of a quote, in SVG: the outline, every hole and slot, and each bend as a dashed line with its direction and angle, drawn from the design the quote priced. A ready plate links it as plate.preview_url; index is the item's place in the quote, from 0. 404 preview_not_found for an item with no drawing: a catalog product or a blocked plate.","operationId":"get_quote_preview","parameters":[{"in":"path","name":"public_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"index","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"content":{"image/svg+xml":{"schema":{"type":"string"}}},"description":"Draw a quoted plate"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Any error, in the one error envelope."}},"summary":"Draw a quoted plate","tags":["quotes"]}},"/rfq-links":{"post":{"description":"For work POST /quotes does not price: a part from a drawing, a weldment, a repair, plate past the laser. Describe the job in words. The link opens our quote request form with it filled in; the person adds their own name and contact details and sends it. Send nothing about the person: a name, email or phone field is refused (422 parameter_unknown), and so is a description carrying a link, a web or email address or a phone number (422 contact_details_not_allowed). The link works for 30 days.","operationId":"create_rfq_link","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RfqLinkRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RfqLink"}}},"description":"Make a link to our quote request form, job filled in"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Any error, in the one error envelope."}},"summary":"Make a link to our quote request form, job filled in","tags":["handoffs"]}},"/status":{"get":{"operationId":"status","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}},"description":"Check the API is up"},"default":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Any error, in the one error envelope."}},"summary":"Check the API is up","tags":["meta"]}}},"servers":[{"url":"https://www.steadysteel.org/api/v1"}]}
