{
  "openapi": "3.1.0",
  "info": {
    "title": "LayerCrew Partner API",
    "version": "2026-10-24",
    "summary": "Send production orders with your own files and references; get back prices, acceptance, production status and tracking.",
    "description": "The Partner API lets a company's own system (a webshop, an ERP, a custom site) order 3D-printed parts from LayerCrew and follow them to delivery. You upload a file, optionally ask for a price, create an order with your own reference and your customer's delivery address, and receive every status change by signed webhook or by polling. Orders use neutral packaging by default. The courier label names LayerCrew as the shipping account and shows your sender name as the contact line.\n\nIntegrating is free. There is no subscription, no minimum volume and no setup fee. You register at https://layercrew.com/developers/register as a company, accept the integration agreement and the data processing agreement, and get test keys at once; live keys follow once LayerCrew countersigns.\n\nBase URL: `https://engine.layercrew.com/v1`. Every response is JSON in an envelope: `{\"data\": …}` for one object, `{\"data\": [...], \"meta\": {page, per_page, total, total_pages}}` for lists, `{\"error\": {code, message, details?}}` for errors. Money is a string with two decimals in EUR. Timestamps are RFC 3339 in UTC. Identifiers are UUIDs.\n\nAuthentication: `Authorization: Bearer lc_live_<key>` or `lc_test_<key>`. Test keys never create real orders, never touch stock, couriers or invoices; they exercise the whole flow and let you advance an order through its states yourself.\n\nPace requests at two per second with small bursts. A JSON 429 carries `Retry-After`. A non-JSON 403 is the network edge throttling your address: back off 90 seconds. Never retry an order creation blindly: send the same `Idempotency-Key` again, or look the order up by your reference.",
    "contact": {
      "name": "LayerCrew developer support",
      "email": "hello@layercrew.com",
      "url": "https://layercrew.com/developers"
    }
  },
  "servers": [
    {
      "url": "https://engine.layercrew.com/v1",
      "description": "Production (live and test keys)"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "tags": [
    {
      "name": "Account",
      "description": "Who you are, your plan and your usage."
    },
    {
      "name": "Materials",
      "description": "What you can order parts in."
    },
    {
      "name": "Files",
      "description": "Upload the 3D files your orders reference."
    },
    {
      "name": "Quotes",
      "description": "Price a file before you order it."
    },
    {
      "name": "Orders",
      "description": "Create and follow production orders."
    },
    {
      "name": "Events",
      "description": "The ordered feed of everything that happened to your account."
    },
    {
      "name": "Webhooks",
      "description": "Signed HTTP notifications and their delivery log."
    },
    {
      "name": "Requests",
      "description": "Your own request log, for debugging."
    },
    {
      "name": "Test mode",
      "description": "Available with test keys only."
    }
  ],
  "paths": {
    "/ping": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "ping",
        "summary": "Check your key",
        "description": "Confirms the key works and tells you which partner, environment and plan it belongs to.",
        "responses": {
          "200": {
            "description": "The key is valid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Ping"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/account": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "getAccount",
        "summary": "Your plan, limits, usage and agreement status",
        "responses": {
          "200": {
            "description": "The account.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Account"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/materials": {
      "get": {
        "tags": [
          "Materials"
        ],
        "operationId": "listMaterials",
        "summary": "Materials, nozzles and colours you can order",
        "description": "The list changes as the catalogue changes. Order with a `material` from this list; a `colour` is optional and must come from the material's colours when given. `in_stock` is live and never a promise.",
        "responses": {
          "200": {
            "description": "Materials.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Material"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/files": {
      "get": {
        "tags": [
          "Files"
        ],
        "operationId": "listFiles",
        "summary": "List your files",
        "parameters": [
          {
            "$ref": "#/components/parameters/page"
          },
          {
            "$ref": "#/components/parameters/per_page"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/FileStatus"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Files, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileList"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "post": {
        "tags": [
          "Files"
        ],
        "operationId": "createFile",
        "summary": "Start an upload",
        "description": "Declares a file and returns a one-time upload URL. PUT the raw bytes to `upload.url` within `upload.expires_at`, sending exactly the headers in `upload.headers` (both `Content-Type` and `x-goog-content-length-range` are mandatory — the signature covers them). Then call `complete`. Formats: STL, OBJ, 3MF. STEP files are priced by an engineer: send them through https://layercrew.com/contact-us. Size limit: your plan's `max_file_bytes`. Units: millimetres.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Upload instructions.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/FileWithUpload"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/files/{file_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/file_id"
        }
      ],
      "get": {
        "tags": [
          "Files"
        ],
        "operationId": "getFile",
        "summary": "Get a file",
        "responses": {
          "200": {
            "description": "The file.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/File"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "delete": {
        "tags": [
          "Files"
        ],
        "operationId": "deleteFile",
        "summary": "Delete a file",
        "description": "A file no order uses is deleted now. A file used only by finished orders is scheduled for deletion within the hour (202). A file an open order, a pending quote or a running price job still needs answers 409 `FILE_IN_USE` and names it.",
        "responses": {
          "202": {
            "description": "Scheduled for deletion."
          },
          "204": {
            "description": "Deleted."
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          }
        }
      }
    },
    "/files/{file_id}/complete": {
      "parameters": [
        {
          "$ref": "#/components/parameters/file_id"
        }
      ],
      "post": {
        "tags": [
          "Files"
        ],
        "operationId": "completeFile",
        "summary": "Finish an upload",
        "description": "Verifies the uploaded bytes against the declared size and SHA-256, reads the model, strips any embedded slicer scripts from a 3MF, and stores the canonical copy. Idempotent: calling it again on a ready file returns the file. A file that fails verification is `rejected` with a `rejection_code`; upload a corrected file.",
        "responses": {
          "200": {
            "description": "The file is ready.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/File"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "Another completion of this file is running.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "422": {
            "description": "The file was rejected; `error.details.rejection_code` says why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/quotes": {
      "get": {
        "tags": [
          "Quotes"
        ],
        "operationId": "listQuotes",
        "summary": "List your quotes",
        "parameters": [
          {
            "$ref": "#/components/parameters/page"
          },
          {
            "$ref": "#/components/parameters/per_page"
          }
        ],
        "responses": {
          "200": {
            "description": "Quotes, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteList"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Quotes"
        ],
        "operationId": "createQuote",
        "summary": "Price a file",
        "description": "Prices one ready file in one material at one quantity. Pricing takes seconds to a few minutes (the file is sliced for real); poll the quote or listen for `quote.priced`. The price is the one an order of the same file, material and quantity would carry today; it is frozen on an order only when the order is accepted.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QuoteCreate"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Pricing started.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Quote"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/quotes/{quote_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/quote_id"
        }
      ],
      "get": {
        "tags": [
          "Quotes"
        ],
        "operationId": "getQuote",
        "summary": "Get a quote",
        "responses": {
          "200": {
            "description": "The quote.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Quote"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/orders": {
      "get": {
        "tags": [
          "Orders"
        ],
        "operationId": "listOrders",
        "summary": "List your orders",
        "parameters": [
          {
            "$ref": "#/components/parameters/page"
          },
          {
            "$ref": "#/components/parameters/per_page"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/OrderStatus"
            }
          },
          {
            "name": "reference",
            "in": "query",
            "description": "Exact match on your reference.",
            "schema": {
              "type": "string",
              "maxLength": 120
            }
          },
          {
            "name": "created_after",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Orders, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderList"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "post": {
        "tags": [
          "Orders"
        ],
        "operationId": "createOrder",
        "summary": "Create an order",
        "description": "Creates a production order from ready files. Requires an `Idempotency-Key` header (any string up to 255 characters, unique per attempt; a retry with the same key and the same body returns the first response with `Idempotent-Replayed: true`). Your `reference` must be unique among your orders in this environment; a duplicate answers 409 `REFERENCE_TAKEN` with the existing order id. The order is priced within minutes (`order.priced`), then a LayerCrew engineer accepts it (`order.accepted`, usually within one business day) or declines it with a reason you can act on (`order.rejected`). Payment instructions appear on acceptance. Production starts after payment unless your plan says otherwise.",
        "parameters": [
          {
            "$ref": "#/components/parameters/idempotency_key"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderCreate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Replayed from a previous request with the same `Idempotency-Key`.",
            "headers": {
              "Idempotent-Replayed": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderEnvelope"
                }
              }
            }
          },
          "202": {
            "description": "Order received; pricing started.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderEnvelope"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/orders/{order_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/order_id"
        }
      ],
      "get": {
        "tags": [
          "Orders"
        ],
        "operationId": "getOrder",
        "summary": "Get an order",
        "description": "`order_id` is the order's id or its number (`PA-2026-0007`).",
        "responses": {
          "200": {
            "description": "The order.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderEnvelope"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/orders/{order_id}/events": {
      "parameters": [
        {
          "$ref": "#/components/parameters/order_id"
        }
      ],
      "get": {
        "tags": [
          "Orders"
        ],
        "operationId": "listOrderEvents",
        "summary": "The order's events, in order",
        "parameters": [
          {
            "$ref": "#/components/parameters/after"
          },
          {
            "$ref": "#/components/parameters/limit"
          }
        ],
        "responses": {
          "200": {
            "description": "Events, oldest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventList"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/orders/{order_id}/cancel": {
      "parameters": [
        {
          "$ref": "#/components/parameters/order_id"
        }
      ],
      "post": {
        "tags": [
          "Orders"
        ],
        "operationId": "cancelOrder",
        "summary": "Cancel an order",
        "description": "Allowed while the order is `received`, `pending_review` or `accepted` (before production starts). Later, write to us from the order page and we will tell you what is still possible.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 500
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Cancelled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderEnvelope"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          }
        }
      }
    },
    "/orders/{order_id}/invoices": {
      "parameters": [
        {
          "$ref": "#/components/parameters/order_id"
        }
      ],
      "get": {
        "tags": [
          "Orders"
        ],
        "operationId": "listOrderInvoices",
        "summary": "Invoices issued for the order",
        "responses": {
          "200": {
            "description": "Invoices.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Invoice"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/orders/{order_id}/invoices/{invoice_id}/download-url": {
      "parameters": [
        {
          "$ref": "#/components/parameters/order_id"
        },
        {
          "name": "invoice_id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "tags": [
          "Orders"
        ],
        "operationId": "getInvoiceDownloadUrl",
        "summary": "A 15-minute link to the invoice PDF",
        "responses": {
          "200": {
            "description": "The link.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": "string",
                          "format": "uri"
                        },
                        "expires_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "url",
                        "expires_at"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/orders/{order_id}/recipient": {
      "parameters": [
        {
          "$ref": "#/components/parameters/order_id"
        }
      ],
      "delete": {
        "tags": [
          "Orders"
        ],
        "operationId": "eraseOrderRecipient",
        "summary": "Erase your customer's personal data from a finished order",
        "description": "Replaces the recipient's name, company, phone, email and street lines with `[redacted]` on the order and on its stored events; city, postal code and country stay for fiscal and zone records. Allowed once the order is delivered, cancelled or rejected. We also do this automatically after the retention window in your plan.",
        "responses": {
          "204": {
            "description": "Erased."
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          }
        }
      }
    },
    "/events": {
      "get": {
        "tags": [
          "Events"
        ],
        "operationId": "listEvents",
        "summary": "Everything that happened, in order",
        "description": "The authoritative, gap-free sequence of your account's events in this environment. Poll with `after` = the last `seq` you processed. Webhooks carry the same events; this feed is the source of truth when a webhook is late or missed.",
        "parameters": [
          {
            "$ref": "#/components/parameters/after"
          },
          {
            "$ref": "#/components/parameters/limit"
          },
          {
            "name": "types",
            "in": "query",
            "description": "Comma-separated event types to include.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Events, oldest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventList"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/webhook-endpoints": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "listWebhookEndpoints",
        "summary": "List endpoints",
        "responses": {
          "200": {
            "description": "Endpoints.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookEndpoint"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "createWebhookEndpoint",
        "summary": "Register an endpoint",
        "description": "The URL must be HTTPS on port 443 (or 8443) on a public host. The signing `secret` is returned once; store it. Each delivery carries `webhook-id`, `webhook-timestamp` and `webhook-signature` (Standard Webhooks). Your plan caps the number of endpoints per environment.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEndpointCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created; `secret` is shown once.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookEndpointWithSecret"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          }
        }
      }
    },
    "/webhook-endpoints/{endpoint_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/endpoint_id"
        }
      ],
      "get": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "getWebhookEndpoint",
        "summary": "Get an endpoint",
        "responses": {
          "200": {
            "description": "The endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookEndpoint"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "patch": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "updateWebhookEndpoint",
        "summary": "Update an endpoint",
        "description": "Re-enabling a disabled endpoint resets its failure count and re-queues deliveries skipped in the last 7 days, in order.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEndpointUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookEndpoint"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          }
        }
      },
      "delete": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "deleteWebhookEndpoint",
        "summary": "Delete an endpoint",
        "responses": {
          "204": {
            "description": "Deleted."
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/webhook-endpoints/{endpoint_id}/rotate-secret": {
      "parameters": [
        {
          "$ref": "#/components/parameters/endpoint_id"
        }
      ],
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "rotateWebhookSecret",
        "summary": "Rotate the signing secret",
        "description": "Returns a new secret once. For 24 hours every delivery is signed with both the new and the old secret, so you can switch without a gap.",
        "responses": {
          "200": {
            "description": "Rotated.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookEndpointWithSecret"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/webhook-endpoints/{endpoint_id}/ping": {
      "parameters": [
        {
          "$ref": "#/components/parameters/endpoint_id"
        }
      ],
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "pingWebhookEndpoint",
        "summary": "Send a signed test event",
        "description": "Queues a `test.ping` delivery so you can verify your signature check before going live.",
        "responses": {
          "202": {
            "description": "Queued.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookDelivery"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/webhook-deliveries": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "listWebhookDeliveries",
        "summary": "Delivery log",
        "parameters": [
          {
            "$ref": "#/components/parameters/page"
          },
          {
            "$ref": "#/components/parameters/per_page"
          },
          {
            "name": "endpoint_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/DeliveryStatus"
            }
          },
          {
            "name": "event_id",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deliveries, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookDeliveryList"
                }
              }
            }
          }
        }
      }
    },
    "/webhook-deliveries/{delivery_id}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/delivery_id"
        }
      ],
      "get": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "getWebhookDelivery",
        "summary": "A delivery with every attempt",
        "responses": {
          "200": {
            "description": "The delivery.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookDeliveryDetail"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/webhook-deliveries/{delivery_id}/redeliver": {
      "parameters": [
        {
          "$ref": "#/components/parameters/delivery_id"
        }
      ],
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "redeliverWebhook",
        "summary": "Send a delivery again",
        "description": "Allowed for delivered, failed and skipped deliveries; a delivery in flight answers 409. The exact original bytes are re-sent with a fresh signature and timestamp.",
        "responses": {
          "202": {
            "description": "Queued.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/WebhookDelivery"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          }
        }
      }
    },
    "/requests": {
      "get": {
        "tags": [
          "Requests"
        ],
        "operationId": "listRequests",
        "summary": "Your request log",
        "description": "Every call made with your keys in the last 90 days: when, which route, the status, the duration and the request id to quote to support. Bodies are never stored.",
        "parameters": [
          {
            "$ref": "#/components/parameters/page"
          },
          {
            "$ref": "#/components/parameters/per_page"
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "route",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Requests, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RequestLogList"
                }
              }
            }
          }
        }
      }
    },
    "/requests/{request_id}": {
      "parameters": [
        {
          "name": "request_id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "tags": [
          "Requests"
        ],
        "operationId": "getRequest",
        "summary": "One request by its id",
        "responses": {
          "200": {
            "description": "The request.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/RequestLogEntry"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/test/orders/{order_id}/advance": {
      "parameters": [
        {
          "$ref": "#/components/parameters/order_id"
        }
      ],
      "post": {
        "tags": [
          "Test mode"
        ],
        "operationId": "advanceTestOrder",
        "summary": "Move a test order to its next state",
        "description": "Test keys only. Emits the same events and webhooks a live order would. Allowed moves: `pending_review` → `accepted` or `rejected`; `accepted` → `in_production` → `ready_to_ship` → `shipped` → `delivered`; any non-terminal state ↔ `on_hold`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "to": {
                    "$ref": "#/components/schemas/OrderStatus"
                  },
                  "reason": {
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "required": [
                  "to"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Advanced.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Use a test key for this route (`TEST_ONLY`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "getOpenApi",
        "summary": "This document",
        "security": [],
        "responses": {
          "200": {
            "description": "The OpenAPI 3.1 description of this API.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {
    "event": {
      "post": {
        "summary": "An event delivered to one of your endpoints",
        "description": "Headers: `webhook-id` (the delivery id, stable across retries), `webhook-timestamp` (unix seconds), `webhook-signature` (`v1,<base64 HMAC-SHA256 of \"<id>.<timestamp>.<raw body>\">`, possibly two space-separated entries during a secret rotation), `X-LayerCrew-Event` (the type), `X-LayerCrew-Sequence` (the event `seq`). Answer 2xx within 10 seconds; anything else is retried with exponential backoff over about two days, in order per endpoint; a 410 disables the endpoint. Verify the timestamp is within five minutes of now, then compare the signature in constant time.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Event"
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Received."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "lc_live_<16 chars>_<64 hex> or lc_test_…",
        "description": "An API key from your dashboard at https://layercrew.com/dashboard/integrations/keys. Keys are shown once. Revocation takes effect within 30 seconds."
      }
    },
    "parameters": {
      "page": {
        "name": "page",
        "in": "query",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "default": 1
        }
      },
      "per_page": {
        "name": "per_page",
        "in": "query",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 25
        }
      },
      "after": {
        "name": "after",
        "in": "query",
        "description": "Return events with `seq` greater than this.",
        "schema": {
          "type": "integer",
          "minimum": 0,
          "default": 0
        }
      },
      "limit": {
        "name": "limit",
        "in": "query",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 200,
          "default": 50
        }
      },
      "idempotency_key": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "description": "Unique per attempt, up to 255 characters of `[A-Za-z0-9._:~-]`. Kept 24 hours.",
        "schema": {
          "type": "string",
          "maxLength": 255,
          "pattern": "^[A-Za-z0-9][A-Za-z0-9._:~-]{0,254}$"
        }
      },
      "file_id": {
        "name": "file_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "quote_id": {
        "name": "quote_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "order_id": {
        "name": "order_id",
        "in": "path",
        "required": true,
        "description": "The order id (UUID) or number (`PA-YYYY-NNNN`).",
        "schema": {
          "type": "string"
        }
      },
      "endpoint_id": {
        "name": "endpoint_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "delivery_id": {
        "name": "delivery_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "The key is missing, malformed, unknown, revoked or for the other environment (`INVALID_API_KEY`, `API_KEY_REVOKED`, `SCOPE_MISMATCH`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "Forbidden": {
        "description": "The partner account is not active (`PARTNER_INACTIVE`) or the route is test-only (`TEST_ONLY`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "NotFound": {
        "description": "No such object in this environment (`NOT_FOUND`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "Conflict": {
        "description": "The request conflicts with the current state; `error.code` says how (`REFERENCE_TAKEN`, `FILE_IN_USE`, `FILE_NOT_READY`, `CANNOT_CANCEL`, `ENDPOINT_LIMIT`, `DELIVERY_IN_FLIGHT`, `IDEMPOTENCY_KEY_REUSED`, `IDEMPOTENCY_IN_PROGRESS`, `TERMS_REACCEPTANCE_REQUIRED`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "ValidationError": {
        "description": "A field is wrong; `error.details` maps field names to messages (`VALIDATION_ERROR`, `IDEMPOTENCY_KEY_REQUIRED`, `MATERIAL_UNAVAILABLE`, `FILE_REJECTED`, `ENDPOINT_URL_INVALID`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Too many requests (`RATE_LIMITED`) or a monthly cap reached (`QUOTA_EXCEEDED`). Honour `Retry-After`.",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            }
          },
          "X-RateLimit-Limit": {
            "schema": {
              "type": "integer"
            }
          },
          "X-RateLimit-Remaining": {
            "schema": {
              "type": "integer"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            }
          }
        }
      }
    },
    "schemas": {
      "Money": {
        "type": "string",
        "pattern": "^-?[0-9]+\\.[0-9]{2}$",
        "description": "EUR with two decimals, as a string.",
        "examples": [
          "12.40"
        ]
      },
      "Environment": {
        "type": "string",
        "enum": [
          "live",
          "test"
        ]
      },
      "ErrorEnvelope": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "details": {
                "type": "object",
                "additionalProperties": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "Pagination": {
        "type": "object",
        "required": [
          "page",
          "per_page",
          "total",
          "total_pages"
        ],
        "properties": {
          "page": {
            "type": "integer"
          },
          "per_page": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "total_pages": {
            "type": "integer"
          }
        }
      },
      "Ping": {
        "type": "object",
        "required": [
          "partner",
          "environment",
          "key_id",
          "plan",
          "rate_limit",
          "server_time"
        ],
        "properties": {
          "partner": {
            "type": "object",
            "required": [
              "id",
              "number",
              "name"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "number": {
                "type": "string",
                "examples": [
                  "LC-PT-0007"
                ]
              },
              "name": {
                "type": "string"
              }
            }
          },
          "environment": {
            "$ref": "#/components/schemas/Environment"
          },
          "key_id": {
            "type": "string"
          },
          "plan": {
            "type": "object",
            "required": [
              "key",
              "name"
            ],
            "properties": {
              "key": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "rate_limit": {
            "type": "object",
            "required": [
              "per_second",
              "burst"
            ],
            "properties": {
              "per_second": {
                "type": "number"
              },
              "burst": {
                "type": "integer"
              }
            }
          },
          "server_time": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Account": {
        "type": "object",
        "required": [
          "partner",
          "status",
          "plan",
          "limits",
          "usage",
          "agreements"
        ],
        "properties": {
          "partner": {
            "type": "object",
            "required": [
              "id",
              "number",
              "name",
              "country_code",
              "locale"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "number": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "country_code": {
                "type": "string"
              },
              "locale": {
                "type": "string",
                "enum": [
                  "en",
                  "ro"
                ]
              }
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "pending_verification",
              "pending_agreement",
              "active",
              "suspended",
              "closed"
            ]
          },
          "plan": {
            "type": "object",
            "required": [
              "key",
              "name"
            ],
            "properties": {
              "key": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "limits": {
            "$ref": "#/components/schemas/PlanLimits"
          },
          "usage": {
            "type": "object",
            "required": [
              "month",
              "requests",
              "orders_live",
              "orders_test",
              "quotes_today"
            ],
            "properties": {
              "month": {
                "type": "string",
                "examples": [
                  "2026-10"
                ]
              },
              "requests": {
                "type": "integer"
              },
              "orders_live": {
                "type": "integer"
              },
              "orders_test": {
                "type": "integer"
              },
              "quotes_today": {
                "type": "integer"
              }
            }
          },
          "agreements": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "document",
                "version",
                "status"
              ],
              "properties": {
                "document": {
                  "type": "string",
                  "enum": [
                    "integration_agreement",
                    "data_processing_agreement"
                  ]
                },
                "version": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "none",
                    "accepted",
                    "countersigned"
                  ]
                },
                "accepted_at": {
                  "type": "string",
                  "format": "date-time"
                },
                "countersigned_at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          }
        }
      },
      "PlanLimits": {
        "type": "object",
        "description": "The limits in force for you (plan plus any agreed overrides).",
        "properties": {
          "discount_pct": {
            "type": "number"
          },
          "rate_per_second": {
            "type": "number"
          },
          "burst": {
            "type": "integer"
          },
          "monthly_request_cap": {
            "type": "integer",
            "description": "0 = unlimited"
          },
          "monthly_order_cap": {
            "type": "integer"
          },
          "monthly_test_order_cap": {
            "type": "integer"
          },
          "max_file_bytes": {
            "type": "integer"
          },
          "max_files": {
            "type": "integer"
          },
          "max_items_per_order": {
            "type": "integer"
          },
          "max_test_items_per_order": {
            "type": "integer"
          },
          "max_quantity_per_item": {
            "type": "integer"
          },
          "allowed_materials": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            }
          },
          "allowed_nozzles": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            }
          },
          "ship_before_payment": {
            "type": "boolean"
          },
          "webhook_endpoints_max": {
            "type": "integer"
          },
          "webhook_max_attempts": {
            "type": "integer"
          },
          "test_file_retention_days": {
            "type": "integer"
          },
          "file_retention_days_after_last_order": {
            "type": "integer"
          },
          "recipient_retention_days": {
            "type": "integer"
          },
          "quote_daily_cap": {
            "type": "integer"
          }
        }
      },
      "Material": {
        "type": "object",
        "required": [
          "material",
          "nozzles",
          "colours"
        ],
        "properties": {
          "material": {
            "type": "string",
            "examples": [
              "PLA"
            ]
          },
          "description": {
            "type": "string"
          },
          "nozzles": {
            "type": "array",
            "items": {
              "type": "string",
              "examples": [
                "0.4"
              ]
            }
          },
          "colours": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "name",
                "in_stock"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "hex": {
                  "type": "string"
                },
                "in_stock": {
                  "type": "boolean"
                }
              }
            }
          }
        }
      },
      "FileStatus": {
        "type": "string",
        "enum": [
          "pending",
          "ready",
          "rejected",
          "purged"
        ]
      },
      "FileFormat": {
        "type": "string",
        "enum": [
          "stl",
          "obj",
          "3mf"
        ]
      },
      "FileCreate": {
        "type": "object",
        "required": [
          "filename",
          "size_bytes",
          "sha256"
        ],
        "properties": {
          "filename": {
            "type": "string",
            "maxLength": 200,
            "description": "With its extension: .stl, .obj or .3mf."
          },
          "size_bytes": {
            "type": "integer",
            "minimum": 1
          },
          "sha256": {
            "type": "string",
            "pattern": "^[0-9a-f]{64}$",
            "description": "Lowercase hex SHA-256 of the exact bytes you will upload."
          },
          "content_type": {
            "type": "string",
            "default": "application/octet-stream"
          }
        }
      },
      "File": {
        "type": "object",
        "required": [
          "id",
          "filename",
          "format",
          "status",
          "size_bytes",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "filename": {
            "type": "string"
          },
          "format": {
            "$ref": "#/components/schemas/FileFormat"
          },
          "status": {
            "$ref": "#/components/schemas/FileStatus"
          },
          "size_bytes": {
            "type": "integer"
          },
          "sha256": {
            "type": "string"
          },
          "rejection_code": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "size_mismatch",
              "hash_mismatch",
              "not_a_model",
              "too_complex",
              "too_large",
              "upload_missing",
              null
            ]
          },
          "facts": {
            "type": "object",
            "description": "What we read from the file: triangles, bounding box in mm, object count, producer.",
            "properties": {
              "triangles": {
                "type": "integer"
              },
              "objects": {
                "type": "integer"
              },
              "bbox_mm": {
                "type": "array",
                "items": {
                  "type": "number"
                },
                "minItems": 3,
                "maxItems": 3
              },
              "producer": {
                "type": "string"
              },
              "sanitised": {
                "type": "boolean"
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "ready_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "purge_after": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the file will be deleted unless an order uses it."
          }
        }
      },
      "FileWithUpload": {
        "allOf": [
          {
            "$ref": "#/components/schemas/File"
          },
          {
            "type": "object",
            "required": [
              "upload"
            ],
            "properties": {
              "upload": {
                "type": "object",
                "required": [
                  "method",
                  "url",
                  "headers",
                  "expires_at"
                ],
                "properties": {
                  "method": {
                    "type": "string",
                    "enum": [
                      "PUT"
                    ]
                  },
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "headers": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Send every header exactly as given."
                  },
                  "expires_at": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            }
          }
        ]
      },
      "FileList": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/File"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      },
      "PriceEstimate": {
        "type": "object",
        "description": "What the slicer measured and the settings it used.",
        "properties": {
          "weight_grams": {
            "type": "number"
          },
          "time_seconds": {
            "type": "integer"
          },
          "unit_yield": {
            "type": "integer",
            "description": "Parts per plate in the file (3MF)."
          },
          "printer_model": {
            "type": "string"
          },
          "nozzle": {
            "type": "string"
          },
          "material": {
            "type": "string"
          },
          "infill_pct": {
            "type": "integer"
          },
          "wall_loops": {
            "type": "integer"
          },
          "support": {
            "type": "string"
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "priced_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "QuoteCreate": {
        "type": "object",
        "required": [
          "file_id",
          "material",
          "quantity"
        ],
        "properties": {
          "file_id": {
            "type": "string",
            "format": "uuid"
          },
          "material": {
            "type": "string"
          },
          "nozzle": {
            "type": "string",
            "default": "0.4"
          },
          "quantity": {
            "type": "integer",
            "minimum": 1
          }
        }
      },
      "Quote": {
        "type": "object",
        "required": [
          "id",
          "file_id",
          "material",
          "nozzle",
          "quantity",
          "status",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "file_id": {
            "type": "string",
            "format": "uuid"
          },
          "material": {
            "type": "string"
          },
          "nozzle": {
            "type": "string"
          },
          "quantity": {
            "type": "integer"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "priced",
              "failed"
            ]
          },
          "unit_price": {
            "$ref": "#/components/schemas/Money"
          },
          "list_unit_price": {
            "$ref": "#/components/schemas/Money"
          },
          "discount_pct": {
            "type": "string"
          },
          "total": {
            "$ref": "#/components/schemas/Money"
          },
          "currency": {
            "type": "string",
            "enum": [
              "EUR"
            ]
          },
          "tiers": {
            "type": "array",
            "description": "Unit price at other quantities.",
            "items": {
              "type": "object",
              "properties": {
                "min_quantity": {
                  "type": "integer"
                },
                "unit_price": {
                  "$ref": "#/components/schemas/Money"
                }
              }
            }
          },
          "estimate": {
            "$ref": "#/components/schemas/PriceEstimate"
          },
          "failure_code": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "model_too_large",
              "not_a_model",
              "material_unavailable",
              "slicer_rejected",
              "file_unavailable",
              null
            ]
          },
          "failure_message": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "priced_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "QuoteList": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Quote"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      },
      "Delivery": {
        "type": "object",
        "required": [
          "name",
          "phone",
          "line1",
          "city",
          "postal_code",
          "country_code"
        ],
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120
          },
          "company": {
            "type": "string",
            "maxLength": 120
          },
          "phone": {
            "type": "string",
            "maxLength": 40,
            "description": "Required by the courier."
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "line1": {
            "type": "string",
            "maxLength": 200
          },
          "line2": {
            "type": "string",
            "maxLength": 200
          },
          "city": {
            "type": "string",
            "maxLength": 120
          },
          "region": {
            "type": "string",
            "maxLength": 120,
            "description": "Required for Romania (județ); a Bucharest address names its sector."
          },
          "postal_code": {
            "type": "string",
            "maxLength": 20
          },
          "country_code": {
            "type": "string",
            "pattern": "^[A-Z]{2}$"
          }
        }
      },
      "WhiteLabel": {
        "type": "object",
        "description": "White label is on by default: neutral packaging, no LayerCrew marks on parts, packaging or inserts, no invoice in the box. The courier label names LayerCrew as the shipping account (a courier requirement) and shows your sender name as the contact line; packaging and inserts carry your branding settings.",
        "properties": {
          "enabled": {
            "type": "boolean",
            "default": true
          },
          "sender_name": {
            "type": "string",
            "maxLength": 80
          },
          "card_text": {
            "type": "string",
            "maxLength": 500,
            "description": "Printed on a card in the parcel; can differ on every order."
          },
          "packaging_preset": {
            "type": "string",
            "maxLength": 60,
            "description": "`neutral` (default) or `partner_supplied` when you send us your packaging."
          },
          "no_invoice_in_box": {
            "type": "boolean",
            "default": true
          },
          "language": {
            "type": "string",
            "maxLength": 5
          }
        }
      },
      "OrderItemCreate": {
        "type": "object",
        "required": [
          "file_id",
          "quantity",
          "material"
        ],
        "properties": {
          "file_id": {
            "type": "string",
            "format": "uuid"
          },
          "quantity": {
            "type": "integer",
            "minimum": 1
          },
          "material": {
            "type": "string"
          },
          "colour": {
            "type": "string",
            "description": "A colour id from `/materials`."
          },
          "nozzle": {
            "type": "string",
            "default": "0.4"
          },
          "notes": {
            "type": "string",
            "maxLength": 500
          }
        }
      },
      "OrderCreate": {
        "type": "object",
        "required": [
          "reference",
          "items",
          "delivery"
        ],
        "properties": {
          "reference": {
            "type": "string",
            "maxLength": 120,
            "description": "Your own order reference; unique per environment."
          },
          "items": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/OrderItemCreate"
            }
          },
          "delivery": {
            "$ref": "#/components/schemas/Delivery"
          },
          "white_label": {
            "$ref": "#/components/schemas/WhiteLabel"
          },
          "notes": {
            "type": "string",
            "maxLength": 2000
          },
          "metadata": {
            "type": "object",
            "maxProperties": 20,
            "additionalProperties": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Returned untouched on the order and in every webhook."
          }
        }
      },
      "OrderStatus": {
        "type": "string",
        "enum": [
          "received",
          "pending_review",
          "accepting",
          "accepted",
          "in_production",
          "ready_to_ship",
          "shipped",
          "delivered",
          "on_hold",
          "cancelled",
          "rejected"
        ],
        "description": "received: pricing in progress · pending_review: priced, a LayerCrew engineer is looking at it · accepted: in the production queue · in_production · ready_to_ship: passed quality check and packed · shipped: handed to the courier · delivered (final) · on_hold: we need something, see `hold` · cancelled · rejected, see `rejection`."
      },
      "OrderItem": {
        "type": "object",
        "required": [
          "id",
          "position",
          "file",
          "quantity",
          "material",
          "nozzle",
          "pricing_status"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "position": {
            "type": "integer"
          },
          "file": {
            "type": "object",
            "required": [
              "id",
              "filename",
              "format"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "filename": {
                "type": "string"
              },
              "format": {
                "$ref": "#/components/schemas/FileFormat"
              }
            }
          },
          "quantity": {
            "type": "integer"
          },
          "material": {
            "type": "string"
          },
          "colour": {
            "type": [
              "string",
              "null"
            ]
          },
          "nozzle": {
            "type": "string"
          },
          "notes": {
            "type": "string"
          },
          "pricing_status": {
            "type": "string",
            "enum": [
              "pending",
              "priced",
              "failed"
            ]
          },
          "list_unit_price": {
            "$ref": "#/components/schemas/Money"
          },
          "discount_pct": {
            "type": "string"
          },
          "unit_price": {
            "$ref": "#/components/schemas/Money"
          },
          "line_total": {
            "$ref": "#/components/schemas/Money"
          },
          "estimate": {
            "$ref": "#/components/schemas/PriceEstimate"
          },
          "failure_code": {
            "type": [
              "string",
              "null"
            ]
          },
          "failure_message": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Pricing": {
        "type": "object",
        "required": [
          "currency",
          "final"
        ],
        "properties": {
          "currency": {
            "type": "string",
            "enum": [
              "EUR"
            ]
          },
          "subtotal": {
            "$ref": "#/components/schemas/Money"
          },
          "discount_total": {
            "$ref": "#/components/schemas/Money"
          },
          "shipping_total": {
            "$ref": "#/components/schemas/Money"
          },
          "tax_total": {
            "$ref": "#/components/schemas/Money"
          },
          "tax_treatment": {
            "type": "string",
            "enum": [
              "standard",
              "reverse_charge",
              "export",
              "exempt",
              "test"
            ]
          },
          "grand_total": {
            "$ref": "#/components/schemas/Money"
          },
          "final": {
            "type": "boolean",
            "description": "false while the order is being priced or reviewed; true from acceptance, when the price is frozen."
          }
        }
      },
      "Payment": {
        "type": "object",
        "required": [
          "method",
          "status",
          "ship_before_payment"
        ],
        "properties": {
          "method": {
            "type": "string",
            "enum": [
              "bank_transfer"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "unpaid",
              "invoiced",
              "partially_paid",
              "paid",
              "refunded",
              "partially_refunded"
            ]
          },
          "ship_before_payment": {
            "type": "boolean"
          },
          "amount_due": {
            "$ref": "#/components/schemas/Money"
          },
          "instructions": {
            "type": "object",
            "properties": {
              "beneficiary": {
                "type": "string"
              },
              "iban": {
                "type": "string"
              },
              "bank": {
                "type": "string"
              },
              "reference": {
                "type": "string",
                "description": "Put this on the transfer."
              }
            }
          },
          "paid_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "Shipment": {
        "type": "object",
        "required": [
          "carrier",
          "status",
          "shipped_at"
        ],
        "properties": {
          "carrier": {
            "type": "string"
          },
          "tracking_number": {
            "type": [
              "string",
              "null"
            ]
          },
          "tracking_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "status": {
            "type": "string",
            "enum": [
              "shipped",
              "in_transit",
              "delivered",
              "returned"
            ]
          },
          "last_tracking_status": {
            "type": [
              "string",
              "null"
            ]
          },
          "shipped_at": {
            "type": "string",
            "format": "date-time"
          },
          "delivered_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "Invoice": {
        "type": "object",
        "required": [
          "id",
          "number",
          "kind",
          "issued_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "number": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "fiscal",
              "proforma",
              "storno"
            ]
          },
          "issued_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Rejection": {
        "type": "object",
        "required": [
          "code",
          "message"
        ],
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "needs_split",
              "design_change_needed",
              "material_unavailable",
              "out_of_capacity",
              "address_unserviceable",
              "price_review",
              "other"
            ],
            "description": "needs_split: the part is laid out larger than our bed; split it or we take it by hand · design_change_needed: a feature will not print as drawn; the note says which · material_unavailable: not in stock for this run; pick another or wait · out_of_capacity: our queue is full for that date; choose a later date · address_unserviceable: check the address for courier service · price_review: we need to price this by hand; we will write · other: see the note."
          },
          "message": {
            "type": "string",
            "description": "The fact and the next step, in plain words."
          },
          "note": {
            "type": [
              "string",
              "null"
            ],
            "description": "What the engineer wrote for you."
          },
          "rejected_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Hold": {
        "type": "object",
        "required": [
          "reason",
          "since"
        ],
        "properties": {
          "reason": {
            "type": "string"
          },
          "since": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Order": {
        "type": "object",
        "required": [
          "id",
          "number",
          "reference",
          "environment",
          "status",
          "pricing_status",
          "items",
          "pricing",
          "delivery",
          "white_label",
          "metadata",
          "shipments",
          "invoices",
          "created_at",
          "updated_at",
          "links"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "number": {
            "type": "string",
            "examples": [
              "PA-2026-0007"
            ]
          },
          "reference": {
            "type": "string"
          },
          "environment": {
            "$ref": "#/components/schemas/Environment"
          },
          "status": {
            "$ref": "#/components/schemas/OrderStatus"
          },
          "pricing_status": {
            "type": "string",
            "enum": [
              "pending",
              "priced",
              "failed"
            ]
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderItem"
            }
          },
          "pricing": {
            "$ref": "#/components/schemas/Pricing"
          },
          "payment": {
            "$ref": "#/components/schemas/Payment"
          },
          "delivery": {
            "$ref": "#/components/schemas/Delivery"
          },
          "white_label": {
            "$ref": "#/components/schemas/WhiteLabel"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "notes": {
            "type": "string"
          },
          "shipments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Shipment"
            }
          },
          "invoices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Invoice"
            }
          },
          "rejection": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Rejection"
              },
              {
                "type": "null"
              }
            ]
          },
          "hold": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/Hold"
              },
              {
                "type": "null"
              }
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "accepted_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "shipped_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "delivered_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "cancelled_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "links": {
            "type": "object",
            "required": [
              "self",
              "events"
            ],
            "properties": {
              "self": {
                "type": "string"
              },
              "events": {
                "type": "string"
              }
            }
          }
        }
      },
      "OrderEnvelope": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Order"
          }
        }
      },
      "OrderList": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Order"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      },
      "EventType": {
        "type": "string",
        "enum": [
          "order.received",
          "order.priced",
          "order.pricing_failed",
          "order.accepted",
          "order.rejected",
          "order.on_hold",
          "order.released",
          "order.in_production",
          "order.ready_to_ship",
          "order.shipped",
          "order.tracking_updated",
          "order.delivered",
          "order.cancelled",
          "order.paid",
          "order.invoiced",
          "order.returned",
          "order.recipient_redacted",
          "quote.priced",
          "quote.failed",
          "file.ready",
          "file.rejected",
          "file.purged",
          "agreement.accepted",
          "agreement.countersigned",
          "key.issued",
          "key.revoked",
          "webhook_endpoint.disabled",
          "webhook_endpoint.secret_rotated",
          "partner.suspended",
          "partner.activated",
          "usage.warning",
          "test.ping"
        ]
      },
      "Event": {
        "type": "object",
        "required": [
          "id",
          "type",
          "api_version",
          "created_at",
          "seq",
          "environment",
          "data"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "$ref": "#/components/schemas/EventType"
          },
          "api_version": {
            "type": "string",
            "examples": [
              "2026-10-24"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "seq": {
            "type": "integer",
            "description": "Per-partner, gap-free, strictly increasing."
          },
          "environment": {
            "$ref": "#/components/schemas/Environment"
          },
          "reason_code": {
            "type": [
              "string",
              "null"
            ]
          },
          "data": {
            "type": "object",
            "description": "`order` for order.* events, `quote` for quote.*, `file` for file.*, `endpoint` for webhook_endpoint.*, `key` for key.* (never the secret), `usage` for usage.warning, `{}` for test.ping.",
            "properties": {
              "order": {
                "$ref": "#/components/schemas/Order"
              },
              "quote": {
                "$ref": "#/components/schemas/Quote"
              },
              "file": {
                "$ref": "#/components/schemas/File"
              }
            },
            "additionalProperties": true
          }
        }
      },
      "EventList": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Event"
            }
          },
          "meta": {
            "type": "object",
            "required": [
              "next_after",
              "has_more"
            ],
            "properties": {
              "next_after": {
                "type": "integer"
              },
              "has_more": {
                "type": "boolean"
              }
            }
          }
        }
      },
      "WebhookEndpointCreate": {
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "maxLength": 500
          },
          "description": {
            "type": "string",
            "maxLength": 200
          },
          "event_types": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/EventType"
            },
            "description": "null = every event."
          }
        }
      },
      "WebhookEndpointUpdate": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "description": {
            "type": "string"
          },
          "event_types": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "$ref": "#/components/schemas/EventType"
            }
          },
          "enabled": {
            "type": "boolean"
          }
        }
      },
      "WebhookEndpoint": {
        "type": "object",
        "required": [
          "id",
          "url",
          "environment",
          "enabled",
          "event_types",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "environment": {
            "$ref": "#/components/schemas/Environment"
          },
          "event_types": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            }
          },
          "enabled": {
            "type": "boolean"
          },
          "disabled_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "consecutive_failures": {
            "type": "integer"
          },
          "last_success_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "secret_rotated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "WebhookEndpointWithSecret": {
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookEndpoint"
          },
          {
            "type": "object",
            "required": [
              "secret"
            ],
            "properties": {
              "secret": {
                "type": "string",
                "description": "`whsec_` + base64. Shown once."
              }
            }
          }
        ]
      },
      "DeliveryStatus": {
        "type": "string",
        "enum": [
          "pending",
          "in_flight",
          "delivered",
          "failed",
          "skipped"
        ]
      },
      "WebhookDelivery": {
        "type": "object",
        "required": [
          "id",
          "endpoint_id",
          "event_id",
          "event_type",
          "seq",
          "status",
          "attempts",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "endpoint_id": {
            "type": "string",
            "format": "uuid"
          },
          "event_id": {
            "type": "string",
            "format": "uuid"
          },
          "event_type": {
            "type": "string"
          },
          "seq": {
            "type": "integer"
          },
          "status": {
            "$ref": "#/components/schemas/DeliveryStatus"
          },
          "attempts": {
            "type": "integer"
          },
          "max_attempts": {
            "type": "integer"
          },
          "next_attempt_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "last_status_code": {
            "type": [
              "integer",
              "null"
            ]
          },
          "last_error": {
            "type": [
              "string",
              "null"
            ]
          },
          "delivered_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "WebhookAttempt": {
        "type": "object",
        "required": [
          "attempt",
          "at",
          "duration_ms"
        ],
        "properties": {
          "attempt": {
            "type": "integer"
          },
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "request_id": {
            "type": "string"
          },
          "status_code": {
            "type": [
              "integer",
              "null"
            ]
          },
          "duration_ms": {
            "type": "integer"
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "response_snippet": {
            "type": [
              "string",
              "null"
            ],
            "description": "The first kilobyte of your response, for debugging."
          }
        }
      },
      "WebhookDeliveryDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/WebhookDelivery"
          },
          {
            "type": "object",
            "required": [
              "attempts_log",
              "event"
            ],
            "properties": {
              "attempts_log": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/WebhookAttempt"
                }
              },
              "event": {
                "$ref": "#/components/schemas/Event"
              }
            }
          }
        ]
      },
      "WebhookDeliveryList": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookDelivery"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      },
      "RequestLogEntry": {
        "type": "object",
        "required": [
          "request_id",
          "method",
          "route",
          "status",
          "duration_ms",
          "created_at"
        ],
        "properties": {
          "request_id": {
            "type": "string"
          },
          "client_request_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "key_id": {
            "type": "string"
          },
          "method": {
            "type": "string"
          },
          "route": {
            "type": "string",
            "examples": [
              "POST /v1/orders"
            ]
          },
          "path": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "error_code": {
            "type": [
              "string",
              "null"
            ]
          },
          "duration_ms": {
            "type": "integer"
          },
          "resource_ref": {
            "type": [
              "string",
              "null"
            ],
            "examples": [
              "order:5d0c…"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "RequestLogList": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RequestLogEntry"
            }
          },
          "meta": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      }
    }
  }
}
