{"openapi":"3.0.1","info":{"title":"EziBrand API","description":"Order decoration programmatically: garments, embroidery, screenprint and transfers, quoted, submitted\nand tracked to despatch.\n\nThis is the same API the EziBrand dashboard runs on — not a reduced side-door version. Anything the\ndashboard does, your system can do.\n\n## Authenticate\n\nOAuth2 client credentials. `POST https://login.ezibrand.com.au/realms/ezibrand/protocol/openid-connect/token` with `client_id` and\n`client_secret` (form-encoded) returns a bearer token; send it as\n`Authorization: Bearer <token>` to `https://api.ezibrand.com.au`. Tokens last 10 minutes. Credentials are\nissued per wholesale account and see only that account's data.\n\n⚠️ The token endpoint is on the **auth** host, which is not the API host — every call after it goes\nto `https://api.ezibrand.com.au`.\n\nGetting them still involves a person: ask your account manager. Self-service issuing is not available yet.\n\n## What you are actually ordering\n\nA job is decoration applied to a garment. So every order answers two questions — **what is being\ndecorated**, and **what is being done to it** — and the API has a line type for each answer.\n\nThere are two ways to supply the garment:\n\n- **We supply it from stock.** `GET /Stock` is the stocked-goods feed: garments held on the shelf,\n  each with variants and their own size runs. A `\"Stock\"` line orders them by size.\n- **You send it in.** An `\"ExternalGarment\"` line is a garment you are shipping to us, counted by\n  size. ⚠️ The goods-in record is created by us when the delivery is booked in, not by you — the\n  API exposes it read-only, so pre-advising a shipment over the API is not available yet. Reference\n  your order number on the job and tell your account manager what is coming.\n\n⚠️ There is a third thing you can order, and it does not work like this at all: a **BOM** — a\nmade-to-order garment that already carries its decoration. It has its own section below, and if\nyou are selling finished garments on your own website it is probably the only part of this document\nyou need.\n\nAnd two ways to specify the decoration:\n\n- **`\"PriceCode\"`** — a new one. `GET /PriceCodes/price-codes` gives the codes your account can\n  order at your prices; the artwork goes on the line as `externalArtworkUrl`.\n- **`\"Asset\"`** — one we have already made for you. Send the asset tag and it reproduces exactly:\n  no artwork, no re-approval, no setup charge.\n\n## Attaching a decoration to a garment\n\nA decoration line and the garment line it goes on are joined by name, not by order in the array.\nGive the garment line a `groupHead`, and every decoration going on it the matching `group`:\n\n```json\n{\n  \"items\": [\n    { \"itemType\": \"ExternalGarment\", \"groupHead\": \"navy-polos\", \"garment\": \"Navy polo, brand supplied\",\n      \"description\": \"Arriving under PO-10482, 3 cartons\",\n      \"sizeQuantities\": { \"S\": 10, \"M\": 20, \"L\": 15 } },\n    { \"itemType\": \"PriceCode\", \"group\": \"navy-polos\", \"code\": \"<a code from /PriceCodes/price-codes>\",\n      \"quantity\": 45, \"externalArtworkUrl\": \"https://<an origin approved on your account>/left-chest.pdf\",\n      \"attributes\": { \"Position\": \"Left chest 80mmW\", \"garment\": \"Navy polo\" } }\n  ]\n}\n```\n\n⚠️ `\"Bom\"` lines cannot be grouped, and that is deliberate: a BOM already names its own garment and\nits own decoration, so there is nothing to attach it to.\n\n## Goods you send in\n\nWhen you are supplying the garments, the delivery is its own record. `GET /Inwards` lists what you\nhave sent — order number, supplier, carton count, per-size quantities and where each delivery has got\nto — and `GET /Inwards/{id}` opens one up. `GET /Lookups/inwards-statuses` is the status\nvocabulary; read it rather than matching strings.\n\nThe job tells you the other half. `GET /Jobs/{jobNumber}` carries `stockStatus` —\n`Stock Complete`, `Partial Stock` or `No Stock` — which is how you know whether a job is waiting\non a delivery that has not landed yet. Poll that, not a calendar.\n\n## The ordering flow\n\n1. **`GET /PriceCodes/processes`** — the processes your account can order (Embroidery, Screen\n   Printing, Digital Transfers …). Start here: availability is per-account, so never hardcode it.\n2. **`GET /PriceCodes/price-codes`** — codes for those processes at *your* tier, each carrying the\n   `attributes` it needs you to fill in. The `priceCode` returned is what goes in a job line.\n3. **`GET /Stock`** — the garments we can supply, if we are supplying them.\n4. **`GET /Jobs/delivery-options`** and **`GET /Jobs/earliest-ship-date`** — the delivery methods\n   available to you, and the soonest despatch. The method code goes in\n   `deliveryAddress.deliveryMethod`.\n5. **`POST /Jobs`** — create the job. ⚠️ Send `\"validateOnly\": true` first: it runs the full\n   validation path and returns the errors without creating anything. Send the COMPLETE payload,\n   `externalArtworkUrl` included — validation checks the artwork URL without fetching it — then\n   send the same bytes again with `validateOnly` false to create the job.\n6. **`GET /Jobs/{jobNumber}`** — status, stock status, money, tracking. **`GET /Jobs/active`**\n   returns everything open in one call; prefer it over polling jobs individually.\n\n## Artwork goes on the job line\n\nPut a URL to the artwork in `externalArtworkUrl` on each `PriceCode` line. There is no separate\nupload step: one request places the order and delivers the art together.\n\n**Put it in the dry run too.** Validation checks the URL and creates nothing, so the payload you\nprove is the payload you send. Three rules, each answering by number (measured 2026-09-01):\n\n- **Absolute `https://`.** `http://`, a bare host, a relative or protocol-relative path and any\n  other scheme are error `10408`, as is a whitespace-only string.\n- **On an origin approved for your account.** Anything else is `10403`; `10409` means no origins\n  are approved on the account at all. Both are account configuration — ask us to approve the origin\n  you serve artwork from rather than reshaping the URL. ⚠️ Reachability is NOT checked here: a URL\n  that resolves and one that does not answer identically, so neither error is about the file.\n- **All-or-nothing across the job.** If one `PriceCode` line carries artwork, every `PriceCode`\n  line must, or the job is `10404` naming the line that does not. `Asset` lines are repeats and\n  are exempt.\n\n⚠️ Omitting the property, `null` and `\"\"` skip all three checks and validate. That is not the\nartwork passing — it is the artwork not being looked at, and the URL you then send for real has\nnever been proved.\n\nThe URL must stay reachable until the job is in production — we fetch it, we do not hold a copy of\nyour link. A signed URL is fine as long as it outlives the job reaching the factory.\n\n## After you have ordered\n\nA job is not frozen the moment you submit it. `GET /Jobs/{jobNumber}` tells you what you may still\ndo, and you should read that rather than assume:\n\n- **`permissions.canEdit`** — whether **`PATCH /Jobs/{jobNumber}`** will be accepted. You can\n  amend the description, your PO number, comments, the requested ship date and the must-ship flag.\n  When it is `false`, `permissions.lockedReason` says why.\n- **`isCancelable`** — whether **`POST /Jobs/{jobNumber}/cancel`** will be accepted. Once the job\n  is in production it will not be, and you get a `409`.\n\n⚠️ They are independent, and they do not change together. A job already in production is commonly\n`canEdit: true` and `isCancelable: false` — you can still fix the PO number, but the order is\npast the point of being called back. Read both, rather than inferring one from the other or caching\nan earlier answer.\n\n## Reordering costs you nothing\n\nAn asset is decoration already made — a digitised embroidery file, a set of screens, a separation.\n`GET /Assets` lists yours. To run it again, send a job line with `\"itemType\": \"Asset\"` and the\nasset tag as `code`: no artwork upload, no re-approval, and the result matches the previous run.\n\n## Made-to-order garments (BOMs)\n\n⛔ **A different product, not a fourth line type.** Everything above composes a job out of a garment\nand a decoration. A BOM is already both: a finished, made-to-order garment with its decoration\nspecified, ordered as one line. If you sell garments on your own website, this is the whole\nintegration and you can skip the ordering machinery entirely — no price codes, no attributes, no\nartwork URL, no grouping.\n\n```json\n{\n  \"orderNumber\": \"WEB-2291\",\n  \"dateDue\": \"2026-09-14\",\n  \"items\": [\n    { \"itemType\": \"Bom\", \"code\": \"BOM10112-M\", \"quantity\": 2 },\n    { \"itemType\": \"Bom\", \"code\": \"BOM10112-L\", \"quantity\": 1, \"customName\": \"A. Patel\" }\n  ],\n  \"deliveryAddress\": {\n    \"contactName\": \"Sam Patel\",\n    \"organisation\": \"Riverside Print Co\",\n    \"streetAddress\": \"12 Tannery Road\",\n    \"city\": \"Auckland\",\n    \"postalCode\": \"1010\",\n    \"country\": \"New Zealand\",\n    \"countryCodeISO2\": \"NZ\",\n    \"deliveryMethod\": \"overnight\",\n    \"emailAddress\": \"sam@example.com\"\n  }\n}\n```\n\nA code, a size and a quantity. That is the whole line.\n\n**How to wire it to your storefront**\n\n1. **`GET /Boms`** on a schedule — your catalogue. ⚠️ It answers with EVERY BOM in one unpaged\n   response (thousands of records, several megabytes), so cache it; never call it per order or per\n   page render.\n2. **Map it to your own product data with the SKU fields.** A BOM carries `customerSku`, and each\n   variant carries `customerVariantSku` — *your* codes, stored against our records. Set them and an\n   order for `RRC-POLO-NAVY-M` on your site becomes a job line with no lookup table of your own to\n   maintain.\n3. **The variants are already in that response** — `bomVariants`, one per size, each with its\n   own `bomVariantCode`. ⛔ Do NOT loop `GET /Boms/{bomCode}` to collect them: you would make\n   thousands of requests for data you have already downloaded. That endpoint is for refreshing a\n   single BOM. ⛔ Order by the `bomVariantCode` you read back. It is *usually*\n   `{bomCode}-{size}` and 197 EW variants are not, so building it by concatenation works right up\n   until it silently orders a size that does not exist. `size: \"Qty\"` means one-size-fits-all.\n4. **`GET /Jobs/delivery-options`** — the delivery methods THIS account may use. ⚠️ Do not\n   copy the `deliveryMethod` from the example above: carriers differ by account, and a method\n   your account does not have makes the address unroutable. Read it once and cache it with the\n   catalogue.\n5. **`POST /Jobs`** with one `\"Bom\"` line per variant sold. `customName` adds a\n   per-item personalisation — a back name from an \"add a name\" option at your checkout — and\n   produces a per-name line rather than one aggregated one. ⛔ **ALWAYS SEND `size` ON A BOM\n   LINE.** Where the code does not already carry one, omitting `size` — or sending `null` —\n   answers an opaque **500**, while `size: \"\"` reaches the real validator and returns a\n   structured `1825 \"Size is required\"`. So the crash is the *absent* case, not the invalid one:\n   send the `size` from `bomVariants` and neither happens. ⚠️ This warning named `dateDue`\n   until 2026-08-29, which was a misattribution — measured 2×2 that day, `dateDue` present or\n   absent makes no difference to this 500, and omitting it is fine on every line type.\n6. **`GET /Jobs/{jobNumber}`** to track it out, the same as any other job.\n\n⛔ **A BOM line cannot be grouped.** `groupHead` and `group` attach a decoration to a garment,\nand a BOM has no separate decoration to attach — it is the finished article. Sending either is a\nschema error, not a no-op.\n\n**Pricing is deliberately not on the BOM.** A BOM total is the sum of its components, and each\ncomponent publishes its own quantity breaks: `GET /Assets/{assetTag}` carries `priceBands`,\n`setup` and `reset` for a decoration, `GET /Stock/{stockCode}` carries `priceBands` for the\ngarment. One BOM-level figure could not express a quantity break, which is the thing that moves on\na real order. ⚠️ The component list is not on the read yet, so you cannot assemble that total\ntoday — ask your account manager for a price list meanwhile. Same for the BOM image. Both are in\nhand.\n\n⛔ **A BOM with no variants cannot be ordered, and nothing says so.** Measured on a real catalogue:\n120 of 5,724 come back with an empty `bomVariants`. Skip them when you sync, or you will list a\nproduct with no size to order.\n\n⚠️ **`title` is the name, not `description`.** On that catalogue `title` was populated on all\nbut one BOM and `description` on 54 — a listing built from `description` is blank 99% of the\ntime.\n\n⚠️ **The SKU mapping has to be filled in.** 141 of those BOMs carried a `customerSku` and 1,148\nvariants a `customerVariantSku`. Both are yours to define — send us the mapping for the products\nyou sell rather than assuming it is already there.\n\n## Conventions that will bite you otherwise\n\n- **`items[].itemType` selects the line type**, and it decides what `code` means. `\"PriceCode\"`\n  (a full price code), `\"Asset\"` (an asset tag), `\"Stock\"` (a stock code), `\"Bom\"` (a BOM code)\n  and `\"ExternalGarment\"` (no code — you name the garment). These are published as an enum on\n  `JobLineType` and as the `itemType` discriminator on the line union, so a generated client\n  already knows them. ⚠️ `\"Bom\"` belongs to the made-to-order path above and\n  mixes badly with the rest: it carries its own decoration and refuses the grouping fields.\n- **Never build a size variant code by hand.** Take `bomVariantCode` from\n  `GET /Boms/{bomCode}`. It is *usually* `{bomCode}-{size}` and 197 EW variants are not, so\n  concatenating works right up until it silently orders the wrong size.\n- **Size runs come from the data, not from your own ordering.** A size set is a named, ordered list\n  from `GET /Lookups/size-sets`; sorting the sizes yourself puts `10` before `2` and `XL`\n  before `XS`.\n- **A 500 from `POST /Jobs` usually means an invalid payload, not an outage.** Empty `items`, an\n  unroutable delivery address, a nonexistent asset code or a bad `sizeQuantities` key all surface\n  as an opaque 500. Fix the payload before retrying; `validateOnly` with a well-formed payload\n  returns real validation messages. If you need to rule out the other possibility, https://integrate.ezibrand.com.au/status.json reports what our own monitoring sees — ⛔ read its `monitoring.usableForDiagnosis` FIRST: when that is false every component reads `unknown` because we could not reach our own monitoring, which is neither reassurance nor alarm, and your own retry is the better signal.\n  Two triggers are isolated and worth checking first, because each has a payload edit that turns\n  the crash into a readable error: a `Bom` line whose `size` is absent or `null` (send it —\n  `\"\"` alone reaches the real `1825`), and a delivery address with no `emailAddress` (send\n  one; every other missing address field returns a numbered error).\n- **Read enums, don't hardcode them.** Job statuses come from `GET /Lookups/job-statuses`,\n  processes from `GET /Lookups/process-codes`, inwards statuses from\n  `GET /Lookups/inwards-statuses`, countries and states from `GET /Lookups/countries`.\n- **Money is in the account's currency.** No conversion is applied anywhere.\n- **`countryCodeISO2` is two characters** — `\"NZ\"`, not `\"NZL\"`. A three-letter code is rejected.\n- **4xx bodies carry the reason.** Every operation documents its failure codes; read the body rather\n  than retrying blind.","version":"V1","contact":{"name":"EziBrand","url":"https://integrate.ezibrand.com.au/developers"}},"paths":{"/account":{"get":{"tags":["Account"],"summary":"Get account profile","description":"The account these credentials belong to. Call it once a token works to confirm you are pointed at the right customer. (It cannot tell you which region to use — you need the right regional host to get a token at all, and that host comes with your credentials.)","responses":{"200":{"description":"Account profile retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dto_Api_AccountProfile"},"examples":{"default":{"summary":"The account these credentials belong to","value":{"id":4820,"name":"Riverside Print Co","priceTierCode":"B","currency":"NZD","taxRateType":"Inclusive","taxRate":15,"taxSystemTaxExempt":false,"taxSystemTaxExemptReason":"","showPayNow":true,"creditCardRequired":false,"shipmentCarriersCSV":"","excludeShipmentsCsv":null,"courierAccountCode":"","courierSiteID":null,"crmId":"","accountManagerName":"Alex Rivera","accountManagerEmail":"alex@example.com","tierLast12Months":"B","paymentTermDays":20,"paymentTermType":"FollowingMonthEnd","entityAddress":{"id":90211,"streetAddress":"12 Tannery Road","addressLine2":"","city":"Auckland","state":"","stateFull":"","postalCode":"1010","countryCode":"NZ","countryName":"New Zealand","contactName":"Sam Patel","organisation":"Riverside Print Co","phone":"+64 9 555 0100","emailAddress":"sam@example.com","addressSummaryOneLine":"12 Tannery Road, Auckland 1010, New Zealand"},"taxCertificates":[],"paymentMode":null,"paymentMethods":[]}}}}}},"401":{"description":"User is not authenticated — No valid bearer token. Request one from this region’s `/api/auth/token` with your `client_id` and `client_secret`, and send it as `Authorization: Bearer <token>`. A token from another region’s host will also produce this.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"Account not found — No such record, or it is not visible to your account. Credentials only ever see their own account’s data, so a valid identifier belonging to another customer answers exactly like one that does not exist.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getAccount"}},"/account/user":{"get":{"tags":["Account"],"summary":"Get current user profile","description":"Retrieves your user profile information including contact details, preferences, and notification settings.","responses":{"200":{"description":"User profile retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dto_Api_AccountUserInfo"},"examples":{"default":{"summary":"The user behind the current credentials","value":{"id":51188,"guid":"3f7c1e28-0000-4a1b-9c44-2b6d5e900001","customerId":4820,"customerName":"Riverside Print Co","userName":"spatel","firstName":"Sam","lastName":"Patel","emailAddress":"sam@example.com","active":true,"phone":"+64 9 555 0100","mobile":"","streetAddress":"12 Tannery Road","addressLine2":"","suburb":"","city":"Auckland","state":"","postalCode":"1010","country":"New Zealand","locationID":null,"locationName":null,"defaultPage":"","orderNumberPrefix":"","receiveEmails":true,"promotionRecipient":false,"receiveInvoice":true,"receiveInwards":false,"textNotifyProof":false,"textNotifyDispatch":false,"usernameLoginOnly":false,"lastLogin":"2026-08-01T09:14:22Z","loginCount":214}}}}}},"401":{"description":"User is not authenticated — No valid bearer token. Request one from this region’s `/api/auth/token` with your `client_id` and `client_secret`, and send it as `Authorization: Bearer <token>`. A token from another region’s host will also produce this.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"User not found — No such record, or it is not visible to your account. Credentials only ever see their own account’s data, so a valid identifier belonging to another customer answers exactly like one that does not exist.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getAccountUser"}},"/account/users":{"get":{"tags":["Account"],"summary":"Get list of users in organization","description":"Retrieves a paginated list of all users in your organization. Only available to customer administrators.\r\nSupports filtering by active status, text search, sorting, and pagination.","parameters":[{"name":"includeInactive","in":"query","description":"Include inactive users (default: false)","schema":{"type":"boolean","default":false}},{"name":"page","in":"query","description":"Page number, 1-based (default: 1)","schema":{"type":"integer","format":"int32","default":1}},{"name":"pageSize","in":"query","description":"Number of records per page (default: 50)","schema":{"type":"integer","format":"int32","default":50}},{"name":"sortBy","in":"query","description":"Column to sort by (default: LastName). Valid values: LastName, FirstName, UserName, Email, LastLoginUtc, LoginCount","schema":{"type":"string","default":"LastName"}},{"name":"sortDirection","in":"query","description":"Sort direction: ASC or DESC (default: ASC)","schema":{"type":"string","default":"ASC"}},{"name":"textFilter","in":"query","description":"Optional text filter to search username, first name, last name, or email","schema":{"type":"string"}}],"responses":{"200":{"description":"User list retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedDataOf1Codewolf_Ctrl_Api_Dto_Api_AccountUserSummary"},"examples":{"default":{"summary":"Users on the account (CustomerAdmin only)","value":{"pageSize":25,"returnedResults":1,"totalResults":1,"totalPages":1,"currentPage":1,"hasNext":false,"hasPrevious":false,"filter":null,"nextUrl":null,"previousUrl":null,"entities":[{"id":51188,"guid":"3f7c1e28-0000-4a1b-9c44-2b6d5e900001","userName":"spatel","firstName":"Sam","lastName":"Patel","emailAddress":"sam@example.com","active":true,"locationName":null,"usernameLoginOnly":false,"lastLogin":"2026-08-01T09:14:22Z","loginCount":214}]}}}}}},"401":{"description":"User is not authenticated — No valid bearer token. Request one from this region’s `/api/auth/token` with your `client_id` and `client_secret`, and send it as `Authorization: Bearer <token>`. A token from another region’s host will also produce this.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"User does not have admin privileges — Authenticated, but this operation is not available to your account’s role. Some operations require the account administrator role; others are back-office only and are not part of this published surface. Do not retry — it will not start working.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getAccountUsers"}},"/account/users/{userId}":{"get":{"tags":["Account"],"summary":"Get specific user details by user ID.\r\nValidates that the user belongs to the authenticated customer's organization.","parameters":[{"name":"userId","in":"path","description":"User ID to retrieve","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"Returns the user details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dto_Api_AccountUserInfo"},"examples":{"default":{"summary":"One user on the account (CustomerAdmin only)","value":{"id":51188,"guid":"3f7c1e28-0000-4a1b-9c44-2b6d5e900001","userName":"spatel","firstName":"Sam","lastName":"Patel","emailAddress":"sam@example.com","active":true,"locationName":null,"usernameLoginOnly":false,"lastLogin":"2026-08-01T09:14:22Z","loginCount":214}}}}}},"401":{"description":"Unauthorized - user not authenticated — No valid bearer token. Request one from this region’s `/api/auth/token` with your `client_id` and `client_secret`, and send it as `Authorization: Bearer <token>`. A token from another region’s host will also produce this.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"Forbidden - user does not have CustomerAdmin role — Authenticated, but this operation is not available to your account’s role. Some operations require the account administrator role; others are back-office only and are not part of this published surface. Do not retry — it will not start working.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"Not found - user does not exist or does not belong to the customer — No such record, or it is not visible to your account. Credentials only ever see their own account’s data, so a valid identifier belonging to another customer answers exactly like one that does not exist.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getAccountUsersByUserId","description":"One user on your account. Requires the account administrator role; an ordinary user credential receives a 403."}},"/account/transactions":{"get":{"tags":["Account"],"summary":"Get payment transaction history","description":"Retrieves a paginated list of payment transactions for the authenticated customer.\r\nIncludes card details (masked), amounts, and transaction status.","parameters":[{"name":"page","in":"query","description":"Page number, 1-based (default: 1)","schema":{"type":"integer","format":"int32","default":1}},{"name":"pageSize","in":"query","description":"Number of records per page (default: 20)","schema":{"type":"integer","format":"int32","default":20}},{"name":"sortBy","in":"query","description":"Column to sort by (default: Id). Valid values: Id, CreatedAt, CompletedAt, AmountSettlement","schema":{"type":"string","default":"Id"}},{"name":"sortDirection","in":"query","description":"Sort direction: ASC or DESC (default: DESC)","schema":{"type":"string","default":"DESC"}},{"name":"completedOnly","in":"query","description":"Filter to show only completed transactions (default: false)","schema":{"type":"boolean","default":false}},{"name":"textFilter","in":"query","description":"Optional text filter to search transaction details","schema":{"type":"string"}}],"responses":{"200":{"description":"Transaction list retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedDataOf1Codewolf_Ctrl_Api_Dto_Api_PaymentTransaction"},"examples":{"default":{"summary":"Invoices and payments, most recent first","value":{"pageSize":25,"returnedResults":0,"totalResults":0,"totalPages":1,"currentPage":1,"hasNext":false,"hasPrevious":false,"filter":null,"nextUrl":null,"previousUrl":null,"entities":[]}}}}}},"401":{"description":"User is not authenticated — No valid bearer token. Request one from this region’s `/api/auth/token` with your `client_id` and `client_secret`, and send it as `Authorization: Bearer <token>`. A token from another region’s host will also produce this.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getAccountTransactions"}},"/account/shipment-settings":{"get":{"tags":["Account"],"summary":"Get shipment settings","description":"Retrieves shipment configuration for your organization.","responses":{"200":{"description":"Shipment settings retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dto_Api_ShipmentSettings"},"examples":{"default":{"summary":"Carriers and freight rules configured for the account","value":{"availableCarriers":["NZC01"],"carrierOptions":["NZC01"],"receiverPays":{"billingAccountNumber":"","billingPostalCode":"","billingCountryCode":""},"showCustomerAddressOnLabel":true,"handlingFee":0,"applyHandlingFeeInsteadOfFreight":false,"jobComment":"","availableShipmentTypes":["Ground"],"shipmentTypeOptions":[{"code":"Ground","name":"GND"}],"freightRates":[{"carrier":"NZC01","carrierName":"Courier","service":null,"serviceName":null,"package":null,"packageName":null,"chargeType":"FlatRatePerJob","value":12.5,"minimum":null,"isDefault":true}]}}}}}},"401":{"description":"User is not authenticated — No valid bearer token. Request one from this region’s `/api/auth/token` with your `client_id` and `client_secret`, and send it as `Authorization: Bearer <token>`. A token from another region’s host will also produce this.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"Customer config not found — No such record, or it is not visible to your account. Credentials only ever see their own account’s data, so a valid identifier belonging to another customer answers exactly like one that does not exist.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getAccountShipmentsettings"}},"/Assets/{assetTag}":{"get":{"tags":["Assets"],"summary":"Gets an individual Assets information","description":"One asset by its tag. Use it to read the reset charge and price bands a reorder will be billed at, and to see whether the customer has retired the design — `isArchived`. ⚠️ Archived is a warning to surface, not a gate: an order referencing an archived asset is still accepted.","parameters":[{"name":"assetTag","in":"path","description":"The asset tag, as returned by `GET /Assets` — the identifier of a decoration we have already made for you.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_AssetDtos_AssetDto"},{"$ref":"#/components/schemas/Codewolf_Api_Support_AssetDtos_AssetExtendedDto"}],"description":"Describes an Asset Dtos"},"examples":{"default":{"summary":"One asset by tag","value":{"assetId":774301,"assetTag":"EW49123","processCode":"DG","description":"Riverside Rugby crest — left chest","garment":"Navy polo","priceTierCode":"B","setup":0,"reset":18.5,"priceCode":"DG_DIGICAD_FLEX220:Cad Cut Film-Flex 220","assetUrl":"https://example.com/assets/EW49123/preview","createDate":"2026-06-18T22:41:05Z","isGlobal":false,"isArchived":false,"priceBands":[{"from":10,"to":19,"unitPrice":4.95},{"from":20,"to":49,"unitPrice":3.6},{"from":50,"to":99,"unitPrice":3.05},{"from":100,"to":null,"unitPrice":2.85}]}}}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_AssetDtos_AssetDto"},{"$ref":"#/components/schemas/Codewolf_Api_Support_AssetDtos_AssetExtendedDto"}],"description":"Describes an Asset Dtos"},"examples":{"default":{"summary":"One asset by tag","value":{"assetId":774301,"assetTag":"EW49123","processCode":"DG","description":"Riverside Rugby crest — left chest","garment":"Navy polo","priceTierCode":"B","setup":0,"reset":18.5,"priceCode":"DG_DIGICAD_FLEX220:Cad Cut Film-Flex 220","assetUrl":"https://example.com/assets/EW49123/preview","createDate":"2026-06-18T22:41:05Z","isGlobal":false,"isArchived":false,"priceBands":[{"from":10,"to":19,"unitPrice":4.95},{"from":20,"to":49,"unitPrice":3.6},{"from":50,"to":99,"unitPrice":3.05},{"from":100,"to":null,"unitPrice":2.85}]}}}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_AssetDtos_AssetDto"},{"$ref":"#/components/schemas/Codewolf_Api_Support_AssetDtos_AssetExtendedDto"}],"description":"Describes an Asset Dtos"},"examples":{"default":{"summary":"One asset by tag","value":{"assetId":774301,"assetTag":"EW49123","processCode":"DG","description":"Riverside Rugby crest — left chest","garment":"Navy polo","priceTierCode":"B","setup":0,"reset":18.5,"priceCode":"DG_DIGICAD_FLEX220:Cad Cut Film-Flex 220","assetUrl":"https://example.com/assets/EW49123/preview","createDate":"2026-06-18T22:41:05Z","isGlobal":false,"isArchived":false,"priceBands":[{"from":10,"to":19,"unitPrice":4.95},{"from":20,"to":49,"unitPrice":3.6},{"from":50,"to":99,"unitPrice":3.05},{"from":100,"to":null,"unitPrice":2.85}]}}}}}},"403":{"description":"Forbidden — Authenticated, but this operation is not available to your account’s role. Some operations require the account administrator role; others are back-office only and are not part of this published surface. Do not retry — it will not start working.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"No asset with that tag on your account. Asset tags are per-account; list yours with `GET /Assets`."}},"security":[{"oauth2":[]}],"operationId":"getAssetsByAssetTag"}},"/Assets":{"get":{"tags":["Assets"],"summary":"Gets all of the Assets","parameters":[{"name":"page","in":"query","description":"The page number","schema":{"type":"integer","format":"int32","default":1}},{"name":"pageSize","in":"query","description":"The size of the Page in rows","schema":{"type":"integer","format":"int32","default":25}},{"name":"sortColumn","in":"query","description":"Column to sort by","schema":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Enums_AssetSortColumn"}],"default":"AssetTag"}},{"name":"sortDirection","in":"query","description":"Sort direction (ascending or descending)","schema":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Enums_SortDirection"}],"default":"Ascending"}},{"name":"includeProcesses","in":"query","description":"(optional)If passed, can contain a list of Process codes to include (comma separated)","schema":{"type":"string"}},{"name":"excludeProcesses","in":"query","description":"(optional)If passed, can contain a list of Process codes to exclude (comma separated)","schema":{"type":"string"}},{"name":"filter","in":"query","description":"(optional)If passed will filter the search using the filter text","schema":{"type":"string"}},{"name":"isArchived","in":"query","description":"(optional)If true, returns only archived assets. If false, only non-archived. If omitted, returns both.","schema":{"type":"boolean"}},{"name":"priceCodeContains","in":"query","description":"(optional)Comma-separated case-insensitive substrings. Asset is included if its PriceCode contains ANY of them. NULL PriceCodes are excluded.","schema":{"type":"string"}},{"name":"priceCodeNotContains","in":"query","description":"(optional)Comma-separated case-insensitive substrings. Asset is included if its PriceCode contains NONE of them, including assets with NULL PriceCode.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/PagedDataOf1Codewolf_Ctrl_Api_Dtos_Api_AssetListDto"},"examples":{"default":{"summary":"Prints already made for this account — reorder any of them by asset tag","value":{"pageSize":25,"returnedResults":1,"totalResults":42,"totalPages":1,"currentPage":1,"hasNext":false,"hasPrevious":false,"filter":null,"nextUrl":null,"previousUrl":null,"entities":[{"assetId":774301,"assetTag":"EW49123","processCode":"DG","description":"Riverside Rugby crest — left chest","garment":"Navy polo","priceTierCode":"B","setup":0,"reset":18.5,"priceCode":"DG_DIGICAD_FLEX220:Cad Cut Film-Flex 220","assetUrl":"https://example.com/assets/EW49123/preview","createDate":"2026-06-18T22:41:05Z","isGlobal":false,"isArchived":false,"priceBands":[{"from":10,"to":19,"unitPrice":4.95},{"from":20,"to":49,"unitPrice":3.6},{"from":50,"to":99,"unitPrice":3.05},{"from":100,"to":null,"unitPrice":2.85}]}]}}}},"application/json":{"schema":{"$ref":"#/components/schemas/PagedDataOf1Codewolf_Ctrl_Api_Dtos_Api_AssetListDto"},"examples":{"default":{"summary":"Prints already made for this account — reorder any of them by asset tag","value":{"pageSize":25,"returnedResults":1,"totalResults":42,"totalPages":1,"currentPage":1,"hasNext":false,"hasPrevious":false,"filter":null,"nextUrl":null,"previousUrl":null,"entities":[{"assetId":774301,"assetTag":"EW49123","processCode":"DG","description":"Riverside Rugby crest — left chest","garment":"Navy polo","priceTierCode":"B","setup":0,"reset":18.5,"priceCode":"DG_DIGICAD_FLEX220:Cad Cut Film-Flex 220","assetUrl":"https://example.com/assets/EW49123/preview","createDate":"2026-06-18T22:41:05Z","isGlobal":false,"isArchived":false,"priceBands":[{"from":10,"to":19,"unitPrice":4.95},{"from":20,"to":49,"unitPrice":3.6},{"from":50,"to":99,"unitPrice":3.05},{"from":100,"to":null,"unitPrice":2.85}]}]}}}},"text/json":{"schema":{"$ref":"#/components/schemas/PagedDataOf1Codewolf_Ctrl_Api_Dtos_Api_AssetListDto"},"examples":{"default":{"summary":"Prints already made for this account — reorder any of them by asset tag","value":{"pageSize":25,"returnedResults":1,"totalResults":42,"totalPages":1,"currentPage":1,"hasNext":false,"hasPrevious":false,"filter":null,"nextUrl":null,"previousUrl":null,"entities":[{"assetId":774301,"assetTag":"EW49123","processCode":"DG","description":"Riverside Rugby crest — left chest","garment":"Navy polo","priceTierCode":"B","setup":0,"reset":18.5,"priceCode":"DG_DIGICAD_FLEX220:Cad Cut Film-Flex 220","assetUrl":"https://example.com/assets/EW49123/preview","createDate":"2026-06-18T22:41:05Z","isGlobal":false,"isArchived":false,"priceBands":[{"from":10,"to":19,"unitPrice":4.95},{"from":20,"to":49,"unitPrice":3.6},{"from":50,"to":99,"unitPrice":3.05},{"from":100,"to":null,"unitPrice":2.85}]}]}}}}}},"403":{"description":"Forbidden — Authenticated, but this operation is not available to your account’s role. Some operations require the account administrator role; others are back-office only and are not part of this published surface. Do not retry — it will not start working.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getAssets","description":"Prints already made for your account. Each carries an asset tag; ordering that tag again reproduces the previous run exactly, with no artwork upload and no colour re-approval."}},"/Assets/global":{"get":{"tags":["Assets"],"summary":"Gets all of the Global Assets","parameters":[{"name":"page","in":"query","description":"The page number","schema":{"type":"integer","format":"int32","default":1}},{"name":"pageSize","in":"query","description":"The size of the Page in rows","schema":{"type":"integer","format":"int32","default":25}},{"name":"sortColumn","in":"query","description":"Column to sort by","schema":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Enums_AssetSortColumn"}],"default":"AssetTag"}},{"name":"sortDirection","in":"query","description":"Sort direction (ascending or descending)","schema":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Enums_SortDirection"}],"default":"Ascending"}},{"name":"includeProcesses","in":"query","description":"(optional)If passed, can contain a list of Process codes to include (comma separated)","schema":{"type":"string"}},{"name":"excludeProcesses","in":"query","description":"(optional)If passed, can contain a list of Process codes to exclude (comma separated)","schema":{"type":"string"}},{"name":"filter","in":"query","description":"(optional)If passed will filter the search using the filter text","schema":{"type":"string"}},{"name":"isArchived","in":"query","description":"(optional)If true, returns only archived assets. If false, only non-archived. If omitted, returns both.","schema":{"type":"boolean"}},{"name":"priceCodeContains","in":"query","description":"(optional)Comma-separated case-insensitive substrings. Asset is included if its PriceCode contains ANY of them. NULL PriceCodes are excluded.","schema":{"type":"string"}},{"name":"priceCodeNotContains","in":"query","description":"(optional)Comma-separated case-insensitive substrings. Asset is included if its PriceCode contains NONE of them, including assets with NULL PriceCode.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/PagedDataOf1Codewolf_Ctrl_Api_Dtos_Api_AssetListDto"},"examples":{"default":{"summary":"Catalogue assets available to every account","value":{"pageSize":25,"returnedResults":1,"totalResults":1,"totalPages":1,"currentPage":1,"hasNext":false,"hasPrevious":false,"filter":null,"nextUrl":null,"previousUrl":null,"entities":[{"assetId":5012,"assetTag":"GL00042","processCode":"STOCK","description":"Care label","garment":null,"priceTierCode":"","setup":0,"reset":0,"priceCode":null,"assetUrl":null,"createDate":"2025-11-02T03:15:00Z","isGlobal":true,"isArchived":false,"priceBands":[{"from":1,"to":null,"unitPrice":0.35}]}]}}}},"application/json":{"schema":{"$ref":"#/components/schemas/PagedDataOf1Codewolf_Ctrl_Api_Dtos_Api_AssetListDto"},"examples":{"default":{"summary":"Catalogue assets available to every account","value":{"pageSize":25,"returnedResults":1,"totalResults":1,"totalPages":1,"currentPage":1,"hasNext":false,"hasPrevious":false,"filter":null,"nextUrl":null,"previousUrl":null,"entities":[{"assetId":5012,"assetTag":"GL00042","processCode":"STOCK","description":"Care label","garment":null,"priceTierCode":"","setup":0,"reset":0,"priceCode":null,"assetUrl":null,"createDate":"2025-11-02T03:15:00Z","isGlobal":true,"isArchived":false,"priceBands":[{"from":1,"to":null,"unitPrice":0.35}]}]}}}},"text/json":{"schema":{"$ref":"#/components/schemas/PagedDataOf1Codewolf_Ctrl_Api_Dtos_Api_AssetListDto"},"examples":{"default":{"summary":"Catalogue assets available to every account","value":{"pageSize":25,"returnedResults":1,"totalResults":1,"totalPages":1,"currentPage":1,"hasNext":false,"hasPrevious":false,"filter":null,"nextUrl":null,"previousUrl":null,"entities":[{"assetId":5012,"assetTag":"GL00042","processCode":"STOCK","description":"Care label","garment":null,"priceTierCode":"","setup":0,"reset":0,"priceCode":null,"assetUrl":null,"createDate":"2025-11-02T03:15:00Z","isGlobal":true,"isArchived":false,"priceBands":[{"from":1,"to":null,"unitPrice":0.35}]}]}}}}}},"403":{"description":"Forbidden — Authenticated, but this operation is not available to your account’s role. Some operations require the account administrator role; others are back-office only and are not part of this published surface. Do not retry — it will not start working.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getAssetsGlobal","description":"Catalogue assets available to every account, rather than ones your account created. Order them exactly like your own: `itemType: \"Asset\"` with the tag as `code`."}},"/Assets/types":{"get":{"tags":["Assets"],"summary":"Gets all of the Asset Types","responses":{"200":{"description":"Success","content":{"text/plain":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_AssetDtos_AssetTypeDto"}},"examples":{"default":{"summary":"Asset type per process code","value":[{"process":"EW","assetType":"Embroidery"},{"process":"MG","assetType":"Direct Screen"},{"process":"DG","assetType":"Digital Transfers"}]}}},"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_AssetDtos_AssetTypeDto"}},"examples":{"default":{"summary":"Asset type per process code","value":[{"process":"EW","assetType":"Embroidery"},{"process":"MG","assetType":"Direct Screen"},{"process":"DG","assetType":"Digital Transfers"}]}}},"text/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_AssetDtos_AssetTypeDto"}},"examples":{"default":{"summary":"Asset type per process code","value":[{"process":"EW","assetType":"Embroidery"},{"process":"MG","assetType":"Direct Screen"},{"process":"DG","assetType":"Digital Transfers"}]}}}}},"403":{"description":"Forbidden — Authenticated, but this operation is not available to your account’s role. Some operations require the account administrator role; others are back-office only and are not part of this published surface. Do not retry — it will not start working.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getAssetsTypes","description":"Which asset type each process produces. Useful for labelling assets in your own UI without hardcoding a mapping that changes."}},"/Assets/{assetTag}/files":{"get":{"tags":["Assets"],"summary":"Get all files associated with an asset","parameters":[{"name":"assetTag","in":"path","description":"The asset tag, as returned by `GET /Assets`.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_AssetFilesResponseDto"},"examples":{"default":{"summary":"Files attached to an asset, current and superseded","value":{"assetTag":"EW49123","currentFiles":[],"historicFiles":[]}}}},"application/json":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_AssetFilesResponseDto"},"examples":{"default":{"summary":"Files attached to an asset, current and superseded","value":{"assetTag":"EW49123","currentFiles":[],"historicFiles":[]}}}},"text/json":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_AssetFilesResponseDto"},"examples":{"default":{"summary":"Files attached to an asset, current and superseded","value":{"assetTag":"EW49123","currentFiles":[],"historicFiles":[]}}}}}},"403":{"description":"Forbidden — Authenticated, but this operation is not available to your account’s role. Some operations require the account administrator role; others are back-office only and are not part of this published surface. Do not retry — it will not start working.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"Not Found — No such record, or it is not visible to your account. Credentials only ever see their own account’s data, so a valid identifier belonging to another customer answers exactly like one that does not exist.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getAssetsByAssetTagFiles","description":"The artwork files held against an asset, current and superseded. `historicFiles` records what was replaced and when."}},"/Assets/{assetCode}/jobs":{"get":{"tags":["Assets"],"summary":"Get all jobs associated with a specific asset code for the authenticated customer","description":"Returns both active and closed jobs for the authenticated customer only.\r\nCustomer ID is extracted from the authentication context.\r\nFilters by Job's customer (CustID), not Asset's ClientID.\r\n            \r\nSorting: Active jobs (dateOut=null) appear FIRST at the top,\r\nfollowed by completed/shipped jobs sorted by dateOut descending (most recent first).\r\n            \r\nUsed by SC Integrate to display Order History on asset detail pages.","parameters":[{"name":"assetCode","in":"path","description":"The asset tag, as returned by `GET /Assets`.","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved job list","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_AssetJobsResponseDto"},"examples":{"default":{"summary":"Every job this asset has been run on","value":{"assetCode":"EW49123","jobs":[],"totalCount":0}}}},"application/json":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_AssetJobsResponseDto"},"examples":{"default":{"summary":"Every job this asset has been run on","value":{"assetCode":"EW49123","jobs":[],"totalCount":0}}}},"text/json":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_AssetJobsResponseDto"},"examples":{"default":{"summary":"Every job this asset has been run on","value":{"assetCode":"EW49123","jobs":[],"totalCount":0}}}}}},"400":{"description":"Invalid asset code provided — The request was rejected before anything happened. Read the response body — validation failures come back as `{ \"isValid\": false, \"validationMessages\": [{ \"errorCode\", \"message\" }] }`. Retrying an unchanged request will fail identically.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"401":{"description":"Unauthorized - customer ID not found in authentication context — No valid bearer token. Request one from this region’s `/api/auth/token` with your `client_id` and `client_secret`, and send it as `Authorization: Bearer <token>`. A token from another region’s host will also produce this.","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"500":{"description":"Internal server error — An unexpected server error. Retry once with backoff; if it persists, contact your account manager with the time of the request and the endpoint."}},"security":[{"oauth2":[]}],"operationId":"getAssetsByAssetCodeJobs"}},"/Boms/{bomCode}":{"get":{"tags":["Boms"],"summary":"Gets an individual BOM's information, by its BOM code or by any of its variant codes.","parameters":[{"name":"bomCode","in":"path","description":"The BOM code, as returned by `GET /Boms` — the product, not one of its size variants. ⛔ Order by the `bomVariantCode` this call returns, never by joining the code and a size.","required":true,"schema":{"type":"string"}},{"name":"includeItems","in":"query","description":"When true, returns the BOM's composition on `items` — the garment plus its branding\r\nlines, each with its asset code, process code and position on the garment. Omitted (null)\r\nby default so the default response shape is unchanged.","schema":{"type":"boolean","default":false}},{"name":"includeArchived","in":"query","description":"When true, an archived (inactive) BOM is returned, and its inactive variants are included.\r\nHard-deleted BOMs are never returned. Defaults to false.","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Codewolf_Api_Support_BomDtos_BomDto"},{"$ref":"#/components/schemas/Codewolf_Api_Support_BomDtos_BomExtendedDto"}],"description":"describes a BOM (Bill of Materials) Lookup Item"},"examples":{"default":{"summary":"One BOM and its size variants — order by bomVariantCode, never by concatenation","value":{"id":41207,"bomCode":"BOM10112","title":"Riverside Rugby — club polo, navy","description":"Navy pique polo, embroidered club crest left chest.","range":"Riverside Rugby","customerSku":"RRC-POLO-NAVY","bomVariants":[{"bomVariantCode":"BOM10112-S","size":"S","customerVariantSku":"RRC-POLO-NAVY-S"},{"bomVariantCode":"BOM10112-M","size":"M","customerVariantSku":"RRC-POLO-NAVY-M"},{"bomVariantCode":"BOM10112-L","size":"L","customerVariantSku":"RRC-POLO-NAVY-L"},{"bomVariantCode":"BOM10112-72R","size":"72","customerVariantSku":null}]}}}}}},"403":{"description":"Forbidden — Authenticated, but this operation is not available to your account’s role. Some operations require the account administrator role; others are back-office only and are not part of this published surface. Do not retry — it will not start working.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"Not Found — No such record, or it is not visible to your account. Credentials only ever see their own account’s data, so a valid identifier belonging to another customer answers exactly like one that does not exist.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getBomsByBomCode","description":"One BOM with its variants — one variant per size, each with its own `bomVariantCode` and your own `customerVariantSku` if you have set one. ⛔ Order by the `bomVariantCode` you read here. It is *usually* `{bomCode}-{size}` and 197 EW variants are not, so building it by concatenation works until it silently orders a size that does not exist. On the job line, `customName` carries a per-item personalisation (a back name); leave it out and the BOM explodes as usual."}},"/Boms":{"get":{"tags":["Boms"],"summary":"Get the BOMs available to the logged-on user's customer.","parameters":[{"name":"filter","in":"query","description":"Substring matched against the BOM code or any variant code.","schema":{"type":"string"}},{"name":"includeItems","in":"query","description":"When true, returns each BOM's composition on `items`. Opt-in because it is a second\r\nquery and fans the response out across every item of every BOM returned.","schema":{"type":"boolean","default":false}},{"name":"includeArchived","in":"query","description":"When true, archived (inactive) BOMs are included, along with their inactive variants.\r\nHard-deleted BOMs are never returned. Defaults to false.","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"The made-up products this account can order (truncated — the real answer is thousands)","content":{"application/json":{"schema":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/Codewolf_Api_Support_BomDtos_BomDto"},{"$ref":"#/components/schemas/Codewolf_Api_Support_BomDtos_BomExtendedDto"}],"description":"describes a BOM (Bill of Materials) Lookup Item"}},"examples":{"default":{"summary":"The made-up products this account can order (truncated — the real answer is thousands)","value":[{"id":41207,"bomCode":"BOM10112","title":"Riverside Rugby — club polo, navy","description":"Navy pique polo, embroidered club crest left chest.","range":"Riverside Rugby","customerSku":"RRC-POLO-NAVY","bomVariants":[{"bomVariantCode":"BOM10112-S","size":"S","customerVariantSku":"RRC-POLO-NAVY-S"},{"bomVariantCode":"BOM10112-M","size":"M","customerVariantSku":"RRC-POLO-NAVY-M"},{"bomVariantCode":"BOM10112-72R","size":"72","customerVariantSku":null}]},{"id":41208,"bomCode":"BOM10113","title":"Riverside Rugby — kit bag","description":"Team kit bag, printed club crest.","range":"Riverside Rugby","customerSku":null,"bomVariants":[{"bomVariantCode":"BOM10113-QTY","size":"Qty","customerVariantSku":null}]}]}}}}},"403":{"description":"Forbidden — Authenticated, but this operation is not available to your account’s role. Some operations require the account administrator role; others are back-office only and are not part of this published surface. Do not retry — it will not start working.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getBoms","description":"The made-up products we can supply you: a garment with its decoration already specified, ordered as one unit. ⚠️ Measured on 2026-08-28: this returns EVERY BOM in one ~4 MB unpaged response (5,724 of them on a real account). Pull it on a schedule and cache it — never per order, and never per page render."}},"/Inwards":{"get":{"tags":["Inwards"],"summary":"List inwards records for the authenticated customer, with optional filters.","parameters":[{"name":"allocated","in":"query","description":"false = unallocated (job=0), true = allocated (job>0)","schema":{"type":"boolean"}},{"name":"dateFrom","in":"query","description":"Filter by delivery date from (ISO 8601)","schema":{"type":"string","format":"date-time"}},{"name":"dateTo","in":"query","description":"Filter by delivery date to (ISO 8601)","schema":{"type":"string","format":"date-time"}},{"name":"status","in":"query","description":"Filter by status name (e.g. \"Arrived\")","schema":{"type":"string"}},{"name":"jobNumber","in":"query","description":"Return only the deliveries assigned to this job. A job belonging to another customer\r\nreturns an empty page rather than an error — the endpoint does not disclose whether a\r\njob number it cannot show you exists.","schema":{"type":"integer","format":"int32"}},{"name":"page","in":"query","description":"Page number (1-based, default 1)","schema":{"type":"integer","format":"int32","default":1}},{"name":"pageSize","in":"query","description":"Items per page (default 20, max 100)","schema":{"type":"integer","format":"int32","default":20}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_InwardsListResponseDto"},"examples":{"default":{"summary":"Deliveries you have sent in, newest first — one allocated to a job, one not yet","value":{"data":[{"id":88213,"orderNumber":"PO-10482","supplier":"Riverside Print Co","dateIn":"2026-09-02T00:00:00","cartons":3,"packageType":"Carton","totalQuantity":45,"itemCount":1,"status":"Arrived","isAllocated":true,"jobNumber":612226,"description":"RRC-POLO-NAVY Polo Navy"},{"id":88240,"orderNumber":"PO-10515","supplier":"Riverside Print Co","dateIn":null,"cartons":1,"packageType":"Satchel","totalQuantity":20,"itemCount":1,"status":"Awaiting Arrival","isAllocated":false,"jobNumber":null,"description":"RRC-TEE-WHITE Tee White"}],"page":1,"pageSize":25,"totalItems":2,"totalPages":1}}}}}},"401":{"description":"Unauthorized — No valid bearer token. Request one from this region’s `/api/auth/token` with your `client_id` and `client_secret`, and send it as `Authorization: Bearer <token>`. A token from another region’s host will also produce this.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"500":{"description":"Server Error — An unexpected server error. Retry once with backoff; if it persists, contact your account manager with the time of the request and the endpoint.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"operationId":"getInwards","description":"Goods you have sent in to be decorated, newest first and paged. Each row carries the order number you shipped under, the supplier, carton count, total quantity, its status, and `isAllocated`/`jobNumber` once it has been matched to a job. ⚠️ `status` has very little variance in practice — nearly every record reads `Arrived` — so `isAllocated` is the field that actually tells you where a delivery has got to."}},"/Inwards/{id}":{"get":{"tags":["Inwards"],"summary":"Get a single inwards record (header + items) for the authenticated customer.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"},"description":"The delivery id, as returned by `GET /Inwards`. Not your order number."}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_InwardsDto"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_PatchInwardsResponseDto"}],"description":"Detailed representation of an inwards record including items."},"examples":{"default":{"summary":"One delivery, item by item, counted per size","value":{"supplierId":4412,"dateDue":"2026-09-02T00:00:00","shelfLocation":"B14","comment":"Left of the roller door.","packingSlipNumber":"ORN0073086","items":[{"id":130551,"code":"RRC-POLO-NAVY","garment":"Polo","colour":"Navy","sizeSetId":12,"sizeSet":"Adult S-3XL","quantities":[{"size":"S","qty":10},{"size":"M","qty":20},{"size":"L","qty":15}],"total":45}]}}}}}},"401":{"description":"Unauthorized — No valid bearer token. Request one from this region’s `/api/auth/token` with your `client_id` and `client_secret`, and send it as `Authorization: Bearer <token>`. A token from another region’s host will also produce this.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"Not Found — No such record, or it is not visible to your account. Credentials only ever see their own account’s data, so a valid identifier belonging to another customer answers exactly like one that does not exist.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"500":{"description":"Server Error — An unexpected server error. Retry once with backoff; if it persists, contact your account manager with the time of the request and the endpoint.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"operationId":"getInwardsById","description":"One delivery in full: every item with its garment, colour, size set and per-size quantities — what actually arrived, against what was expected. The size set names an ordered run from `GET /Lookups/size-sets`; a line returns only its non-zero sizes, so read the order from the size set rather than from the item."}},"/Jobs/{jobNumber}":{"get":{"tags":["Jobs"],"summary":"Get the full Job information","parameters":[{"name":"jobNumber","in":"path","description":"A Job Number","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobDto"},"examples":{"default":{"summary":"Full job detail — status, money, lines and tracking","value":{"customerId":4820,"dateIn":"2026-08-01T02:10:00Z","dateOut":null,"shippedDateStatus":null,"shippedDaysToProcess":null,"processingDays":3,"taxTotal":24.53,"isCancelable":false,"location":null,"permissions":{"canEdit":true,"lockedReason":null},"invoiceFile":null,"lines":[{"jobLineId":990412,"assetSku":"EW49123","processCode":"DG","garment":"Navy polo","description":"Riverside Rugby crest — left chest","comments":null,"quantity":45,"unitPrice":3.6,"customerReference":"PO-10482-1","imageUrl":"https://example.com/assets/EW49123/preview","gang":null,"jobLineStatus":"In production"}],"shippingAddresses":[{"trackingNumber":null,"trackingLink":null}]}}}}}},"403":{"description":"Forbidden — Authenticated, but this operation is not available to your account’s role. Some operations require the account administrator role; others are back-office only and are not part of this published surface. Do not retry — it will not start working.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"Not Found — No job with that number on your account. `GET /Jobs/active` lists everything currently open.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getJobsByJobNumber","description":"Full job detail: status, money, artwork state and tracking once despatched. Status values come from `GET /Lookups/job-statuses` — read that list rather than matching strings you have seen before."},"patch":{"tags":["Jobs"],"summary":"Patch job details","parameters":[{"name":"jobNumber","in":"path","description":"The job number to update","required":true,"schema":{"type":"integer","format":"int32"}}],"requestBody":{"description":"The patch data containing fields to update. Only non-null fields are updated. The locationCode field is SuperUser-only.","content":{"application/json-patch+json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dto_PatchJobDto"}],"description":"DTO for patching job details"},"examples":{"default":{"summary":"Amend the PO number and push the ship date out — omitted fields are left alone","value":{"orderNumber":"PO-10482-REV2","dateDue":"2026-08-21","comments":"Customer asked to hold for the revised crest."}}}},"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dto_PatchJobDto"}],"description":"DTO for patching job details"},"examples":{"default":{"summary":"Amend the PO number and push the ship date out — omitted fields are left alone","value":{"orderNumber":"PO-10482-REV2","dateDue":"2026-08-21","comments":"Customer asked to hold for the revised crest."}}}},"text/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dto_PatchJobDto"}],"description":"DTO for patching job details"},"examples":{"default":{"summary":"Amend the PO number and push the ship date out — omitted fields are left alone","value":{"orderNumber":"PO-10482-REV2","dateDue":"2026-08-21","comments":"Customer asked to hold for the revised crest."}}}},"application/*+json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dto_PatchJobDto"}],"description":"DTO for patching job details"},"examples":{"default":{"summary":"Amend the PO number and push the ship date out — omitted fields are left alone","value":{"orderNumber":"PO-10482-REV2","dateDue":"2026-08-21","comments":"Customer asked to hold for the revised crest."}}}}}},"responses":{"200":{"description":"Job details updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobDto"},"examples":{"default":{"summary":"The updated job — the same shape GET /Jobs/{jobNumber} returns","value":{"customerId":4820,"dateIn":"2026-08-01T02:10:00Z","dateOut":null,"shippedDateStatus":null,"shippedDaysToProcess":null,"processingDays":3,"taxTotal":24.53,"isCancelable":true,"location":null,"permissions":{"canEdit":true,"lockedReason":null},"invoiceFile":null,"lines":[{"jobLineId":990412,"assetSku":"EW49123","processCode":"DG","garment":"Navy polo","description":"Riverside Rugby crest — left chest","comments":null,"quantity":45,"unitPrice":3.6,"customerReference":"PO-10482-1","imageUrl":"https://example.com/assets/EW49123/preview","gang":null,"jobLineStatus":"In production"}],"shippingAddresses":[{"trackingNumber":null,"trackingLink":null}]}}}}}},"400":{"description":"Invalid location code (does not exist, inactive, or virtual) — The request was rejected before anything happened. Read the response body — validation failures come back as `{ \"isValid\": false, \"validationMessages\": [{ \"errorCode\", \"message\" }] }`. Retrying an unchanged request will fail identically.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"401":{"description":"Unauthorized — No valid bearer token. Request one from this region’s `/api/auth/token` with your `client_id` and `client_secret`, and send it as `Authorization: Bearer <token>`. A token from another region’s host will also produce this.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"Job is locked for editing, or a non-SuperUser supplied locationCode (see response body for reason) — Authenticated, but this operation is not available to your account’s role. Some operations require the account administrator role; others are back-office only and are not part of this published surface. Do not retry — it will not start working.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"Job not found — No such record, or it is not visible to your account. Credentials only ever see their own account’s data, so a valid identifier belonging to another customer answers exactly like one that does not exist.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"updateJobsByJobNumber","description":"Amend a job after submitting it — the description, your PO number, the comments, the requested ship date and the must-ship flag. ⚠️ Check `permissions.canEdit` on `GET /Jobs/{jobNumber}` first: a job locks once it is dispatched, closed, returned or cancelled, and `permissions.lockedReason` says which. Send only the fields you are changing; anything you omit is left alone. Returns the updated job."}},"/Jobs/delivery-options":{"get":{"tags":["Jobs"],"summary":"Get delivery options available to customer","responses":{"200":{"description":"Delivery methods available to this account","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Interfaces_IDeliveryOption"}},"examples":{"default":{"summary":"Delivery methods available to this account","value":[{"code":"Ground","label":"GND","isCollection":false,"rank":10,"gangRank":0,"value":"Ground","deliveryLabelEnabled":false},{"code":"Will Collect","label":"COL","isCollection":true,"rank":90,"gangRank":0,"value":"Will Collect","deliveryLabelEnabled":false}]}}}}},"403":{"description":"Forbidden — Authenticated, but this operation is not available to your account’s role. Some operations require the account administrator role; others are back-office only and are not part of this published surface. Do not retry — it will not start working.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getJobsDeliveryoptions","description":"Delivery methods your account can use. The returned method code goes in `deliveryAddress.deliveryMethod` on `POST /Jobs`. Availability varies by region and account, so read it rather than assuming a carrier."}},"/Jobs/earliest-ship-date":{"get":{"tags":["Jobs"],"summary":"Get calculated shipping date based on process codes","description":"The soonest despatch date, accounting for factory workload and cut-offs — so never assume a fixed lead time. Returns `shippingDateUtc`, `shippingDateLocal`, the factory `timezone` as an IANA name, and `dateExclusions`. ⛔ Take the DATE from `shippingDateLocal`: `dateDue` is a calendar date in factory-local terms, and the UTC instant lands on the previous or next day either side of midnight. ⚠️ `processCodes` is optional and, measured on 2026-08-29, made NO difference to the answer on this tenant — the same date came back for `EW`, `MG`, `EW,MG` and for a code that does not exist. Send the codes you are ordering anyway (it is the documented input and may bind on other tenants or later), but do not model per-process lead times on it, and do not treat a differing answer as impossible.","parameters":[{"name":"processCodes","in":"query","description":"Optional comma-separated process codes (e.g., \"PR,WE\")","schema":{"type":"string"}}],"responses":{"200":{"description":"Shipping date calculated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dto_ShippingDateResponseDto"},"examples":{"default":{"summary":"Soonest despatch for the processes being quoted","value":{"shippingDateUtc":"2026-08-05T18:00:00+00:00","shippingDateLocal":"2026-08-06T06:00:00+12:00","timezone":"Pacific/Auckland","dateExclusions":[]}}}}}},"401":{"description":"User is not authenticated — No valid bearer token. Request one from this region’s `/api/auth/token` with your `client_id` and `client_secret`, and send it as `Authorization: Bearer <token>`. A token from another region’s host will also produce this.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"User not found or no shipping date available — No such record, or it is not visible to your account. Credentials only ever see their own account’s data, so a valid identifier belonging to another customer answers exactly like one that does not exist.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getJobsEarliestshipdate"}},"/Jobs":{"post":{"tags":["Jobs"],"summary":"Create a job","parameters":[{"name":"X-Application-Name","in":"header","description":"An Valid OriginCode value (this will be validated)","schema":{"type":"string","default":"API"}}],"requestBody":{"description":"The job candidate","content":{"application/json-patch+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobCandidate"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ShopJobs_ShopJobCandidate"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ShopifyJobs_CustomerShopJobCandidate"}],"description":"Job class to enable the creation of jobs from the web API"},"examples":{"default":{"summary":"Dry run — garments you sent in, decorated. This is the WHOLE payload, artwork included: to create the job, send these same bytes with validateOnly false, and the response example is what comes back. ⛔ `externalArtworkUrl` must be an absolute https URL on an origin approved for your account (otherwise error 10408 or 10403), and if any PriceCode line carries it they all must (10404). (Ordering a made-to-order garment is a different shape — see the BOM section.)","value":{"validateOnly":true,"orderNumber":"PO-10482","description":"Riverside Rugby — club polos","dateDue":"2026-09-14","mustDate":false,"items":[{"itemType":"ExternalGarment","groupHead":"navy-polos","garment":"Navy polo — customer supplied","description":"Arriving under PO-10482, 3 cartons","customerReference":"PO-10482-G","sizeQuantities":{"S":10,"M":20,"L":15}},{"itemType":"PriceCode","group":"navy-polos","code":"DG_DIGICAD_FLEX220:Cad Cut Film-Flex 220","quantity":45,"customerReference":"PO-10482-1","attributes":{"description":"Club crest, left chest","garment":"Navy polo","Position":"Left chest 80mmW","Colours":"PMS 288C, PMS 186C","Size":"80mmW","DG-X":8,"DG-Y":6.5},"externalArtworkUrl":"https://<an origin approved on your account>/riverside/crest.pdf"}],"deliveryAddress":{"contactName":"Sam Patel","organisation":"Riverside Print Co","streetAddress":"12 Tannery Road","city":"Auckland","postalCode":"1010","country":"New Zealand","countryCodeISO2":"NZ","deliveryMethod":"overnight","phone":"+64 9 555 0100","emailAddress":"sam@example.com"}}}}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobCandidate"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ShopJobs_ShopJobCandidate"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ShopifyJobs_CustomerShopJobCandidate"}],"description":"Job class to enable the creation of jobs from the web API"},"examples":{"default":{"summary":"Dry run — garments you sent in, decorated. This is the WHOLE payload, artwork included: to create the job, send these same bytes with validateOnly false, and the response example is what comes back. ⛔ `externalArtworkUrl` must be an absolute https URL on an origin approved for your account (otherwise error 10408 or 10403), and if any PriceCode line carries it they all must (10404). (Ordering a made-to-order garment is a different shape — see the BOM section.)","value":{"validateOnly":true,"orderNumber":"PO-10482","description":"Riverside Rugby — club polos","dateDue":"2026-09-14","mustDate":false,"items":[{"itemType":"ExternalGarment","groupHead":"navy-polos","garment":"Navy polo — customer supplied","description":"Arriving under PO-10482, 3 cartons","customerReference":"PO-10482-G","sizeQuantities":{"S":10,"M":20,"L":15}},{"itemType":"PriceCode","group":"navy-polos","code":"DG_DIGICAD_FLEX220:Cad Cut Film-Flex 220","quantity":45,"customerReference":"PO-10482-1","attributes":{"description":"Club crest, left chest","garment":"Navy polo","Position":"Left chest 80mmW","Colours":"PMS 288C, PMS 186C","Size":"80mmW","DG-X":8,"DG-Y":6.5},"externalArtworkUrl":"https://<an origin approved on your account>/riverside/crest.pdf"}],"deliveryAddress":{"contactName":"Sam Patel","organisation":"Riverside Print Co","streetAddress":"12 Tannery Road","city":"Auckland","postalCode":"1010","country":"New Zealand","countryCodeISO2":"NZ","deliveryMethod":"overnight","phone":"+64 9 555 0100","emailAddress":"sam@example.com"}}}}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobCandidate"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ShopJobs_ShopJobCandidate"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ShopifyJobs_CustomerShopJobCandidate"}],"description":"Job class to enable the creation of jobs from the web API"},"examples":{"default":{"summary":"Dry run — garments you sent in, decorated. This is the WHOLE payload, artwork included: to create the job, send these same bytes with validateOnly false, and the response example is what comes back. ⛔ `externalArtworkUrl` must be an absolute https URL on an origin approved for your account (otherwise error 10408 or 10403), and if any PriceCode line carries it they all must (10404). (Ordering a made-to-order garment is a different shape — see the BOM section.)","value":{"validateOnly":true,"orderNumber":"PO-10482","description":"Riverside Rugby — club polos","dateDue":"2026-09-14","mustDate":false,"items":[{"itemType":"ExternalGarment","groupHead":"navy-polos","garment":"Navy polo — customer supplied","description":"Arriving under PO-10482, 3 cartons","customerReference":"PO-10482-G","sizeQuantities":{"S":10,"M":20,"L":15}},{"itemType":"PriceCode","group":"navy-polos","code":"DG_DIGICAD_FLEX220:Cad Cut Film-Flex 220","quantity":45,"customerReference":"PO-10482-1","attributes":{"description":"Club crest, left chest","garment":"Navy polo","Position":"Left chest 80mmW","Colours":"PMS 288C, PMS 186C","Size":"80mmW","DG-X":8,"DG-Y":6.5},"externalArtworkUrl":"https://<an origin approved on your account>/riverside/crest.pdf"}],"deliveryAddress":{"contactName":"Sam Patel","organisation":"Riverside Print Co","streetAddress":"12 Tannery Road","city":"Auckland","postalCode":"1010","country":"New Zealand","countryCodeISO2":"NZ","deliveryMethod":"overnight","phone":"+64 9 555 0100","emailAddress":"sam@example.com"}}}}},"application/*+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobCandidate"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ShopJobs_ShopJobCandidate"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ShopifyJobs_CustomerShopJobCandidate"}],"description":"Job class to enable the creation of jobs from the web API"},"examples":{"default":{"summary":"Dry run — garments you sent in, decorated. This is the WHOLE payload, artwork included: to create the job, send these same bytes with validateOnly false, and the response example is what comes back. ⛔ `externalArtworkUrl` must be an absolute https URL on an origin approved for your account (otherwise error 10408 or 10403), and if any PriceCode line carries it they all must (10404). (Ordering a made-to-order garment is a different shape — see the BOM section.)","value":{"validateOnly":true,"orderNumber":"PO-10482","description":"Riverside Rugby — club polos","dateDue":"2026-09-14","mustDate":false,"items":[{"itemType":"ExternalGarment","groupHead":"navy-polos","garment":"Navy polo — customer supplied","description":"Arriving under PO-10482, 3 cartons","customerReference":"PO-10482-G","sizeQuantities":{"S":10,"M":20,"L":15}},{"itemType":"PriceCode","group":"navy-polos","code":"DG_DIGICAD_FLEX220:Cad Cut Film-Flex 220","quantity":45,"customerReference":"PO-10482-1","attributes":{"description":"Club crest, left chest","garment":"Navy polo","Position":"Left chest 80mmW","Colours":"PMS 288C, PMS 186C","Size":"80mmW","DG-X":8,"DG-Y":6.5},"externalArtworkUrl":"https://<an origin approved on your account>/riverside/crest.pdf"}],"deliveryAddress":{"contactName":"Sam Patel","organisation":"Riverside Print Co","streetAddress":"12 Tannery Road","city":"Auckland","postalCode":"1010","country":"New Zealand","countryCodeISO2":"NZ","deliveryMethod":"overnight","phone":"+64 9 555 0100","emailAddress":"sam@example.com"}}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ReturnDtos_CreateJobReturnDto"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ReturnDtos_CreateShopJobReturnDto"}],"description":"Returns the information from a successful Job Creation to the caller"},"examples":{"default":{"summary":"Job created — the same payload with validateOnly dropped. The decoration line was filed under a new asset tag","value":{"jobNumber":612340,"location":"AKL","dateDue":"2026-09-14T00:00:00Z","totalJobCost":513,"expectingArtworkToBeUploaded":false,"jobLineDetails":[{"needsArtworkToBeUploaded":false,"customerReference":"PO-10482-1","quantity":45,"newAssetSku":"EW49510","jobLineLabelUrl":null}]}}}}}},"400":{"description":"Bad Request — Validation rejected the job and nothing was created. The body carries `validationMessages` with an `errorCode` and a human-readable `message` per problem — for example an asset that is not in an orderable state.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"Forbidden — Authenticated, but this operation is not available to your account’s role. Some operations require the account administrator role; others are back-office only and are not part of this published surface. Do not retry — it will not start working.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"500":{"description":"⚠️ On this endpoint a 500 usually means an INVALID PAYLOAD, not an outage. Known triggers: an empty `items` array; a delivery address that cannot be routed; an asset `code` that does not exist; a missing `dateDue`; a `sizeQuantities` key that is not one of the variant’s sizes. Send the same payload with `\"validateOnly\": true` and fix what it reports before retrying."}},"security":[{"oauth2":[]}],"operationId":"createJobs","description":"Create a job. ⚠️ Send `\"validateOnly\": true` while building: the payload runs the entire validation path and returns errors without creating anything (\"Validated with NO Errors. Job NOT created.\"). Set `items[].itemType` on every line — it selects the line type AND what `code` means: `\"PriceCode\"` (a price code, new decoration), `\"Asset\"` (an asset tag, a repeat), `\"Stock\"` (a stock code), `\"Bom\"` (a BOM code, a made-up product) or `\"ExternalGarment\"` (no code — a garment you are sending in, counted by size in `sizeQuantities`). Join a decoration to the garment it goes on with `groupHead` on the garment line and a matching `group` on each decoration line; ⚠️ `\"Bom\"` lines cannot be grouped, since a BOM already names its own garment and decoration. Put the artwork on each `PriceCode` line as `externalArtworkUrl` — one request places the order and delivers the art — and keep the URL reachable until the job reaches production. Include it while validating: the dry run checks it and creates nothing. ⛔ It must be an absolute `https://` URL (`10408` otherwise) on an origin approved for your account (`10403`, or `10409` where the account has none approved — both are account configuration, so ask rather than reshape the URL), and if any `PriceCode` line carries artwork then every one of them must (`10404`). Reachability is not checked during validation. A 500 from this endpoint usually means an invalid payload (empty `items`, unroutable address, unknown asset or BOM code, bad `sizeQuantities` key), not an outage. The response returns a `jobNumber` and, per decoration line, the asset tag it was filed under."}},"/Jobs/active":{"get":{"tags":["Jobs"],"summary":"Get active jobs for the current customer (by default excludes Closed and Cancelled jobs)","parameters":[{"name":"excludeJobNumber","in":"query","description":"Optional job number to exclude from results","schema":{"type":"integer","format":"int32"}},{"name":"page","in":"query","description":"Page number (1-based)","schema":{"type":"integer","format":"int32","default":1}},{"name":"pageSize","in":"query","description":"Page size (default 20, max 100)","schema":{"type":"integer","format":"int32","default":20}},{"name":"searchText","in":"query","description":"Search by job number, order number, or description","schema":{"type":"string"}},{"name":"includeClosedJobs","in":"query","description":"Include closed jobs in results. Cancelled jobs are never included","schema":{"type":"boolean","default":false}},{"name":"sortColumn","in":"query","description":"","schema":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Enums_ActiveJobSortColumn"}]}},{"name":"sortDirection","in":"query","description":"","schema":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Enums_SortDirection"}],"default":"Ascending"}},{"name":"orderGroup","in":"query","description":"Optional order group to restrict results to","schema":{"type":"string"}},{"name":"customerUserId","in":"query","description":"Optional Customer User (job owner) to narrow the results to - the customer's own user the\r\njob belongs to, not the Control staff member who keyed it in. Narrowing happens server-side,\r\nso totalCount, totalPages and paging describe the narrowed set. Must be a user of the\r\ncalling customer; anything else is rejected with 400 rather than silently ignored.","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_PagedActiveJobsDto"},"examples":{"default":{"summary":"Every open job for the account in one call","value":{"items":[{"permissions":{"canEdit":true,"lockedReason":null},"jobNumber":30291,"masterJobStatus":"In production","originCode":"WEB","description":"Riverside Rugby — club polos","mustDate":false,"dateDue":"2026-08-14T00:00:00Z","dateOut":null,"shippedDaysToProcess":null,"orderNumber":"PO-10482","orderGroup":null,"orderGroupSequence":null,"tracking":[]}],"totalCount":1,"pageNumber":1,"pageSize":25,"totalPages":1,"hasPreviousPage":false,"hasNextPage":false}}}}}},"400":{"description":"customerUserId is not a user of the calling customer — The request was rejected before anything happened. Read the response body — validation failures come back as `{ \"isValid\": false, \"validationMessages\": [{ \"errorCode\", \"message\" }] }`. Retrying an unchanged request will fail identically.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"Forbidden — Authenticated, but this operation is not available to your account’s role. Some operations require the account administrator role; others are back-office only and are not part of this published surface. Do not retry — it will not start working.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getJobsActive","description":"Every open job for the account in one call. Prefer this over looping `GET /Jobs/{jobNumber}`: it is one request regardless of how many jobs are open, and it is what our own dashboard polls."}},"/Jobs/{jobNumber}/cancel":{"post":{"tags":["Jobs"],"summary":"Cancel a job. Cancelling an already-cancelled job returns success.","parameters":[{"name":"jobNumber","in":"path","description":"The job number to cancel","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"204":{"description":"Job cancelled successfully (or was already cancelled)"},"404":{"description":"Job not found or user not authorized to view this job — No such record, or it is not visible to your account. Credentials only ever see their own account’s data, so a valid identifier belonging to another customer answers exactly like one that does not exist.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"409":{"description":"Job cannot be cancelled in its current status","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"createJobsByJobNumberCancel","description":"⚠️ Check first, do not guess. `GET /Jobs/{jobNumber}` returns `isCancelable`; only call this when it is `true`. Once the job has entered production the answer is **409** and it cannot be undone from the API — talk to your account manager instead. Success is **204 with no body**. Cancelling an already-cancelled job succeeds rather than erroring, so a retry after a dropped connection is safe."}},"/Lookups/process-codes":{"get":{"tags":["Lookups"],"summary":"Get list of available process codes","description":"Returns a list of manufacturing process codes available to you, ordered by rank (ascending).","responses":{"200":{"description":"Successfully retrieved process codes","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_ProcessCodeDto"}},"examples":{"default":{"summary":"Process codes with their production characteristics","value":[{"processCode":"EW","description":"Embroidery","rank":10,"metadata":{"setupApplies":true,"resetApplies":false,"scheduleable":true,"physicalStockRequired":false,"printable":true}}]}}}}},"401":{"description":"Authentication required — No valid bearer token. Request one from this region’s `/api/auth/token` with your `client_id` and `client_secret`, and send it as `Authorization: Bearer <token>`. A token from another region’s host will also produce this.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"Access denied - user lacks required role — Authenticated, but this operation is not available to your account’s role. Some operations require the account administrator role; others are back-office only and are not part of this published surface. Do not retry — it will not start working.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"500":{"description":"An error occurred — An unexpected server error. Retry once with backoff; if it persists, contact your account manager with the time of the request and the endpoint.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getLookupsProcesscodes"}},"/Lookups/job-statuses":{"get":{"tags":["Lookups"],"summary":"Get list of available process codes","description":"The full set of job statuses. Read this rather than hardcoding: statuses are added over time, and an unrecognised status should never break your integration.","responses":{"200":{"description":"Successfully retrieved process codes","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobStatusDto"}},"examples":{"default":{"summary":"Every job status — read this rather than matching strings","value":[{"id":1,"name":"Awaiting artwork"},{"id":2,"name":"In production"},{"id":3,"name":"Shipped"}]}}}}},"401":{"description":"Authentication required — No valid bearer token. Request one from this region’s `/api/auth/token` with your `client_id` and `client_secret`, and send it as `Authorization: Bearer <token>`. A token from another region’s host will also produce this.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"500":{"description":"An error occurred — An unexpected server error. Retry once with backoff; if it persists, contact your account manager with the time of the request and the endpoint.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"operationId":"getLookupsJobstatuses"}},"/Lookups/countries":{"get":{"tags":["Lookups"],"summary":"Get list of available countries","description":"Returns a list of countries available for address selection, along with the tenant's default country.","responses":{"200":{"description":"Successfully retrieved countries","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_CountryListResponse"},"examples":{"default":{"summary":"Countries, with which address parts each one needs","value":{"countries":[{"name":"New Zealand","iso2":"NZ","iso3":"NZL","hasSuburb":true,"hasState":false,"hasPostalCode":true},{"name":"United States","iso2":"US","iso3":"USA","hasSuburb":false,"hasState":true,"hasPostalCode":true}],"defaultCountry":"NZ"}}}}}},"401":{"description":"Authentication required — No valid bearer token. Request one from this region’s `/api/auth/token` with your `client_id` and `client_secret`, and send it as `Authorization: Bearer <token>`. A token from another region’s host will also produce this.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"500":{"description":"An error occurred — An unexpected server error. Retry once with backoff; if it persists, contact your account manager with the time of the request and the endpoint.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getLookupsCountries"}},"/Lookups/countries/{countryCode}/states":{"get":{"tags":["Lookups"],"summary":"Get list of states/provinces for a country","description":"Returns a list of states/provinces/regions for the specified country code.\r\nSome countries may return an empty list if they don't have administrative divisions.","parameters":[{"name":"countryCode","in":"path","description":"ISO 3166-1 alpha-2 country code (e.g., US, NZ, GB)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully retrieved states","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_StateListResponse"},"examples":{"default":{"summary":"States for a country — empty where the country has none","value":{"countryCode":"US","states":[]}}}}}},"401":{"description":"Authentication required — No valid bearer token. Request one from this region’s `/api/auth/token` with your `client_id` and `client_secret`, and send it as `Authorization: Bearer <token>`. A token from another region’s host will also produce this.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"500":{"description":"An error occurred — An unexpected server error. Retry once with backoff; if it persists, contact your account manager with the time of the request and the endpoint.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getLookupsCountriesByCountryCodeStates"}},"/Lookups/size-sets":{"get":{"tags":["Lookups"],"summary":"Get list of available size templates for inwards/sizing operations.","responses":{"200":{"description":"Successfully retrieved size sets","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_InwardsSizeSetDto"}},"examples":{"default":{"summary":"Named size runs used by stock and garment lines","value":[{"id":3,"name":"Adult","sizes":["S","M","L","XL","2XL"]}]}}}}},"401":{"description":"Authentication required — No valid bearer token. Request one from this region’s `/api/auth/token` with your `client_id` and `client_secret`, and send it as `Authorization: Bearer <token>`. A token from another region’s host will also produce this.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"500":{"description":"An error occurred — An unexpected server error. Retry once with backoff; if it persists, contact your account manager with the time of the request and the endpoint.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"operationId":"getLookupsSizesets","description":"The named size runs used by stock lines, BOM variants and inwards records — 300 of them, each an ORDERED list of size codes. ⛔ Read both the sizes and their order from here. Sorting them yourself puts `10` before `2` and `XL` before `XS`, and a size run displayed out of order is a mis-picked order."}},"/Lookups/inwards-statuses":{"get":{"tags":["Lookups"],"summary":"Get list of available inwards statuses.","responses":{"200":{"description":"Successfully retrieved inwards statuses","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_InwardsStatusDto"}},"examples":{"default":{"summary":"The status vocabulary for a delivery — every value, including the blank one","value":[{"id":1,"name":""},{"id":2,"name":"Cart"},{"id":3,"name":"Awaiting Arrival"},{"id":4,"name":"Arrived"}]}}}}},"401":{"description":"Authentication required — No valid bearer token. Request one from this region’s `/api/auth/token` with your `client_id` and `client_secret`, and send it as `Authorization: Bearer <token>`. A token from another region’s host will also produce this.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"500":{"description":"An error occurred — An unexpected server error. Retry once with backoff; if it persists, contact your account manager with the time of the request and the endpoint.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"operationId":"getLookupsInwardsstatuses","description":"Every status an inwards delivery can hold. Read this rather than hardcoding, for the same reason as job statuses. ⚠️ To know whether a JOB is waiting on stock, read `stockStatus` on `GET /Jobs/{jobNumber}` instead — it answers `Stock Complete` / `Partial Stock` / `No Stock` across all of that job's deliveries at once."}},"/PriceCodes/{priceCode}":{"get":{"tags":["PriceCodes"],"summary":"Gets the priceCodes for the current Customer","parameters":[{"name":"priceCode","in":"path","description":"The Price Code to find","required":true,"schema":{"type":"string"}},{"name":"dgX","in":"query","description":"(optional)Needed if the PriceCode has additional MetaData requirements","schema":{"type":"number","format":"double","default":0}},{"name":"dgY","in":"query","description":"(optional)Needed if the PriceCode has additional MetaData requirements","schema":{"type":"number","format":"double","default":0}},{"name":"stitches","in":"query","description":"(optional)Needed if the PriceCode has additional MetaData requirements","schema":{"type":"integer","format":"int32","default":0}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Pricing_PriceCodeDto"},"examples":{"default":{"summary":"One price code, with its attributes and quantity breaks","value":{"priceCode":"DG_DIGICAD_FLEX220:Cad Cut Film-Flex 220","description":"Cad Cut Film-Flex 220","categoryCode":"DG_DIGICAD_FLEX220","categoryName":"Cad Cut Film","name":"Cad cut film — left chest 80mm","processCode":"DG","masterProcessCode":"DG","minimumQuantity":1,"externalSupplier":null,"externalPriceCode":null,"hasMetaDataAttributes":false,"standardSetup":34.77,"standardReset":20.9,"sampleAvailable":true,"samplePrice":9.5,"sampleLabel":"Sample","sizeUnit":null,"sizeWidth":null,"sizeHeight":null,"attributes":[],"priceBands":[{"from":10,"to":19,"unitPrice":4.95},{"from":20,"to":49,"unitPrice":3.6},{"from":50,"to":99,"unitPrice":3.05},{"from":100,"to":null,"unitPrice":2.85}]}}}}}},"400":{"description":"Bad Request — The request was rejected before anything happened. Read the response body — validation failures come back as `{ \"isValid\": false, \"validationMessages\": [{ \"errorCode\", \"message\" }] }`. Retrying an unchanged request will fail identically.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"Forbidden — Authenticated, but this operation is not available to your account’s role. Some operations require the account administrator role; others are back-office only and are not part of this published surface. Do not retry — it will not start working.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"Not Found — No such record, or it is not visible to your account. Credentials only ever see their own account’s data, so a valid identifier belonging to another customer answers exactly like one that does not exist.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getPriceCodesByPriceCode","description":"⛔ NOT a substitute for the list when you are building a form. Measured 2026-08-28: this endpoint returns a calculated code with `hasMetaDataAttributes: null` and NO metadata attributes, while `GET /PriceCodes/price-codes` returns the same code declaring `DG-X` and `DG-Y` — so inputs built from here silently omit the dimensions the code cannot be ordered without, and nothing in the response says they are missing. Read attributes from the list; use this to price a size you already know, including the calculated codes via `?dgX=…&dgY=…`. ⚠️ Percent-encode the code for the path: 20 of 25 codes on a real EW account contain spaces, so `DG_DIGICAD_FLEX220:Cad Cut Film-Flex 220` is sent as `DG_DIGICAD_FLEX220%3ACad%20Cut%20Film-Flex%20220`."}},"/PriceCodes/price-codes":{"get":{"tags":["PriceCodes"],"summary":"Gets the priceCodes for the current Customer","parameters":[{"name":"page","in":"query","description":"The page number","schema":{"type":"integer","format":"int32","default":1}},{"name":"pageSize","in":"query","description":"The size of the Page in rows","schema":{"type":"integer","format":"int32","default":25}},{"name":"filter","in":"query","description":"(optional)If supplied will filter the search results","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Pricing_PriceCodeDto"}},"examples":{"default":{"summary":"Price codes for this account, at this account’s tier","value":[{"priceCode":"DG_DIGICAD_FLEX220:Cad Cut Film-Flex 220","description":"Cad Cut Film-Flex 220","categoryCode":"DG_DIGICAD_FLEX220","categoryName":"Cad Cut Film","name":"Cad cut film — left chest 80mm","processCode":"DG","masterProcessCode":"DG","minimumQuantity":1,"externalSupplier":null,"externalPriceCode":null,"hasMetaDataAttributes":true,"standardSetup":34.77,"standardReset":20.9,"sampleAvailable":true,"sizeUnit":null,"sizeWidth":null,"sizeHeight":null,"attributes":[{"minLength":0,"maxLength":60,"name":"description","type":"text","label":"Description","description":"Shown on the job line","required":true,"isMetaDataAttribute":false,"assetAttributeName":null}],"priceBands":[{"from":10,"to":19,"unitPrice":4.95},{"from":20,"to":49,"unitPrice":3.6},{"from":50,"to":99,"unitPrice":3.05},{"from":100,"to":null,"unitPrice":2.85}]}]}}}}},"400":{"description":"Bad Request — The request was rejected before anything happened. Read the response body — validation failures come back as `{ \"isValid\": false, \"validationMessages\": [{ \"errorCode\", \"message\" }] }`. Retrying an unchanged request will fail identically.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"Forbidden — Authenticated, but this operation is not available to your account’s role. Some operations require the account administrator role; others are back-office only and are not part of this published surface. Do not retry — it will not start working.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getPriceCodesPricecodes","description":"Price codes for your account, with sizes and prices at your tier. The `code` value is what you pass as a job line `code` when `itemType` is `PriceCode`. Prices are yours, not list — do not cache them across accounts."}},"/PriceCodes/processes":{"get":{"tags":["PriceCodes"],"summary":"Get list of pricing processes from the Pricing database","description":"The processes available to your account. Start every integration here: availability is per-account and changes, so a hardcoded process list will break for some customers and silently exclude products for others.","responses":{"200":{"description":"Successfully retrieved pricing processes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_PricingProcessesResponse"},"examples":{"default":{"summary":"Processes this account can order — start every integration here","value":{"processes":[{"processCode":"EW","description":"Embroidery","active":true,"sheetRank":10,"sheetColor":"E4572E","tooltip":"Embroidery","mapsToMaster":"WE","maximumSheetUnit":null,"maximumSheetWidth":null,"maximumSheetHeight":null}]}}}}}},"401":{"description":"Authentication required — No valid bearer token. Request one from this region’s `/api/auth/token` with your `client_id` and `client_secret`, and send it as `Authorization: Bearer <token>`. A token from another region’s host will also produce this.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"Access denied - user lacks required permissions — Authenticated, but this operation is not available to your account’s role. Some operations require the account administrator role; others are back-office only and are not part of this published surface. Do not retry — it will not start working.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"500":{"description":"An error occurred — An unexpected server error. Retry once with backoff; if it persists, contact your account manager with the time of the request and the endpoint.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"operationId":"getPriceCodesProcesses"}},"/promocode/validate/{code}":{"get":{"tags":["PromoCodes"],"summary":"Validate promo code","description":"Validates a promo code for the authenticated customer.\r\nChecks if the code exists, is active, not expired, and hasn't exceeded usage limits (overall or per-customer).\r\nOptionally validates that the promo code is applicable to specific process codes.\r\n            \r\nReturns:\r\n- isValid: Whether the promo code can be used\r\n- promoCode: The promo code that was validated\r\n- discount: Discount amount (cents if isFixed=true, percentage if isFixed=false)\r\n- isFixed: true for fixed amount discount, false for percentage discount\r\n- message: Error message if not valid (expired, max uses reached, not applicable to process, etc.)","parameters":[{"name":"code","in":"path","description":"Promo code to validate","required":true,"schema":{"type":"string"}},{"name":"processCodes","in":"query","description":"Optional comma-separated list of process codes (e.g., \"Embroidery,Printing\") from ProcessRank.Process","schema":{"type":"string"}}],"responses":{"200":{"description":"Promo code validation result returned successfully (check isValid field)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dto_Api_ValidatePromocodeResponse"},"examples":{"default":{"summary":"A promotional code checked before it is applied to a job","value":{"isValid":true,"promoCode":"WINTER10","description":null,"discount":10,"isFixed":false,"message":"Promotion applied successfully.","applicableProcessCodes":null}}}}}},"401":{"description":"User is not authenticated — No valid bearer token. Request one from this region’s `/api/auth/token` with your `client_id` and `client_secret`, and send it as `Authorization: Bearer <token>`. A token from another region’s host will also produce this.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getPromocodeValidateByCode"}},"/Stock/{code}":{"get":{"tags":["Stock"],"summary":"Get a List of stock and its variants","parameters":[{"name":"code","in":"path","description":"A stock Code or stock variant code","required":true,"schema":{"type":"string"}},{"name":"includePricing","in":"query","description":"","schema":{"type":"boolean","default":true}},{"name":"variantSortColumn","in":"query","description":"","schema":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Enums_VariantSortColumn"}],"default":"VariantCode"}},{"name":"variantSortDirection","in":"query","description":"","schema":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Enums_SortDirection"}],"default":"Ascending"}},{"name":"includeArchived","in":"query","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Stocks_StockDto"},"examples":{"default":{"summary":"One stocked item, with variants and shipping configuration","value":{"supplier":"Example Apparel Ltd","categoryName":"Polos","stockCode":"POL_1","processCode":"STOCK","stockName":"MENS PERFORMANCE POLO SHIRT","stockDescription":"Polos","stockSpecifications":"100% polyester pique, 160gsm.","priceCompatibleLookupCode":"STOCKLOOKUP","rank":10,"stockVariants":[{"variantCode":"POL-1-NV.WH","colour":"Navy / White","variantImageUrl":"https://example.com/stock/POL-1-NV.WH/image","numberOfSizes":6,"sizesCsv":"S,M,L,XL,2XL,3XL"}],"stockImageUrl":"https://example.com/stock/POL_1/image","images":[{"url":"https://example.com/stock/POL_1/image","name":null,"altText":null}],"showAvailableStock":true,"shippingConfigs":[{"id":71,"markets":["NZ"],"shipMode":"Standard","weight":null,"weightUnit":"kg","length":null,"width":null,"height":null,"dimensionUnit":"cm","fixedShipping":null,"groundOnly":false,"estimatedLeadDays":null,"fulfilmentLocations":[],"shipmentTypeOptions":[{"code":"Ground","name":"GND","price":12.5}]}],"markets":["NZ"],"badges":["Best seller"],"slug":"heavy-cotton-tee","seoTitle":"Heavy Cotton Adult T-Shirt","seoDescription":"A 180gsm cotton tee, stocked in five sizes.","priceBands":[{"from":10,"to":19,"unitPrice":4.95},{"from":20,"to":49,"unitPrice":3.6},{"from":50,"to":99,"unitPrice":3.05},{"from":100,"to":null,"unitPrice":2.85}]}}}}}},"400":{"description":"Bad Request — The request was rejected before anything happened. Read the response body — validation failures come back as `{ \"isValid\": false, \"validationMessages\": [{ \"errorCode\", \"message\" }] }`. Retrying an unchanged request will fail identically.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"Forbidden — Authenticated, but this operation is not available to your account’s role. Some operations require the account administrator role; others are back-office only and are not part of this published surface. Do not retry — it will not start working.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getStockByCode","description":"One stocked item with its variants, sizes and shipping configuration. The `stockVariants[].sizesCsv` values are the only valid keys for a stock line's `sizeQuantities`."}},"/Stock":{"get":{"tags":["Stock"],"summary":"Get a List of stock and its variants","parameters":[{"name":"page","in":"query","description":"The page number","schema":{"type":"integer","format":"int32","default":1}},{"name":"pageSize","in":"query","description":"The size of the Page in rows","schema":{"type":"integer","format":"int32","default":25}},{"name":"filter","in":"query","description":"(optional)If supplied will filter the search results","schema":{"type":"string"}},{"name":"includePricing","in":"query","description":"","schema":{"type":"boolean","default":true}},{"name":"stockSortColumn","in":"query","description":"","schema":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Enums_StockSortColumn"}],"default":"StockCode"}},{"name":"stockSortDirection","in":"query","description":"","schema":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Enums_SortDirection"}],"default":"Ascending"}},{"name":"variantSortColumn","in":"query","description":"","schema":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Enums_VariantSortColumn"}],"default":"VariantCode"}},{"name":"variantSortDirection","in":"query","description":"","schema":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Enums_SortDirection"}],"default":"Ascending"}},{"name":"markets","in":"query","description":"CW-4317: optional comma-separated list of market codes (e.g. \"US,NZ\"). When\r\nsupplied, only stock items with at least one ACTIVE shipping configuration\r\ncovering ANY of the listed markets are returned (OR semantics). Input is\r\ntrimmed, uppercased, and de-duplicated. Omitted or empty => no market filter\r\n(existing behaviour). The filter is applied at the SQL level so pagination\r\nstays correct.","schema":{"type":"string"}},{"name":"code","in":"query","description":"Optional exact match against a stock code or any of its variant codes. Matched exactly\r\nand not trimmed, so leading whitespace is significant; a value over the maximum code\r\nlength returns 400. Combined with filter when both are supplied.\r\nBecause a code is not guaranteed unique across stock codes and variant codes, this may\r\nreturn more than one item.","schema":{"type":"string"}},{"name":"includeArchived","in":"query","description":"When true, retired stock and its variants are included. Defaults to false. Stock hidden\r\nfrom the API by configuration is never returned, regardless of this setting.","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Stocks_StockDto"}},"examples":{"default":{"summary":"The stocked-goods catalogue","value":[{"supplier":"Example Apparel Ltd","categoryName":"Polos","stockCode":"POL_1","processCode":"STOCK","stockName":"MENS PERFORMANCE POLO SHIRT","stockDescription":"Polos","stockSpecifications":"100% polyester pique, 160gsm.","priceCompatibleLookupCode":"STOCKLOOKUP","rank":10,"stockVariants":[{"variantCode":"POL-1-NV.WH","colour":"Navy / White","variantImageUrl":"https://example.com/stock/POL-1-NV.WH/image","numberOfSizes":6,"sizesCsv":"S,M,L,XL,2XL,3XL"}],"stockImageUrl":"https://example.com/stock/POL_1/image","images":[{"url":"https://example.com/stock/POL_1/image","name":null,"altText":null}],"showAvailableStock":true,"markets":["NZ"],"badges":["Best seller"],"slug":"heavy-cotton-tee","seoTitle":"Heavy Cotton Adult T-Shirt","seoDescription":"A 180gsm cotton tee, stocked in five sizes.","priceBands":[{"from":10,"to":19,"unitPrice":4.95},{"from":20,"to":49,"unitPrice":3.6},{"from":50,"to":99,"unitPrice":3.05},{"from":100,"to":null,"unitPrice":2.85}]}]}}}}},"400":{"description":"Bad Request — The request was rejected before anything happened. Read the response body — validation failures come back as `{ \"isValid\": false, \"validationMessages\": [{ \"errorCode\", \"message\" }] }`. Retrying an unchanged request will fail identically.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"Forbidden — Authenticated, but this operation is not available to your account’s role. Some operations require the account administrator role; others are back-office only and are not part of this published surface. Do not retry — it will not start working.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"security":[{"oauth2":[]}],"operationId":"getStock","description":"The stocked-goods feed: garments and supplies held on the shelf, ready to be decorated or shipped as they are. A stock line on `POST /Jobs` uses `itemType: \"Stock\"`, the `stockCode` as `code`, a `variantCode` from `stockVariants`, and `sizeQuantities` keyed by the sizes in `stockVariants[].sizesCsv` (equipment and one-size goods use the single key `Qty`). Group a decoration onto it exactly as you would a garment you sent in."}},"/stock/{stockItemId}/shipping":{"get":{"tags":["StockItemShipping"],"summary":"Get all active shipping configurations for a stock item.","parameters":[{"name":"stockItemId","in":"path","description":"The stock item ID","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"List of shipping configurations","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_StockItemShippingDto"}},"examples":{"default":{"summary":"Shipping configuration for one stocked item","value":[{"id":71,"stockItemId":545,"markets":["NZ"],"shipMode":"ShipsSeparately","fulfilmentLocations":[{"locationCode":"AKL","locationName":"Auckland","locale":"NZ","shipFromCity":"Auckland","shipFromCountryCodeIso2":"NZ"}],"weight":0.25,"weightUnit":"kg","length":30,"width":22,"height":4,"dimensionUnit":"cm","fixedShipping":null,"groundOnly":false,"estimatedLeadDays":2,"active":true,"createdAt":"2026-03-11T20:00:00Z","updatedAt":"2026-07-02T04:30:00Z","shipmentTypeOptions":[]}]}}}}},"400":{"description":"Invalid stock item ID — The request was rejected before anything happened. Read the response body — validation failures come back as `{ \"isValid\": false, \"validationMessages\": [{ \"errorCode\", \"message\" }] }`. Retrying an unchanged request will fail identically.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"operationId":"getStockByStockItemIdShipping","description":"How one stocked item ships — weight, dimensions, lead time and which warehouses it can ship from."}},"/stock/shipping":{"get":{"tags":["StockItemShipping"],"summary":"Get all active stock item shipping configurations for a specific market.\r\nPrimary query used by Integrate for fetching all shipping metadata for a region.","parameters":[{"name":"market","in":"query","description":"The market code (e.g., US, AU, NZ, UK)","schema":{"type":"string"}}],"responses":{"200":{"description":"List of stock item shipping configurations","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_StockItemShippingDto"}},"examples":{"default":{"summary":"Shipping configuration for every stocked item in a market","value":[{"id":71,"stockItemId":545,"markets":["NZ"],"shipMode":"ShipsSeparately","fulfilmentLocations":[{"locationCode":"AKL","locationName":"Auckland","locale":"NZ","shipFromCity":"Auckland","shipFromCountryCodeIso2":"NZ"}],"weight":0.25,"weightUnit":"kg","length":30,"width":22,"height":4,"dimensionUnit":"cm","fixedShipping":null,"groundOnly":false,"estimatedLeadDays":2,"active":true,"createdAt":"2026-03-11T20:00:00Z","updatedAt":"2026-07-02T04:30:00Z","shipmentTypeOptions":[]}]}}}}},"400":{"description":"Market is required — The `market` query parameter is required, even though the schema does not mark it as such. Pass a market code from the `markets` array on a stock item.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}},"operationId":"getStockShipping","description":"Shipping options for stocked items. ⚠️ The `market` query parameter is required even though the schema does not mark it required — omitting it returns a 400."}}},"components":{"schemas":{"Codewolf_Api_Support_AssetDtos_AssetExtendedDto":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_AssetDtos_AssetDto"}],"properties":{"customerId":{"type":"integer","description":"Customer Id","format":"int32"}},"additionalProperties":false,"description":"Extends the AssetDto to include the CustomerId for SuperUser users who make the call"},"Codewolf_Api_Support_BomDtos_BomDto":{"type":"object","properties":{"id":{"type":"integer","description":"BOM Id","format":"int32"},"bomCode":{"type":"string","description":"The code which identifies the BOM","nullable":true},"title":{"type":"string","description":"The BOM's title. Sourced from the BOM.Title column (previously BOM.Description before CW-4323).\r\nThis is the short descriptive name of the BOM used as the Shopify product title.","nullable":true},"description":{"type":"string","description":"Plain-text description of the BOM. Sourced from the BOM.Description column (added in CW-4323).\r\nManually edited on the BOM edit page or auto-filled from the stock garment's StockSpecifications\r\nwhen the first stock item is added. Null if never populated.","nullable":true},"range":{"type":"string","description":"The range the BOM belongs to","nullable":true},"customerSku":{"type":"string","description":"Customer SKU code (if applicable)","nullable":true},"active":{"type":"boolean","description":"Whether the BOM is active. An archived (Active = false) BOM is excluded from the reads by\r\ndefault and is returned only when the caller asks for archived rows explicitly. Added in\r\nCW-4664 so a consumer can tell an archived BOM from an active one — previously an archived\r\nBOM simply vanished from the response with no way to distinguish it from one that never\r\nexisted. Hard-deleted BOMs (Deleted = 1) are never returned under any flag."},"imageUrl":{"type":"string","description":"Absolute CDN URL for the BOM's image, or null when the BOM has no image uploaded.\r\nExample: \"https://tenant-domain.example.com/cdn/boms/UjHmCJKgOu\". Added in CW-4664.\r\nShares the URL shape and the underlying EntityFile lookup with `ShopBomDto.ImageUrl`.","nullable":true},"items":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Api_Support_BomDtos_BomItemDto"},"description":"The BOM's composition — the garment plus its branding lines. Populated only when the caller\r\nrequests it (`?includeItems=true`); `null` otherwise, so the default response shape\r\nis unchanged for existing consumers and the list endpoint does not fan out to one row per\r\nitem across thousands of BOMs. Added in CW-4664.","nullable":true},"bomVariants":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Api_Support_BomDtos_BomVariantDto"},"description":"The variants of this BOM (normally relates to sizes of the BOM)","nullable":true}},"additionalProperties":false,"description":"describes a BOM (Bill of Materials) Lookup Item"},"Codewolf_Api_Support_BomDtos_BomExtendedDto":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Api_Support_BomDtos_BomDto"}],"properties":{"customerId":{"type":"integer","description":"Customer Id","format":"int32"}},"additionalProperties":false,"description":"Extends the BomDto to include the CustomerId - for when the call comes in from a SuperUser"},"Codewolf_Api_Support_BomDtos_BomItemDto":{"type":"object","properties":{"id":{"type":"integer","description":"The BOM item's id. Stable, and the handle a future write endpoint would use to address a\r\nsingle item for edit or removal.","format":"int32"},"assetCode":{"type":"string","description":"The asset or stock variant code for this component. For the garment this is the stock\r\nvariant code; for a branding line it is the asset code.","nullable":true},"isStockItem":{"type":"boolean","description":"True for the garment, false for a branding line. There is at most one active stock item on\r\na BOM, and it is the item that determines the BOM's size run."},"processCode":{"type":"string","description":"The process applied by this component (for example `STOCK` for the garment, or the\r\ndecoration process for a branding line). Derived from the asset code by the\r\n`tr_SetProcessCode` trigger.","nullable":true},"position":{"type":"string","description":"Where the component sits on the garment — for example \"Left chest\". Null on the garment\r\nitself and on any branding line where a position was never recorded.","nullable":true}},"additionalProperties":false,"description":"One component of a BOM — either the garment or one of the branding lines applied to it.\r\nReturned on `BomDto.Items` when the caller passes `?includeItems=true`. Added in\r\nCW-4664 so a consumer can render a BOM as a product rather than as a code and a size list,\r\nand so a proof can be generated from the components and their positions."},"Codewolf_Api_Support_BomDtos_BomVariantDto":{"type":"object","properties":{"id":{"type":"integer","description":"The BOM variant's own identifier. Additive to the read surface: the variant write endpoint\r\naddresses a variant by this id, and there is no other way for a caller to obtain it.","format":"int32"},"bomVariantCode":{"type":"string","description":"The BOM variant code - relating to size variants","nullable":true},"size":{"type":"string","description":"The BOM Variant Size\r\nNOTE: if the Size string is equal to \"Qty\" then this implies it is one size fits all and the Qty should just be assigned","nullable":true},"customerVariantSku":{"type":"string","description":"Customer Variant SKU code (if applicable)","nullable":true},"active":{"type":"boolean","description":"Whether this variant is active. Added in CW-4664. A BOM with no active variants is not\r\norderable, and before this field a consumer could not tell such a BOM apart from one that\r\nnever had a size run — the variant join filtered inactive rows out silently. Inactive\r\nvariants are returned only when the caller asks for archived rows explicitly."}},"additionalProperties":false,"description":"defines the Variant of a BOM (this normally relates to size variants)"},"Codewolf_Ctrl_Api_Dto_Api_AccountProfile":{"type":"object","properties":{"id":{"type":"integer","description":"Customer ID","format":"int32"},"name":{"type":"string","description":"Customer name (for reference)","nullable":true},"priceTierCode":{"type":"string","description":"Customer's pricing tier code","nullable":true},"currency":{"type":"string","description":"Currency code for transactions","nullable":true},"taxRateType":{"type":"string","description":"Tax rate type (e.g., \"GST\", \"VAT\", \"Sales Tax\")","nullable":true},"taxRate":{"type":"number","description":"Tax rate percentage (null if using TaxJar or tax exempt)","format":"double","nullable":true},"taxSystemTaxExempt":{"type":"boolean","description":"Whether customer is tax exempt"},"taxSystemTaxExemptReason":{"type":"string","description":"Reason for tax exemption (if applicable)","nullable":true},"showPayNow":{"type":"boolean","description":"Whether to show \"Pay Now\" option"},"creditCardRequired":{"type":"boolean","description":"Whether credit card is required for orders"},"shipmentCarriersCSV":{"type":"string","description":"Comma-separated list of available shipment carriers","nullable":true},"excludeShipmentsCsv":{"type":"string","description":"Comma-separated list of excluded shipment types","nullable":true},"courierAccountCode":{"type":"string","description":"Customer's courier account code (if shipping on own account)","nullable":true},"courierSiteID":{"type":"string","description":"Courier site ID","nullable":true},"crmId":{"type":"string","description":"External CRM system ID (for reference only)","nullable":true},"accountManagerName":{"type":"string","description":"Account manager full name (FirstName LastName format)","nullable":true},"accountManagerEmail":{"type":"string","description":"Account manager email address","nullable":true},"tierLast12Months":{"type":"string","description":"Customer tier based on last 12 months of activity","nullable":true},"paymentTermDays":{"type":"integer","description":"Gets or sets the number of days allowed for payment after an invoice is issued.","format":"int32","nullable":true},"paymentTermType":{"type":"string","description":"Gets or sets the type of payment terms (e.g., \"Net\", \"Due on Receipt\").","nullable":true},"entityAddress":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dto_Api_EntityAddressDto"}],"description":"Entity (company) street address associated with this account","nullable":true},"taxCertificates":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dto_Api_TaxCertificate"},"description":"List of tax exemption certificates for this account","nullable":true},"paymentMode":{"type":"string","description":"Payment mode for this customer (e.g., \"credit_card_required\", \"pay_up_front\").\r\nDetermines checkout behaviour for retail integrations.","nullable":true},"paymentMethods":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dto_Api_PaymentMethod"},"description":"List of saved payment methods for this account","nullable":true}},"additionalProperties":false,"description":"Account profile information for authenticated customer users.\r\nRead-only company/organization-level data.\r\nMatches what customers can currently see in the secure portal."},"Codewolf_Ctrl_Api_Dto_Api_AccountUserInfo":{"type":"object","properties":{"id":{"type":"integer","description":"User ID","format":"int32"},"guid":{"type":"string","description":"User GUID","format":"uuid"},"customerId":{"type":"integer","description":"Customer/account ID this user belongs to","format":"int32"},"customerName":{"type":"string","description":"Customer/company name","nullable":true},"userName":{"type":"string","description":"Login username","nullable":true},"firstName":{"type":"string","description":"First name","nullable":true},"lastName":{"type":"string","description":"Last name","nullable":true},"emailAddress":{"type":"string","description":"Email address","nullable":true},"active":{"type":"boolean","description":"Whether user is active (can log in)"},"phone":{"type":"string","description":"Phone number","nullable":true},"mobile":{"type":"string","description":"Mobile number","nullable":true},"streetAddress":{"type":"string","description":"Street address line 1","nullable":true},"addressLine2":{"type":"string","description":"Street address line 2","nullable":true},"suburb":{"type":"string","description":"Suburb/neighborhood","nullable":true},"city":{"type":"string","description":"City","nullable":true},"state":{"type":"string","description":"State/province","nullable":true},"postalCode":{"type":"string","description":"Postal/ZIP code","nullable":true},"country":{"type":"string","description":"Country","nullable":true},"locationID":{"type":"integer","description":"Location ID (if multi-location enabled)","format":"int32","nullable":true},"locationName":{"type":"string","description":"Location name (if multi-location enabled)","nullable":true},"defaultPage":{"type":"string","description":"Default landing page URL","nullable":true},"orderNumberPrefix":{"type":"string","description":"Custom order number prefix (max 5 chars)","nullable":true},"receiveEmails":{"type":"boolean","description":"Receive general emails"},"promotionRecipient":{"type":"boolean","description":"Receive promotional emails"},"receiveInvoice":{"type":"boolean","description":"Receive invoice emails"},"receiveInwards":{"type":"boolean","description":"Receive inward shipment notifications"},"textNotifyProof":{"type":"boolean","description":"SMS notification when job proof sent"},"textNotifyDispatch":{"type":"boolean","description":"SMS notification when job dispatched"},"usernameLoginOnly":{"type":"boolean","description":"Whether this user logs in with username only (email is shared with another user)"},"lastLogin":{"type":"string","description":"Last login timestamp (UTC)","format":"date-time","nullable":true},"loginCount":{"type":"integer","description":"Total login count","format":"int32"}},"additionalProperties":false,"description":"Complete user profile information for authenticated user.\r\nExcludes sensitive fields like passwords and internal role flags."},"Codewolf_Ctrl_Api_Dto_Api_AccountUserSummary":{"type":"object","properties":{"id":{"type":"integer","description":"User ID","format":"int32"},"guid":{"type":"string","description":"User GUID","format":"uuid"},"userName":{"type":"string","description":"Login username","nullable":true},"firstName":{"type":"string","description":"First name","nullable":true},"lastName":{"type":"string","description":"Last name","nullable":true},"emailAddress":{"type":"string","description":"Email address","nullable":true},"active":{"type":"boolean","description":"Whether user is active (can log in)"},"locationName":{"type":"string","description":"Location name (if multi-location enabled)","nullable":true},"usernameLoginOnly":{"type":"boolean","description":"Whether this user logs in with username only (email is shared with another user)"},"lastLogin":{"type":"string","description":"Last login timestamp (UTC)","format":"date-time","nullable":true},"loginCount":{"type":"integer","description":"Total login count","format":"int32"}},"additionalProperties":false,"description":"Lightweight user summary for list view (GET /account/users).\r\nProvides essential user information for administrative user management."},"Codewolf_Ctrl_Api_Dto_Api_EntityAddressDto":{"type":"object","properties":{"id":{"type":"integer","description":"Entity address ID","format":"int32"},"streetAddress":{"type":"string","description":"Street address (line 1)","nullable":true},"addressLine2":{"type":"string","description":"Address line 2","nullable":true},"city":{"type":"string","description":"City","nullable":true},"state":{"type":"string","description":"State/province abbreviation (e.g., \"CA\", \"NY\")","nullable":true},"stateFull":{"type":"string","description":"Full state/province name (e.g., \"California\", \"New York\")","nullable":true},"postalCode":{"type":"string","description":"Postal/ZIP code","nullable":true},"countryCode":{"type":"string","description":"ISO 3166-1 alpha-2 country code (e.g., \"US\", \"NZ\")","nullable":true},"countryName":{"type":"string","description":"Full country name","nullable":true},"contactName":{"type":"string","description":"Contact name","nullable":true},"organisation":{"type":"string","description":"Organisation name","nullable":true},"phone":{"type":"string","description":"Phone number","nullable":true},"emailAddress":{"type":"string","description":"Email address","nullable":true},"addressSummaryOneLine":{"type":"string","description":"One-line summary of the full address","nullable":true}},"additionalProperties":false,"description":"Entity (company) address associated with a customer account.\r\nRead from the EntityAddress table where RelatedToEntityType = 'CUSTOMER'."},"Codewolf_Ctrl_Api_Dto_Api_FreightRateDto":{"type":"object","properties":{"carrier":{"type":"string","description":"Carrier code (e.g. \"FedEx\", \"UPS\"). Null for the global default row.","nullable":true},"carrierName":{"type":"string","description":"Carrier display name (e.g. \"FedEx\", \"DEFAULT\").","nullable":true},"service":{"type":"string","description":"Service code (e.g. \"fedex_2day\"). Null when not applicable.","nullable":true},"serviceName":{"type":"string","description":"Service display name (e.g. \"FedEx 2Day®\"). Null when not applicable.","nullable":true},"package":{"type":"string","description":"Package code (e.g. \"YOUR_PACKAGING\"). \"DEFAULT\" for default package. Null when not applicable.","nullable":true},"packageName":{"type":"string","description":"Package display name. Null when not applicable.","nullable":true},"chargeType":{"type":"string","description":"Charge type: \"markup_on_order\" (percentage of order value) or \"fixed_per_package\".","nullable":true},"value":{"type":"number","description":"Rate value (percentage or fixed amount).","format":"double"},"minimum":{"type":"number","description":"Minimum charge (null if none).","format":"double","nullable":true},"isDefault":{"type":"boolean","description":"True if this rate is inherited from system/tenant defaults (read-only).\r\nFalse if this is a customer-specific override (editable/deletable)."}},"additionalProperties":false,"description":"Freight rate rule from the cascaded view: system defaults → tenant defaults → customer overrides."},"Codewolf_Ctrl_Api_Dto_Api_PaymentMethod":{"type":"object","properties":{"id":{"type":"string","description":"Token ID (GUID)","format":"uuid"},"gatewayProvider":{"type":"string","description":"Gateway provider name (e.g., \"Stripe\", \"PaymentExpress\", \"Windcave\")","nullable":true},"cardName":{"type":"string","description":"Card type (e.g., \"Visa\", \"Mastercard\", \"Amex\")","nullable":true},"cardNumber":{"type":"string","description":"Masked card number (e.g., \"****1234\")","nullable":true},"cardExpiry":{"type":"string","description":"Card expiry (MM/YY format)","nullable":true},"cardHolderName":{"type":"string","description":"Cardholder name","nullable":true},"dateCreatedUtc":{"type":"string","description":"When card was added","format":"date-time"},"isDefault":{"type":"boolean","description":"Whether this is the default payment method"}},"additionalProperties":false,"description":"Saved payment method (credit card token) information (read-only)"},"Codewolf_Ctrl_Api_Dto_Api_PaymentTransaction":{"type":"object","properties":{"id":{"type":"integer","description":"Transaction ID","format":"int32"},"gatewayType":{"type":"string","description":"Payment gateway provider (e.g., \"Stripe\", \"PaymentExpress\", \"Windcave\")","nullable":true},"transactionStatus":{"type":"string","description":"Transaction status (e.g., \"Completed\", \"Pending\", \"Failed\", \"Cancelled\")","nullable":true},"createdAt":{"type":"string","description":"When transaction was created","format":"date-time"},"completedAt":{"type":"string","description":"When transaction completed (null if pending/failed)","format":"date-time","nullable":true},"cardName":{"type":"string","description":"Card type (e.g., \"Visa\", \"Mastercard\", \"Amex\")","nullable":true},"cardNumber":{"type":"string","description":"Masked card number (e.g., \"****1234\")","nullable":true},"cardExpiry":{"type":"string","description":"Card expiry (MM/YY format)","nullable":true},"currencySettlement":{"type":"string","description":"Settlement currency code (e.g., \"USD\", \"NZD\", \"GBP\")","nullable":true},"amountSettlement":{"type":"number","description":"Settlement amount","format":"double"},"merchantEntityType":{"type":"string","description":"Entity type this transaction is for (e.g., \"JOB\", \"CUSTOMER\")","nullable":true},"merchantEntityId":{"type":"integer","description":"Related entity ID (e.g., Job ID if transaction is for a job payment)","format":"int32","nullable":true}},"additionalProperties":false,"description":"Payment transaction history record (read-only)"},"Codewolf_Ctrl_Api_Dto_Api_ReceiverPaysSettings":{"type":"object","properties":{"billingAccountNumber":{"type":"string","description":"Customer's carrier account number for third-party billing.","nullable":true},"billingPostalCode":{"type":"string","description":"Billing postal code for the carrier account.","nullable":true},"billingCountryCode":{"type":"string","description":"Billing country code (e.g., \"US\", \"NZ\").","nullable":true}},"additionalProperties":false,"description":"Third-party billing (receiver pays) configuration."},"Codewolf_Ctrl_Api_Dto_Api_ShipmentSettings":{"type":"object","properties":{"availableCarriers":{"type":"array","items":{"type":"string"},"description":"Carriers available to this customer.\r\nIf customer has no restrictions, this contains all carrier options.","nullable":true},"carrierOptions":{"type":"array","items":{"type":"string"},"description":"All carrier options available for selection (carrier names).","nullable":true},"receiverPays":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dto_Api_ReceiverPaysSettings"}],"description":"Third-party billing configuration for customer's own carrier account.","nullable":true},"showCustomerAddressOnLabel":{"type":"boolean","description":"Whether to show customer's address as return address on shipping labels."},"handlingFee":{"type":"number","description":"Handling fee amount.\r\nNote: Automatically set to 0 when receiverPays is enabled.","format":"double"},"applyHandlingFeeInsteadOfFreight":{"type":"boolean","description":"If true, handling fee replaces freight charges.\r\nNote: Automatically set to true when receiverPays is enabled."},"jobComment":{"type":"string","description":"Default comment that appears on jobs for shipping department.","nullable":true},"availableShipmentTypes":{"type":"array","items":{"type":"string"},"description":"Shipment type codes available for this customer.\r\nDerived from ExcludeShipmentsCsv (inverted logic).\r\nEmpty array means all shipment types are available.","nullable":true},"shipmentTypeOptions":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dto_Api_ShipmentType"},"description":"All shipment type options available for selection.","nullable":true},"freightRates":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dto_Api_FreightRateDto"},"description":"Freight rate rules with cascading defaults (read-only).","nullable":true}},"additionalProperties":false,"description":"Customer shipment settings - company-level shipping configuration."},"Codewolf_Ctrl_Api_Dto_Api_ShipmentType":{"type":"object","properties":{"code":{"type":"string","description":"Shipment type code.","nullable":true},"name":{"type":"string","description":"Display name for the shipment type.","nullable":true}},"additionalProperties":false,"description":"Shipment type with code and display name."},"Codewolf_Ctrl_Api_Dto_Api_TaxCertificate":{"type":"object","properties":{"id":{"type":"integer","description":"Tax certificate ID","format":"int32"},"customerId":{"type":"integer","description":"Customer ID (always matches authenticated customer)","format":"int32"},"name":{"type":"string","description":"Contact name on certificate","nullable":true},"businessName":{"type":"string","description":"Business name on certificate","nullable":true},"exemptionNumber":{"type":"string","description":"Certificate/exemption number","nullable":true},"employerIdentificationNumber":{"type":"string","description":"Employer Identification Number (EIN/Tax ID) - optional","nullable":true},"businessEntityId":{"type":"string","description":"Business entity ID - optional","nullable":true},"licenseExpiryDate":{"type":"string","description":"License expiry date (null if no expiry)","format":"date-time","nullable":true},"exemptionType":{"type":"string","description":"Type of exemption (e.g., \"Resale\", \"Manufacturing\", \"Non-Profit\")","nullable":true},"exemptionState":{"type":"string","description":"State where exemption applies (e.g., \"CA\", \"TX\")","nullable":true},"fileName":{"type":"string","description":"Uploaded certificate file name (null if no file uploaded)","nullable":true},"hasFile":{"type":"boolean","description":"Whether a certificate file has been uploaded","readOnly":true},"createdAt":{"type":"string","description":"When this certificate was created","format":"date-time"},"updatedAt":{"type":"string","description":"When this certificate was last updated","format":"date-time"},"entityFileId":{"type":"integer","format":"int32","description":"Identifier of the stored certificate file."},"cdnUrl":{"type":"string","nullable":true,"description":"Time-limited link to download the certificate."},"fileStatus":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Enums_FileStatus"}],"description":"Where the certificate has got to in review."},"fileStatusDescription":{"type":"string","nullable":true,"readOnly":true,"description":"The review status in words, suitable for display."}},"additionalProperties":false,"description":"Full tax exemption certificate details"},"Codewolf_Ctrl_Api_Dto_Api_ValidatePromocodeResponse":{"type":"object","properties":{"isValid":{"type":"boolean","description":"Whether the promo code is valid for the customer"},"promoCode":{"type":"string","description":"The promo code that was validated","nullable":true},"description":{"type":"string","description":"Description of the promo code","nullable":true},"discount":{"type":"integer","description":"Discount amount (cents if IsFixed=true, percentage if IsFixed=false)","format":"int32"},"isFixed":{"type":"boolean","description":"Whether this is a fixed amount discount (true) or percentage discount (false)"},"message":{"type":"string","description":"Error message if the promo code is not valid. Empty if valid.","nullable":true},"applicableProcessCodes":{"type":"array","items":{"type":"string"},"description":"List of applicable process codes from the ones provided (if processCodes parameter was supplied).\r\nReturns null if no processCodes were provided or if promo code is not process-specific.","nullable":true}},"additionalProperties":false,"description":"Response from promo code validation"},"Codewolf_Ctrl_Api_Dto_PatchJobDto":{"type":"object","properties":{"description":{"maxLength":500,"type":"string","description":"The job description shown on the job and on your invoice.","nullable":true},"comments":{"maxLength":1000,"type":"string","description":"Notes carried on the job. Sent to the factory with the order.","nullable":true},"orderNumber":{"maxLength":50,"type":"string","description":"Your own PO or order reference for this job.","nullable":true},"mustDate":{"type":"boolean","description":"Whether `dateDue` is a hard requirement rather than a preference. Setting it commits the factory to the date, so only use it when the date genuinely cannot move.","nullable":true},"dateDue":{"type":"string","description":"The ship date you are asking for. Check it against `GET /Jobs/earliest-ship-date` — a date the factory cannot meet is rejected rather than silently moved.","format":"date-time","nullable":true},"locationCode":{"maxLength":50,"type":"string","description":"⚠️ Not available to customer credentials — this field is SuperUser-only. Production location is set by us. Omit it.","nullable":true}},"additionalProperties":false,"description":"DTO for patching job details"},"Codewolf_Ctrl_Api_Dto_ShippingDateExclusionDto":{"type":"object","properties":{"dateFrom":{"type":"string","description":"Start date of the exclusion period (date only, no time)","format":"date"},"dateTo":{"type":"string","description":"End date of the exclusion period (date only, no time)","format":"date"}},"additionalProperties":false,"description":"Date exclusion (holiday/non-working day) for calendar blocking"},"Codewolf_Ctrl_Api_Dto_ShippingDateResponseDto":{"type":"object","properties":{"shippingDateUtc":{"type":"string","description":"Calculated earliest shipping date in UTC","format":"date-time"},"shippingDateLocal":{"type":"string","description":"Calculated earliest shipping date in customer's local timezone","format":"date-time"},"timezone":{"type":"string","description":"IANA timezone used for calculations (e.g., \"Pacific/Auckland\")","nullable":true},"dateExclusions":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dto_ShippingDateExclusionDto"},"description":"List of date exclusions (holidays, non-working days) to block on calendar UI","nullable":true}},"additionalProperties":false,"description":"Response containing calculated shipping date and date exclusions for calendar blocking"},"Codewolf_Ctrl_Api_Dtos_Api_AssetFileDto":{"type":"object","properties":{"fileId":{"type":"string","description":"Hashed file identifier (matches the hashId in cdnUrl)\r\nCan be used to construct CDN URLs or for download requests","nullable":true},"fileName":{"type":"string","description":"Original filename","nullable":true},"fileSize":{"type":"integer","description":"File size in bytes","format":"int64"},"dateUploaded":{"type":"string","description":"Date and time when the file was uploaded","format":"date-time"},"isImage":{"type":"boolean","description":"Indicates whether this file is an image type (jpg, jpeg, png, gif, bmp)\r\nFor image files, clients can append ?size=100 to cdnUrl for thumbnails"},"cdnUrl":{"type":"string","description":"Full CDN URL for accessing the file\r\nFor images, append ?size=50, ?size=100, or ?size=150 for thumbnails","nullable":true}},"additionalProperties":false,"description":"Individual asset file information"},"Codewolf_Ctrl_Api_Dtos_Api_AssetFilesResponseDto":{"type":"object","properties":{"assetTag":{"type":"string","description":"The asset tag (also known as asset code)","nullable":true},"currentFiles":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_AssetFileDto"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_HistoricAssetFileDto"}],"description":"Individual asset file information"},"description":"List of current (active) files associated with this asset (ordered by date uploaded descending)","nullable":true},"historicFiles":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_HistoricAssetFileDto"},"description":"List of historic (archived) files associated with this asset (ordered by date uploaded descending)","nullable":true}},"additionalProperties":false,"description":"Response DTO for retrieving asset files"},"Codewolf_Ctrl_Api_Dtos_Api_AssetJobDto":{"type":"object","properties":{"jobNumber":{"type":"integer","description":"Job number","format":"int32"},"orderNumber":{"type":"string","description":"Customer's order number","nullable":true},"description":{"type":"string","description":"Job description","nullable":true},"quantity":{"type":"integer","description":"Quantity from the job line matching this asset (not total job qty)","format":"int32","nullable":true},"dateOut":{"type":"string","description":"Date the job was dispatched (null for active jobs not yet shipped)","format":"date-time","nullable":true},"masterJobStatus":{"type":"string","description":"Current job status","nullable":true}},"additionalProperties":false,"description":"Individual job information in asset jobs response"},"Codewolf_Ctrl_Api_Dtos_Api_AssetJobsResponseDto":{"type":"object","properties":{"assetCode":{"type":"string","description":"The asset code that was queried","nullable":true},"jobs":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_AssetJobDto"},"description":"List of jobs containing this asset","nullable":true},"totalCount":{"type":"integer","description":"Total count of jobs returned","format":"int32"}},"additionalProperties":false,"description":"Response DTO for asset jobs endpoint"},"Codewolf_Ctrl_Api_Dtos_Api_AssetListDto":{"type":"object","properties":{"assetId":{"type":"integer","format":"int32","description":"Internal numeric id. Use `assetTag` when ordering — that is what a job line accepts."},"assetTag":{"type":"string","nullable":true,"description":"The asset's code, and the thing you reorder by: send it as a job line `code` with `itemType: \"Asset\"`. Reordering a tag reproduces the previous run exactly — no artwork upload, no colour re-approval."},"processCode":{"type":"string","nullable":true,"description":"The production process this asset is made with. Values come from `GET /Lookups/process-codes`."},"description":{"type":"string","nullable":true,"description":"The asset's name as it appears on jobs and invoices."},"garment":{"type":"string","nullable":true,"description":"The garment this asset was set up against, where one was recorded."},"priceTierCode":{"type":"string","nullable":true,"description":"The pricing tier the `priceBands` below are quoted at — your account's tier."},"setup":{"type":"number","format":"double","description":"One-off charge to create the asset. Already paid on an existing asset, so a reorder does not incur it."},"reset":{"type":"number","format":"double","description":"Charge applied each time the asset is run again. This is the real cost of a reorder, alongside the unit price."},"priceCode":{"type":"string","nullable":true,"description":"The price code the asset was originally created from."},"assetUrl":{"type":"string","nullable":true,"description":"Link to a preview image of the asset. Null where no preview has been generated."},"createDate":{"type":"string","format":"date-time","description":"When the asset was first created, UTC."},"isGlobal":{"type":"boolean","description":"True for catalogue assets available to every account rather than ones your account created. Global assets are also listed by `GET /Assets/global`."},"isArchived":{"type":"boolean","description":"True when the asset has been retired. Archived assets are hidden from the default library listing — pass `isArchived=true` to list them. ⚠️ Archiving does not block reordering: the record still resolves and an order referencing it is accepted."},"priceBands":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Interfaces_IPriceBandDto"},"nullable":true,"description":"Quantity-break pricing for reordering this asset, at your account's tier."},"attributes":{"type":"object","additionalProperties":{"type":"string","nullable":true},"description":"Free-form asset attributes (the AssetAttributes table) as name/value pairs.\r\n<br>\r\nPopulated for SuperUser callers only. NullValueHandling.Ignore is set explicitly at the\r\nproperty level because the MVC response pipeline (ApiConfigurationHelper.ConfigureControllers)\r\ndoes not override Newtonsoft's default of Include — without this attribute a null would\r\nserialize as an explicit \"attributes\": null key and leak the property's existence to\r\nnon-SuperUser callers.\r\n<br>\r\nAn empty dictionary means \"authorised, but this asset has no attributes\"; an absent key\r\nmeans \"not authorised to see them\".\r\n","nullable":true}},"additionalProperties":false,"description":"Asset DTO for list endpoints - excludes ExternalId per CW-4024"},"Codewolf_Ctrl_Api_Dtos_Api_CountryDto":{"type":"object","properties":{"name":{"type":"string","description":"Full country name","nullable":true,"example":"United States"},"iso2":{"type":"string","description":"ISO 3166-1 alpha-2 code","nullable":true,"example":"US"},"iso3":{"type":"string","description":"ISO 3166-1 alpha-3 code","nullable":true,"example":"USA"},"hasSuburb":{"type":"boolean","description":"Indicates whether this country uses a suburb/district field in addresses (Dependent Locality)","example":true},"hasState":{"type":"boolean","description":"Indicates whether this country uses a state/province field in addresses (Administrative Area)","example":true},"hasPostalCode":{"type":"boolean","description":"Indicates whether this country uses a postal/zip code field in addresses","example":true}},"additionalProperties":false,"description":"Country information for lookup"},"Codewolf_Ctrl_Api_Dtos_Api_CountryListResponse":{"type":"object","properties":{"countries":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_CountryDto"},"description":"List of available countries","nullable":true},"defaultCountry":{"type":"string","description":"Default country ISO2 code for this tenant","nullable":true,"example":"US"}},"additionalProperties":false,"description":"Response containing list of countries with default"},"Codewolf_Ctrl_Api_Dtos_Api_FulfilmentLocationDto":{"type":"object","properties":{"locationCode":{"type":"string","nullable":true,"description":"Short code for the fulfilment location."},"locationName":{"type":"string","nullable":true,"description":"Human-readable name of the fulfilment location."},"locale":{"type":"string","nullable":true,"description":"The region the location sits in."},"shipFromCity":{"type":"string","nullable":true,"description":"City goods leave from — the origin used when rating shipping."},"shipFromCountryCodeIso2":{"type":"string","nullable":true,"description":"Two-character ISO country code goods ship from."}},"additionalProperties":false,"description":"Nested DTO representing a resolved fulfilment location within a shipping config."},"Codewolf_Ctrl_Api_Dtos_Api_HistoricAssetFileDto":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_AssetFileDto"}],"properties":{"action":{"type":"string","description":"Action that caused this file to be archived (e.g., \"Replaced\", \"Archived\")","nullable":true}},"additionalProperties":false,"description":"Historic (archived) asset file information with action details"},"Codewolf_Ctrl_Api_Dtos_Api_InwardsDto":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_InwardsSummaryDto"}],"properties":{"supplierId":{"type":"integer","format":"int32","nullable":true,"description":"The supplier the goods came from, by id."},"dateDue":{"type":"string","format":"date-time","nullable":true,"description":"When the delivery was expected, which is not when it arrived."},"shelfLocation":{"type":"string","nullable":true,"description":"Where the goods are physically held in the factory once booked in."},"comment":{"type":"string","nullable":true,"description":"Free-text note recorded against the delivery at goods-in."},"packingSlipNumber":{"type":"string","description":"Packing slip reference for this delivery, or null when none is recorded. Free text, not a\r\nnumber — live values are frequently alphanumeric (for example \"ORN0073086\") and a\r\nplaceholder \"-\" is common, so treat this as an opaque display string.","nullable":true},"scanFile":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_InwardsScanFileDto"}],"description":"Link to the supplier's packing slip as scanned at goods-in, or null when this delivery has\r\nno scan on file. Distinct from Codewolf.Ctrl.Api.Dtos.Api.InwardsDto.PackingSlipNumber, which is the reference the\r\nsupplier printed on the paperwork — this is the document itself.","nullable":true},"items":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_InwardsItemDto"},"nullable":true,"description":"The lines of the delivery — each a garment in one colour, counted per size. ⚠️ Nullable: treat an absent array as an empty one rather than letting it reach `.map`."}},"additionalProperties":false,"description":"Detailed representation of an inwards record including items."},"Codewolf_Ctrl_Api_Dtos_Api_InwardsItemDto":{"type":"object","properties":{"id":{"type":"integer","format":"int32","description":"The delivery line."},"code":{"type":"string","nullable":true,"description":"The garment code as you supplied it — commonly your own SKU."},"garment":{"type":"string","nullable":true,"description":"What the garment is, in words."},"colour":{"type":"string","nullable":true,"description":"The garment colour, as counted in. One colour per line."},"sizeSetId":{"type":"integer","format":"int32","description":"The size set this line is counted against, by id."},"sizeSet":{"type":"string","nullable":true,"description":"The name of the size run — look it up in `GET /Lookups/size-sets` to get the sizes IN ORDER. Sorting them yourself puts `10` before `2` and `XL` before `XS`."},"quantities":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_SizeQuantityDto"},"nullable":true,"description":"⚠️ Only the NON-ZERO sizes, and not necessarily in size order. Build the row from the size set and fill it from here, rather than reading this as the whole run."},"total":{"type":"integer","format":"int32","description":"Units on this line, across every size."}},"additionalProperties":false,"description":"A line item on an inwards record."},"Codewolf_Ctrl_Api_Dtos_Api_InwardsListResponseDto":{"type":"object","properties":{"data":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_InwardsSummaryDto"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_InwardsDto"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_PatchInwardsResponseDto"}],"description":"Summary representation of an inwards record (used in list responses)."},"nullable":true,"description":"The deliveries on this page. ⚠️ Nullable — normalise it before iterating."},"page":{"type":"integer","format":"int32","description":"Which page this is. One-based."},"pageSize":{"type":"integer","format":"int32","description":"How many records one page can hold."},"totalItems":{"type":"integer","format":"int32","description":"How many deliveries match across every page. ⚠️ Guard a page past the end BOTH ways, because the shape changed: since CW-4654 it returns the real totals with an empty `data` (measured 2026-08-28: `page=9999` → `totalItems: 3305`, `totalPages: 133`, no rows), and older builds returned `totalItems: 0`, which is indistinguishable from an empty collection. `page > 1 && (totalItems === 0 || (totalPages > 0 && page > totalPages))` catches both; reset to page 1."},"totalPages":{"type":"integer","format":"int32","description":"How many pages the result set spans at the current `pageSize`."}},"additionalProperties":false,"description":"Paginated list response for GET /Inwards."},"Codewolf_Ctrl_Api_Dtos_Api_InwardsScanFileDto":{"type":"object","properties":{"uri":{"type":"string","description":"The URI to fetch the scan. Points at Control's public `/cdn/inwardscans/{token}`\r\nendpoint, where the token is a Hashids code (obfuscation, not encryption) keyed by the\r\ntenant Salt, carrying the customer, the inwards id and a lease expiry. Control re-validates\r\nthe lease and the customer's ownership of the delivery server-side on every request.\r\n<br>\r\nRequires no Authorization header, so it can be opened or downloaded directly by a browser.\r\n","nullable":true},"uriExpires":{"type":"string","description":"Expiry of the Codewolf.Ctrl.Api.Dtos.Api.InwardsScanFileDto.Uri — the end of the link's lease window. The CDN endpoint\r\nrejects the link once this passes; re-read the record to obtain a fresh one.","format":"date-time","nullable":true}},"additionalProperties":false,"description":"A slim public representation of an inwards scan on the Inwards contract. Mirrors the job\r\ncontract's invoice file: only the fetch URI and its expiry are exposed, never the internal\r\nstorage record."},"Codewolf_Ctrl_Api_Dtos_Api_InwardsSizeSetDto":{"type":"object","properties":{"id":{"type":"integer","description":"tblSizeMain.ID","format":"int32"},"name":{"type":"string","description":"tblSizeMain.szDesc","nullable":true},"sizes":{"type":"array","items":{"type":"string"},"description":"Active size labels, in position order (sz1..sz20, skipping null/empty).","nullable":true}},"additionalProperties":false,"description":"A size template — e.g. \"2XS-5XL\", \"One Size\"."},"Codewolf_Ctrl_Api_Dtos_Api_InwardsStatusDto":{"type":"object","properties":{"id":{"type":"integer","format":"int32","description":"The status, by id."},"name":{"type":"string","nullable":true,"description":"The status as displayed."}},"additionalProperties":false,"description":"An inwards status lookup entry."},"Codewolf_Ctrl_Api_Dtos_Api_InwardsSummaryDto":{"type":"object","properties":{"id":{"type":"integer","format":"int32","description":"The delivery, for `GET /Inwards/{id}`. Not your order number."},"orderNumber":{"type":"string","nullable":true,"description":"The order reference the goods were shipped under — yours, echoed back. This is what you match a delivery to your own purchase order by."},"supplier":{"type":"string","nullable":true,"description":"Who the goods came from. Often the garment supplier rather than you."},"dateIn":{"type":"string","format":"date-time","nullable":true,"description":"When the delivery arrived. Null while it is still expected."},"cartons":{"type":"integer","format":"int32","nullable":true,"description":"How many packages arrived, as counted at goods-in."},"packageType":{"type":"string","nullable":true,"description":"What they arrived in — carton, satchel and so on. Free text."},"totalQuantity":{"type":"integer","format":"int32","description":"Total units across every line of the delivery."},"itemCount":{"type":"integer","format":"int32","description":"How many distinct lines the delivery has, not how many units."},"status":{"type":"string","nullable":true,"description":"⚠️ Where the delivery has got to, from `GET /Lookups/inwards-statuses`. In practice this has very little variance — nearly every record reads `Arrived` — so use `isAllocated` to tell a delivery still waiting to be matched from one already on a job."},"isAllocated":{"type":"boolean","description":"Whether the delivery has been matched to a job yet. This, not `status`, is the field that moves."},"jobNumber":{"type":"integer","format":"int32","nullable":true,"description":"The job the delivery was allocated to, or null while it is unallocated. Filter the list by `?jobNumber=` to get every delivery for one job."},"description":{"type":"string","description":"Auto-generated summary of the line items (\"code garment colour\" per line, CRLF-separated,\r\ncapped at 250 characters). Maintained by the same routine the intranet uses, so this is the\r\nidentical string the legacy inwards list renders. Null or empty on records whose line items\r\nhave no code/garment/colour — those lines are skipped when the summary is composed.","nullable":true}},"additionalProperties":false,"description":"Summary representation of an inwards record (used in list responses)."},"Codewolf_Ctrl_Api_Dtos_Api_PagedActiveJobsDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ReturnDtos_ActiveJobDto"},"description":"The collection of active jobs for the current page.","nullable":true},"totalCount":{"type":"integer","description":"The total number of active jobs across all pages.","format":"int32"},"pageNumber":{"type":"integer","description":"The current page number (1-based).","format":"int32"},"pageSize":{"type":"integer","description":"The number of items per page.","format":"int32"},"totalPages":{"type":"integer","description":"The total number of pages available.","format":"int32"},"hasPreviousPage":{"type":"boolean","description":"Indicates whether there is a previous page available.","readOnly":true},"hasNextPage":{"type":"boolean","description":"Indicates whether there is a next page available.","readOnly":true}},"additionalProperties":false,"description":"Represents a paginated response containing active jobs."},"Codewolf_Ctrl_Api_Dtos_Api_PatchInwardsResponseDto":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_InwardsDto"}],"properties":{"stockStatus":{"type":"string","description":"The current stock status of the job this delivery is now associated with: the job just\r\nallocated to, or — when the allocation was cleared — the job it was removed from. One of\r\n\"No Stock\", \"Partial Stock\" or \"Stock Complete\", matching the value the job endpoints\r\nreport for the same job.","nullable":true}},"additionalProperties":false,"description":"Response for PATCH /Inwards/{id} — the updated record plus the affected job's recomputed\r\nstock status, so a client refreshing a job's stock panel does not need a second call to\r\nupdate the status badge and cannot render a value that disagrees with the job's real state."},"Codewolf_Ctrl_Api_Dtos_Api_PricingProcessDto":{"type":"object","properties":{"processCode":{"type":"string","description":"Process code identifier","nullable":true,"example":"EW"},"description":{"type":"string","description":"Human-readable process description","nullable":true,"example":"Embroidery"},"active":{"type":"boolean","description":"Whether process is currently available","example":true},"sheetRank":{"type":"integer","description":"Sort order for UI display","format":"int32","example":10},"sheetColor":{"type":"string","description":"Hex color code for UI display","nullable":true,"example":"ddd9c4"},"tooltip":{"type":"string","description":"Tooltip text for UI","nullable":true,"example":"Embroidery"},"mapsToMaster":{"type":"string","description":"Master process code for grouping variants","nullable":true,"example":"EW"},"maximumSheetUnit":{"type":"string","description":"Unit of measure for the maximum sheet dimensions (cm / in / mm)","nullable":true,"example":"mm"},"maximumSheetWidth":{"type":"number","description":"Maximum sheet width in Codewolf.Ctrl.Api.Dtos.Api.PricingProcessDto.MaximumSheetUnit","format":"double","nullable":true,"example":500},"maximumSheetHeight":{"type":"number","description":"Maximum sheet height in Codewolf.Ctrl.Api.Dtos.Api.PricingProcessDto.MaximumSheetUnit","format":"double","nullable":true,"example":700},"metadata":{"type":"string","description":"An opaque tenant-defined JSON string describing the process. Control stores and serves\r\nthis verbatim and never interprets it - parse it client-side.","nullable":true}},"additionalProperties":false,"description":"Pricing process information from the Pricing database"},"Codewolf_Ctrl_Api_Dtos_Api_PricingProcessesResponse":{"type":"object","properties":{"processes":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_PricingProcessDto"},"description":"List of pricing processes","nullable":true}},"additionalProperties":false,"description":"Response wrapper for pricing processes"},"Codewolf_Ctrl_Api_Dtos_Api_ProcessCodeDto":{"required":["description","processCode"],"type":"object","properties":{"processCode":{"minLength":1,"type":"string","description":"Process code identifier","example":"EW"},"description":{"minLength":1,"type":"string","description":"Human-readable process description","example":"Embroidery"},"rank":{"type":"integer","description":"Display order rank (lower values appear first)","format":"int32","example":10},"metadata":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_ProcessCodeMetadataDto"}],"description":"Process metadata containing operational flags","nullable":true}},"additionalProperties":false,"description":"Process code information"},"Codewolf_Ctrl_Api_Dtos_Api_ProcessCodeMetadataDto":{"type":"object","properties":{"setupApplies":{"type":"boolean","description":"Indicates if setup charges apply to this process","example":true},"resetApplies":{"type":"boolean","description":"Indicates if reset charges apply to this process","example":true},"scheduleable":{"type":"boolean","description":"Indicates if this process can be scheduled in production","example":true},"physicalStockRequired":{"type":"boolean","description":"Indicates if physical stock is required for this process","example":false},"printable":{"type":"boolean","description":"Indicates if this process produces printable output","example":true}},"additionalProperties":false,"description":"Process metadata containing operational flags"},"Codewolf_Ctrl_Api_Dtos_Api_SizeQuantityDto":{"type":"object","properties":{"size":{"type":"string","nullable":true,"description":"The size code, which is a member of the line's size set. `\"Qty\"` means one-size-fits-all."},"qty":{"type":"integer","format":"int32","description":"How many of that size."}},"additionalProperties":false,"description":"A quantity for a specific size label within an item."},"Codewolf_Ctrl_Api_Dtos_Api_StateDto":{"type":"object","properties":{"name":{"type":"string","description":"Full state/province name","nullable":true,"example":"California"},"abbreviation":{"type":"string","description":"State/province abbreviation","nullable":true,"example":"CA"}},"additionalProperties":false,"description":"State/province/region information for lookup"},"Codewolf_Ctrl_Api_Dtos_Api_StateListResponse":{"type":"object","properties":{"countryCode":{"type":"string","description":"Country ISO2 code","nullable":true,"example":"US"},"states":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_StateDto"},"description":"List of states/provinces for the country","nullable":true}},"additionalProperties":false,"description":"Response containing list of states/provinces for a country"},"Codewolf_Ctrl_Api_Dtos_Api_StockItemShipmentTypeOptionDto":{"type":"object","properties":{"code":{"type":"string","description":"Shipment-type code (e.g. \"USPS\", \"Ground\", \"2 Day Air\"). Must be a code\r\nconfigured in the tenant's `JobForm_DeliveryOptions` OrgPref. Matched\r\ncase-insensitively; the server normalises to the canonical casing on\r\npersistence.","nullable":true},"name":{"type":"string","description":"Display label shown to end-users. <b>Server-supplied</b> — populated from\r\nthe matched `IDeliveryOption.Label` on write; client-sent values are\r\nignored. Corresponds to the same Label exposed as `ShipmentType.Name`\r\nat `/account/shipment-settings`.","nullable":true},"price":{"type":"number","description":"Price override. `null` = use rate-API price; `0` = free; positive = flat override.\r\nAlways non-negative when set.","format":"double","nullable":true}},"additionalProperties":false,"description":"A per-method shipping override for a stock item. Determines which shipment\r\nmethods are available for this stock item in this market and what they cost."},"Codewolf_Ctrl_Api_Dtos_Api_StockItemShippingDto":{"type":"object","properties":{"id":{"type":"integer","format":"int32","description":"Identifier for this shipping configuration row."},"stockItemId":{"type":"integer","format":"int32","description":"The stocked item this configuration belongs to."},"markets":{"type":"array","items":{"type":"string"},"nullable":true,"description":"Market codes this configuration applies in. An item can ship differently per market."},"shipMode":{"type":"string","nullable":true,"description":"How the item ships — for example bundled with the rest of the order, or as its own consignment."},"fulfilmentLocations":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_FulfilmentLocationDto"},"nullable":true,"description":"The warehouses this item can ship from."},"weight":{"type":"number","format":"double","nullable":true,"description":"Shipping weight, in `weightUnit`. Null where not captured, in which case rating falls back to defaults."},"weightUnit":{"type":"string","nullable":true,"description":"Unit for `weight` — `kg` or `lb`."},"length":{"type":"number","format":"double","nullable":true,"description":"Package length, in `dimensionUnit`."},"width":{"type":"number","format":"double","nullable":true,"description":"Package width, in `dimensionUnit`."},"height":{"type":"number","format":"double","nullable":true,"description":"Package height, in `dimensionUnit`."},"dimensionUnit":{"type":"string","nullable":true,"description":"Unit for `length`, `width` and `height` — `cm` or `in`."},"fixedShipping":{"type":"number","format":"double","nullable":true,"description":"A flat shipping charge that replaces live carrier rating for this item. Null means rate it normally."},"groundOnly":{"type":"boolean","description":"True when the item cannot travel by air, which removes express methods from its options."},"estimatedLeadDays":{"type":"integer","format":"int32","nullable":true,"description":"Working days to expect before despatch, on top of any production time."},"active":{"type":"boolean","description":"Whether this configuration is in use. Inactive rows are retained for history."},"createdAt":{"type":"string","format":"date-time","description":"When the configuration was created, UTC."},"updatedAt":{"type":"string","format":"date-time","description":"When the configuration was last changed, UTC."},"shipmentTypeOptions":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_StockItemShipmentTypeOptionDto"},"description":"Per-method shipping overrides for this stock item in this market.\r\nEmpty array if no overrides are configured.\r\nOrder is meaningful — rows are returned in the sort order they were saved\r\n(first row may be treated by the consumer as the default method).","nullable":true}},"additionalProperties":false,"description":"Response DTO for a stock item shipping configuration, including resolved\r\nfulfilment location details from the junction table."},"Codewolf_Ctrl_Common_Classes_AssetDtos_AssetDto":{"type":"object","properties":{"assetId":{"type":"integer","description":"Internal Id for Asset","format":"int32"},"assetTag":{"type":"string","description":"The Tag (code) which identifies a unique asset","nullable":true},"processCode":{"type":"string","description":"The Process the Asset is used in","nullable":true},"description":{"type":"string","description":"The Asset Description","nullable":true},"garment":{"type":"string","description":"The Garment the Asset is used on","nullable":true},"priceTierCode":{"type":"string","description":"The price Tier Code","nullable":true},"setup":{"type":"number","description":"The cost to setup for this asset job ($)","format":"double"},"reset":{"type":"number","description":"The reset cost to for this asset job ($)","format":"double"},"priceCode":{"type":"string","description":"Price code used to create the Asset","nullable":true},"assetUrl":{"type":"string","description":"URL to the Asset image","nullable":true},"createDate":{"type":"string","description":"Create Date","format":"date-time"},"isGlobal":{"type":"boolean","description":"Indicates if the Asset is a Global Asset - that anyone can see/use"},"externalId":{"type":"string","description":"External identifier from third-party systems (e.g., BuildAGangSheet designId)","nullable":true},"customerId":{"type":"integer","description":"Owning customer id (ClientId on the underlying asset row). Populated when the asset is fetched\r\nvia the data-reader constructor (e.g. SuperUser flows) so callers can derive the owning customer\r\nfrom the asset itself. Nullable so the parameterless-constructor path yields null rather than a\r\nmisleading 0.\r\n<br>\r\nNOTE: null does NOT mean the key is omitted from API responses. The MVC pipeline\r\n(ApiConfigurationHelper.ConfigureControllers) does not override Newtonsoft's default\r\nNullValueHandling.Include, so this serializes as an explicit \"customerId\": null.\r\nThe global NullValueHandling.Ignore in Startup.cs applies only to manual JsonConvert calls.\r\nSee API-Technical-Debt item 29.\r\n","format":"int32","nullable":true},"isArchived":{"type":"boolean","description":"Indicates if the asset is archived (hidden from default view)"},"priceBands":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Interfaces_IPriceBandDto"},"description":"Pricing Bands for the Asset","nullable":true},"attributes":{"type":"object","additionalProperties":{"type":"string","nullable":true},"description":"Free-form asset attributes (the AssetAttributes table) as name/value pairs — the same set\r\nshown on the Attributes tab of the Asset dialog in Control (Description, Garment, Colors,\r\nSize, PriceCode, ...). The set varies by tenant and process, so it is not a fixed schema.\r\n<br>\r\nPopulated for SuperUser callers only. For every other caller it is left null and the key is\r\nomitted from the JSON entirely (see M:Codewolf.Ctrl.Common.Classes.AssetDtos.AssetDto.ShouldSerializeAttributes), so a non-SuperUser\r\nresponse is byte-identical to one produced before this property existed.\r\n<br>\r\nAn empty dictionary means \"authorised, but this asset has no attributes\" — distinct from the\r\nkey being absent, which means \"not authorised to see them\".\r\n","nullable":true}},"additionalProperties":false,"description":"Describes an Asset Dtos"},"Codewolf_Ctrl_Common_Classes_AssetDtos_AssetTypeDto":{"type":"object","properties":{"process":{"type":"string","description":"The Process Code which normally is included at the front of the AssetCode so you can understand the process that the Asset uses","nullable":true},"assetType":{"type":"string","description":"The description of the Asset Type","nullable":true}},"additionalProperties":false,"description":"Holds the information about an Asset Type"},"Codewolf_Ctrl_Common_Classes_Jobs_BaseAddress":{"type":"object","properties":{"streetAddress":{"type":"string","description":"Street Address for Delivery/Shipping","nullable":true},"address2":{"type":"string","description":"Street Address (2nd line) for Delivery/Shipping","nullable":true},"suburb":{"type":"string","description":"Suburb (or area) for Delivery/Shipping","nullable":true},"city":{"type":"string","description":"City for Delivery/Shipping","nullable":true},"state":{"type":"string","description":"State (or area) for Delivery/Shipping","nullable":true},"stateCode":{"type":"string","description":"State code i.e. NSW, CA, FL","nullable":true},"postalCode":{"type":"string","description":"Postcode for Delivery/Shipping","nullable":true},"countryCodeISO2":{"type":"string","description":"Two-character ISO 3166-1 alpha-2 country code — `\"US\"`, `\"NZ\"`, `\"GB\"`. ⚠️ Two letters, not three: `\"USA\"` is rejected. Valid codes come from `GET /Lookups/countries` (`iso2`).","nullable":true},"country":{"type":"string","description":"Country Name","nullable":true}},"additionalProperties":false},"Codewolf_Ctrl_Common_Classes_Jobs_DeliveryAddress":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_DeliveryBaseAddress"}],"additionalProperties":false,"description":"Simplified address class for use in api for entering initial job delivery address."},"Codewolf_Ctrl_Common_Classes_Jobs_DeliveryBaseAddress":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_BaseAddress"}],"properties":{"deliveryMethod":{"type":"string","description":"Delivery method for the order shipping\r\nThis must be one of the valid delivery methods available. \r\nsee Http GET: delivery methods","nullable":true},"shippingInstructions":{"type":"string","description":"Any shipping instructions for the delivery","nullable":true},"contactName":{"type":"string","description":"Contact Name for Delivery/Shipping","nullable":true},"organisation":{"type":"string","description":"Organisation for Delivery/Shipping","nullable":true},"phone":{"type":"string","description":"Phone for Delivery/Shipping","nullable":true},"mobile":{"type":"string","description":"Mobile for Delivery/Shipping","nullable":true},"emailAddress":{"type":"string","description":"Email Address for Delivery/Shipping","nullable":true},"isSaturdayDelivery":{"type":"boolean","description":"Indicates whether Saturday delivery is requested for this shipment.\r\nSupported by UPS and FedEx express services. Optional, defaults to false."}},"additionalProperties":false,"description":"Simplified address class for use in api for entering initial job delivery address."},"Codewolf_Ctrl_Common_Classes_Jobs_InvoiceFileDto":{"type":"object","properties":{"uri":{"type":"string","description":"The URI to fetch the invoice PDF. This points at Control's public\r\n`/cdn/invoices/{token}` endpoint, where the token is a Hashids code\r\n(obfuscation, not encryption) keyed by the tenant Salt, carrying the customer,\r\njob and a lease expiry. Control re-validates the lease and job ownership\r\nserver-side on every request. The invoice is served from storage as-is\r\n(Control generates and stores it) — nothing is generated on access.","nullable":true},"uriExpires":{"type":"string","description":"Expiry of the Codewolf.Ctrl.Common.Classes.Jobs.InvoiceFileDto.Uri — the end of the link's lease window. The\r\nCDN endpoint rejects the link once this passes. Populated whenever an invoice\r\nis advertised.","format":"date-time","nullable":true}},"additionalProperties":false,"description":"A slim public representation of a job's invoice file on the Job contract.\r\nOnly exposes the URI to fetch the invoice and an optional expiry; the full\r\ninternal EntityFileLite is never exposed on the public job contract."},"Codewolf_Ctrl_Common_Classes_Jobs_JobBaseDto":{"type":"object","properties":{"jobNumber":{"type":"integer","description":"Job Number which identifies the job","format":"int32"},"description":{"type":"string","description":"The description associated with the Job","nullable":true},"comments":{"type":"string","description":"The comments associated with the Job","nullable":true},"jobStatus":{"type":"string","description":"The current status of the Job","nullable":true},"orderNumber":{"type":"string","description":"Any associated Order Number information for the Job","nullable":true},"dateDue":{"type":"string","description":"The Date the Job is due to complete","format":"date-time"},"mustDate":{"type":"boolean","description":"Indicates if the Due Date is a Must be on time flag"},"creator":{"type":"string","description":"Person who Created the Job","nullable":true},"invoiceNumber":{"type":"string","description":"Invoice Number (if been invoiced)","nullable":true},"orderGroup":{"type":"string","description":"Shared identifier linking multiple jobs from one checkout","nullable":true},"orderGroupSequence":{"type":"integer","description":"Position within the order group (1, 2, 3...)","format":"int32","nullable":true}},"additionalProperties":false,"description":"The Job record"},"Codewolf_Ctrl_Common_Classes_Jobs_JobCandidate":{"type":"object","properties":{"orderNumber":{"type":"string","description":"(optional) Order # reference (for the creating user's companies Order #)","nullable":true},"orderComment":{"type":"string","description":"Any comment associated with the Order","nullable":true},"customerUserId":{"type":"integer","description":"(Optional) The associated Customer User Id - defaults to current logged on user.\r\nWhen supplied, the user must exist, be active, and belong to the customer the job is created for,\r\nand is set as the job's Customer User (owner/contact).","format":"int32","nullable":true},"dateDue":{"type":"string","description":"The ship date you are asking for. ⚠️ OPTIONAL, measured 2026-08-29: omitting it validates, as do `null` and omitting it alongside `mustDate: true`. A date in the PAST is rejected with error `10303` (\"Due date must be after today\") rather than silently moved, so check it against `GET /Jobs/earliest-ship-date` and take the date from `shippingDateLocal`. An unparseable string is rejected by model binding with an `errors` object instead of `validationMessages`, so handle both shapes. ⛔ Its absence is NOT a cause of an opaque 500 on this endpoint — that claim stood here until 2026-08-29 and was a misattribution; see `JobLineBom.size`.","format":"date-time","nullable":true},"mustDate":{"type":"boolean","description":"only applicable if due date is specified. Indicates the Due date is a Must be met date"},"timeSensitive":{"type":"boolean","description":"Indicates whether this job is Time Sensitive which means that the DueDate will incorporate the default Due TIME of the day for the Due date"},"description":{"type":"string","description":"A description of the order","nullable":true},"deliveryAddress":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_DeliveryAddress"}],"description":"Delivery address information","nullable":true},"promocode":{"type":"string","description":"(Optional) Promo code - Must be a valid Promo code or Job will return a validation error","nullable":true},"items":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobLineBaseGrouping"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobLineBom"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobLineExternalGarment"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobLinePriceCode"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobLineStock"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ReturnDtos_JobLineAsset"}],"description":"Abstract class for a basic Job Line","discriminator":{"propertyName":"itemType","mapping":{"Asset":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ReturnDtos_JobLineAsset","PriceCode":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobLinePriceCode","Stock":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobLineStock","Bom":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobLineBom","ExternalGarment":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobLineExternalGarment"}}},"description":"A List of Items to add to the Job. Supports adding the inherited classes JobLineAsset, JobLinePriceCode, JobLineStock, JobLineBom \r\nItems will be added in the same order as this supplied list","nullable":true},"orderGroup":{"type":"string","description":"Shared identifier linking multiple jobs from one checkout (e.g. RO-1234567).\r\nNull for single-job orders.","nullable":true},"orderGroupSequence":{"type":"integer","description":"Position within the order group (1, 2, 3...).\r\nNull for single-job orders.","format":"int32","nullable":true},"validateOnly":{"type":"boolean","description":"Run the whole authentication and validation path and create nothing, answering `\"Validated with NO Errors. Job NOT created.\"` when the payload is good. Send the payload you actually intend to create — `externalArtworkUrl` included. Measured 2026-09-01: the dry run checks each artwork URL's shape and origin and neither fetches nor stores it, so a validated payload and a created one differ by this flag alone."},"locationCodeOverride":{"type":"string","description":"(Optional) Override the customer's default factory location.\r\nWhen provided, the job is routed to this location instead of the customer's profile location.\r\nMust reference an active, non-virtual Location.Code (e.g., \"LA\", \"AT\", \"NZ\").\r\nWhen omitted or null, existing behaviour is unchanged.","nullable":true}},"additionalProperties":false,"description":"Job class to enable the creation of jobs from the web API"},"Codewolf_Ctrl_Common_Classes_Jobs_JobDto":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobBaseDto"}],"properties":{"stockStatus":{"type":"string","description":"The plain-English stock status for the job: \"No Stock\", \"Partial Stock\" or \"Stock Complete\".\r\nTenant-conditional: only populated for tenants with the ShowInwardsList org pref enabled,\r\nand omitted entirely from the response otherwise. Only meaningful where inwards is in use.","nullable":true},"customerUserId":{"type":"integer","description":"The Customer User (owner/contact) the job belongs to - tblJobs.OwnerID.\r\nThis is the customer's own user who placed the job, not Codewolf.Ctrl.Common.Classes.Jobs.JobBaseDto.Creator\r\n(the Control staff member who keyed it in) and not the owning customer.\r\nNull on legacy rows that were written without an owner.","format":"int32","nullable":true},"customerUserName":{"type":"string","description":"The display name of the Customer User identified by Codewolf.Ctrl.Common.Classes.Jobs.JobDto.CustomerUserId.\r\nReturned alongside the id because a plain CustomerUser token cannot resolve ids itself\r\n(/account/users is admin-only), so an id on its own would render as a bare number for\r\nexactly the users this field exists to serve. Null when the job has no owner.","nullable":true},"shippingAddresses":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ShippingAddress"},"description":"Holds the Shipping addresses and any tracking links","nullable":true},"lines":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobLineDto"},"description":"The Lines in the Job","nullable":true},"location":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobLocationDto"}],"description":"Location information for the job","nullable":true},"taxTotal":{"type":"number","description":"The total tax amount for all job lines","format":"double","nullable":true},"dateOut":{"type":"string","description":"The date the job was shipped/dispatched","format":"date-time","nullable":true},"dateIn":{"type":"string","description":"The date the job was created/entered","format":"date-time","nullable":true},"shippedDateStatus":{"type":"string","description":"A formatted status string indicating if the job was shipped early, on time, or late\r\n(e.g., \"1.35 Days Early\", \"On Time\", \"2 Days Late\")","nullable":true},"shippedDaysToProcess":{"type":"number","description":"The number of days the job was shipped early or late relative to the due date.\r\nNegative values indicate early shipment, positive values indicate late shipment.","format":"double","nullable":true},"processingDays":{"type":"number","description":"The number of days it took to process the job from creation to shipping","format":"double","nullable":true},"permissions":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_PermissionsDto"}],"description":"Edit permissions for this job","nullable":true},"isCancelable":{"type":"boolean","description":"Indicates whether the job can be cancelled via the API.\r\nThis is determined by the CanCancelCustomer flag on the job's current MasterJobStatus."},"invoiceFile":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_InvoiceFileDto"}],"description":"The downloadable invoice file for this job. Populated only when the job is\r\nDispatched or Closed AND an invoice PDF has been stored for it (Control\r\ngenerates and stores invoices; the API never generates them). Null otherwise.\r\nThe URI points at Control's public, time-limited CDN invoice endpoint.","nullable":true},"customerId":{"type":"integer","description":"Customer ID that owns this job. Hidden from JSON output (matches the\r\n`OwnerId` pattern on Codewolf.Ctrl.Common.Classes.Jobs.JobExtendedDto) — used at the\r\ncontroller layer for a strict customer-isolation re-check after the\r\nlegacy `(CustomerMismatch AND UserMismatch)` ownership check, to\r\ndefend against `OwnerId` collisions on retail rows.","format":"int32"}},"additionalProperties":false,"description":"The Job record"},"Codewolf_Ctrl_Common_Classes_Jobs_JobLineBase":{"required":["itemType"],"type":"object","properties":{"itemType":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobLineType"}],"description":"Which kind of line this is, and therefore what `code` must contain. `\"PriceCode\"` — a new decoration, `code` is a full price code from `GET /PriceCodes/price-codes`. `\"Asset\"` — a repeat, `code` is an asset tag from `GET /Assets`. `\"Stock\"` — stocked goods, `code` is a `stockCode` from `GET /Stock`. `\"Bom\"` — a made-up product, `code` is a `bomVariantCode` from `GET /Boms/{bomCode}`. `\"ExternalGarment\"` — a garment you are sending in, which carries no `code` at all. These values are published as an enum on `JobLineType` and as the `itemType` discriminator on the line union, so a generated client already knows them; this list says what the `code` must be for each."},"code":{"type":"string","description":"Identifies the item, in the form `itemType` selects: a full price-code string such as `DG_DIGICAD_FLEX220:Cad Cut Film-Flex 220` (PriceCode), an asset tag such as `EW49123` (Asset), a stock code such as `5000` (Stock), or a BOM variant code such as `BOM10112-M` (Bom). ⛔ `ExternalGarment` lines carry no code. Passing the wrong form for the type is the most common cause of a rejected job.","nullable":true},"quantity":{"type":"integer","description":"How many to make. Ignored for `Stock` lines, which carry their run in `sizeQuantities` instead. Quantity drives which price band applies, so ordering the same design as two lines costs more than one line of the combined quantity.","format":"int32"},"customerReference":{"type":"string","description":"Your own reference for this line, echoed back per line so you can match a returned asset tag to the line you sent. ⛔ NOT required, but it must be UNIQUE ACROSS THE JOB and BLANK COUNTS AS A VALUE — two lines that both omit it collide exactly like two carrying the same string, and answer error `1830`. Measured 2026-08-29: absent and `null` are the same value as each other and `\"\"` is a third distinct value, so at most one line may omit it and at most one may send `\"\"`. ⚠️ Do not parse the number in that message: it is unreliable — three colliding lines reported \"1 duplicated values\" and two reported \"2\" — and it names neither the value nor the line index. Give every line its own reference and none of this applies.","nullable":true}},"additionalProperties":false,"description":"Abstract class for a basic Job Line","discriminator":{"propertyName":"itemType"}},"Codewolf_Ctrl_Common_Classes_Jobs_JobLineBaseGrouping":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobLineBase"}],"properties":{"groupHead":{"type":"string","description":"(optional) If this Line Item is to be a Grouping for other lines. Note this can contain any string value, but if specified in the head the children will use the same string value \r\nThis means that other Line items with this same value set in the Group field will be grouped under this item","nullable":true},"group":{"type":"string","description":"(optional) If this line is set it should match to the name of a Group Head on another line, and this will create the current line as a child line under the Group Head line (of the same group name)","nullable":true}},"additionalProperties":false},"Codewolf_Ctrl_Common_Classes_Jobs_JobLineBom":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobLineBase"}],"properties":{"size":{"type":"string","description":"The size code for this BOM line, from the `bomVariants` of `GET /Boms/{bomCode}`. Required when the BOM code does not already carry a size indicator. ⛔ ALWAYS SEND IT. Measured 2026-08-29: when it is required and ABSENT — or explicitly `null` — the request answers an opaque **500**, while `size: \"\"` reaches the real validator and returns a structured `1825 \"Size is required\"`. The crash is the absent case, not the invalid one. A code that already carries its size (`BOM10112-M`) does not need it and does not crash without it.","nullable":true},"customName":{"type":"string","description":"An optional per-item personalisation, such as a back name from an \"add a name\" option at your checkout. It produces a per-name line rather than one aggregated line.","nullable":true}},"additionalProperties":false,"description":"Defines a Line of a Job which uses a Bill of Material code to identify an entire process for creating an item"},"Codewolf_Ctrl_Common_Classes_Jobs_JobLineDto":{"type":"object","properties":{"jobLineId":{"type":"integer","description":"Unique Identifier for the Job Line","format":"int32"},"assetSku":{"type":"string","description":"The Program value assigned to the Job Line\r\nThis could be the Asset Code or a new Asset code created from a PriceCode","nullable":true},"processCode":{"type":"string","description":"The production process for this line. Values come from `GET /Lookups/process-codes`.","nullable":true},"garment":{"type":"string","description":"The garment to be used","nullable":true},"description":{"type":"string","description":"The description o the Job line","nullable":true},"comments":{"type":"string","description":"The Comments on the Job line","nullable":true},"quantity":{"type":"integer","description":"The quantity of this Job Line","format":"int32"},"unitPrice":{"type":"number","description":"The price of each unit","format":"double"},"customerReference":{"type":"string","description":"The Customers reference string","nullable":true},"imageUrl":{"type":"string","description":"CDN URL for the jobline image (asset or stock variant thumbnail)","nullable":true},"gang":{"type":"string","description":"Gets or sets the name of the gang associated with the entity.","nullable":true},"jobLineStatus":{"type":"string","description":"The line's current production status. ⚠️ Values come from `GET /Lookups/job-statuses`; do not hardcode them. (Upstream's own description of this field — \"the programmatic comment associated with this instance\" — is a copy-paste error and describes a comment field, not this one.)","nullable":true},"parentJobLineId":{"type":"integer","description":"The JobLineId of the line this line is grouped under, or null when this line is itself a\r\ntop-level (head) line. Lines sharing a ParentJobLineId belong to the same decoration - for\r\nexample an applique head line with its outer stitch and repeat setup. Grouping can nest more\r\nthan one level deep (a stock garment, a decoration on it, and that decoration's setup line).\r\nWhen not null the value always refers to another line present in the same response, so it is\r\nsafe to use as a key when building a tree.","format":"int32","nullable":true},"order":{"type":"integer","description":"The position of this line among its siblings. It is scoped to the parent, not to the job: a\r\nchild line's Order restarts at 1 within each parent, and most lines report 0 because a value\r\nis only assigned when a job is explicitly reordered. It is therefore not a job-wide sequence\r\nand not a usable sort key on its own - group using ParentJobLineId rather than this field.\r\nFor display position prefer Rank, which is a job-wide sequence that reproduces the Control job\r\nscreen - but only on the reads that populate it. See Rank for which those are.","format":"int32"},"rank":{"type":"integer","description":"The line's position on the Control job screen, banded so one number carries both the sequence and the grouping. Where it is populated, sorting by `rank` ascending reproduces Control's display order exactly — no secondary sort, and the lines already arrive in that order.\n\n**Not every read populates it.** `rank` is set by `GET /Jobs/{jobNumber}` and `GET /Jobs/{jobIdentifier}/extended`. Reads that do not — the agent job read is the example — leave it at its default of 0 on every line. A response whose lines are ALL 0 is unranked, not same-ranked: fall back to the order the lines were returned in.\n\n`rank / 100` identifies the group: lines sharing a hundreds band render together, and the first line of a band is the band's head. A top-level line with no children of its own occupies a band by itself, so a band of one is a standalone line rather than a group — use the band's line COUNT to decide whether to render it as a group.\n\n`rank >= 100000` means the line belongs to no group and renders at the bottom, in rank order. ⚠️ It does NOT mean the line is a setup, discount or shipping line, and you cannot use it to identify them: measured over 572 live jobs, 35% have every line in that band (decorations included), 23% have a genuine work line there, and 10% carry a discount or shipping line BELOW it. Treat the band as \"Control has not been asked to sort this\", never as a line type — hiding or grey-ing it blanks a third of jobs.\n\n`rank` and `parentJobLineId` answer different questions and can legitimately disagree: rank is where Control draws the line, `parentJobLineId` is which line it was created from. A setup such as `RESPA` points into its group and still ranks 100000+, because Control renders setups at the bottom. Use `rank` for placement and `parentJobLineId` for lineage.\n\nStable for a given job state, not permanent — editing or reordering a job re-ranks it — and scoped to the job, so ranks are only comparable within one job.","format":"int32"}},"additionalProperties":false,"description":"defines a Line of a Job"},"Codewolf_Ctrl_Common_Classes_Jobs_JobLineExternalGarment":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobLineBaseGrouping"}],"properties":{"sizeQuantities":{"type":"object","additionalProperties":{"type":"integer","format":"int32"},"description":"How many of each size are coming in, keyed by size code. The size run and its order come from `GET /Lookups/size-sets`.","nullable":true},"garment":{"type":"string","description":"⛔ REQUIRED, though the schema does not mark it. What the garment is, in words. Omitting it is error 1900.","nullable":true},"description":{"type":"string","description":"⛔ REQUIRED, though the schema does not mark it. A garment you are sending in must carry a non-empty description or the job is rejected with error 1901 — verified omitted, empty and grouped-without-one.","nullable":true},"quantity":{"type":"integer","description":"The quantity from the array of Size * Quantities list","format":"int32","readOnly":true}},"additionalProperties":false,"description":"Defines a new Job Line which uses an existing Stock item","required":["description","garment"]},"Codewolf_Ctrl_Common_Classes_Jobs_JobLinePriceCode":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobLineBaseGrouping"}],"properties":{"attributes":{"type":"object","additionalProperties":{},"description":"The answers to this price code’s own `attributes` questions, keyed by each attribute’s `name` exactly as given. Read them from `GET /PriceCodes/price-codes` — they differ per code and the keys are case-sensitive.","nullable":true},"externalArtworkUrl":{"type":"string","description":"A URL to the artwork for this new decoration. One request places the order and delivers the art; the URL must stay reachable until the job reaches production, since we fetch it rather than holding your link. Include it in your `validateOnly` dry run — validation checks it and creates nothing. Three rules, each measured 2026-09-01 and each answering by number. (1) An ABSOLUTE `https://` URL: `http://`, a bare host, a relative or protocol-relative path and any other scheme are error `10408`, as is a whitespace-only string. (2) Its ORIGIN must be on your account's approved artwork origins — anything else is error `10403`, and `10409` means no origins are configured on the account at all. Both are account configuration rather than something wrong with your URL, so ask us to approve the origin you serve artwork from. Reachability is NOT checked here: a URL that resolves and one that does not answer identically, so a `10403` is never about the file. (3) ALL-OR-NOTHING across the job — if any `PriceCode` line carries artwork, every `PriceCode` line must, or the job is error `10404` naming the line that does not. `Asset` lines are repeats and are unaffected. ⚠️ Omitting the property, `null` and `\"\"` all skip these checks and validate, which means the artwork was not verified — not that it passed.","nullable":true},"externalId":{"type":"string","description":"(Optional) External identifier from third-party systems (e.g., BuildAGangSheet designId)\r\nUsed to link the asset back to the original external design for editing","nullable":true},"isSample":{"type":"boolean","description":"Gets or sets a value indicating whether this instance is marked as a sample.\r\nThis allows the job line to be identified as a sample item, and therefore bypass the normal quantity minimums"}},"additionalProperties":false,"description":"defines a Job line which is used with a Price Code in the system to define a new Job Asset"},"Codewolf_Ctrl_Common_Classes_Jobs_JobLineStock":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobLineBaseGrouping"}],"properties":{"variantCode":{"type":"string","description":"a variant code which can also identify the Stock item","nullable":true},"sizeQuantities":{"type":"object","additionalProperties":{"type":"integer","format":"int32"},"description":"A list of size quantities for a stock item\r\nDictionary indexed via SizeCode","nullable":true},"quantity":{"type":"integer","description":"The quantity from the array of Size * Quantities list","format":"int32","readOnly":true}},"additionalProperties":false,"description":"Defines a new Job Line which uses an existing Stock item"},"Codewolf_Ctrl_Common_Classes_Jobs_JobLineType":{"enum":["Asset","PriceCode","Stock","Bom","ExternalGarment"],"type":"string","description":"Job Line Type - used to load the different line types into the Create Job Web API"},"Codewolf_Ctrl_Common_Classes_Jobs_JobLocationDto":{"type":"object","properties":{"name":{"type":"string","description":"The name of the location","nullable":true},"timezone":{"type":"string","description":"The timezone of the location (Time zone identifier in IANA TZ database format)","nullable":true}},"additionalProperties":false,"description":"Location information for a job"},"Codewolf_Ctrl_Common_Classes_Jobs_JobStatusDto":{"type":"object","properties":{"id":{"type":"integer","description":"MasterJobStatusID","format":"int32"},"name":{"type":"string","description":"Name","nullable":true}},"additionalProperties":false,"description":"Configuration for a single supported job status"},"Codewolf_Ctrl_Common_Classes_Jobs_PermissionsDto":{"type":"object","properties":{"canEdit":{"type":"boolean","description":"Whether `PATCH /Jobs/{jobNumber}` will be accepted for this job. Read it before amending rather than catching the rejection: a job locks once it is dispatched, closed, returned or cancelled."},"lockedReason":{"type":"string","description":"Why editing is locked, when `canEdit` is false. Null while the job is still editable.","nullable":true}},"additionalProperties":false,"description":"DTO for edit permissions information"},"Codewolf_Ctrl_Common_Classes_Jobs_ReturnDtos_ActiveJobDto":{"type":"object","properties":{"permissions":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_PermissionsDto"}],"description":"Edit permissions for this job based on its status.","nullable":true},"jobNumber":{"type":"integer","description":"The unique identifier for the job.","format":"int32"},"masterJobStatus":{"type":"string","description":"The job's current status. ⚠️ Read the full set from `GET /Lookups/job-statuses` rather than matching strings you have seen before — statuses are added over time, and an unrecognised one must never break your integration.","nullable":true},"stockStatus":{"type":"string","description":"The plain-English stock status for the job: \"No Stock\", \"Partial Stock\" or \"Stock Complete\".\r\nTenant-conditional: only populated for tenants with the ShowInwardsList org pref enabled,\r\nand omitted entirely from the response otherwise. Only meaningful where inwards is in use.","nullable":true},"originCode":{"type":"string","description":"The origin code indicating where the job originated from.","nullable":true},"description":{"type":"string","description":"A brief description of the job.","nullable":true},"customerUserId":{"type":"integer","description":"The Customer User (owner/contact) the job belongs to - tblJobs.OwnerID.\r\nThis is the customer's own user who placed the job, not the Control staff member who\r\nkeyed it in (that is Creator on the job detail DTO) and not the owning customer.\r\nNull on legacy rows that were written without an owner.","format":"int32","nullable":true},"customerUserName":{"type":"string","description":"The display name of the Customer User identified by Codewolf.Ctrl.Common.Classes.Jobs.ReturnDtos.ActiveJobDto.CustomerUserId.\r\nReturned alongside the id because a plain CustomerUser token cannot resolve ids itself\r\n(/account/users is admin-only), so an id on its own would render as a bare number for\r\nexactly the users this field exists to serve. Null when the job has no owner.","nullable":true},"mustDate":{"type":"boolean","description":"Indicates whether the job has a strict deadline that must be met."},"dateDue":{"type":"string","description":"The date the job is due to be completed.","format":"date-time","nullable":true},"dateOut":{"type":"string","description":"The date the job was shipped or dispatched.","format":"date-time","nullable":true},"shippedDaysToProcess":{"type":"number","description":"The number of days the job was shipped early or late relative to the due date.\r\nNegative values indicate early shipment, positive values indicate late shipment.","format":"double","nullable":true},"orderNumber":{"type":"string","description":"Order number reference","nullable":true},"orderGroup":{"type":"string","description":"Shared identifier linking multiple jobs from one checkout (e.g. RO-1234567).\r\nNull for single-job orders.","nullable":true},"orderGroupSequence":{"type":"integer","description":"Position within the order group (1, 2, 3...).\r\nNull for single-job orders.","format":"int32","nullable":true},"tracking":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ReturnDtos_TrackingItemDto"},"description":"Tracking information for this job's shipments.\r\nEach entry represents one shipment with its tracking number and optional tracking link.\r\nEmpty list if no tracking data is available.","nullable":true}},"additionalProperties":false,"description":"Represents an active job with essential tracking and status information."},"Codewolf_Ctrl_Common_Classes_Jobs_ReturnDtos_CreateJobReturnDto":{"type":"object","properties":{"jobNumber":{"type":"integer","description":"The new Job number created for the Job","format":"int32","readOnly":true},"location":{"type":"string","description":"indicates the location that the job will be manufactured","nullable":true},"dateDue":{"type":"string","description":"The DueDate. Either the passed DueDate or Calculated due date if requested was earlier than possible\r\nNOTE: that this will always be the date and/or time in the locations timezone","nullable":true,"readOnly":true},"jobLineDetails":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ReturnDtos_JobLineReturnDto"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ReturnDtos_JobLinePriceCodeReturnDto"}],"description":"Base class returned as an array of items - holds the return information for each Job line\r\nNOTE: Create either a JobItemPriceCodeReturnDto object or one of these which doesn't extend the basic data in here"},"description":"A list of unique key values passed in as part of the CreateJob Item - these should only include job items that require new artwork to be uploaded","nullable":true,"readOnly":true},"totalJobCost":{"type":"number","description":"Total Job Cost","format":"double"},"expectingArtworkToBeUploaded":{"type":"boolean","description":"Indicates to the WebApi User whether this newly created Job is expecting Artwork for any of the lines in the Job Itself","readOnly":true}},"additionalProperties":false,"description":"Returns the information from a successful Job Creation to the caller"},"Codewolf_Ctrl_Common_Classes_Jobs_ReturnDtos_CreateShopJobReturnDto":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ReturnDtos_CreateJobReturnDto"}],"properties":{"customerId":{"type":"integer","description":"The Customer Id for this shopify user","format":"int32"},"userId":{"type":"integer","description":"The User Id for this shopify user","format":"int32"}},"additionalProperties":false,"description":"Returns the information from a successful Job Creation to the caller"},"Codewolf_Ctrl_Common_Classes_Jobs_ReturnDtos_JobLineAsset":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobLineBaseGrouping"}],"properties":{"garment":{"type":"string","description":"(optional) Garment","nullable":true},"comment":{"type":"string","description":"Any Comment","nullable":true}},"additionalProperties":false,"description":"Create a Job Line Item which uses an existing Asset in the system. Identified via the Asset Code (Code property)"},"Codewolf_Ctrl_Common_Classes_Jobs_ReturnDtos_JobLinePriceCodeReturnDto":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ReturnDtos_JobLineReturnDto"}],"properties":{"newAssetSku":{"type":"string","description":"The associated AssetSKU associated with the job line \r\nShows the new AssetTag code if the JobLine used a Price Code","nullable":true},"jobLineLabelUrl":{"type":"string","description":"If this is an external supplier order, this will contain the link to the jobline label","nullable":true}},"additionalProperties":false,"description":"The Job line information returned to the WEBAPI caller from the Create Job call"},"Codewolf_Ctrl_Common_Classes_Jobs_ReturnDtos_JobLineReturnDto":{"type":"object","properties":{"needsArtworkToBeUploaded":{"type":"boolean","description":"indicates whether artwork NEEDS to be uploaded for this item"},"customerReference":{"type":"string","description":"The customer reference Id value that is passed on new PriceCode lines and passed back when new Artwork is needed to be uploaded for the line","nullable":true},"quantity":{"type":"integer","description":"the unit cost of the job line (priced based on customer price tier etc.)","format":"int32"}},"additionalProperties":false,"description":"Base class returned as an array of items - holds the return information for each Job line\r\nNOTE: Create either a JobItemPriceCodeReturnDto object or one of these which doesn't extend the basic data in here"},"Codewolf_Ctrl_Common_Classes_Jobs_ReturnDtos_TrackingItemDto":{"type":"object","properties":{"trackingNumber":{"type":"string","description":"The carrier tracking number for this shipment.","nullable":true},"trackingLink":{"type":"string","description":"The URL to track this shipment on the carrier's website.\r\nMay be null if the carrier does not provide a tracking link.","nullable":true}},"additionalProperties":false,"description":"Represents a single tracking entry for a job shipment.\r\nContains the tracking number and optional tracking link URL."},"Codewolf_Ctrl_Common_Classes_Jobs_ShippingAddress":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_DeliveryBaseAddress"}],"properties":{"shipmentId":{"type":"integer","description":"Stable identifier for this shipment on the job (dbo.JobShipment.Id).\r\nA job can carry several shipments, each with its own address and delivery\r\nmethod; this is what PATCH /Jobs/{jobNumber}/shipping uses to target one of them.","format":"int32"},"trackingLink":{"type":"string","description":"A Tracking link - if one has been allocated","nullable":true},"trackingNumber":{"type":"string","description":"The Tracking number associated to the Shipping address (for the service)","nullable":true}},"additionalProperties":false,"description":"One shipment on a job as returned by the job read endpoints — an address plus its delivery\r\nmethod and tracking details."},"Codewolf_Ctrl_Common_Classes_Jobs_ShopJobs_DiscountTargetEnum":{"enum":["Item","Shipping"],"type":"string"},"Codewolf_Ctrl_Common_Classes_Jobs_ShopJobs_DiscountTargetValueEnum":{"enum":["Percentage","FixedValue"],"type":"string"},"Codewolf_Ctrl_Common_Classes_Jobs_ShopJobs_ShopDiscount":{"type":"object","properties":{"name":{"type":"string","description":"The name for Discount - may be either the discount title or the dicount code","nullable":true},"target":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ShopJobs_DiscountTargetEnum"}],"description":"The target for the discount, shipping or Items"},"value":{"type":"number","description":"The discount Value - as a money value","format":"double"},"targetValue":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ShopJobs_DiscountTargetValueEnum"}],"description":"the type of value, either a percentage or a fixed value"},"isDiscountCode":{"type":"boolean","description":"Indicates whether this is a discount code or not"}},"additionalProperties":false,"description":"represents a discount application"},"Codewolf_Ctrl_Common_Classes_Jobs_ShopJobs_ShopJobCandidate":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ShopifyJobs_CustomerShopJobCandidate"}],"properties":{"itemsTotal":{"type":"number","description":"Total value of the Items","format":"double"},"taxTotal":{"type":"number","description":"Total amount of the Tax charged","format":"double"},"taxLines":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_TaxLine"},"description":"The TAX lines as divided up and included in the Tax amount","nullable":true},"totalAmount":{"type":"number","description":"The total Amount of the Order","format":"double"},"shippingTotal":{"type":"number","description":"The total amount of shipping paid","format":"double"},"shippingType":{"type":"string","description":"Type of shipping","nullable":true},"paymentType":{"type":"array","items":{"type":"string"},"description":"How was the order paid for - may list multiple sources","nullable":true},"discounts":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ShopJobs_ShopDiscount"},"description":"Any discount codes that contributed to the price","nullable":true},"userDetails":{"allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ShopJobs_ShopUserDetails"}],"description":"The Shopify users details (see if we need to create the user at the same time as the Job)\r\n(Optional) - only passed if we need to create the customer and user for the Shopify user","nullable":true},"customerId":{"type":"integer","description":"The customer Id passed in if we know the customer/user has already been created","format":"int32","nullable":true},"userId":{"type":"integer","description":"The user Id passed in if we know the customer/user has already been created","format":"int32","nullable":true}},"additionalProperties":false,"description":"Create Job Candidate for Shop information \r\nExtends the Job Candidate object to include the prices/taxes paid"},"Codewolf_Ctrl_Common_Classes_Jobs_ShopJobs_ShopUserDetails":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_UserDetails"}],"properties":{"shopUserId":{"type":"integer","format":"int64","description":"Identifier of the shopper in the originating storefront."},"bypassCustomerMatch":{"type":"boolean","description":"indicates whether to bypass the customer match checks \r\nthis is normally set from the Shopify Admin app once an admin user has decided to create the Customer even though there was a previous customer match"}},"additionalProperties":false},"Codewolf_Ctrl_Common_Classes_Jobs_ShopifyJobs_CustomerShopJobCandidate":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_JobCandidate"}],"properties":{"shopName":{"type":"string","description":"The Shop Name\r\nThis is the shop name for the link of the order","nullable":true},"shopOrderName":{"type":"string","description":"The Shopify Order Name","nullable":true},"shopOrderId":{"type":"string","description":"The Shop Order Id\r\nThis is different from the JobCandidate.OrderNumber\r\nThis is the BigInt order id for the shop","nullable":true},"currencyCode":{"type":"string","description":"The paid currency","nullable":true}},"additionalProperties":false},"Codewolf_Ctrl_Common_Classes_Jobs_TaxLine":{"type":"object","properties":{"title":{"type":"string","description":"The type of tax collected","nullable":true},"rate":{"type":"number","description":"the rate for the tax collected","format":"double"},"price":{"type":"number","description":"the tax collected for this type","format":"double"}},"additionalProperties":false},"Codewolf_Ctrl_Common_Classes_Jobs_UserDetails":{"type":"object","properties":{"email":{"type":"string","nullable":true,"description":"Email address for order correspondence about this job."},"firstName":{"type":"string","nullable":true,"description":"Given name of the person the job is for."},"lastName":{"type":"string","nullable":true,"description":"Family name of the person the job is for."},"name":{"type":"string","nullable":true,"description":"Full display name, where supplied instead of the separate name parts."},"phone":{"type":"string","nullable":true,"description":"Contact phone number for queries about the job."},"userAddress":{"oneOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_BaseAddress"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_DeliveryAddress"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_DeliveryBaseAddress"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Jobs_ShippingAddress"}],"nullable":true,"description":"Address associated with the person, where one was supplied."}},"additionalProperties":false},"Codewolf_Ctrl_Common_Classes_Pricing_PriceCodeDto":{"type":"object","properties":{"priceCode":{"type":"string","description":"The price code itself — pass this verbatim as a job line `code` when `itemType` is `\"PriceCode\"`. ⚠️ The size inside the string (`…-4\" x 4\"`) is part of the code's NAME, not a measurement. Never parse it to compute artwork dimensions; read `sizeWidth`/`sizeHeight`/`sizeUnit` instead.","nullable":true},"description":{"type":"string","description":"price code description","nullable":true},"categoryCode":{"type":"string","description":"The Category Code that the PriceCode belongs to","nullable":true},"categoryName":{"type":"string","description":"The Category Name that the PriceCode belongs to","nullable":true},"name":{"type":"string","description":"The name of the item for this Price Code","nullable":true},"processCode":{"type":"string","description":"The Process Code for the Price code","nullable":true},"masterProcessCode":{"type":"string","description":"The Master Process Code for the Price code - this maps to the Asset Type code","nullable":true},"minimumQuantity":{"type":"integer","description":"The fewest units this code can be ordered in. A job line below it is rejected.","format":"int32"},"externalSupplier":{"type":"string","description":"Indicates that this PriceCode is supplied Externally","nullable":true},"externalPriceCode":{"type":"string","description":"The External Price Code for the Price Code","nullable":true},"hasMetaDataAttributes":{"type":"boolean","description":"⚠️ Whether this code is calculated — priced from inputs rather than a fixed size. MEASURED INCONSISTENCY: `GET /PriceCodes/price-codes` returns `true` for a calculated code while `GET /PriceCodes/{priceCode}` returns null for the SAME code and omits its metadata attributes entirely. Build input forms from the LIST."},"standardSetup":{"type":"number","description":"The cost to setup for this asset job ($) - if outputs as NULL then the Setup DOES NOT APPLY","format":"double","nullable":true},"standardReset":{"type":"number","description":"The reset cost to for this asset job ($) - if outputs as NULL then the Setup DOES NOT APPLY","format":"double","nullable":true},"sampleAvailable":{"type":"boolean","description":"Gets or sets a value indicating whether the same resource is available for use."},"samplePrice":{"type":"number","description":"Sample value that outputs conditionally based on ShouldSerializeSample - if outputs as NULL then the Sample IS NOT AVAILABLE, and will be removed as a return field","format":"double","nullable":true},"sampleLabel":{"type":"string","description":"Gets or sets the label associated with the sample - if outputs as NULL then the Sample IS NOT AVAILABLE, and will be removed as a return field","nullable":true},"sizeUnit":{"type":"string","description":"The unit of `sizeWidth`/`sizeHeight`, and the unit any `DG-X`/`DG-Y` you send must be in. It is a property of THIS PRICE CODE — never of the region, and never of another code in the same process. ⛔ NULL means unknown, not a default: it is populated only where the size label can be parsed, so it is absent on exactly the calculated codes whose `DG-X`/`DG-Y` need it. Where it is null, ask us rather than assuming millimetres — assuming misquotes by 10× per axis, 100× on area.","nullable":true},"sizeWidth":{"type":"number","description":"Width as a number, in `sizeUnit`. Helper data derived from the code’s own size label; the label string itself is never modified.","format":"double","nullable":true},"sizeHeight":{"type":"number","description":"Height as a number, in `sizeUnit`.","format":"double","nullable":true},"categoryDescription":{"type":"string","description":"The tenant-authored description of the price category this Price Code belongs to\r\n(sourced from Category.PriceDescription)","nullable":true,"example":"Full colour heat transfers supplied on a carrier sheet, ready to press."},"categoryMetadata":{"type":"string","description":"An opaque tenant-defined JSON string describing the category. Control stores and serves\r\nthis verbatim and never interprets it - parse it client-side.","nullable":true},"unitType":{"type":"string","description":"The category unit as a first-class value. Previously this was only available embedded\r\nin the composite priceCode string.","nullable":true,"example":"120mm x 60mm"},"attributes":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Pricing_ProcessAttribute"},{"$ref":"#/components/schemas/ProcessNumericAttributeOf1T"},{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Pricing_ProcessTextAttribute"}],"description":"Process Attribute base\r\nType identifies the type of attribute"},"description":"Any attributes available for the Price code (note: some may be required when being used)","nullable":true},"priceBands":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Interfaces_IPriceBandDto"},"description":"The quantity-break ladder at YOUR account's tier. Prices are per-tier, so never cache them across accounts or show them to another customer.","nullable":true}},"additionalProperties":false,"description":"Defines a Price Code that can be used to create new Jobs"},"Codewolf_Ctrl_Common_Classes_Pricing_ProcessAttribute":{"type":"object","properties":{"name":{"type":"string","description":"The key to send this answer back under, on the job line’s `attributes` object. Case-sensitive, and per price code — never hardcode the set.","nullable":true},"type":{"type":"string","description":"How to render the input: `text` bounded by `maxLength`, `select` over `enumerableValues`, `decimal` as a number. Branch on this — the subtypes carry different fields.","nullable":true},"label":{"type":"string","description":"Label - this would be used to show a label  for a screen field","nullable":true},"description":{"type":"string","description":"⚠️ A hint for the human, and NOT a source of truth for units. The `DG-X` description reads “In centimetres” in every region including ones where that is wrong; read `sizeUnit` instead.","nullable":true},"required":{"type":"boolean","description":"Indicates the attribute value MUST be passed"},"isMetaDataAttribute":{"type":"boolean","description":"⛔ `true` means this is not a question for a human: it is an input to the PRICE. `DG-X` and `DG-Y` are the width and height of a cut-to-size product, and their unit is the price code’s `sizeUnit` — which is null on exactly these codes, so ask rather than assume. Pass them to `GET /PriceCodes/{priceCode}?dgX=…&dgY=…` to price a size."},"enumerableValues":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"description":{"type":"string"}}},"nullable":true,"description":"The permitted values when this attribute is a choice. Read them from here rather than hardcoding — they change per account and per process."},"assetAttributeName":{"type":"string","description":"Determines that the element must be saved to the AssetAttribute if provided","nullable":true}},"additionalProperties":false,"description":"Process Attribute base\r\nType identifies the type of attribute"},"Codewolf_Ctrl_Common_Classes_Pricing_ProcessTextAttribute":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Pricing_ProcessAttribute"}],"properties":{"minLength":{"type":"integer","description":"Min length of string","format":"int32"},"maxLength":{"type":"integer","description":"max length of string","format":"int32"}},"additionalProperties":false,"description":"Text attribute for Process"},"Codewolf_Ctrl_Common_Classes_Stocks_StockDto":{"type":"object","properties":{"supplier":{"type":"string","description":"Stock Supplier","nullable":true},"categoryName":{"type":"string","description":"Stock Category","nullable":true},"categoryUnitId":{"type":"string","description":"Stock Category Unit ID (for Pricing)","nullable":true},"stockItemId":{"type":"integer","description":"Internal StockItemId used to enrich list responses with per-item data\r\n(e.g. markets from StockItemShipping). Never serialised to API consumers.","format":"int32"},"stockCode":{"type":"string","description":"The code which identifies the Stock","nullable":true},"processCode":{"type":"string","description":"the Process Code","nullable":true,"readOnly":true},"stockName":{"type":"string","description":"Stock name","nullable":true},"stockDescription":{"type":"string","description":"Gets or sets the description of the stock item.","nullable":true},"stockSpecifications":{"type":"string","description":"Gets or sets the specifications for the stock item.","nullable":true},"priceCompatibleLookupCode":{"type":"string","description":"The Price Compatible Lookup Code","nullable":true},"rank":{"type":"integer","description":"Gets or sets the rank or position associated with the current instance.","format":"int32"},"stockVariants":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Stocks_StockVariantDto"},"description":"The stock Variants as a list","nullable":true},"stockImageUrl":{"type":"string","description":"Gets or sets the URL or file path of the hero stock image associated with the item.\r\nBackwards compatible field — mirrors `Images[0]?.Url` when the gallery is\r\nnon-empty.","nullable":true},"images":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Stocks_StockImageDto"},"description":"CW-4346: ordered gallery of images for this stock item. Index 0 is the hero\r\n(matches Codewolf.Ctrl.Common.Classes.Stocks.StockDto.StockImageUrl); subsequent entries are additional gallery\r\nimages. Empty list when the stock item has no images. Always serialised.","nullable":true},"showAvailableStock":{"type":"boolean","description":"Gets or sets a value indicating whether the available stock should be displayed to users."},"shippingConfigs":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Stocks_StockItemShippingSummary"},"description":"Per-market shipping configurations for this stock item.\r\nOnly populated on single stock item endpoint (GET /stock/{code}).","nullable":true},"markets":{"type":"array","items":{"type":"string"},"description":"Distinct union of markets (ISO country codes) drawn from this item's active\r\nshipping configurations. An empty array means the item has no active shipping\r\nconfiguration and should be hidden from all locale-filtered catalogues\r\n(fail-closed). Always serialised.","nullable":true},"badges":{"type":"array","items":{"type":"string"},"description":"Short display badges rendered as pills on the product card\r\n(e.g. \"Free shipping\", \"No minimums\", \"Ground only\").\r\nOrder is preserved. Always serialised as an array — consumers\r\ncan rely on the field being present (empty array means no badges).","nullable":true},"slug":{"type":"string","description":"URL-friendly slug for the stock item, used to form canonical\r\nproduct URLs in consuming storefronts (e.g. /products/{slug}).\r\nLowercase, alphanumerics and hyphens only, globally unique across\r\nactive non-deleted stock items.","nullable":true},"seoTitle":{"type":"string","description":"Optional override for the HTML <title> tag on the storefront\r\nproduct page. Falls back to the default title if null or empty.","nullable":true},"seoDescription":{"type":"string","description":"Optional override for the HTML meta description on the storefront\r\nproduct page. Falls back to the default description if null or empty.","nullable":true},"priceBands":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Interfaces_IPriceBandDto"},"nullable":true,"description":"Quantity-break pricing for this stocked item, at your account's tier."}},"additionalProperties":false,"description":"Information about an available Stock"},"Codewolf_Ctrl_Common_Classes_Stocks_StockImageDto":{"type":"object","properties":{"url":{"type":"string","description":"CDN URL of the image. Use this directly for both rendering and linking.","nullable":true},"name":{"type":"string","description":"Optional display name for captions / lightbox titles. May be null.","nullable":true},"altText":{"type":"string","description":"Optional alt text for accessibility. May be null. Consumers should\r\nfall back to a sensible default (e.g. the stock name) when absent.","nullable":true}},"additionalProperties":false,"description":"CW-4346: a single image in a stock item's ordered gallery. Index 0 in\r\nCodewolf.Ctrl.Common.Classes.Stocks.StockDto.Images is the hero (the storefront hero CDN URL,\r\n`StockDto.StockImageUrl`, mirrors that entry's Codewolf.Ctrl.Common.Classes.Stocks.StockImageDto.Url)."},"Codewolf_Ctrl_Common_Classes_Stocks_StockItemShipmentTypeOptionSummary":{"type":"object","properties":{"code":{"type":"string","nullable":true,"description":"Shipment type code, as sent on a job."},"name":{"type":"string","nullable":true,"description":"Short display abbreviation for the shipment type."},"price":{"type":"number","format":"double","nullable":true,"description":"Charge for this shipment type, in the account's currency."}},"additionalProperties":false,"description":"Lightweight shipment-type option summary for StockItemShippingSummary.\r\nMirrors the API-layer DTO shape: per-method override of shipment type availability and price."},"Codewolf_Ctrl_Common_Classes_Stocks_StockItemShippingLocationSummary":{"type":"object","properties":{"locationCode":{"type":"string","nullable":true,"description":"Short code for the fulfilment location."},"locationName":{"type":"string","nullable":true,"description":"Human-readable name of the fulfilment location."},"locale":{"type":"string","nullable":true,"description":"The region the location sits in."}},"additionalProperties":false,"description":"Lightweight fulfilment location summary for StockItemShippingSummary."},"Codewolf_Ctrl_Common_Classes_Stocks_StockItemShippingSummary":{"type":"object","properties":{"id":{"type":"integer","format":"int32","description":"Identifier for this shipping configuration row."},"markets":{"type":"array","items":{"type":"string"},"nullable":true,"description":"Market codes this configuration applies in."},"shipMode":{"type":"string","nullable":true,"description":"How the item ships — bundled with the order, or as its own consignment."},"weight":{"type":"number","format":"double","nullable":true,"description":"Shipping weight, in `weightUnit`."},"weightUnit":{"type":"string","nullable":true,"description":"Unit for `weight` — `kg` or `lb`."},"length":{"type":"number","format":"double","nullable":true,"description":"Package length, in `dimensionUnit`."},"width":{"type":"number","format":"double","nullable":true,"description":"Package width, in `dimensionUnit`."},"height":{"type":"number","format":"double","nullable":true,"description":"Package height, in `dimensionUnit`."},"dimensionUnit":{"type":"string","nullable":true,"description":"Unit for `length`, `width` and `height` — `cm` or `in`."},"fixedShipping":{"type":"number","format":"double","nullable":true,"description":"A flat shipping charge replacing live rating. Null means rate normally."},"groundOnly":{"type":"boolean","description":"True when the item cannot travel by air."},"estimatedLeadDays":{"type":"integer","format":"int32","nullable":true,"description":"Working days to expect before despatch."},"fulfilmentLocations":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Stocks_StockItemShippingLocationSummary"},"nullable":true,"description":"The warehouses this item can ship from."},"shipmentTypeOptions":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Stocks_StockItemShipmentTypeOptionSummary"},"description":"Per-shipment-method overrides for this stock item's shipping entry. Each option's\r\n`price` is null/absent when the rate-API price should be used, `0` for a\r\nfree override on this method, or positive for a flat override amount.","nullable":true}},"additionalProperties":false,"description":"Lightweight shipping configuration summary for inclusion in StockDto responses.\r\nContains only the fields needed for the GET /stock/{code} enrichment."},"Codewolf_Ctrl_Common_Classes_Stocks_StockVariantDto":{"type":"object","properties":{"variantCode":{"type":"string","description":"The unique identifier for the Stock Variant","nullable":true},"colour":{"type":"string","description":"The Stock Variant Colour","nullable":true},"variantImageUrl":{"type":"string","description":"Gets or sets the URL of the image associated with the product variant.","nullable":true},"numberOfSizes":{"type":"integer","description":"The number of sizes available for this variant","format":"int32"},"sizesCsv":{"type":"string","description":"Gets or sets a comma-separated list of sizes.","nullable":true}},"additionalProperties":false,"description":"A Colour variant of a stock item"},"Codewolf_Ctrl_Common_Enums_ActiveJobSortColumn":{"enum":["JobNumber","DateIn","DateDue","DateOut","OrderGroupSequence"],"type":"string"},"Codewolf_Ctrl_Common_Enums_AssetSortColumn":{"enum":["AssetId","AssetTag","PriceCode","CreateDate"],"type":"string"},"Codewolf_Ctrl_Common_Enums_FileStatus":{"enum":["Active","Archived","Deleted"],"type":"string"},"Codewolf_Ctrl_Common_Enums_SortDirection":{"enum":["Ascending","Descending"],"type":"string"},"Codewolf_Ctrl_Common_Enums_StockSortColumn":{"enum":["StockCode","StockName","PriceCompatibleLookupCode"],"type":"string"},"Codewolf_Ctrl_Common_Enums_VariantSortColumn":{"enum":["VariantCode","Colour"],"type":"string"},"Codewolf_Ctrl_Common_Interfaces_IDeliveryOption":{"type":"object","properties":{"code":{"type":"string","nullable":true,"description":"The delivery method code. This is the value to send as `deliveryAddress.deliveryMethod` on `POST /Jobs`."},"label":{"type":"string","nullable":true,"description":"Short display abbreviation, e.g. `GND`. For your UI; do not send it back."},"isCollection":{"type":"boolean","description":"True when the customer collects from the factory rather than the order being shipped. A collection method needs no courier address."},"rank":{"type":"integer","format":"int32","description":"Display order for a normal job. Lower sorts first."},"gangRank":{"type":"integer","format":"int32","description":"Display order when the job is a gang sheet, which can differ from `rank`."},"value":{"type":"string","nullable":true,"description":"The same value as `code`, provided for form bindings."},"deliveryLabelEnabled":{"type":"boolean","description":"Whether a delivery label can be produced for this method."}},"additionalProperties":false},"Codewolf_Ctrl_Common_Interfaces_IPriceBandDto":{"type":"object","properties":{"from":{"type":"integer","format":"int32","description":"Lowest quantity this band applies to, inclusive."},"to":{"type":"integer","format":"int32","nullable":true,"description":"Highest quantity this band applies to, inclusive. Null on the top band, which has no upper limit."},"unitPrice":{"type":"number","format":"double","description":"Price per unit within this band, in the account's currency. ⚠️ Per-tier: this is your account's price, not a list price."}},"additionalProperties":false},"HttpValidationProblemDetails":{"type":"object","allOf":[{"$ref":"#/components/schemas/ProblemDetails"}],"properties":{"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}},"nullable":true,"description":"Validation failures keyed by the field that caused them, each with one or more messages. Read this rather than the top-level `detail` when the status is 400."}},"additionalProperties":{}},"PagedDataOf1Codewolf_Ctrl_Api_Dto_Api_AccountUserSummary":{"type":"object","properties":{"pageSize":{"type":"integer","format":"int32","description":"How many records one page can hold — the size requested, not the number returned."},"returnedResults":{"type":"integer","format":"int32","readOnly":true,"description":"How many records this page actually contains. Lower than `pageSize` on the last page."},"totalResults":{"type":"integer","format":"int32","description":"How many records match across every page. Use this for \"N results\", not the page length."},"totalPages":{"type":"integer","format":"int32","description":"How many pages the full result set spans at the current `pageSize`."},"currentPage":{"type":"integer","format":"int32","description":"Which page this is. One-based — the first page is 1, not 0."},"hasNext":{"type":"boolean","description":"Whether another page follows. Prefer this over comparing page numbers yourself."},"hasPrevious":{"type":"boolean","description":"Whether a page precedes this one."},"filter":{"type":"string","nullable":true,"description":"The filter applied to produce this result set, echoed back. Null when unfiltered."},"nextUrl":{"type":"string","nullable":true,"description":"Ready-made URL for the next page. Follow it rather than assembling your own — it carries the filter and page size already. Null on the last page."},"previousUrl":{"type":"string","nullable":true,"description":"Ready-made URL for the previous page. Null on the first page."},"entities":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dto_Api_AccountUserSummary"},"nullable":true,"description":"The records themselves. Everything else on this object describes the page, not the data."}},"additionalProperties":false},"PagedDataOf1Codewolf_Ctrl_Api_Dto_Api_PaymentTransaction":{"type":"object","properties":{"pageSize":{"type":"integer","format":"int32","description":"How many records one page can hold — the size requested, not the number returned."},"returnedResults":{"type":"integer","format":"int32","readOnly":true,"description":"How many records this page actually contains. Lower than `pageSize` on the last page."},"totalResults":{"type":"integer","format":"int32","description":"How many records match across every page. Use this for \"N results\", not the page length."},"totalPages":{"type":"integer","format":"int32","description":"How many pages the full result set spans at the current `pageSize`."},"currentPage":{"type":"integer","format":"int32","description":"Which page this is. One-based — the first page is 1, not 0."},"hasNext":{"type":"boolean","description":"Whether another page follows. Prefer this over comparing page numbers yourself."},"hasPrevious":{"type":"boolean","description":"Whether a page precedes this one."},"filter":{"type":"string","nullable":true,"description":"The filter applied to produce this result set, echoed back. Null when unfiltered."},"nextUrl":{"type":"string","nullable":true,"description":"Ready-made URL for the next page. Follow it rather than assembling your own — it carries the filter and page size already. Null on the last page."},"previousUrl":{"type":"string","nullable":true,"description":"Ready-made URL for the previous page. Null on the first page."},"entities":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dto_Api_PaymentTransaction"},"nullable":true,"description":"The records themselves. Everything else on this object describes the page, not the data."}},"additionalProperties":false},"PagedDataOf1Codewolf_Ctrl_Api_Dtos_Api_AssetListDto":{"type":"object","properties":{"pageSize":{"type":"integer","format":"int32","description":"How many records one page can hold — the size requested, not the number returned."},"returnedResults":{"type":"integer","format":"int32","readOnly":true,"description":"How many records this page actually contains. Lower than `pageSize` on the last page."},"totalResults":{"type":"integer","format":"int32","description":"How many records match across every page. Use this for \"N results\", not the page length."},"totalPages":{"type":"integer","format":"int32","description":"How many pages the full result set spans at the current `pageSize`."},"currentPage":{"type":"integer","format":"int32","description":"Which page this is. One-based — the first page is 1, not 0."},"hasNext":{"type":"boolean","description":"Whether another page follows. Prefer this over comparing page numbers yourself."},"hasPrevious":{"type":"boolean","description":"Whether a page precedes this one."},"filter":{"type":"string","nullable":true,"description":"The filter applied to produce this result set, echoed back. Null when unfiltered."},"nextUrl":{"type":"string","nullable":true,"description":"Ready-made URL for the next page. Follow it rather than assembling your own — it carries the filter and page size already. Null on the last page."},"previousUrl":{"type":"string","nullable":true,"description":"Ready-made URL for the previous page. Null on the first page."},"entities":{"type":"array","items":{"$ref":"#/components/schemas/Codewolf_Ctrl_Api_Dtos_Api_AssetListDto"},"nullable":true,"description":"The records themselves. Everything else on this object describes the page, not the data."}},"additionalProperties":false},"ProblemDetails":{"type":"object","properties":{"type":{"type":"string","nullable":true,"description":"URI identifying the problem type (RFC 7807). Stable enough to branch on; the human-readable part is `title`."},"title":{"type":"string","nullable":true,"description":"Short summary of the problem, the same for every occurrence of this type."},"status":{"type":"integer","format":"int32","nullable":true,"description":"The HTTP status code, repeated in the body so it survives logging."},"detail":{"type":"string","nullable":true,"description":"What went wrong on THIS request. The most useful field for a human reading a failure."},"instance":{"type":"string","nullable":true,"description":"The path that produced the problem."}},"additionalProperties":{}},"ProcessNumericAttributeOf1T":{"type":"object","allOf":[{"$ref":"#/components/schemas/Codewolf_Ctrl_Common_Classes_Pricing_ProcessAttribute"}],"properties":{"minValue":{"allOf":[{"$ref":"#/components/schemas/T"}],"description":"Minimum value for number","nullable":true},"maxValue":{"allOf":[{"$ref":"#/components/schemas/T"}],"description":"max number for number value","nullable":true}},"additionalProperties":false,"description":"Text attribute for Process"},"T":{"type":"object","additionalProperties":false}},"securitySchemes":{"oauth2":{"type":"oauth2","description":"OAuth2 client credentials against THIS region's token endpoint. Credentials belong to exactly one region and only work here. Note the token endpoint is on the region's auth host, not the API host.","flows":{"clientCredentials":{"tokenUrl":"https://login.ezibrand.com.au/realms/ezibrand/protocol/openid-connect/token","scopes":{}}}},"Bearer":{"type":"apiKey","description":"JWT Authorization header using the Bearer scheme.\n                      Enter 'Bearer' [space] and then your token in the text input below.\n                      Example: 'Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...'","name":"Authorization","in":"header"}}},"security":[{"oauth2":[]},{"Bearer":[]}],"tags":[{"name":"PriceCodes","description":"What your account can order and what it costs. The first call in any integration — process availability and pricing are per-account, so never hardcode them."},{"name":"Stock","description":"Stocked goods held on the shelf — garments, supplies and equipment — with their variants, size runs and shipping options."},{"name":"Jobs","description":"Orders. Create a job from garment and decoration lines, then track it to despatch. `validateOnly: true` dry-runs the complete payload — artwork URL included — so you can build without creating real jobs."},{"name":"Inwards","description":"Goods you have sent in to be decorated: what was dispatched, what arrived, and whether it has been allocated to a job yet."},{"name":"Assets","description":"Decoration already made for you — a digitisation, a set of screens, a separation. Reorder by asset tag: no artwork, no re-approval, no setup."},{"name":"Boms","description":"Made-to-order garments, decoration included, ordered as one line by variant code. A complete integration on its own: no price codes, no artwork, no grouping."},{"name":"Lookups","description":"Reference data — countries, states, job statuses, inwards statuses, process codes, size sets. Read these instead of hardcoding values that change."},{"name":"Account","description":"Your account: address, users, tax certificates, transactions. `GET /account` confirms which account a set of credentials belongs to."},{"name":"PromoCodes","description":"Validate a promotional code before applying it to a job."},{"name":"StockItemShipping","description":"Shipping options for stocked items, by stock item and market."}],"servers":[{"url":"https://api.ezibrand.com.au","description":"Staging"}]}