{"openapi":"3.1.0","info":{"title":"Inventory API","version":"1.22.0","description":"Organization-scoped API for configurable inventory structures, localized content, indoor 3D room scans, location-aware stock, cycle counts, assignments, internal requests, reservation planning, CSV exchange, typed custom fields, label setups, shared label printing, stock planning, media, AI, outgoing integration webhooks, and data quality. User-bound credentials may select one of their memberships with X-Organization-ID. Standalone API tokens are pinned to their issuing organization.","license":{"name":"MIT License","identifier":"MIT"}},"servers":[{"url":"https://inventory.example.com/api/v1","description":"Your Open Inventory instance"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Authentication","description":"Native sign-in, token revocation, and scope discovery."},{"name":"Organizations","description":"Membership discovery, active-organization selection, creation, and administration."},{"name":"Access control","description":"Session-administered roles, granular permissions, and conditional inventory-item access rules."},{"name":"Resources","description":"Inventory item creation, lookup, retrieval, and lifecycle."},{"name":"Contacts","description":"Organization-scoped customers and suppliers with inventory and stock-ledger assignments."},{"name":"Inventory structure","description":"Configurable inventory types, relationship types, and directed resource relationships."},{"name":"Data exchange","description":"Idempotent CSV import and complete CSV export."},{"name":"Custom fields","description":"Typed field definitions, including filtered record references, for inventory items and serialized stock units."},{"name":"Content translations","description":"Canonical content languages and field-aware AI translations."},{"name":"Label setups","description":"Reusable physical dimensions and positioned content for printed inventory labels."},{"name":"Label printing","description":"Personal saved queues, shared Office printers, Windows agents and local QZ signing. Browser-session operations cannot use ordinary API tokens."},{"name":"Stock","description":"Stock health, configuration, movements, and serialized units."},{"name":"Inventory cycles","description":"Recurring count policies, due-count queues, and stock reconciliation."},{"name":"Assignments","description":"Checkout, assignment, reservation, return, and cancellation workflows."},{"name":"Internal requests","description":"Multi-item inventory requests with approval, reservation, fulfillment, and calendar planning."},{"name":"Manufacturing","description":"Bills of materials and atomic assembly builds."},{"name":"Purchasing","description":"Purchase orders, incoming quantities, and stock receipts."},{"name":"Orders","description":"Shared purchase, sales, and multi-item loan workflows with line-linked stock movements, outbound parcels, and shipment history."},{"name":"Scan workflows","description":"Configurable scan actions and execution."},{"name":"Media","description":"Resource images, metadata, and ordering."},{"name":"Spatial rooms","description":"Versioned RoomPlan scenes, native AR world-map assets, and measured indoor item placements."},{"name":"AI","description":"Visual inventory recognition, counting, item analysis, web-grounded enrichment, and generated covers."},{"name":"Insights","description":"Workspace statistics and duplicate detection."},{"name":"Notifications","description":"Session-scoped in-app inbox, anti-noise preferences, Web Push subscriptions, and preview-only channel tests."},{"name":"Integrations","description":"Session-administered connections to external inventory and commerce systems."},{"name":"Webhooks","description":"Session-administered outgoing integration events with durable at-least-once delivery, HMAC signatures, retry history, and manual replay."}],"paths":{"/notifications":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Notifications"],"summary":"List the current user's in-app notifications","description":"The inbox is always available. Events are deduplicated using the user's configured cooldown; external delivery is not required.","security":[{"adminSession":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":30}},{"name":"unreadOnly","in":"query","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Notifications plus the complete unread count","content":{"application/json":{"schema":{"type":"object","required":["notifications","unread"],"properties":{"notifications":{"type":"array","items":{"$ref":"#/components/schemas/Notification"}},"unread":{"type":"integer","minimum":0}}}}}},"403":{"description":"An authenticated browser session is required"}}}},"/notifications/{id}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"patch":{"tags":["Notifications"],"summary":"Mark one notification read","security":[{"adminSession":[]}],"responses":{"200":{"description":"Notification marked read"},"404":{"description":"Notification not found for this user"}}}},"/notifications/read-all":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["Notifications"],"summary":"Mark every notification for the current user read","security":[{"adminSession":[]}],"responses":{"200":{"description":"Number of updated inbox entries"}}}},"/notifications/preferences":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Notifications"],"summary":"Read personal anti-noise and channel preferences","security":[{"adminSession":[]}],"responses":{"200":{"description":"Preferences, redacted runtime channel state, and Push subscription count"}}},"patch":{"tags":["Notifications"],"summary":"Update personal notification preferences","description":"External channels default off and must be explicitly enabled. Destination URLs remain server environment variables and are never accepted by this endpoint.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationPreferencePatch"}}}},"responses":{"200":{"description":"Preferences updated"},"422":{"description":"Invalid thresholds, cadence, fields, locale, or channel opt-ins"}}}},"/notifications/push-subscriptions":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["Notifications"],"summary":"Subscribe the current browser to Web Push","description":"Subscription endpoint and key material are encrypted before storage using the deployment notification encryption key.","security":[{"adminSession":[]}],"responses":{"201":{"description":"Encrypted subscription stored"},"503":{"description":"VAPID or at-rest encryption is not configured"}}},"delete":{"tags":["Notifications"],"summary":"Revoke the current browser's Web Push subscription","security":[{"adminSession":[]}],"responses":{"200":{"description":"Subscription revoked when present"}}}},"/notifications/test":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["Notifications"],"summary":"Preview one delivery channel without sending","description":"Dry-run only. This endpoint never invokes SMTP, Web Push, Slack, Teams, or generic webhook transports.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["channel"],"properties":{"channel":{"type":"string","enum":["email","push","slack","teams","webhook"]}}}}}},"responses":{"200":{"description":"Redacted sample payload with dryRun true"}}}},"/notifications/run":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["Notifications"],"summary":"Run notification detection and due digest dispatch","description":"Invokes one deduplicated detector/dispatcher cycle. Authenticate with `Authorization: Bearer NOTIFICATION_CRON_SECRET`, or with an authenticated browser session that has `tokens.manage`. Safe retries rely on cooldown, inbox uniqueness, and dispatch dedupe keys.","security":[{"cronSecret":[]},{"adminSession":[]}],"responses":{"200":{"description":"Detection and dispatch counters"},"401":{"description":"Missing or invalid cron secret or browser session"},"403":{"description":"Browser session lacks tokens.manage"}}}},"/integrations/woocommerce":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Integrations"],"summary":"Read the WooCommerce connection status","description":"Requires an authenticated browser session with `webhooks.manage`. Credentials are never returned.","security":[{"adminSession":[]}],"responses":{"200":{"description":"Current connection status and encryption readiness","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WooCommerceConnectionStatusResponse"}}}},"401":{"description":"An authenticated browser session is required"},"403":{"description":"Browser session lacks webhooks.manage"}}},"put":{"tags":["Integrations"],"summary":"Connect or replace a WooCommerce store","description":"Tests the credentials against WooCommerce REST API v3 before encrypting and storing them. Requires `webhooks.manage`.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WooCommerceConnectionInput"}}}},"responses":{"200":{"description":"Connection tested and stored","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WooCommerceConnectionMutationResponse"}}}},"400":{"description":"Request body is not valid JSON"},"401":{"description":"An authenticated browser session is required"},"403":{"description":"Browser session lacks webhooks.manage"},"422":{"description":"Invalid store URL or credential format"},"502":{"description":"WooCommerce rejected the request or returned an invalid response"},"503":{"description":"Integration credential encryption is not configured"}}},"patch":{"tags":["Integrations"],"summary":"Enable or disable WooCommerce order synchronization","description":"Creates or removes signed order.created and order.updated webhooks in WooCommerce. Enabling requires a public HTTPS AUTH_URL and a Consumer Key with write access.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WooCommerceSyncPatch"}}}},"responses":{"200":{"description":"Order synchronization state updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WooCommerceConnectionStatusResponse"}}}},"401":{"description":"An authenticated browser session is required"},"403":{"description":"Browser session lacks webhooks.manage"},"404":{"description":"No WooCommerce connection is configured"},"422":{"description":"Invalid stock sync setting"},"502":{"description":"WooCommerce webhook registration failed"},"503":{"description":"Public callback URL or integration encryption is not configured"}}},"delete":{"tags":["Integrations"],"summary":"Disconnect the WooCommerce store","description":"Permanently removes the encrypted credentials for the selected organization. Requires `webhooks.manage`.","security":[{"adminSession":[]}],"responses":{"204":{"description":"Connection removed, or no connection existed"},"401":{"description":"An authenticated browser session is required"},"403":{"description":"Browser session lacks webhooks.manage"}}}},"/integrations/woocommerce/test":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["Integrations"],"summary":"Test the saved WooCommerce connection","description":"Decrypts the saved credentials only in memory and verifies product read access against WooCommerce REST API v3. Requires `webhooks.manage`.","security":[{"adminSession":[]}],"responses":{"200":{"description":"Connection test succeeded and status was updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WooCommerceConnectionMutationResponse"}}}},"401":{"description":"An authenticated browser session is required"},"403":{"description":"Browser session lacks webhooks.manage"},"404":{"description":"No WooCommerce connection is configured"},"502":{"description":"WooCommerce rejected the request or returned an invalid response"},"503":{"description":"Integration credential encryption is not configured"}}}},"/integrations/woocommerce/sync":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["Integrations"],"summary":"Import recent WooCommerce orders, reconcile one order, or retry issues","description":"Fetches canonical order and refund data from WooCommerce, projects the customer and sales order into Inventory, maps exact item or variant SKUs, and writes idempotent issue or return stock movements. Set window to last-7-days for a read-only WooCommerce import based on order creation time. Omitting both fields retries up to 20 recorded orders with issues.","security":[{"adminSession":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WooCommerceManualSyncRequest"}}}},"responses":{"200":{"description":"Reconciliation results"},"401":{"description":"An authenticated browser session is required"},"403":{"description":"Browser session lacks webhooks.manage"},"404":{"description":"No WooCommerce connection is configured"},"422":{"description":"Invalid order ID"},"502":{"description":"WooCommerce order or refund retrieval failed"}}}},"/integrations/woocommerce/webhook/{connectionId}":{"parameters":[{"name":"connectionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"post":{"tags":["Integrations"],"summary":"Receive a signed WooCommerce order webhook","description":"Public callback registered automatically in WooCommerce. The exact raw body is authenticated with X-WC-Webhook-Signature and the registered webhook ID before canonical order data is fetched.","security":[],"parameters":[{"name":"X-WC-Webhook-Signature","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-WC-Webhook-Topic","in":"header","required":true,"schema":{"type":"string","enum":["order.created","order.updated"]}},{"name":"X-WC-Webhook-ID","in":"header","required":true,"schema":{"type":"integer"}},{"name":"X-WC-Webhook-Delivery-ID","in":"header","required":false,"schema":{"type":"string","maxLength":160}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id"],"properties":{"id":{"type":"integer","minimum":1}},"additionalProperties":true}}}},"responses":{"200":{"description":"Delivery authenticated and reconciled, or safely recognized as a duplicate"},"400":{"description":"Invalid JSON or unsupported topic"},"401":{"description":"Invalid signature or unknown WooCommerce webhook ID"},"410":{"description":"WooCommerce order synchronization is disabled"},"413":{"description":"Payload exceeds one megabyte"},"422":{"description":"Payload has no valid order ID"},"502":{"description":"Canonical WooCommerce order retrieval failed and the delivery may be retried"}}}},"/webhooks":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Webhooks"],"summary":"List outgoing webhook endpoints","description":"Requires an authenticated browser session with `webhooks.manage`. Stored targets are redacted in responses, and API bearer tokens are not accepted.","security":[{"adminSession":[]}],"responses":{"200":{"description":"Configured webhook endpoints","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookListResponse"}}}},"401":{"description":"An authenticated browser session is required"},"403":{"description":"Browser session lacks webhooks.manage"}}},"post":{"tags":["Webhooks"],"summary":"Create an outgoing webhook endpoint","description":"Requires `webhooks.manage`. The signing secret is returned only by this response; store it before leaving the page.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointCreate"}}}},"responses":{"201":{"description":"Webhook endpoint created and its signing secret disclosed once","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreatedResponse"}}}},"400":{"description":"Request body is not valid JSON"},"401":{"description":"An authenticated browser session is required"},"403":{"description":"Browser session lacks webhooks.manage"},"422":{"description":"Invalid name, target URL, event subscription, or enabled state"},"503":{"description":"Webhook at-rest encryption is not configured"}}}},"/webhooks/{id}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/WebhookId"}],"get":{"tags":["Webhooks"],"summary":"Retrieve one outgoing webhook endpoint","description":"Requires an authenticated browser session with `webhooks.manage`. The target is redacted and the signing secret is never returned.","security":[{"adminSession":[]}],"responses":{"200":{"description":"Webhook endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResponse"}}}},"401":{"description":"An authenticated browser session is required"},"403":{"description":"Browser session lacks webhooks.manage"},"404":{"description":"Webhook endpoint not found"},"422":{"description":"Invalid webhook endpoint identifier"}}},"patch":{"tags":["Webhooks"],"summary":"Update an outgoing webhook endpoint","description":"Requires `webhooks.manage`. Submit at least one field. A new target must be supplied in full because stored targets are only returned in redacted form.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointPatch"}}}},"responses":{"200":{"description":"Webhook endpoint updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResponse"}}}},"400":{"description":"Request body is not valid JSON"},"401":{"description":"An authenticated browser session is required"},"403":{"description":"Browser session lacks webhooks.manage"},"404":{"description":"Webhook endpoint not found"},"422":{"description":"Empty or invalid webhook endpoint update"},"503":{"description":"Webhook at-rest encryption is not configured"}}},"delete":{"tags":["Webhooks"],"summary":"Delete an outgoing webhook endpoint","description":"Requires an authenticated browser session with `webhooks.manage`.","security":[{"adminSession":[]}],"responses":{"204":{"description":"Webhook endpoint deleted"},"401":{"description":"An authenticated browser session is required"},"403":{"description":"Browser session lacks webhooks.manage"},"404":{"description":"Webhook endpoint not found"},"422":{"description":"Invalid webhook endpoint identifier"}}}},"/webhooks/{id}/test":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/WebhookId"}],"post":{"tags":["Webhooks"],"summary":"Enqueue a real signed test delivery","description":"Requires `webhooks.manage`. Unlike notification channel previews, this creates an event and sends an actual HTTP request through the durable delivery queue.","security":[{"adminSession":[]}],"responses":{"202":{"description":"Test event and delivery accepted for asynchronous processing","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookTestResponse"}}}},"401":{"description":"An authenticated browser session is required"},"403":{"description":"Browser session lacks webhooks.manage"},"404":{"description":"Webhook endpoint not found"},"422":{"description":"Invalid webhook endpoint identifier"},"503":{"description":"Webhook at-rest encryption is not configured"}}}},"/webhooks/{id}/rotate-secret":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/WebhookId"}],"post":{"tags":["Webhooks"],"summary":"Rotate a webhook signing secret","description":"Requires `webhooks.manage`. The replacement secret is returned only by this response and cannot be read again.","security":[{"adminSession":[]}],"responses":{"200":{"description":"Signing secret rotated and disclosed once","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSecretResponse"}}}},"401":{"description":"An authenticated browser session is required"},"403":{"description":"Browser session lacks webhooks.manage"},"404":{"description":"Webhook endpoint not found"},"422":{"description":"Invalid webhook endpoint identifier"},"503":{"description":"Webhook at-rest encryption is not configured"}}}},"/webhooks/{id}/deliveries":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/WebhookId"}],"get":{"tags":["Webhooks"],"summary":"List delivery attempts for one webhook endpoint","description":"Requires an authenticated browser session with `webhooks.manage`.","security":[{"adminSession":[]}],"parameters":[{"name":"limit","in":"query","description":"Maximum number of recent deliveries returned; values above 100 are capped.","schema":{"type":"integer","minimum":1,"default":50}}],"responses":{"200":{"description":"Recent deliveries and their retry state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDeliveryListResponse"}}}},"401":{"description":"An authenticated browser session is required"},"403":{"description":"Browser session lacks webhooks.manage"},"404":{"description":"Webhook endpoint not found"},"422":{"description":"Invalid webhook endpoint identifier or delivery limit"}}}},"/webhooks/{id}/deliveries/{deliveryId}/retry":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/WebhookId"},{"$ref":"#/components/parameters/WebhookDeliveryId"}],"post":{"tags":["Webhooks"],"summary":"Manually retry a failed delivery","description":"Requires `webhooks.manage` and an enabled endpoint. The same event identity is retained so receivers can deduplicate an at-least-once replay.","security":[{"adminSession":[]}],"responses":{"202":{"description":"Delivery accepted for asynchronous retry","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDeliveryResponse"}}}},"401":{"description":"An authenticated browser session is required"},"403":{"description":"Browser session lacks webhooks.manage"},"404":{"description":"Enabled webhook endpoint or failed delivery not found"},"422":{"description":"Invalid webhook endpoint or delivery identifier"}}}},"/webhooks/run":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["Webhooks"],"summary":"Process due outgoing webhook deliveries","description":"Runs one bounded delivery cycle for deployments without the built-in worker. Authenticate only with `Authorization: Bearer WEBHOOK_CRON_SECRET`; browser sessions and API tokens are not accepted.","security":[{"webhookCronSecret":[]}],"parameters":[{"name":"limit","in":"query","description":"Maximum number of due deliveries claimed during this bounded cycle.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Due deliveries processed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookRunResponse"}}}},"401":{"description":"Missing, invalid, or unconfigured webhook cron secret"},"422":{"description":"Limit must be an integer between 1 and 100"}}}},"/spatial-structures":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Spatial rooms"],"summary":"List buildings and their active indoor-scan coverage","responses":{"200":{"description":"Structures with active room, floor, coordinate-space, and compatible-bounds counts","content":{"application/json":{"schema":{"type":"object","required":["structures"],"properties":{"structures":{"type":"array","items":{"$ref":"#/components/schemas/SpatialStructureSummary"}}}}}}}}},"post":{"tags":["Spatial rooms"],"summary":"Create a building or other multi-room structure","description":"Requires write scope. A structure may also be created atomically by the first grouped room-scan upload.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpatialStructureCreate"}}}},"responses":{"201":{"description":"Structure created"},"409":{"description":"The client-provided structure id already exists"},"422":{"description":"Invalid structure or georeference"}}}},"/spatial-structures/{structureId}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"structureId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Spatial rooms"],"summary":"Retrieve active rooms grouped by floor and AR coordinate space","responses":{"200":{"description":"Structure, coordinate spaces, floors, room scenes, and placements"},"404":{"description":"Spatial structure not found"},"422":{"description":"Invalid spatial structure identifier"}}},"patch":{"tags":["Spatial rooms"],"summary":"Update a structure's name or canonical map anchor","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpatialStructurePatch"}}}},"responses":{"200":{"description":"Structure updated"},"404":{"description":"Spatial structure not found"},"422":{"description":"Invalid structure change or georeference"}}}},"/room-scans":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Spatial rooms"],"summary":"List active 3D room scans","parameters":[{"name":"includeSuperseded","in":"query","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Room scans ordered by capture time","content":{"application/json":{"schema":{"type":"object","required":["scans"],"properties":{"scans":{"type":"array","items":{"$ref":"#/components/schemas/RoomScanSummary"}}}}}}},"401":{"description":"Missing or invalid session or bearer token"},"403":{"description":"Authenticated identity does not have the read scope"}}},"post":{"tags":["Spatial rooms"],"summary":"Upload a normalized RoomPlan scan and its native assets","description":"Requires write scope. The client-generated scan id makes exact retries idempotent. The referenced resource must have type `place`. RGB keyframes carry ARKit camera poses and intrinsics in the scan's coordinate space; each JPEG part name must match its metadata fileField.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["id","roomResourceId","capturedAt","scene","worldMap","model"],"properties":{"id":{"type":"string","format":"uuid"},"roomResourceId":{"type":"string","format":"uuid"},"capturedAt":{"type":"string","format":"date-time"},"deviceModel":{"type":"string","maxLength":120},"structureId":{"type":"string","format":"uuid","description":"Groups this room into a building. The first upload may create this id."},"structureName":{"type":"string","minLength":1,"maxLength":240},"coordinateSpaceId":{"type":"string","format":"uuid","description":"Shared by rooms captured or relocalized in the same ARKit world frame. Never reuse it for independently captured coordinate systems."},"floorIdentifier":{"type":"string","minLength":1,"maxLength":120},"floorIndex":{"type":"integer","minimum":-1000,"maximum":10000},"roomIdentifier":{"type":"string","minLength":1,"maxLength":120},"georeference":{"type":"string","contentMediaType":"application/json","description":"UTF-8 JSON encoding of SpatialGeoreference for this coordinate space."},"scene":{"type":"string","description":"UTF-8 JSON encoding of the RoomScene schema.","contentMediaType":"application/json"},"worldMap":{"type":"string","format":"binary","description":"NSSecureCoding archive of the ARWorldMap used for later relocalization."},"model":{"type":"string","format":"binary","description":"Original RoomPlan USDZ mesh."},"structureModel":{"type":"string","format":"binary","description":"Optional combined multi-room USDZ model produced by StructureBuilder."},"guideImage":{"type":"string","format":"binary"},"keyframes":{"type":"string","contentMediaType":"application/json","description":"UTF-8 JSON array of at most 32 RoomCameraKeyframeInput records. Each record references one JPEG multipart field named keyframe:<frame-id>."},"texturedMesh":{"type":"string","format":"binary","description":"Optional self-contained, bounded GLB v2 textured room mesh whose vertices are already in the scan's ARKit world frame in metres (model/gltf-binary, maximum 80 MB). External resources, unsafe accessor ranges/counts, oversized embedded textures, and unsupported required codecs are rejected."},"gaussianSplat":{"type":"string","format":"binary","description":"Optional bounded binary-little-endian, vertex-only PLY Gaussian Splat whose vertices are already in the scan's ARKit world frame in metres (maximum 80 MB)."}}}}}},"responses":{"200":{"description":"Exact scan-id replay; no duplicate revision was created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoomScanUploadResult"}}}},"201":{"description":"Scan created and made the active revision for its room","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoomScanUploadResult"}}}},"404":{"description":"Room resource not found"},"409":{"description":"Scan id belongs to another room"},"411":{"description":"Content-Length is required before buffering the multipart upload"},"413":{"description":"Combined upload exceeds the configured room-scan limit"},"415":{"description":"A keyframe or photorealistic derivative has an unsafe MIME type/extension pair"},"422":{"description":"Invalid scene, identifier, date, or non-place resource"}}}},"/room-scans/{scanId}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"scanId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Spatial rooms"],"summary":"Retrieve a web-viewer scene with positioned inventory","responses":{"200":{"description":"Normalized room scene, assets, and current placements attached to this revision","content":{"application/json":{"schema":{"type":"object","required":["scene"],"properties":{"scene":{"$ref":"#/components/schemas/RoomSceneManifest"}}}}}},"404":{"description":"Room scan not found"},"422":{"description":"Invalid room scan identifier"}}}},"/room-scans/{scanId}/layout":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"scanId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"patch":{"tags":["Spatial rooms"],"summary":"Position one room inside its floor layout","description":"Requires spatial management permission. The transform is a column-major world-from-model matrix in metres. Set it to null to restore automatic floor arrangement.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoomLayoutTransformPatch"}}}},"responses":{"200":{"description":"Room layout position updated"},"404":{"description":"Room scan not found"},"422":{"description":"Invalid room scan identifier or layout transform"}}}},"/room-scans/{scanId}/assets/{kind}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"scanId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"kind","in":"path","required":true,"schema":{"type":"string","enum":["world_map","model_usdz","structure_model","guide_image","textured_mesh","gaussian_splat"]}}],"get":{"tags":["Spatial rooms"],"summary":"Download an authenticated native room-scan asset","responses":{"200":{"description":"Binary asset returned as an attachment"},"404":{"description":"Scan asset or stored bytes not found"},"422":{"description":"Invalid room scan identifier"}}},"put":{"tags":["Spatial rooms"],"summary":"Attach or replace a photorealistic room derivative","description":"Accepts raw GLB bytes for textured_mesh or raw bounded PLY bytes for gaussian_splat. Vertices must already use the scan's shared ARKit world frame (metres, right-handed, Y-up); no alignment transform is inferred. The web client renders PLY as a bounded point-splat preview; textured GLB is the full photorealistic path. This mutable enrichment does not change the idempotent identity of the original room capture. Content-Length is required before the server buffers the body.","requestBody":{"required":true,"content":{"model/gltf-binary":{"schema":{"type":"string","format":"binary","maxLength":80000000}},"application/octet-stream":{"schema":{"type":"string","format":"binary","maxLength":80000000}}}},"responses":{"200":{"description":"Existing derivative replaced"},"201":{"description":"Derivative attached"},"404":{"description":"Room scan or mutable asset kind not found"},"411":{"description":"Content-Length is required"},"413":{"description":"Asset exceeds its 80 MB limit"},"415":{"description":"Content-Type does not match the asset kind"},"422":{"description":"Invalid identifier or malformed GLB/PLY data"}}}},"/room-scans/{scanId}/keyframes/{keyframeId}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"scanId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"keyframeId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Spatial rooms"],"summary":"Download an authenticated RGB localization keyframe","responses":{"200":{"description":"Inline JPEG keyframe","content":{"image/jpeg":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"Keyframe or stored bytes not found"},"422":{"description":"Invalid room scan or keyframe identifier"}}}},"/room-scans/{scanId}/placements/{resourceId}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"scanId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"resourceId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"put":{"tags":["Spatial rooms"],"summary":"Create or replace an item's current indoor 3D placement","description":"The scan must still be the active revision. Coordinates use its ARKit world frame in metres.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpatialPlacementInput"}}}},"responses":{"200":{"description":"Placement saved"},"404":{"description":"Room scan or inventory item not found"},"409":{"description":"Room scan was superseded and the item must be relocalized"},"422":{"description":"Invalid identifier or placement"}}},"delete":{"tags":["Spatial rooms"],"summary":"Remove an item's placement from this scan","responses":{"204":{"description":"Placement removed"},"404":{"description":"Placement not found"},"422":{"description":"Invalid identifier"}}}},"/auth/login":{"post":{"tags":["Authentication"],"summary":"Sign in a native client with a local account","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email","maxLength":320},"password":{"type":"string","format":"password","minLength":1,"maxLength":72},"deviceName":{"type":"string","minLength":1,"maxLength":80,"default":"iOS"},"organizationId":{"type":"string","format":"uuid","description":"Optional membership to select when signing in. The first membership is used when omitted."}}}}}},"responses":{"201":{"description":"Signed in and issued a revocable user-bound bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NativeLoginResponse"}}}},"400":{"description":"Invalid login request"},"401":{"description":"Email or password is incorrect"},"429":{"description":"Too many login attempts","headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}}}}},"/auth/logout":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["Authentication"],"summary":"Revoke the current bearer token","responses":{"204":{"description":"Token revoked"},"401":{"description":"Missing or invalid bearer token"}}}},"/auth/capabilities":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Authentication"],"summary":"Inspect the authenticated token's available scopes","responses":{"200":{"description":"Token identity and capabilities","content":{"application/json":{"schema":{"type":"object","required":["name","principal","scopes","role","roleName","permissions","organization","organizations"],"properties":{"name":{"type":"string"},"principal":{"type":"string","description":"Opaque organization-scoped principal identifier for binding durable client state."},"scopes":{"type":"array","items":{"type":"string","enum":["read","write","ai"]}},"role":{"type":["string","null"],"pattern":"^[a-z][a-z0-9_-]{0,63}$","description":"Stable role key for user-bound identities; null for standalone API tokens."},"roleName":{"type":["string","null"],"description":"Human-readable role name for user-bound identities; null for standalone API tokens."},"permissions":{"type":"array","description":"Granular workspace-wide permissions available through this token.","items":{"$ref":"#/components/schemas/AppPermission"}},"organization":{"$ref":"#/components/schemas/OrganizationMembership"},"organizations":{"type":"array","items":{"$ref":"#/components/schemas/OrganizationMembership"}}}}}}},"401":{"description":"Missing or invalid token"}}}},"/organizations":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Organizations"],"summary":"List organizations available to the current identity","responses":{"200":{"description":"Memberships and the organization active for this request","content":{"application/json":{"schema":{"type":"object","required":["organizations","activeOrganizationId"],"properties":{"organizations":{"type":"array","items":{"$ref":"#/components/schemas/OrganizationMembership"}},"activeOrganizationId":{"type":"string","format":"uuid"}}}}}},"401":{"description":"Missing or invalid authentication"}}},"post":{"tags":["Organizations"],"summary":"Create an organization for the current browser user","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":160},"slug":{"type":"string","minLength":1,"maxLength":48,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Optional short Webapp URL slug; generated from the name when omitted."}}}}}},"responses":{"201":{"description":"Organization created with the current user as admin","content":{"application/json":{"schema":{"type":"object","required":["organization"],"properties":{"organization":{"$ref":"#/components/schemas/OrganizationMembership"}}}}}},"403":{"description":"A browser session is required, and regular-user organization creation must be enabled unless the user is a superadmin"},"409":{"description":"Requested organization slug is already in use"},"422":{"description":"Invalid organization name or slug"}}}},"/organizations/select":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["Organizations"],"summary":"Select one of the current user's organizations","description":"Browser sessions persist the choice in an HTTP-only cookie. Native clients should send X-Organization-ID on subsequent requests.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["organizationId"],"properties":{"organizationId":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Selected organization","content":{"application/json":{"schema":{"type":"object","required":["organization"],"properties":{"organization":{"$ref":"#/components/schemas/OrganizationMembership"}}}}}},"404":{"description":"Organization is not available to this identity"}}}},"/organizations/{id}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"patch":{"tags":["Organizations"],"summary":"Update an organization's settings","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"name":{"type":"string","minLength":1,"maxLength":160},"slug":{"type":"string","minLength":1,"maxLength":48,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"allowNegativeStock":{"type":"boolean","description":"Allow bulk stock balances to fall below zero."}}}}}},"responses":{"200":{"description":"Updated organization","content":{"application/json":{"schema":{"type":"object","required":["organization"],"properties":{"organization":{"$ref":"#/components/schemas/OrganizationMembership"}}}}}},"403":{"description":"Browser user lacks organization administration permission"},"404":{"description":"Organization not found or not available to this user"},"409":{"description":"Requested organization slug is already in use"},"422":{"description":"Invalid organization name or slug"}}}},"/admin/organizations":{"get":{"tags":["Organizations"],"summary":"List every organization in the deployment","description":"Requires a browser session whose email is configured in `SUPERADMIN_EMAILS`.","security":[{"superadminSession":[]}],"responses":{"200":{"description":"Every organization in the deployment","content":{"application/json":{"schema":{"type":"object","required":["organizations"],"properties":{"organizations":{"type":"array","items":{"$ref":"#/components/schemas/OrganizationSummary"}}}}}}},"401":{"description":"An authenticated browser session is required"},"403":{"description":"The browser user is not a configured superadmin"}}},"post":{"tags":["Organizations"],"summary":"Create an organization as a deployment superadmin","description":"Creates an administrator membership for the superadmin who creates the organization.","security":[{"superadminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":160},"slug":{"type":"string","minLength":1,"maxLength":48,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"}}}}}},"responses":{"201":{"description":"Organization created","content":{"application/json":{"schema":{"type":"object","required":["organization"],"properties":{"organization":{"$ref":"#/components/schemas/OrganizationSummary"}}}}}},"401":{"description":"An authenticated browser session is required"},"403":{"description":"The browser user is not a configured superadmin"},"409":{"description":"Requested organization slug is already in use"},"422":{"description":"Invalid organization name or slug"}}}},"/admin/organizations/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"patch":{"tags":["Organizations"],"summary":"Update any organization as a deployment superadmin","security":[{"superadminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"name":{"type":"string","minLength":1,"maxLength":160},"slug":{"type":"string","minLength":1,"maxLength":48,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"allowNegativeStock":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Organization updated","content":{"application/json":{"schema":{"type":"object","required":["organization"],"properties":{"organization":{"$ref":"#/components/schemas/OrganizationSummary"}}}}}},"401":{"description":"An authenticated browser session is required"},"403":{"description":"The browser user is not a configured superadmin"},"404":{"description":"Organization not found"},"409":{"description":"Requested organization slug is already in use"},"422":{"description":"Invalid organization name or slug"}}}},"/api/access/roles":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"servers":[{"url":"/"}],"get":{"tags":["Access control"],"summary":"List roles, inventory access rules, and permission metadata","description":"Requires an authenticated browser session with the roles.manage permission. Rules grant additional item-specific permissions when every condition matches.","security":[{"adminSession":[]}],"responses":{"200":{"description":"Roles, rules, and metadata used to administer granular access","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["roles","rules","permissionGroups","resourceRulePermissions"],"properties":{"roles":{"type":"array","items":{"$ref":"#/components/schemas/AccessRole"}},"rules":{"type":"array","items":{"$ref":"#/components/schemas/InventoryAccessRule"}},"permissionGroups":{"type":"array","items":{"$ref":"#/components/schemas/PermissionGroup"}},"resourceRulePermissions":{"type":"array","items":{"$ref":"#/components/schemas/InventoryRulePermission"}}}}}}},"401":{"description":"Missing or invalid authenticated session"},"403":{"description":"A browser session with the roles.manage permission is required"}}},"post":{"tags":["Access control"],"summary":"Create an access role","description":"Requires an authenticated browser session with the roles.manage permission. Role keys are stable identifiers used by users and conditional rules.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessRoleInput"}}}},"responses":{"201":{"description":"Role created","content":{"application/json":{"schema":{"type":"object","required":["role"],"properties":{"role":{"$ref":"#/components/schemas/AccessRole"}}}}}},"400":{"description":"Request body is not valid JSON"},"401":{"description":"Missing or invalid authenticated session"},"403":{"description":"A browser session with the roles.manage permission is required"},"409":{"description":"A role with the requested key already exists"},"422":{"description":"Invalid role"}}}},"/api/access/roles/{key}":{"servers":[{"url":"/"}],"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"key","in":"path","required":true,"description":"Stable role key.","schema":{"$ref":"#/components/schemas/AccessRoleKey"}}],"patch":{"tags":["Access control"],"summary":"Update an access role","description":"Requires an authenticated browser session with the roles.manage permission. Changing permissions revokes user-bound API tokens for members of this role. The built-in Admin role must retain every permission.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessRolePatch"}}}},"responses":{"200":{"description":"Role updated","content":{"application/json":{"schema":{"type":"object","required":["role"],"properties":{"role":{"$ref":"#/components/schemas/AccessRole"}}}}}},"400":{"description":"Request body is not valid JSON"},"401":{"description":"Missing or invalid authenticated session"},"403":{"description":"A browser session with the roles.manage permission is required"},"404":{"description":"Role not found"},"409":{"description":"The built-in Admin role would lose one or more permissions"},"422":{"description":"Invalid or empty role update"}}},"delete":{"tags":["Access control"],"summary":"Delete an access role","description":"Requires an authenticated browser session with the roles.manage permission. Built-in roles and roles assigned to users cannot be deleted; deleting a role also deletes its conditional inventory rules.","security":[{"adminSession":[]}],"responses":{"204":{"description":"Role and its conditional inventory rules deleted"},"401":{"description":"Missing or invalid authenticated session"},"403":{"description":"A browser session with the roles.manage permission is required"},"404":{"description":"Role not found"},"409":{"description":"Built-in role or role still assigned to one or more users"}}}},"/api/access/rules":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"servers":[{"url":"/"}],"post":{"tags":["Access control"],"summary":"Create a conditional inventory access rule","description":"Requires an authenticated browser session with the roles.manage permission. The rule grants its permissions to members of the selected role only for inventory items that match every condition.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryAccessRuleInput"}}}},"responses":{"201":{"description":"Inventory access rule created","content":{"application/json":{"schema":{"type":"object","required":["rule"],"properties":{"rule":{"$ref":"#/components/schemas/InventoryAccessRule"}}}}}},"400":{"description":"Request body is not valid JSON"},"401":{"description":"Missing or invalid authenticated session"},"403":{"description":"A browser session with the roles.manage permission is required"},"422":{"description":"Invalid rule or selected role does not exist"}}}},"/api/access/rules/{id}":{"servers":[{"url":"/"}],"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"id","in":"path","required":true,"description":"Inventory access rule identifier.","schema":{"type":"string","format":"uuid"}}],"patch":{"tags":["Access control"],"summary":"Update a conditional inventory access rule","description":"Requires an authenticated browser session with the roles.manage permission. Changing a rule revokes user-bound API tokens for its previous and current roles.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryAccessRulePatch"}}}},"responses":{"200":{"description":"Inventory access rule updated","content":{"application/json":{"schema":{"type":"object","required":["rule"],"properties":{"rule":{"$ref":"#/components/schemas/InventoryAccessRule"}}}}}},"400":{"description":"Invalid rule id or request body is not valid JSON"},"401":{"description":"Missing or invalid authenticated session"},"403":{"description":"A browser session with the roles.manage permission is required"},"404":{"description":"Inventory access rule not found"},"422":{"description":"Invalid or empty inventory access rule update"}}},"delete":{"tags":["Access control"],"summary":"Delete a conditional inventory access rule","description":"Requires an authenticated browser session with the roles.manage permission. Deleting a rule revokes user-bound API tokens for its role.","security":[{"adminSession":[]}],"responses":{"204":{"description":"Inventory access rule deleted"},"400":{"description":"Invalid inventory access rule id"},"401":{"description":"Missing or invalid authenticated session"},"403":{"description":"A browser session with the roles.manage permission is required"},"404":{"description":"Inventory access rule not found"}}}},"/custom-fields":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Custom fields"],"summary":"List custom-field definitions","description":"Requires the read scope. Active definitions are returned by default, ordered by entity, position, and label.","parameters":[{"name":"entityType","in":"query","description":"Limit definitions to inventory items or serialized stock units.","schema":{"type":"string","enum":["inventory","stock_unit"]}},{"name":"includeArchived","in":"query","description":"Include soft-deleted definitions.","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Matching custom-field definitions","content":{"application/json":{"schema":{"type":"object","required":["definitions"],"properties":{"definitions":{"type":"array","items":{"$ref":"#/components/schemas/CustomFieldDefinition"}}}}}}},"401":{"description":"Missing or invalid session or bearer token"},"403":{"description":"Authenticated identity does not have the read scope"},"422":{"description":"Invalid query parameters"}}},"post":{"tags":["Custom fields"],"summary":"Create a custom-field definition","description":"Requires an authenticated administrator session. Bearer tokens cannot create definitions. The key is generated from the label when omitted.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomFieldDefinitionInput"}}}},"responses":{"201":{"description":"Custom-field definition created","content":{"application/json":{"schema":{"type":"object","required":["definition"],"properties":{"definition":{"$ref":"#/components/schemas/CustomFieldDefinition"}}}}}},"401":{"description":"Missing or invalid administrator session"},"403":{"description":"A browser session with the admin role is required"},"409":{"description":"The generated or supplied key already exists in this entity scope"},"422":{"description":"Invalid custom-field definition"}}}},"/custom-fields/{id}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/CustomFieldId"}],"get":{"tags":["Custom fields"],"summary":"Retrieve a custom-field definition","description":"Requires the read scope and can return either an active or archived definition.","responses":{"200":{"description":"Custom-field definition","content":{"application/json":{"schema":{"type":"object","required":["definition"],"properties":{"definition":{"$ref":"#/components/schemas/CustomFieldDefinition"}}}}}},"401":{"description":"Missing or invalid session or bearer token"},"403":{"description":"Authenticated identity does not have the read scope"},"404":{"description":"Custom-field definition not found"},"422":{"description":"Invalid definition id"}}},"patch":{"tags":["Custom fields"],"summary":"Update a custom-field definition","description":"Requires an authenticated administrator session. Entity scope and key are immutable. Send the last observed revision to prevent overwriting a concurrent edit; a successful edit increments it.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomFieldDefinitionPatch"}}}},"responses":{"200":{"description":"Custom-field definition updated","content":{"application/json":{"schema":{"type":"object","required":["definition"],"properties":{"definition":{"$ref":"#/components/schemas/CustomFieldDefinition"}}}}}},"401":{"description":"Missing or invalid administrator session"},"403":{"description":"A browser session with the admin role is required"},"404":{"description":"Custom-field definition not found"},"409":{"description":"Revision conflict; reload the definition before applying the update again","content":{"application/json":{"schema":{"type":"object","required":["error","details"],"properties":{"error":{"type":"string"},"details":{"type":"object","required":["currentRevision"],"properties":{"currentRevision":{"type":"integer","minimum":1}}}}}}}},"422":{"description":"Invalid or empty custom-field update"}}},"delete":{"tags":["Custom fields"],"summary":"Archive a custom-field definition","description":"Requires an authenticated administrator session. Soft deletion increments the definition revision and preserves existing values stored under its key.","security":[{"adminSession":[]}],"responses":{"204":{"description":"Definition archived"},"401":{"description":"Missing or invalid administrator session"},"403":{"description":"A browser session with the admin role is required"},"404":{"description":"Custom-field definition not found"},"422":{"description":"Invalid definition id"}}}},"/custom-fields/{id}/options":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/CustomFieldId"}],"get":{"tags":["Custom fields"],"summary":"Search or resolve reference-field choices","description":"Requires the read scope. The definition must be an active reference field. Search results enforce its target type, category, and status filters; explicitly selected IDs are also resolved so previously saved values remain readable after filter changes.","parameters":[{"name":"q","in":"query","description":"Case-insensitive name, SKU, stock-unit code, or UUID search.","schema":{"type":"string","maxLength":120}},{"name":"selected","in":"query","description":"A saved target ID to resolve. Repeat for multiple IDs.","schema":{"type":"array","maxItems":100,"items":{"type":"string","format":"uuid"}},"style":"form","explode":true},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":25}}],"responses":{"200":{"description":"Matching and explicitly selected reference options","content":{"application/json":{"schema":{"type":"object","required":["options"],"properties":{"options":{"type":"array","items":{"$ref":"#/components/schemas/CustomFieldReferenceOption"}}}}}}},"401":{"description":"Missing or invalid session or bearer token"},"403":{"description":"Authenticated identity does not have the read scope"},"404":{"description":"Custom-field definition not found"},"422":{"description":"Invalid query or the definition is not a reference field"}}}},"/label-setups":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Label setups"],"summary":"List reusable label setups","description":"Requires labels.read (read scope for standalone tokens). Setups are ordered by name and contain the complete print layout.","responses":{"200":{"description":"Label setups","content":{"application/json":{"schema":{"type":"object","required":["labelSetups"],"properties":{"labelSetups":{"type":"array","items":{"$ref":"#/components/schemas/LabelSetup"}}}}}}},"401":{"description":"Missing or invalid session or bearer token"},"403":{"description":"Authenticated identity does not have the read scope"}}},"post":{"tags":["Label setups"],"summary":"Create a label setup","description":"Requires labels.manage (write scope for standalone tokens). Setup names are unique case-insensitively.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LabelSetupInput"}}}},"responses":{"201":{"description":"Label setup created","content":{"application/json":{"schema":{"type":"object","required":["labelSetup"],"properties":{"labelSetup":{"$ref":"#/components/schemas/LabelSetup"}}}}}},"400":{"description":"Request body is not valid JSON"},"401":{"description":"Missing or invalid session or bearer token"},"403":{"description":"Authenticated identity does not have the write scope"},"409":{"description":"A label setup with that name already exists"},"422":{"description":"Invalid label setup"}}}},"/label-setups/{id}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"id","in":"path","required":true,"description":"Label setup identifier.","schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Label setups"],"summary":"Retrieve a label setup","description":"Requires labels.read (read scope for standalone tokens).","responses":{"200":{"description":"Label setup","content":{"application/json":{"schema":{"type":"object","required":["labelSetup"],"properties":{"labelSetup":{"$ref":"#/components/schemas/LabelSetup"}}}}}},"401":{"description":"Missing or invalid session or bearer token"},"403":{"description":"Authenticated identity does not have the read scope"},"404":{"description":"Label setup not found"},"422":{"description":"Invalid label setup id"}}},"patch":{"tags":["Label setups"],"summary":"Update a label setup using its current revision","description":"Requires labels.manage (write scope for standalone tokens). Send the last observed revision to prevent overwriting a concurrent edit; a successful update increments it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LabelSetupPatch"}}}},"responses":{"200":{"description":"Label setup updated","content":{"application/json":{"schema":{"type":"object","required":["labelSetup"],"properties":{"labelSetup":{"$ref":"#/components/schemas/LabelSetup"}}}}}},"400":{"description":"Request body is not valid JSON"},"401":{"description":"Missing or invalid session or bearer token"},"403":{"description":"Authenticated identity does not have the write scope"},"404":{"description":"Label setup not found"},"409":{"description":"Revision conflict or case-insensitive setup-name conflict"},"422":{"description":"Invalid or empty label setup update"}}},"delete":{"tags":["Label setups"],"summary":"Delete a label setup","description":"Requires labels.manage (write scope for standalone tokens) and the last observed revision so a stale editor cannot delete newer work.","parameters":[{"name":"revision","in":"query","required":true,"description":"Current setup revision, preventing deletion from a stale editor.","schema":{"type":"integer","minimum":1}}],"responses":{"204":{"description":"Label setup deleted"},"401":{"description":"Missing or invalid session or bearer token"},"403":{"description":"Authenticated identity does not have the write scope"},"404":{"description":"Label setup not found"},"409":{"description":"Setup revision changed; reload before deleting"},"422":{"description":"Invalid label setup id or revision"}}}},"/inventory-types":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Inventory structure"],"summary":"List configured inventory types","description":"Requires the read scope. Active definitions are returned in configured display order. Administrators may include archived definitions.","parameters":[{"name":"includeArchived","in":"query","description":"Include archived definitions when authenticated as an administrator.","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Inventory type definitions","content":{"application/json":{"schema":{"type":"object","required":["types"],"properties":{"types":{"type":"array","items":{"$ref":"#/components/schemas/InventoryTypeDefinition"}}}}}}},"401":{"description":"Missing or invalid session or bearer token"},"403":{"description":"Authenticated identity does not have the read scope"}}},"post":{"tags":["Inventory structure"],"summary":"Create an inventory type","description":"Requires an authenticated administrator browser session. Type keys are stable identifiers used by inventory records.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryTypeInput"}}}},"responses":{"201":{"description":"Inventory type created","content":{"application/json":{"schema":{"type":"object","required":["type"],"properties":{"type":{"$ref":"#/components/schemas/InventoryTypeDefinition"}}}}}},"401":{"description":"Missing or invalid administrator session"},"403":{"description":"A browser session with the admin role is required"},"409":{"description":"The type key already exists"},"422":{"description":"Invalid inventory type definition"}}}},"/inventory-types/{key}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"key","in":"path","required":true,"schema":{"$ref":"#/components/schemas/InventoryTypeKey"}}],"patch":{"tags":["Inventory structure"],"summary":"Update or restore an inventory type","description":"Requires an authenticated administrator browser session. The stable type key is immutable.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryTypePatch"}}}},"responses":{"200":{"description":"Inventory type updated","content":{"application/json":{"schema":{"type":"object","required":["type"],"properties":{"type":{"$ref":"#/components/schemas/InventoryTypeDefinition"}}}}}},"401":{"description":"Missing or invalid administrator session"},"403":{"description":"A browser session with the admin role is required"},"404":{"description":"Inventory type not found"},"409":{"description":"The fallback type cannot be archived"},"422":{"description":"Invalid or empty inventory type update"}}},"delete":{"tags":["Inventory structure"],"summary":"Archive an inventory type","description":"Requires an authenticated administrator browser session. Existing inventory records retain their type; the fallback type cannot be archived.","security":[{"adminSession":[]}],"responses":{"200":{"description":"Inventory type archived","content":{"application/json":{"schema":{"type":"object","required":["type"],"properties":{"type":{"$ref":"#/components/schemas/InventoryTypeDefinition"}}}}}},"401":{"description":"Missing or invalid administrator session"},"403":{"description":"A browser session with the admin role is required"},"404":{"description":"Inventory type not found"},"409":{"description":"The fallback type cannot be archived"},"422":{"description":"Invalid type key"}}}},"/relation-types":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Inventory structure"],"summary":"List configured relationship types","description":"Requires the read scope. Administrators may include archived definitions.","parameters":[{"name":"includeArchived","in":"query","description":"Include archived definitions when authenticated as an administrator.","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Relationship type definitions","content":{"application/json":{"schema":{"type":"object","required":["relationTypes"],"properties":{"relationTypes":{"type":"array","items":{"$ref":"#/components/schemas/RelationTypeDefinition"}}}}}}},"401":{"description":"Missing or invalid session or bearer token"},"403":{"description":"Authenticated identity does not have the read scope"}}},"post":{"tags":["Inventory structure"],"summary":"Create a relationship type","description":"Requires an authenticated administrator browser session.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RelationTypeInput"}}}},"responses":{"201":{"description":"Relationship type created","content":{"application/json":{"schema":{"type":"object","required":["relationType"],"properties":{"relationType":{"$ref":"#/components/schemas/RelationTypeDefinition"}}}}}},"401":{"description":"Missing or invalid administrator session"},"403":{"description":"A browser session with the admin role is required"},"409":{"description":"The relationship type key already exists"},"422":{"description":"Invalid relationship type definition"}}}},"/relation-types/{key}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"key","in":"path","required":true,"schema":{"$ref":"#/components/schemas/RelationTypeKey"}}],"patch":{"tags":["Inventory structure"],"summary":"Update, archive, or restore a relationship type","description":"Requires an authenticated administrator browser session. Built-in relationship types cannot be archived.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RelationTypePatch"}}}},"responses":{"200":{"description":"Relationship type updated","content":{"application/json":{"schema":{"type":"object","required":["relationType"],"properties":{"relationType":{"$ref":"#/components/schemas/RelationTypeDefinition"}}}}}},"401":{"description":"Missing or invalid administrator session"},"403":{"description":"A browser session with the admin role is required"},"404":{"description":"Relationship type not found"},"409":{"description":"A built-in relationship type cannot be archived"},"422":{"description":"Invalid or empty relationship type update"}}}},"/ai/recognize":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["AI"],"summary":"Match one photographed object to existing inventory items","description":"Requires direct inventory.read permission and the ai scope/ai.use permission. The uploaded image is transient and is not attached to an item. The server describes the dominant object, shortlists a bounded inventory catalog, and visually reranks up to five advisory matches. Clients must let the user review the result instead of treating it as an exact identifier.","parameters":[{"$ref":"#/components/parameters/RequiredIdempotencyKey"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","additionalProperties":false,"required":["image"],"properties":{"image":{"type":"string","format":"binary","description":"Exactly one JPEG, PNG, WebP, AVIF, HEIC, or HEIF image."}}}}}},"responses":{"200":{"description":"Ranked, advisory inventory matches; matches may be empty.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryRecognitionResult"}}}},"202":{"description":"An identical idempotent request is still processing; retry with the same image and key after Retry-After."},"400":{"description":"Malformed idempotency key or multipart request"},"403":{"description":"Missing AI or direct inventory-read permission"},"409":{"description":"Idempotency-Key was reused for another identity or image"},"413":{"description":"Image exceeds the configured upload limit"},"415":{"description":"Request is not multipart or the image type is unsupported"},"422":{"description":"Missing, duplicate, empty, or unreadable image"},"429":{"description":"AI recognition is disabled or the request limit was reached"},"502":{"description":"Vision provider or structured-output error"},"503":{"description":"Inventory catalog, retry protection, or shared rate limiter unavailable"}}}},"/ai/count":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["AI"],"summary":"Count matching physical items in one transient image","description":"Requires the ai scope. A selectable server-side Replicate model analyzes the image; text-aware models use itemHint as their query. The result is advisory and does not mutate stock. Supply a stable Idempotency-Key when retrying the same upload so a lost start response cannot create another paid prediction.","parameters":[{"$ref":"#/components/parameters/RequiredIdempotencyKey"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["image"],"properties":{"image":{"type":"string","format":"binary","description":"One JPEG, PNG, WebP, AVIF, HEIC, or HEIF image."},"itemHint":{"type":"string","minLength":1,"maxLength":240,"description":"Optional description of the object that should be counted."},"itemId":{"type":"string","format":"uuid","description":"Optional inventory item identifier used to scope idempotent retries."},"modelId":{"type":"string","enum":["grounding-dino","yolo-world","sam-2","sam-3"],"description":"Optional counting model. The server default is used when omitted."}}}}}},"responses":{"200":{"description":"Advisory visual count","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryCount"}}}},"202":{"description":"The Replicate prediction was created and is warming or processing; poll it with the signed jobToken.","headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryCountJob"}}}},"400":{"description":"Missing or malformed Idempotency-Key, or malformed multipart request"},"409":{"description":"The same idempotent start is still being persisted, or Replicate may have accepted it without returning a job ID. Retry only with the same image and Idempotency-Key after Retry-After; the server keeps the attempt reserved long enough to prevent an overlapping paid prediction.","headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"413":{"description":"Image exceeds the configured upload limit"},"415":{"description":"Request is not multipart or the image type is unsupported"},"422":{"description":"Invalid image, item hint, model, or provider detection limit"},"429":{"description":"AI request limit reached","headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"502":{"description":"Replicate prediction creation or result-validation error"},"503":{"description":"Replicate configuration, billing, authentication, capacity, or shared rate limiter unavailable"},"504":{"description":"Replicate prediction exceeded the configured deadline"}}}},"/ai/count/jobs":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["AI"],"summary":"Poll one signed Replicate count job","description":"Requires the ai scope and the same authenticated identity that created the job. Polling checks the existing prediction and does not start or bill another prediction.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["jobToken"],"properties":{"jobToken":{"type":"string","minLength":1,"maxLength":4096}}}}}},"responses":{"200":{"description":"Completed advisory visual count","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryCount"}}}},"202":{"description":"Prediction is still processing","headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryCountJob"}}}},"401":{"description":"Missing or invalid identity"},"403":{"description":"Identity is missing the ai scope"},"422":{"description":"Invalid, expired, or wrong-identity job token"},"502":{"description":"Replicate polling or result-validation error. terminal=true means the prediction itself has finished and a new count may be started; terminal=false means the same signed job should be resumed.","content":{"application/json":{"schema":{"type":"object","required":["error","terminal"],"properties":{"error":{"type":"string"},"terminal":{"type":"boolean"}}}}}},"503":{"description":"Replicate authentication/configuration error, or a transient capacity/poll timeout marked with Retry-After"},"504":{"description":"Prediction exceeded its deadline"}}}},"/ai/count-models":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["AI"],"summary":"List Replicate counting models enabled for this deployment","description":"Requires the ai scope. The same catalog is consumed by the web app and iOS app.","responses":{"200":{"description":"Available counting models and the deployment default","content":{"application/json":{"schema":{"type":"object","required":["models","defaultModelId"],"properties":{"models":{"type":"array","items":{"$ref":"#/components/schemas/InventoryCountModel"}},"defaultModelId":{"type":"string","enum":["grounding-dino","yolo-world","sam-2","sam-3"]}}}}}},"401":{"description":"Missing or invalid token"},"403":{"description":"Token is missing the ai scope"}}}},"/ai/image-models":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["AI"],"summary":"List image-generation models enabled for this deployment","description":"Requires the ai scope. Only allowlisted models with configured provider credentials are returned.","responses":{"200":{"description":"Available image-generation models and the deployment default","content":{"application/json":{"schema":{"type":"object","required":["models","defaultModelId"],"properties":{"models":{"type":"array","items":{"$ref":"#/components/schemas/ImageGenerationModel"}},"defaultModelId":{"type":["string","null"]}}}}}},"401":{"description":"Missing or invalid token"},"403":{"description":"Token is missing the ai scope"}}}},"/languages":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Content translations"],"summary":"List active content languages","responses":{"200":{"description":"Canonical and target languages"}}},"post":{"tags":["Content translations"],"summary":"Add a content language","description":"Requires an administrator browser session. The first language becomes the canonical default.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["code","label"],"properties":{"code":{"type":"string","minLength":2,"maxLength":35,"examples":["de"]},"label":{"type":"string","minLength":1,"maxLength":120,"examples":["German"]},"isDefault":{"type":"boolean","default":false},"autoTranslate":{"type":"boolean","default":true},"instructions":{"type":"string","maxLength":5000},"position":{"type":"integer","minimum":0,"maximum":100000}}}}}},"responses":{"201":{"description":"Language added"},"409":{"description":"Duplicate code or unsafe default-language change"},"422":{"description":"Invalid language"}}}},"/languages/{code}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"code","in":"path","required":true,"schema":{"type":"string","maxLength":35}}],"patch":{"tags":["Content translations"],"summary":"Update a content language","description":"Requires an administrator browser session. The canonical default cannot change after translations exist.","responses":{"200":{"description":"Language updated"},"404":{"description":"Language not found"},"409":{"description":"Unsafe default-language change"}}},"delete":{"tags":["Content translations"],"summary":"Archive a target content language","description":"Requires an administrator browser session. Saved translations are retained.","responses":{"200":{"description":"Language archived"},"409":{"description":"The default language cannot be archived"}}}},"/translations/regenerate":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["Content translations","AI"],"summary":"Queue a durable translation backfill","description":"Requires an administrator browser session. All selected resource-locale jobs are persisted before the response; processing continues in the background.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"languageCodes":{"type":"array","maxItems":20,"items":{"type":"string","maxLength":35}},"force":{"type":"boolean","default":false}}}}}},"responses":{"200":{"description":"No target-language jobs were needed"},"202":{"description":"Durable translation jobs queued"}}}},"/contacts":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Contacts"],"summary":"List customers and suppliers","parameters":[{"name":"q","in":"query","schema":{"type":"string","maxLength":240}},{"name":"role","in":"query","schema":{"type":"string","enum":["customer","supplier"]}},{"name":"includeArchived","in":"query","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Contacts with linked inventory and movement counts","content":{"application/json":{"schema":{"type":"object","required":["contacts"],"properties":{"contacts":{"type":"array","items":{"$ref":"#/components/schemas/Contact"}}}}}}}}},"post":{"tags":["Contacts"],"summary":"Create a customer, supplier, or dual-role contact","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactInput"}}}},"responses":{"201":{"description":"Contact created","content":{"application/json":{"schema":{"type":"object","required":["contact"],"properties":{"contact":{"$ref":"#/components/schemas/Contact"}}}}}},"422":{"description":"Invalid contact or cross-organization inventory assignment"}}}},"/contacts/{id}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Contacts"],"summary":"Get one contact","responses":{"200":{"description":"Contact details","content":{"application/json":{"schema":{"type":"object","required":["contact"],"properties":{"contact":{"$ref":"#/components/schemas/Contact"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["Contacts"],"summary":"Update a contact and its inventory assignments","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactPatch"}}}},"responses":{"200":{"description":"Contact updated","content":{"application/json":{"schema":{"type":"object","required":["contact"],"properties":{"contact":{"$ref":"#/components/schemas/Contact"}}}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"description":"Invalid contact or cross-organization inventory assignment"}}},"delete":{"tags":["Contacts"],"summary":"Archive a contact","description":"Historical stock-movement references are retained.","responses":{"204":{"description":"Contact archived"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/contacts/{id}/comments":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Contacts"],"summary":"List a contact's comments","responses":{"200":{"description":"Chronological contact comment thread","content":{"application/json":{"schema":{"type":"object","required":["comments"],"properties":{"comments":{"type":"array","items":{"$ref":"#/components/schemas/ContactComment"}}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"tags":["Contacts"],"summary":"Add a comment to a contact","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentInput"}}}},"responses":{"201":{"description":"Comment created","content":{"application/json":{"schema":{"type":"object","required":["comment"],"properties":{"comment":{"$ref":"#/components/schemas/ContactComment"}}}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"description":"Invalid comment body"}}}},"/contacts/{id}/comments/{commentId}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"commentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"patch":{"tags":["Contacts"],"summary":"Edit an owned contact comment","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentInput"}}}},"responses":{"200":{"description":"Comment updated"},"403":{"description":"Comment belongs to another author"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Contacts"],"summary":"Delete an owned contact comment","responses":{"204":{"description":"Comment deleted"},"403":{"description":"Comment belongs to another author"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/resources":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Resources"],"summary":"List inventory items","parameters":[{"name":"q","in":"query","schema":{"type":"string"}},{"name":"type","in":"query","schema":{"$ref":"#/components/schemas/InventoryTypeKey"}},{"name":"status","in":"query","schema":{"type":"string"}},{"name":"page","in":"query","schema":{"type":"integer","minimum":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":500}},{"name":"language","in":"query","description":"Active BCP 47 content locale. Missing or stale fields fall back individually to canonical content.","schema":{"type":"string","maxLength":35}}],"responses":{"200":{"description":"Paginated inventory","content":{"application/json":{"schema":{"type":"object","properties":{"resources":{"type":"array","items":{"$ref":"#/components/schemas/Resource"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}}}},"post":{"tags":["Resources"],"summary":"Create an inventory item","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceInput"}}}},"responses":{"200":{"description":"Replayed the original creation response"},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"resource":{"$ref":"#/components/schemas/Resource"}}}}}},"409":{"description":"Idempotency key was used with a different request"}}}},"/resources/import":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["Data exchange"],"summary":"Import inventory items from UTF-8 CSV","description":"Creates up to 1,000 items from a raw CSV body of at most 5 MB. Rows are validated independently, existing items are never overwritten, and structured fields may contain JSON. The same Idempotency-Key and identical file can be retried safely.","parameters":[{"$ref":"#/components/parameters/RequiredIdempotencyKey"}],"requestBody":{"required":true,"content":{"text/csv":{"schema":{"type":"string","format":"binary","description":"UTF-8 CSV with a required name header. See CsvImportResponse for row-level outcomes."}},"application/csv":{"schema":{"type":"string","format":"binary"}},"application/vnd.ms-excel":{"schema":{"type":"string","format":"binary"}},"text/plain":{"schema":{"type":"string"}}}},"responses":{"200":{"description":"Every row replayed from an earlier identical import","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CsvImportResponse"}}}},"201":{"description":"Import completed without row errors and at least one row was created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CsvImportResponse"}}}},"207":{"description":"Import completed with one or more row-level errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CsvImportResponse"}}}},"400":{"description":"Missing or invalid Idempotency-Key, malformed CSV, or invalid UTF-8"},"413":{"description":"File exceeds 5 MB or contains more than 1,000 data rows"},"415":{"description":"Unsupported media type"},"422":{"description":"Missing rows or invalid CSV headers"}}}},"/resources/export":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Data exchange"],"summary":"Export the complete inventory as CSV, Excel, or PDF","description":"Returns up to 100,000 inventory records. CSV remains the default and is BOM-prefixed with potential spreadsheet formulas escaped. Excel includes formatted, filterable inventory and variant sheets; PDF is a compact printable report.","parameters":[{"in":"query","name":"format","schema":{"type":"string","enum":["csv","xlsx","pdf"],"default":"csv"},"description":"Download format. Omitting the parameter preserves the existing CSV response."},{"in":"query","name":"lang","schema":{"type":"string","enum":["en","de"],"default":"en"},"description":"Report language used for generated Excel and PDF labels."}],"responses":{"200":{"description":"Inventory export in the requested format","headers":{"Content-Disposition":{"schema":{"type":"string"},"description":"Dated inventory filename with an extension matching the requested format."}},"content":{"text/csv":{"schema":{"type":"string"}},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"type":"string","format":"binary"}},"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Unsupported export format"},"413":{"description":"The workspace contains more than 100,000 records"}}}},"/resources/batch":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"patch":{"tags":["Resources"],"summary":"Apply shared fields and additional tags to multiple inventory items atomically","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["ids"],"properties":{"ids":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string","format":"uuid"}},"changes":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/InventoryTypeKey"},"status":{"type":"string","enum":["available","in-use","maintenance","archived"]},"location":{"type":["string","null"],"maxLength":240},"priority":{"type":"integer","minimum":1,"maximum":5}}},"addTags":{"type":"array","maxItems":40,"items":{"type":"string","minLength":1,"maxLength":60}}}}}}},"responses":{"200":{"description":"Selected inventory items updated"},"404":{"description":"At least one selected inventory item no longer exists"},"422":{"description":"Invalid or empty batch update"}}}},"/resources/{id}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceReference"}],"get":{"tags":["Resources"],"summary":"Retrieve an inventory item","parameters":[{"name":"language","in":"query","description":"Enabled BCP 47 content language. Missing or stale translated fields fall back to canonical content.","schema":{"type":"string","maxLength":35,"examples":["de"]}}],"responses":{"200":{"description":"Inventory item","content":{"application/json":{"schema":{"type":"object","properties":{"resource":{"$ref":"#/components/schemas/Resource"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["Resources"],"summary":"Update an inventory item","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourcePatch"}}}},"responses":{"200":{"description":"Updated"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Resources"],"summary":"Delete an inventory item and its local media","responses":{"204":{"description":"Deleted"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Primary item still has linked first-class variants"}}}},"/resources/{id}/family":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"}],"get":{"tags":["Resources"],"summary":"Retrieve a first-class inventory variant family","description":"Resolves the primary item and its ordinary resource variants. Every returned member has independent stock, locations, serialization, relationships, and manufacturing history. The request fails rather than exposing a partially authorized family.","responses":{"200":{"description":"Variant family","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceFamily"}}}},"403":{"description":"One or more family members are outside the caller's inventory access rules"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"tags":["Resources"],"summary":"Create a first-class variant or connect an existing inventory item","description":"With identity fields, creates a zero-stock resource linked to this primary by a protected `variant_of` relationship. With `existingResourceId`, connects an existing standalone item without moving its stock, locations, serial units, relationships, assignments, or history. Existing catalog and BOM differences are retained as sparse overrides. Variant families cannot be nested.","requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ResourceFamilyVariantInput"},{"$ref":"#/components/schemas/ResourceFamilyExistingVariantInput"}]}}}},"responses":{"200":{"description":"Existing inventory item connected as a first-class variant","content":{"application/json":{"schema":{"type":"object","required":["variant"],"properties":{"variant":{"$ref":"#/components/schemas/ResourceFamilyMember"}}}}}},"201":{"description":"First-class variant created","content":{"application/json":{"schema":{"type":"object","required":["variant"],"properties":{"variant":{"$ref":"#/components/schemas/ResourceFamilyMember"}}}}}},"403":{"description":"Missing primary-item update access, candidate-item update access, or inventory create permission when creating"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Identifier conflict, archived item, option-managed family, existing membership, or nested family attempt"},"422":{"description":"Invalid variant identity"}}},"delete":{"tags":["Resources"],"summary":"Detach a first-class variant from its primary item","description":"Removes only the protected `variant_of` family link. The currently effective inherited bill of materials is materialized onto the same inventory resource first. Stock, locations, serial units, ordinary relationships, assignments, and manufacturing history stay attached to that resource.","responses":{"200":{"description":"Variant detached and its effective bill of materials materialized","content":{"application/json":{"schema":{"type":"object","required":["detached"],"properties":{"detached":{"$ref":"#/components/schemas/ResourceVariantDetachResult"}}}}}},"403":{"description":"Missing update access to the variant item"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Item is not a linked variant or its effective bill of materials cannot be preserved"},"422":{"description":"Invalid resource id"}}}},"/resources/{id}/options":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"}],"get":{"tags":["Resources","Manufacturing"],"summary":"Retrieve option groups and the current resource's selections","description":"The primary item represents the all-default combination. Generated combinations are ordinary first-class resource variants with independent operational data and sparse BOM overrides.","responses":{"200":{"description":"Option matrix, BOM slots, and current selection","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceOptions"}}}},"403":{"description":"The primary item is outside the caller's inventory access rules"},"404":{"$ref":"#/components/responses/NotFound"}}},"put":{"tags":["Resources","Manufacturing"],"summary":"Replace option-group definitions before variants are generated","description":"A group may map to one stable primary BOM slot. Its default component must equal the primary BOM component in that slot. Definitions lock after generation.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["groups"],"properties":{"groups":{"type":"array","maxItems":4,"items":{"$ref":"#/components/schemas/ResourceOptionGroupInput"}}}}}}},"responses":{"200":{"description":"Saved option definitions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceOptions"}}}},"409":{"description":"Definitions are locked, the item is a child variant, or the family already has manual variants"},"422":{"description":"Invalid group, value, component, BOM mapping, or matrix size"}}},"post":{"tags":["Resources","Manufacturing"],"summary":"Generate every non-default option combination","description":"Atomically creates the Cartesian product as protected first-class variants, copies catalog and stock settings, stores selections, and writes only BOM differences. Maximum 100 total combinations.","responses":{"201":{"description":"Option variants generated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceOptionGenerationResult"}}}},"403":{"description":"Missing inventory create or primary-item update access"},"409":{"description":"Variants already exist, generation already ran, or the primary is archived"},"422":{"description":"Invalid option matrix or circular effective BOM"}}}},"/resources/{id}/translations":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"}],"get":{"tags":["Content translations"],"summary":"Inspect field-level translation freshness","responses":{"200":{"description":"Per-language current, stale, and missing fields"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"tags":["Content translations","AI"],"summary":"Queue stale fields for background translation","description":"Requires ai scope. Omit languageCodes to queue every active target language. Jobs are coalesced per resource and locale and survive restarts.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"languageCodes":{"type":"array","maxItems":20,"items":{"type":"string","maxLength":35}},"force":{"type":"boolean","default":false}}}}}},"responses":{"200":{"description":"No target-language jobs were needed"},"202":{"description":"Durable translation jobs queued"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"description":"Invalid or inactive target language"}}}},"/resources/{id}/translations/{languageCode}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"},{"name":"languageCode","in":"path","required":true,"schema":{"type":"string","maxLength":35}}],"patch":{"tags":["Content translations"],"summary":"Edit, approve, or unlock translated fields","description":"Requires write scope and the current locale-document revision. Human edits are protected from AI overwrite; accepting a suggestion keeps the field human-managed.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["expectedRevision","operations"],"properties":{"expectedRevision":{"type":"integer","minimum":0},"operations":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"object","required":["action","fieldKey"],"properties":{"action":{"type":"string","enum":["set","accept_suggestion","use_ai"]},"fieldKey":{"type":"string","maxLength":96},"translatedText":{"type":"string","maxLength":100000}}}}}}}}},"responses":{"200":{"description":"Translation document updated"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Translation revision changed or suggestion became stale"},"422":{"description":"Invalid language, field, or operation"}}}},"/resources/{id}/relations":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"}],"get":{"tags":["Inventory structure"],"summary":"List relationships touching an inventory item","description":"Returns incoming and outgoing directed relationships with both endpoint summaries and the relationship definition.","responses":{"200":{"description":"Resource relationships","content":{"application/json":{"schema":{"type":"object","required":["relations"],"properties":{"relations":{"type":"array","items":{"$ref":"#/components/schemas/ResourceRelation"}}}}}}},"422":{"description":"Invalid resource id"}}},"post":{"tags":["Inventory structure"],"summary":"Create or pin a manual relationship","description":"One endpoint must match the resource id in the path. Containment relationships reject invalid parents, self-reference, and direct or indirect cycles. Creating an existing spatial relationship converts it to a manual relationship.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceRelationInput"}}}},"responses":{"201":{"description":"Manual relationship created or pinned","content":{"application/json":{"schema":{"type":"object","required":["relation"],"properties":{"relation":{"$ref":"#/components/schemas/ResourceRelationRecord"}}}}}},"404":{"description":"One of the inventory items or the relationship type was not found"},"409":{"description":"The containment relationship would create a cycle"},"422":{"description":"Invalid relationship or a relationship type that disallows manual use"}}}},"/relations/{relationId}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"relationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"delete":{"tags":["Inventory structure"],"summary":"Remove a manual resource relationship","description":"Spatially derived relationships cannot be deleted directly. After deletion, spatial containment is recalculated.","parameters":[{"name":"resourceId","in":"query","required":true,"description":"One endpoint of the relationship, used to scope the deletion.","schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Manual relationship removed"},"404":{"description":"Manual relationship not found"},"422":{"description":"Invalid relationship or resource id"}}}},"/resources/lookup":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Resources"],"summary":"Resolve a scanned QR or barcode to an inventory item","description":"Accepts an item UUID, Inventory resource URL, item or variant SKU/barcode, or serial number. Variants are ordinary resources and return their own resource ID.","parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":2048}}],"responses":{"200":{"description":"Matching inventory item","content":{"application/json":{"schema":{"type":"object","required":["resource","matchedBy"],"properties":{"resource":{"$ref":"#/components/schemas/Resource"},"matchedBy":{"type":"string","enum":["id","sku","barcode","serialNumber"]}}}}}},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Serial number is ambiguous"}}}},"/stock":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Stock"],"summary":"Retrieve stock health and replenishment forecasts","responses":{"200":{"description":"Stock overview","content":{"application/json":{"schema":{"type":"object","required":["summary","items"],"properties":{"summary":{"type":"object","properties":{"trackedItems":{"type":"integer"},"totalQuantity":{"type":"integer"},"totalOnOrder":{"type":"integer"},"incomingItems":{"type":"integer"},"lowStockItems":{"type":"integer"},"outOfStockItems":{"type":"integer"},"predictedStockouts":{"type":"integer"},"reorderItems":{"type":"integer"}}},"items":{"type":"array","items":{"$ref":"#/components/schemas/StockOverviewItem"}}}}}}}}}},"/stock/scan-workflows/{workflowId}/runner":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"workflowId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Scan workflows"],"summary":"Load targets, variants and conditional inputs for an action chain","responses":{"200":{"description":"Runner configuration in workflow: id, name, description, extraction, codeTypes, inputFields, targetSelectionMode, fixedCode, action summaries and targetGroups"},"404":{"description":"Flow unavailable or has no action chain"}}},"post":{"tags":["Scan workflows"],"summary":"Prepare a native scan and return the server-extracted identifier","description":"Requires workflows.read. Returns the runner configuration plus identifier. Validates the code type and extraction rules without changing stock or requiring form inputs.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["code"],"properties":{"code":{"type":"string","minLength":1,"maxLength":2048},"codeType":{"type":["string","null"],"enum":["qr_code","data_matrix","aztec","pdf417","code_128","code_93","code_39","codabar","ean_13","ean_8","upc_a","upc_e","itf",null]}}}}}},"responses":{"200":{"description":"Runner configuration including the extracted identifier"},"404":{"description":"Flow unavailable"},"422":{"description":"Invalid code type or code does not match extraction rules"}}}},"/stock/action-chains/preview":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["Scan workflows"],"summary":"Preview all actions without committing changes","description":"Requires workflows.read. Runs the complete chain and rolls it back, returning planHash. Conditions and component selections are evaluated in order.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionChainRunInput"}}}},"responses":{"200":{"description":"Reviewed plan or previously completed execution","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionChainRunReport"}}}},"404":{"description":"Flow or target unavailable"},"409":{"description":"Stale preview, stock conflict or idempotency mismatch"},"422":{"description":"Invalid input or failed action, with actionId in details"}}}},"/stock/action-chains/execute":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["Scan workflows"],"summary":"Confirm all actions in one transaction","description":"Requires workflows.manage, an Idempotency-Key UUID and the exact reviewed inputs with expectedPlanHash. Stale plans return 409. Stock, units, manufacturing records, audit and webhook outbox commit together. oncePerCode also deduplicates workflow + identifier + selected target set.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionChainRunInput"}}}},"responses":{"200":{"description":"Idempotent replay","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionChainRunReport"}}}},"201":{"description":"All actions committed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionChainRunReport"}}}},"404":{"description":"Flow or target unavailable"},"409":{"description":"Stale preview, stock conflict or idempotency mismatch"},"422":{"description":"Invalid input or failed action, with actionId in details"}}}},"/public/action-flows/{triggerId}/chain":{"servers":[{"url":"/api"}],"parameters":[{"name":"triggerId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Scan workflows"],"summary":"Load targets, variants and conditional inputs for an action chain","responses":{"200":{"description":"Runner configuration in workflow: id, name, description, extraction, codeTypes, inputFields, targetSelectionMode, fixedCode, action summaries and targetGroups"},"404":{"description":"Flow unavailable or has no action chain"}},"security":[]}},"/public/action-flows/{triggerId}/chain/{mode}":{"servers":[{"url":"/api"}],"parameters":[{"name":"triggerId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"mode","in":"path","required":true,"schema":{"type":"string","enum":["preview","execute"]}}],"post":{"tags":["Scan workflows"],"summary":"Preview or confirm an enabled public action chain","description":"Same-origin, rate-limited public endpoint. The trigger must remain enabled. The configured fixed code overrides submitted code. Preview does not need an Idempotency-Key; execute requires a UUID key and expectedPlanHash. All actions roll back on failure.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionChainRunInput"}}}},"responses":{"200":{"description":"Idempotent replay","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionChainRunReport"}}}},"201":{"description":"All actions committed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionChainRunReport"}}}},"404":{"description":"Flow or target unavailable"},"409":{"description":"Stale preview, stock conflict or idempotency mismatch"},"422":{"description":"Invalid input or failed action, with actionId in details"}},"security":[]}},"/stock/scan-workflows":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Scan workflows"],"summary":"List configurable stock scan workflows","responses":{"200":{"description":"Scan workflows","content":{"application/json":{"schema":{"type":"object","required":["workflows"],"properties":{"workflows":{"type":"array","items":{"$ref":"#/components/schemas/ScanWorkflow"}}}}}}}}},"post":{"tags":["Scan workflows"],"summary":"Create a stock scan workflow","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanWorkflowInput"}}}},"responses":{"201":{"description":"Workflow created","content":{"application/json":{"schema":{"type":"object","required":["workflow"],"properties":{"workflow":{"$ref":"#/components/schemas/ScanWorkflow"}}}}}},"409":{"description":"The target item does not use serialized tracking"},"422":{"description":"Invalid workflow definition"}}}},"/stock/scan-workflows/{workflowId}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"workflowId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Scan workflows"],"summary":"Retrieve one stock scan workflow","responses":{"200":{"description":"Scan workflow","content":{"application/json":{"schema":{"type":"object","required":["workflow"],"properties":{"workflow":{"$ref":"#/components/schemas/ScanWorkflow"}}}}}},"404":{"description":"Workflow not found"}}},"patch":{"tags":["Scan workflows"],"summary":"Update a workflow using its current revision","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanWorkflowPatch"}}}},"responses":{"200":{"description":"Workflow updated","content":{"application/json":{"schema":{"type":"object","required":["workflow"],"properties":{"workflow":{"$ref":"#/components/schemas/ScanWorkflow"}}}}}},"404":{"description":"Workflow not found"},"409":{"description":"Revision conflict or incompatible target item"},"422":{"description":"Invalid workflow update"}}},"delete":{"tags":["Scan workflows"],"summary":"Delete a stock scan workflow","parameters":[{"name":"revision","in":"query","required":true,"description":"Current workflow revision, preventing deletion from a stale editor.","schema":{"type":"integer","minimum":1}}],"responses":{"204":{"description":"Workflow deleted; immutable scan audit rows are preserved"},"404":{"description":"Workflow not found"},"409":{"description":"Workflow revision changed; reload before deleting"},"422":{"description":"The workflow id or required single positive revision is invalid"}}}},"/stock/scan-workflows/{workflowId}/public-trigger/rotate":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"workflowId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"post":{"tags":["Scan workflows"],"summary":"Replace a workflow's unlisted public action URL","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["revision"],"additionalProperties":false,"properties":{"revision":{"type":"integer","minimum":1}}}}}},"responses":{"200":{"description":"Public trigger replaced; the previous URL is immediately invalid","content":{"application/json":{"schema":{"type":"object","required":["workflow"],"properties":{"workflow":{"$ref":"#/components/schemas/ScanWorkflow"}}}}}},"404":{"description":"Workflow not found"},"409":{"description":"Workflow revision changed"},"422":{"description":"Invalid workflow or revision"}}}},"/stock/scan-workflows/extraction-suggestions":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["Scan workflows"],"summary":"Generate a validated regex extractor from a sample code with AI","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["sampleCode"],"additionalProperties":false,"properties":{"sampleCode":{"type":"string","minLength":1,"maxLength":2048},"codeType":{"oneOf":[{"$ref":"#/components/schemas/ScanCodeType"},{"type":"null"}]},"selectedResourceIds":{"type":"array","maxItems":24,"uniqueItems":true,"items":{"type":"string","format":"uuid"}},"desiredValue":{"type":"string","maxLength":180},"instruction":{"type":"string","maxLength":500}}}}}},"responses":{"200":{"description":"Validated extraction suggestion","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanExtractionSuggestion"}}}},"402":{"description":"Organization AI budget exceeded"},"422":{"description":"Invalid sample or extraction goal"},"429":{"description":"AI request limit reached"}}}},"/stock/scans/resolve":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["Scan workflows"],"summary":"Resolve and preview a scanned code without changing stock","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["workflowId","code"],"additionalProperties":false,"properties":{"workflowId":{"type":"string","format":"uuid"},"code":{"type":"string","minLength":1,"maxLength":2048},"codeType":{"oneOf":[{"$ref":"#/components/schemas/ScanCodeType"},{"type":"null"}]}}}}}},"responses":{"200":{"description":"Reviewed scan target and required operator inputs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StockScanResolution"}}}},"404":{"description":"Workflow not found"},"409":{"description":"Workflow disabled or target is not serialized"},"422":{"description":"Invalid request or the code does not match the configured extractor"}}}},"/stock/scans/execute":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["Scan workflows"],"summary":"Apply a previously reviewed stock scan to its selected targets","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StockScanExecutionInput"}}}},"responses":{"200":{"description":"Replayed the original scan execution response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StockScanExecution"}}}},"201":{"description":"Unit, stock ledger, and immutable scan audit updated atomically","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StockScanExecution"}}}},"400":{"description":"Missing or invalid Idempotency-Key"},"404":{"description":"Workflow or target unit not found"},"409":{"description":"Revision, stale resource or unit preview, idempotency, tracking-mode, or stock conflict"},"422":{"description":"Invalid code or operator input"}}}},"/public/action-flows/{triggerId}":{"servers":[{"url":"/api"}],"parameters":[{"name":"triggerId","in":"path","required":true,"description":"Random bearer identifier embedded in the unlisted public URL.","schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Scan workflows"],"summary":"Load the form definition for an enabled public action URL","security":[],"responses":{"200":{"description":"Public action form","content":{"application/json":{"schema":{"type":"object","required":["action"],"properties":{"action":{"$ref":"#/components/schemas/PublicActionFlow"}}}}}},"404":{"description":"Public action URL is disabled, revoked, or unknown"}}}},"/public/action-flows/{triggerId}/execute":{"servers":[{"url":"/api"}],"parameters":[{"name":"triggerId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"post":{"tags":["Scan workflows"],"summary":"Confirm and execute an unlisted public action","security":[],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicActionFlowExecutionInput"}}}},"responses":{"200":{"description":"Replayed an earlier execution with the same Idempotency-Key"},"201":{"description":"Public action applied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StockScanExecution"}}}},"400":{"description":"Missing or invalid Idempotency-Key"},"403":{"description":"Cross-origin request rejected"},"404":{"description":"Public action URL is disabled, revoked, or unknown"},"409":{"description":"Workflow revision, stock, or idempotency conflict"},"422":{"description":"Invalid code, quantity, or form input"},"429":{"description":"Public action rate limit reached"}}}},"/resources/{id}/stock":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"}],"get":{"tags":["Stock"],"summary":"Retrieve one item's stock policy, forecast, units, and ledger","responses":{"200":{"description":"Complete stock detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StockDetail"}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/resources/{id}/stock/locations":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"}],"get":{"tags":["Stock"],"summary":"Retrieve stock balances by structured inventory location","description":"Bulk balances are derived from location-aware movements; serialized balances count available units at each location. The response also lists active inventory records whose types can contain stock.","responses":{"200":{"description":"Per-location stock breakdown and selectable locations","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StockLocationsResponse"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"description":"Invalid resource id"}}}},"/inventory-counts/due":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Inventory cycles"],"summary":"List inventory cycles that are currently due","responses":{"200":{"description":"Due inventory counts ordered by due date","content":{"application/json":{"schema":{"type":"object","required":["due"],"properties":{"due":{"type":"array","items":{"$ref":"#/components/schemas/DueInventoryCycle"}}}}}}}}}},"/resources/{id}/inventory-cycle":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"}],"get":{"tags":["Inventory cycles"],"summary":"Retrieve an item's inventory cycle and recent count history","responses":{"200":{"description":"Inventory cycle, nullable policy, and up to 25 recent counts","content":{"application/json":{"schema":{"type":"object","required":["cycle"],"properties":{"cycle":{"$ref":"#/components/schemas/InventoryCycle"}}}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"description":"Invalid resource id"}}},"put":{"tags":["Inventory cycles"],"summary":"Create or replace an item's recurring count policy","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryCyclePolicyInput"}}}},"responses":{"200":{"description":"Inventory cycle policy saved","content":{"application/json":{"schema":{"type":"object","required":["policy"],"properties":{"policy":{"$ref":"#/components/schemas/InventoryCyclePolicy"}}}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"description":"Invalid resource id or count interval"}}}},"/resources/{id}/inventory-counts":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"}],"get":{"tags":["Inventory cycles"],"summary":"List an item's recent inventory counts","responses":{"200":{"description":"Up to 25 recent counts","content":{"application/json":{"schema":{"type":"object","required":["counts"],"properties":{"counts":{"type":"array","items":{"$ref":"#/components/schemas/InventoryCountRecord"}}}}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"description":"Invalid resource id"}}},"post":{"tags":["Inventory cycles"],"summary":"Record an inventory count or serialized-unit review","description":"Bulk counts reconcile either the global balance or one structured location. Serialized items are reviewed through their individual units and may complete the cycle when the submitted whole-item count matches current serialized availability. Every completion appends an inventory-count movement and advances an existing cycle policy.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryCountInput"}}}},"responses":{"200":{"description":"Replayed an earlier count with the same Idempotency-Key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryCountMutation"}}}},"201":{"description":"Count recorded and stock reconciled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryCountMutation"}}}},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Serialized count differs from current unit availability, conflicting idempotency key, or an invalid global count below assigned location stock"},"422":{"description":"Invalid count or structured location"}}}},"/internal-requests":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Internal requests"],"summary":"List visible internal requests","description":"Users with request-management access see the workspace queue; other users see only requests they submitted.","parameters":[{"name":"status","in":"query","schema":{"$ref":"#/components/schemas/InternalRequestStatus"}},{"name":"mine","in":"query","schema":{"type":"boolean","default":false}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":100}}],"responses":{"200":{"description":"Requests visible to the current principal and their available actions","content":{"application/json":{"schema":{"type":"object","required":["requests","capabilities"],"properties":{"requests":{"type":"array","items":{"$ref":"#/components/schemas/InternalRequest"}},"capabilities":{"type":"object","required":["canCreate","canManage"],"properties":{"canCreate":{"type":"boolean"},"canManage":{"type":"boolean"}}}}}}}},"403":{"description":"Request read access is required"}}},"post":{"tags":["Internal requests"],"summary":"Submit a multi-item inventory request","description":"Creates a request without changing stock. Policies that require approval leave it submitted; when every item permits automatic approval, availability is checked and the request is approved atomically.","parameters":[{"$ref":"#/components/parameters/RequiredIdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalRequestCreate"}}}},"responses":{"200":{"description":"Replayed the original request for this Idempotency-Key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalRequestMutation"}}}},"201":{"description":"Request submitted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalRequestMutation"}}}},"400":{"description":"Missing or invalid Idempotency-Key"},"403":{"description":"Request creation and inventory read access are required"},"409":{"description":"Conflicting Idempotency-Key"},"422":{"description":"Invalid request window, items, quantities, or delivery resource"}}}},"/internal-requests/calendar":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Internal requests"],"summary":"List reservation calendar entries","description":"Returns submitted, approved, and fulfilled request lines that overlap the range. Active direct reservations are included when the caller may view assignments.","parameters":[{"name":"from","in":"query","required":true,"schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","required":true,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Calendar entries in the requested range","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReservationCalendar"}}}},"403":{"description":"Request read access is required"},"422":{"description":"Invalid or greater-than-370-day range"}}}},"/internal-requests/{id}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Internal requests"],"summary":"Read one visible internal request","responses":{"200":{"description":"Request with item lines and lifecycle events","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalRequestMutation"}}}},"403":{"description":"Request read access is required"},"404":{"description":"Request not found or not visible to this principal"},"422":{"description":"Invalid request id"}}},"patch":{"tags":["Internal requests"],"summary":"Transition an internal request","description":"Managers may approve, reject, cancel, or fulfill requests. A requester may cancel their own submitted or approved request. Approval atomically checks overlapping availability; fulfillment issues stock and creates active checkouts.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalRequestAction"}}}},"responses":{"200":{"description":"Updated request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalRequestMutation"}}}},"403":{"description":"The principal cannot perform this transition"},"404":{"description":"Request not found"},"409":{"description":"Invalid lifecycle transition or unavailable inventory"},"422":{"description":"Invalid request id or action"}}}},"/resources/{id}/assignments":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"}],"get":{"tags":["Assignments"],"summary":"List checkout, assignment, and reservation records for an item","responses":{"200":{"description":"Assignment history, current availability, and selectable serialized units","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryAssignmentList"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"description":"Invalid resource id"}}},"post":{"tags":["Assignments"],"summary":"Check out, assign, or reserve inventory","description":"Atomically creates an active loan or assignment and updates stock. A future reservation blocks its time window without changing current stock; its serialized unit is selected during checkout.","parameters":[{"$ref":"#/components/parameters/RequiredIdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryAssignmentInput"}}}},"responses":{"200":{"description":"Replayed the original assignment response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryAssignmentMutation"}}}},"201":{"description":"Assignment created and stock allocated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryAssignmentMutation"}}}},"400":{"description":"Missing or invalid Idempotency-Key"},"404":{"description":"Inventory item or serialized unit not found"},"409":{"description":"Insufficient stock, unavailable unit, or conflicting idempotency key"},"422":{"description":"Invalid recipient, quantity, dates, or tracking-mode combination"}}}},"/resources/{id}/lending":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"}],"get":{"tags":["Assignments"],"summary":"Read the resource lending policy","responses":{"200":{"description":"Resource lending policy, with disabled defaults when none has been stored","content":{"application/json":{"schema":{"type":"object","required":["lending"],"properties":{"lending":{"$ref":"#/components/schemas/LendingSettings"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["Assignments"],"summary":"Enable or configure loans for an inventory item","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LendingSettings"}}}},"responses":{"200":{"description":"Lending policy updated"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"description":"Invalid duration policy"}}}},"/loans":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Assignments"],"summary":"List loans and direct reservations across the workspace","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":500}}],"responses":{"200":{"description":"Loans and reservations with resource context and management capability"},"403":{"description":"Assignment read access is required"}}}},"/assignments/{assignmentId}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"assignmentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"patch":{"tags":["Assignments"],"summary":"Check out, return, or cancel an active assignment","description":"A checkout action converts a reservation into a stock-affecting loan. Completion restores stock only when the assignment had previously affected stock.","parameters":[{"$ref":"#/components/parameters/RequiredIdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/InventoryAssignmentCompletion"},{"$ref":"#/components/schemas/InventoryReservationCheckout"}]}}}},"responses":{"200":{"description":"Assignment completed or an identical completion replayed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryAssignmentMutation"}}}},"400":{"description":"Missing or invalid Idempotency-Key"},"404":{"description":"Assignment, inventory item, or serialized unit not found"},"409":{"description":"Assignment already completed, stock overflow, or conflicting idempotency key"},"422":{"description":"Invalid status or completion date"}}}},"/resources/{id}/stock/config":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"}],"patch":{"tags":["Stock"],"summary":"Update tracking mode and replenishment policy","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StockConfigInput"}}}},"responses":{"200":{"description":"Updated stock policy"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Tracking mode transition would break serialized-unit integrity"}}}},"/resources/{id}/bom":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"}],"get":{"tags":["Manufacturing"],"summary":"Retrieve an item's effective bill of materials and current build capacity","description":"A primary item returns its local BOM. A first-class variant returns the primary BOM with its sparse removals, replacements, and variant-only slots applied.","responses":{"200":{"description":"Bill of materials with component availability","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BomDetail"}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"put":{"tags":["Manufacturing"],"summary":"Replace an item's effective bill of materials","description":"Primary items store the submitted recipe as stable BOM slots. Variants compare the submitted effective recipe with the primary and persist only sparse differences.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["components"],"properties":{"components":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/BomComponentInput"}}}}}}},"responses":{"200":{"description":"Bill of materials replaced"},"409":{"description":"Circular dependency or concurrent referenced-resource conflict"},"422":{"description":"Invalid, duplicate, missing, or self-referencing component list"}}},"delete":{"tags":["Manufacturing"],"summary":"Reset a variant's bill of materials to its primary item","description":"Removes manual BOM overrides for a linked first-class variant while preserving configured component selections. Primary and standalone items cannot use this operation.","responses":{"200":{"description":"Reset effective bill of materials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BomDetail"}}}},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Item is not a linked variant"}}}},"/resources/{id}/assembly-configuration":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"}],"get":{"tags":["Manufacturing"],"summary":"Preview an automatic finished-product configuration without creating records","parameters":[{"name":"selection","in":"query","required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssemblyOutputConfiguration"}}}}],"responses":{"200":{"description":"Effective recipe; existingResourceId is null for a virtual configuration, otherwise the reusable finished article ID","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/BomDetail"},{"type":"object","properties":{"existingResourceId":{"type":["string","null"],"format":"uuid"}}}]}}}},"403":{"description":"Matching variant or components are inaccessible or archived"},"409":{"description":"Multiple finished articles match; select one explicitly"},"422":{"description":"Incomplete or invalid configuration"}}},"post":{"tags":["Manufacturing"],"summary":"Prepare only the selected configuration for manual customization","description":"Requires inventory.update and inventory.create. Reuses matching articles and preserves customizations. Creates no stock movements. Repeated requests return the same resource.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssemblyOutputConfiguration"}}}},"responses":{"200":{"description":"Ready to customize","content":{"application/json":{"schema":{"type":"object","properties":{"resourceId":{"type":"string","format":"uuid"}}}}}},"403":{"description":"Missing permission or archived resource"},"409":{"description":"Ambiguous configuration"},"422":{"description":"Invalid configuration"}}}},"/resources/{id}/bom-parents":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"}],"get":{"tags":["Manufacturing"],"summary":"List assemblies whose effective bill of materials uses this item","description":"Includes direct primary-item BOM lines, inherited variant BOM lines, and sparse variant overrides. Parent assemblies that the caller cannot read are omitted.","responses":{"200":{"description":"Readable parent assemblies using this item","content":{"application/json":{"schema":{"type":"object","required":["parents"],"properties":{"parents":{"type":"array","items":{"$ref":"#/components/schemas/BomParent"}}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/resources/{id}/stock/builds":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"}],"get":{"tags":["Manufacturing"],"summary":"List completed assembly builds for an item","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}}],"responses":{"200":{"description":"Completed builds with immutable component snapshots","content":{"application/json":{"schema":{"type":"object","required":["builds"],"properties":{"builds":{"type":"array","items":{"$ref":"#/components/schemas/AssemblyBuild"}}}}}}}}},"post":{"tags":["Manufacturing"],"summary":"Atomically consume components and create finished stock","parameters":[{"$ref":"#/components/parameters/RequiredIdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssemblyBuildInput"}}}},"responses":{"200":{"description":"Replayed the original assembly build"},"201":{"description":"Components consumed and finished stock created atomically"},"400":{"description":"Missing or invalid Idempotency-Key"},"409":{"description":"Component shortage, serialized-unit, or idempotency conflict"},"422":{"description":"Invalid build request"}}}},"/resources/{id}/stock/movements":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"}],"get":{"tags":["Stock"],"summary":"List the dated stock ledger","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"default":100}},{"name":"before","in":"query","description":"Return movements that occurred before this timestamp.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Stock movements","content":{"application/json":{"schema":{"type":"object","required":["movements"],"properties":{"movements":{"type":"array","items":{"$ref":"#/components/schemas/StockMovement"}}}}}}}}},"post":{"tags":["Stock"],"summary":"Book a bulk stock change or structured location transfer","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StockMovementInput"}}}},"responses":{"200":{"description":"Replayed the original stock movement response"},"201":{"description":"Movement booked and balance updated"},"409":{"description":"Insufficient stock, serialized mode, or conflicting idempotency key"},"422":{"description":"Invalid quantity, movement direction, or structured location transfer"}}}},"/resources/{id}/stock/movements/{movementId}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"},{"name":"movementId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"patch":{"tags":["Stock"],"summary":"Correct a manual bulk stock movement","description":"System-linked movements and inbound movements whose cost layer has already been consumed cannot be changed.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StockMovementInput"}}}},"responses":{"200":{"description":"Movement and current balance updated atomically","content":{"application/json":{"schema":{"type":"object","required":["resource","movement"],"properties":{"resource":{"type":"object","required":["id","quantity"],"properties":{"id":{"type":"string","format":"uuid"},"quantity":{"type":"integer"}}},"movement":{"$ref":"#/components/schemas/StockMovement"}}}}}},"404":{"description":"Movement not found"},"409":{"description":"Movement is system-linked or cannot be corrected safely"},"422":{"description":"Invalid movement correction"}}},"delete":{"tags":["Stock"],"summary":"Delete a manual bulk stock movement","description":"Corrects the current quantity and subsequent ledger balances atomically. System-linked movements cannot be deleted.","responses":{"204":{"description":"Movement deleted and stock corrected"},"404":{"description":"Movement not found"},"409":{"description":"Movement is system-linked or cannot be deleted safely"}}}},"/resources/{id}/stock/units":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"}],"get":{"tags":["Stock"],"summary":"List individually identified stock units","responses":{"200":{"description":"Serialized units","content":{"application/json":{"schema":{"type":"object","required":["units"],"properties":{"units":{"type":"array","items":{"$ref":"#/components/schemas/StockUnit"}}}}}}}}},"post":{"tags":["Stock"],"summary":"Create one or more individually identified stock units","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StockUnitInput"}}}},"responses":{"201":{"description":"Units created with audit entries"},"409":{"description":"Duplicate code or incompatible tracking mode"}}}},"/resources/{id}/stock/units/{unitId}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"},{"name":"unitId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"delete":{"tags":["Stock"],"summary":"Delete an unlinked serialized unit while retaining movement history","description":"Requires stock.manage. Atomically deletes the unit, records a unit-deleted audit entry with its code and UUID, and reduces available stock and its cost layers by one only when the unit was available. Existing QR links will no longer select this unit. Units linked to orders, assignments, or assemblies (including historical links and assembly outputs) cannot be deleted.","responses":{"200":{"description":"Unit deleted, stock reconciled, and audit movement recorded","content":{"application/json":{"schema":{"type":"object","required":["deletedUnitId","quantity","movement"],"properties":{"deletedUnitId":{"type":"string","format":"uuid"},"quantity":{"type":"integer","minimum":0},"movement":{"$ref":"#/components/schemas/StockMovement"}}}}}},"403":{"description":"Stock management permission required"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Unit is linked to another operation, tracking is not serialized, or stock would become negative"},"422":{"description":"Invalid resource or unit ID"}}},"patch":{"tags":["Stock"],"summary":"Change a unit's code, status, location, or metadata with an audit entry","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StockUnitPatch"}}}},"responses":{"200":{"description":"Unit updated and movement recorded"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Unit code already exists for this item or unit update conflicts with its current state"},"422":{"description":"Invalid unit update"}}}},"/purchase-orders":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Purchasing"],"summary":"List purchase orders and their open incoming quantities","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["draft","ordered","partially-received","received","cancelled"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":100}}],"responses":{"200":{"description":"Purchase orders","content":{"application/json":{"schema":{"type":"object","required":["orders"],"properties":{"orders":{"type":"array","items":{"$ref":"#/components/schemas/PurchaseOrder"}}}}}}}}},"post":{"tags":["Purchasing"],"summary":"Create a draft or ordered purchase order","parameters":[{"$ref":"#/components/parameters/RequiredIdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PurchaseOrderInput"}}}},"responses":{"200":{"description":"Replayed the original purchase-order response"},"201":{"description":"Purchase order created"},"400":{"description":"Missing or invalid Idempotency-Key"},"409":{"description":"Idempotency conflict or supported open-order total exceeded"},"422":{"description":"Invalid purchase order, duplicate line, or missing inventory item"}}}},"/purchase-orders/{orderId}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"orderId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Purchasing"],"summary":"Retrieve one purchase order","responses":{"200":{"description":"Purchase order","content":{"application/json":{"schema":{"type":"object","required":["order"],"properties":{"order":{"$ref":"#/components/schemas/PurchaseOrder"}}}}}},"404":{"description":"Purchase order not found"}}},"patch":{"tags":["Purchasing"],"summary":"Update or cancel a purchase order","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"reference":{"type":["string","null"],"maxLength":160},"supplier":{"type":"string","maxLength":240},"status":{"type":"string","enum":["draft","ordered","cancelled"]},"orderedAt":{"type":"string","format":"date-time"},"expectedAt":{"type":["string","null"],"format":"date-time"},"note":{"type":"string","maxLength":20000}}}}}},"responses":{"200":{"description":"Purchase order updated"},"409":{"description":"Invalid lifecycle transition"}}}},"/purchase-orders/{orderId}/lines/{lineId}/receipts":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"orderId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"lineId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"post":{"tags":["Purchasing"],"summary":"Receive all or part of an ordered line into physical stock","parameters":[{"$ref":"#/components/parameters/RequiredIdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PurchaseReceiptInput"}}}},"responses":{"200":{"description":"Replayed the original goods receipt"},"201":{"description":"Receipt and physical stock movements created atomically"},"400":{"description":"Missing or invalid Idempotency-Key"},"409":{"description":"Over-receipt, order-state, serialized-unit, or idempotency conflict"}}}},"/orders":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Orders"],"summary":"List purchase, sales, or loan orders from the shared order model","parameters":[{"name":"type","in":"query","schema":{"type":"string","enum":["purchase","sale","loan"]}},{"name":"status","in":"query","schema":{"$ref":"#/components/schemas/OrderStatus"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":100}}],"responses":{"200":{"description":"Orders and their embedded lines","content":{"application/json":{"schema":{"type":"object","required":["orders"],"properties":{"orders":{"type":"array","items":{"$ref":"#/components/schemas/Order"}}}}}}}}},"post":{"tags":["Orders"],"summary":"Create a purchase, sales, or multi-item loan order","parameters":[{"$ref":"#/components/parameters/RequiredIdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderInput"}}}},"responses":{"200":{"description":"Replayed original response"},"201":{"description":"Order created"},"409":{"description":"Idempotency conflict"},"422":{"description":"Invalid contact, status, or order line"}}}},"/orders/{orderId}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"orderId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Orders"],"summary":"Retrieve one shared order with all lines","responses":{"200":{"description":"Order","content":{"application/json":{"schema":{"type":"object","required":["order"],"properties":{"order":{"$ref":"#/components/schemas/Order"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["Orders"],"summary":"Update common order fields or change lifecycle state","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderPatch"}}}},"responses":{"200":{"description":"Order updated"},"409":{"description":"Completed or cancelled orders cannot be reopened"},"422":{"description":"Invalid type-specific status or contact role"}}}},"/orders/{orderId}/shipments":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"orderId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Orders"],"summary":"List outbound parcels for a sales order","responses":{"200":{"description":"Shipments with lines, serialized units, and immutable status history","content":{"application/json":{"schema":{"type":"object","required":["shipments"],"properties":{"shipments":{"type":"array","items":{"$ref":"#/components/schemas/Shipment"}}}}}}}}},"post":{"tags":["Orders"],"summary":"Create an outbound parcel from fulfilled sales-order lines","description":"Assigns fulfilled bulk quantities and concrete serialized units to a parcel. This endpoint records Inventory shipping data and does not write to WooCommerce.","parameters":[{"$ref":"#/components/parameters/RequiredIdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShipmentInput"}}}},"responses":{"200":{"description":"Replayed the original shipment response"},"201":{"description":"Shipment created"},"400":{"description":"Missing or invalid Idempotency-Key"},"409":{"description":"Quantity, serialized-unit, tracking-number, or idempotency conflict"},"422":{"description":"Invalid shipment, line, or order type"}}}},"/orders/{orderId}/shipments/{shipmentId}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"orderId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"shipmentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"patch":{"tags":["Orders"],"summary":"Update shipment details or advance its delivery status","description":"Records every change in the shipment event history. Entering shipped or delivered records the effective timestamp automatically unless occurredAt is supplied.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShipmentPatch"}}}},"responses":{"200":{"description":"Shipment updated","content":{"application/json":{"schema":{"type":"object","required":["shipment"],"properties":{"shipment":{"$ref":"#/components/schemas/Shipment"}}}}}},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Invalid lifecycle transition or duplicate tracking number"},"422":{"description":"Invalid shipment details or timestamp"}}}},"/orders/{orderId}/lines/{lineId}/movements":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"orderId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"lineId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"post":{"tags":["Orders"],"summary":"Issue or return a bulk-tracked sales or loan line","description":"Creates an idempotent stock movement linked to the order line and recalculates the order status atomically. Bulk-tracked inventory is supported by this endpoint.","parameters":[{"$ref":"#/components/parameters/RequiredIdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderLineMovementInput"}}}},"responses":{"200":{"description":"Replayed original stock movement"},"201":{"description":"Movement created and order progress updated"},"409":{"description":"Insufficient stock, excessive quantity, or invalid lifecycle state"},"422":{"description":"Invalid movement for the order type"}}}},"/orders/{orderId}/lines/{lineId}/units":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"orderId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"lineId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Orders"],"summary":"List available and assigned serialized units for an order line","responses":{"200":{"description":"Serialized units available to the line and its assignment history","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SerializedOrderLineUnits"}}}},"404":{"$ref":"#/components/responses/NotFound"},"422":{"description":"The line does not use serialized stock tracking"}}},"post":{"tags":["Orders"],"summary":"Reserve, release, issue, or return concrete serialized units","description":"Updates the unit lifecycle, available stock, order progress, cost layers, and immutable stock movement ledger atomically.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderLineUnitActionInput"}}}},"responses":{"200":{"description":"Unit action applied, including replay-safe no-op actions","content":{"application/json":{"schema":{"type":"object","required":["changed","movementIds","order","units"],"properties":{"changed":{"type":"integer","minimum":0},"movementIds":{"type":"array","items":{"type":"string","format":"uuid"}},"order":{"$ref":"#/components/schemas/Order"},"units":{"$ref":"#/components/schemas/SerializedOrderLineUnits"}}}}}},"409":{"description":"Unit state, capacity, assignment, or order lifecycle conflict"},"422":{"description":"Invalid action or non-serialized order line"}}}},"/resources/{id}/media":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/ResourceId"}],"post":{"tags":["Media"],"summary":"Upload up to 12 media files, including Apple USDZ object models","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"files":{"type":"array","maxItems":12,"description":"Images, videos, PDF documents, or .usdz models sent as model/vnd.usdz+zip.","items":{"type":"string","format":"binary"}}}}}}},"responses":{"200":{"description":"Replayed the existing upload batch"},"201":{"description":"Uploaded"},"409":{"description":"Idempotency key belongs to another resource"},"413":{"description":"A file exceeds MAX_UPLOAD_MB, or a USDZ model exceeds MAX_USDZ_UPLOAD_MB"},"415":{"description":"Unsupported media type, invalid USDZ filename, or structurally invalid USDZ package"},"422":{"description":"A USDZ Object Capture model was uploaded without an existing or accompanying item image"},"503":{"description":"The configured storage provider cannot store the accepted media type"}}},"patch":{"tags":["Media"],"summary":"Reorder all media","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["order"],"properties":{"order":{"type":"array","items":{"type":"string","format":"uuid"}}}}}}},"responses":{"200":{"description":"Reordered"}}}},"/resources/{id}/media/{mediaId}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"delete":{"tags":["Media"],"summary":"Remove one media file","parameters":[{"$ref":"#/components/parameters/ResourceId"},{"name":"mediaId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Removed"}}}},"/resources/{id}/analyze":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["AI"],"summary":"Generate structured item fields from the first three images","parameters":[{"$ref":"#/components/parameters/ResourceId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"overwrite":{"type":"boolean","default":true},"prompt":{"type":"string","maxLength":5000,"description":"Optional replacement for the built-in inventory-analysis prompt. Omit it to use the server default."}}}}}},"responses":{"200":{"description":"Item enriched or completed response replayed"},"202":{"description":"An operation with this key is still processing"},"409":{"description":"Idempotency key belongs to another resource or payload"},"422":{"description":"Invalid analysis request"},"429":{"description":"AI request limit reached","headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"502":{"description":"AI provider error"},"503":{"description":"Shared AI rate limiter unavailable"}}}},"/resources/{id}/research":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["AI"],"summary":"Add missing item details using saved content, images, and GPT web search","description":"Preserves existing fields, appends newly researched description details, merges tags and categories, fills tracking identifiers or value only at high confidence, and adds sourced internal notes only when blank.","parameters":[{"$ref":"#/components/parameters/ResourceId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":false}}}},"responses":{"200":{"description":"Missing details added, no reliable additions found, or completed response replayed"},"202":{"description":"An operation with this key is still processing"},"403":{"description":"Proposed changes fall outside the caller's inventory access rules"},"409":{"description":"Idempotency key belongs to another resource or payload"},"422":{"description":"Invalid AI research request"},"429":{"description":"AI web-research request limit reached","headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"502":{"description":"AI provider or web-search error"},"503":{"description":"Shared AI rate limiter unavailable"}}}},"/resources/{id}/cover":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["AI"],"summary":"Generate a square studio or transparent cover from an item image","parameters":[{"$ref":"#/components/parameters/ResourceId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"sourceMediaId":{"type":"string","format":"uuid","description":"Image to use as the visual reference. Defaults to the first non-AI image, then falls back to the first image."},"prompt":{"type":"string","maxLength":5000,"description":"Optional replacement for the built-in studio or transparent-cover prompt. Omit it to use the matching server default."},"modelId":{"type":"string","maxLength":240,"description":"An ID returned by GET /ai/image-models. Omit it to use the deployment default."},"maximumImageSize":{"type":"integer","enum":[1024,2048,4096],"default":1024,"description":"Maximum requested longest edge in pixels. Models use the largest supported standard square size at or below this value; transparent covers are capped at 2048 for safe processing."},"transparentBackground":{"type":"boolean","default":false,"description":"When true, store a transparent PNG instead of an opaque JPEG."},"transparencyMethod":{"type":"string","enum":["greenscreen","difference-matting"],"default":"difference-matting","description":"Greenscreen uses one generated chroma-key pass. Difference matting uses aligned white and black passes for higher-quality alpha, including translucent details and soft shadows."}}}}}},"responses":{"200":{"description":"Cover generated or completed response replayed"},"202":{"description":"An operation with this key is still processing"},"409":{"description":"Idempotency key belongs to another resource or payload"},"422":{"description":"Invalid request or unavailable image model"},"429":{"description":"Image generation limit reached","headers":{"Retry-After":{"schema":{"type":"integer","minimum":1}}}},"502":{"description":"AI provider error"},"503":{"description":"Shared AI rate limiter unavailable"}}}},"/resources/{id}/image":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["AI"],"summary":"Find a reusable web image or generate a new AI image and append it to an item","parameters":[{"$ref":"#/components/parameters/ResourceId"},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","additionalProperties":false,"required":["mode"],"properties":{"mode":{"type":"string","const":"search"},"query":{"type":"string","minLength":1,"maxLength":500,"description":"Optional brand, model, or exact-item search hint. Saved item details are always included."}}},{"type":"object","additionalProperties":false,"required":["mode"],"properties":{"mode":{"type":"string","const":"generate"},"prompt":{"type":"string","minLength":1,"maxLength":5000,"description":"Optional image direction. Omit it for a catalogue-style prompt based on the saved item."},"modelId":{"type":"string","maxLength":240,"description":"An ID returned by GET /ai/image-models. Omit it to use the deployment default."},"maximumImageSize":{"type":"integer","enum":[1024,2048,4096],"default":1024}}}]}}}},"responses":{"200":{"description":"Image imported or generated, appended to the item, or completed response replayed"},"202":{"description":"An operation with this key is still processing"},"409":{"description":"Idempotency key belongs to another resource or payload"},"422":{"description":"Invalid request or unavailable image model"},"429":{"description":"AI research or image-generation limit reached"},"502":{"description":"AI provider, web-search, remote-image, or storage error"},"503":{"description":"Shared AI rate limiter unavailable"}}}},"/stats":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Insights"],"summary":"Retrieve aggregate dashboard statistics","responses":{"200":{"description":"Statistics"}}}},"/duplicates":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Insights"],"summary":"Find likely duplicate item pairs","responses":{"200":{"description":"Ranked duplicate pairs"}}},"post":{"tags":["Insights"],"summary":"Merge one duplicate into another","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["keepResourceId","removeResourceId"],"properties":{"keepResourceId":{"type":"string","format":"uuid"},"removeResourceId":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Merged resource"}}}},"/label-workspace":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Label printing"],"summary":"Read the personal saved print list","description":"Requires a user browser session with labels.read. Data is scoped to the current user and organization.","security":[{"adminSession":[]}],"responses":{"200":{"description":"Saved queue and preferences.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LabelWorkspace"}}}},"403":{"description":"Required permission or browser session missing; printing mutations also reject read-only organizations and cross-site requests."}}},"patch":{"tags":["Label printing"],"summary":"Save print preferences or replace the prepared list","description":"Requires a user browser session with labels.read. Queue updates require the current revision; 409 prevents a stale browser from overwriting another window. At most 100 labels, one tape width and a 24 MiB JSON body. Preference updates merge only supplied keys.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LabelWorkspaceMutation"}}}},"responses":{"200":{"description":"Queue updates return the workspace; preference updates return preferences only.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/LabelWorkspace"},{"type":"object","required":["preferences"],"properties":{"preferences":{"$ref":"#/components/schemas/LabelPreferences"}}}]}}}},"400":{"description":"Malformed request."},"403":{"description":"Required permission or browser session missing; printing mutations also reject read-only organizations and cross-site requests."},"409":{"description":"Saved queue revision changed; reload before editing."},"413":{"description":"Request exceeds the size limit."},"422":{"description":"Invalid input or raster data."}}}},"/label-printers":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Label printing"],"summary":"List enabled shared printers","description":"Requires a browser session with labels.read. online means an agent poll was received within 45 seconds.","security":[{"adminSession":[]}],"responses":{"200":{"description":"Enabled printers in this organization.","content":{"application/json":{"schema":{"type":"object","required":["printers"],"properties":{"printers":{"type":"array","items":{"$ref":"#/components/schemas/SharedPrinter"}}}}}}},"403":{"description":"Required permission or browser session missing; printing mutations also reject read-only organizations and cross-site requests."}}},"post":{"tags":["Label printing"],"summary":"Provision a shared Office printer","description":"Requires a browser session with tokens.manage. Currently provisions 24 mm tape only. The returned iprt_ token is shown once and is restricted to this printer; store it in the agent configuration.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":120},"tape":{"type":"number","const":24,"default":24}},"additionalProperties":false}}}},"responses":{"201":{"description":"Printer and one-time agent credential.","content":{"application/json":{"schema":{"type":"object","required":["printer","token"],"properties":{"printer":{"type":"object","required":["id","name","tape"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"tape":{"type":"number","const":24}}},"token":{"type":"string"}}}}}},"400":{"description":"Malformed request."},"403":{"description":"Required permission or browser session missing; printing mutations also reject read-only organizations and cross-site requests."},"413":{"description":"Request exceeds the size limit."},"422":{"description":"Invalid input or raster data."}}},"patch":{"tags":["Label printing"],"summary":"Disable a shared printer","description":"Requires a browser session with tokens.manage. Revokes agent access and cancels queued jobs. To rotate credentials, provision a replacement printer.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","enabled"],"properties":{"id":{"type":"string","format":"uuid"},"enabled":{"type":"boolean","const":false}},"additionalProperties":false}}}},"responses":{"200":{"description":"Printer disabled.","content":{"application/json":{"schema":{"type":"object","required":["disabled"],"properties":{"disabled":{"type":"boolean","const":true}}}}}},"400":{"description":"Malformed request."},"403":{"description":"Required permission or browser session missing; printing mutations also reject read-only organizations and cross-site requests."},"404":{"description":"Printer not found in this organization."},"413":{"description":"Request exceeds the size limit."},"422":{"description":"Invalid input or raster data."}}}},"/label-print-jobs":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Label printing"],"summary":"List your latest shared print jobs","description":"Requires a browser session with labels.read. Returns at most 20 jobs submitted by the current user in this organization.","security":[{"adminSession":[]}],"responses":{"200":{"description":"Recent jobs.","content":{"application/json":{"schema":{"type":"object","required":["jobs"],"properties":{"jobs":{"type":"array","items":{"$ref":"#/components/schemas/SharedPrintJob"}}}}}}},"403":{"description":"Required permission or browser session missing; printing mutations also reject read-only organizations and cross-site requests."}}},"post":{"tags":["Label printing"],"summary":"Queue a prepared PT-P710BT print job","description":"Requires a browser session with labels.read. The browser renders and validates labels before submission. Reuse body.id only with identical data to retrieve an existing job. Limits: 100 labels, 4 MB RAW data, 10 submissions/minute per user/printer and 20 pending jobs per printer. Queued jobs expire after 10 minutes.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SharedPrintInput"}}}},"responses":{"201":{"description":"Queued job or replay of the same submission.","content":{"application/json":{"schema":{"type":"object","required":["job"],"properties":{"job":{"$ref":"#/components/schemas/SharedPrintJob"}}}}}},"400":{"description":"Malformed request."},"403":{"description":"Required permission or browser session missing; printing mutations also reject read-only organizations and cross-site requests."},"404":{"description":"Printer unavailable."},"409":{"description":"Idempotency ID reused with different data, or tape width differs from the printer."},"413":{"description":"Request exceeds the size limit."},"422":{"description":"Invalid input or raster data."},"429":{"description":"Submission rate or pending queue limit reached."}}},"delete":{"tags":["Label printing"],"summary":"Cancel one of your waiting print jobs","description":"Requires a browser session with labels.read. Only a queued job owned by the caller can be cancelled.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id"],"properties":{"id":{"type":"string","format":"uuid"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Job cancelled.","content":{"application/json":{"schema":{"type":"object","required":["cancelled"],"properties":{"cancelled":{"type":"boolean","const":true}}}}}},"400":{"description":"Malformed request."},"403":{"description":"Required permission or browser session missing; printing mutations also reject read-only organizations and cross-site requests."},"409":{"description":"Job already dispatched or not found."},"413":{"description":"Request exceeds the size limit."},"422":{"description":"Invalid input or raster data."}}}},"/label-print-agent/claim":{"post":{"tags":["Label printing"],"summary":"Claim the next job for a printer","description":"Windows agent endpoint; use the dedicated iprt_ credential, not an inventory API token. Reuse claimId to recover the same claim. Stale claims become uncertain after five minutes and are never handed out again. History cleanup runs on polling after seven days.","security":[{"printAgent":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["claimId"],"properties":{"claimId":{"type":"string","format":"uuid"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Claimed RAW data or null when no job is available.","content":{"application/json":{"schema":{"type":"object","required":["job"],"properties":{"job":{"anyOf":[{"type":"object","required":["id","data","sha256"],"properties":{"id":{"type":"string","format":"uuid"},"data":{"type":"string","contentEncoding":"base64"},"sha256":{"type":"string"}}},{"type":"null"}]}}}}}},"400":{"description":"Malformed request."},"401":{"description":"Invalid, disabled or read-only printer credential."},"403":{"description":"Required permission or browser session missing; printing mutations also reject read-only organizations and cross-site requests."},"413":{"description":"Request exceeds the size limit."}}}},"/label-print-agent/ack":{"post":{"tags":["Label printing"],"summary":"Acknowledge a printer claim","description":"Agent only. Report submitted after Windows accepts the RAW job, failed after a definite failure, or uncertain if acceptance is ambiguous. The receipt clears the stored payload. It does not prove physical printing.","security":[{"printAgent":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id","claimId","status"],"properties":{"id":{"type":"string","format":"uuid"},"claimId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["submitted","failed","uncertain"]},"spoolJobId":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"default":null}},"additionalProperties":false}}}},"responses":{"200":{"description":"Receipt recorded.","content":{"application/json":{"schema":{"type":"object","required":["ok"],"properties":{"ok":{"type":"boolean","const":true}}}}}},"400":{"description":"Malformed request."},"401":{"description":"Invalid printer credential."},"409":{"description":"Matching claim not found."},"413":{"description":"Request exceeds the size limit."}}}},"/labels/qz-certificate":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Label printing"],"summary":"Read the optional QZ signing certificate","description":"Requires a browser session with labels.read. Without signing configuration the application uses QZ approval prompts.","security":[{"adminSession":[]}],"responses":{"200":{"description":"PEM signing certificate.","content":{"text/plain":{"schema":{"type":"string"}}}},"403":{"description":"Required permission or browser session missing; printing mutations also reject read-only organizations and cross-site requests."},"500":{"description":"Certificate could not be read."},"503":{"description":"QZ signing not configured."}}}},"/labels/qz-sign":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"post":{"tags":["Label printing"],"summary":"Sign an allowed QZ print request","description":"Requires a browser session with labels.read. Only recent printer-discovery requests and bounded, single-copy raw PT-P710BT jobs are accepted. Cross-site, file, network, serial and direct USB commands are rejected. Private keys remain on the server.","security":[{"adminSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["request"],"properties":{"request":{"type":"string","description":"Exact serialized QZ request string."}}}}}},"responses":{"200":{"description":"Base64 RSA SHA-512 signature.","content":{"text/plain":{"schema":{"type":"string"}}}},"400":{"description":"Malformed request."},"403":{"description":"Session permission missing or signing request disallowed."},"413":{"description":"Request exceeds the size limit."},"500":{"description":"Signing failed."},"503":{"description":"QZ signing not configured."}}}},"/stock/forecast":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["Stock"],"summary":"Read stock planning inputs and history","description":"Requires stock.read. Returns a consistent snapshot for non-archived items with stock settings: up to 90 days of consumption, recent 30-day consumption, daily stock balances and outstanding purchase receipts. Consumption includes issues, production consumption and waste; loans, transfers and corrections are excluded. This endpoint returns inputs; the web client calculates forecast curves and replenishment suggestions. It neither orders nor changes stock.","responses":{"200":{"description":"Planning data.","content":{"application/json":{"schema":{"type":"object","required":["generatedAt","items"],"properties":{"generatedAt":{"type":"string","format":"date-time"},"items":{"type":"array","items":{"$ref":"#/components/schemas/StockPlanningItem"}}}}}}},"403":{"description":"stock.read required."},"500":{"description":"Unable to load planning data."}}}},"/ai/count/bulk":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"$ref":"#/components/parameters/RequiredIdempotencyKey"}],"post":{"tags":["AI"],"summary":"Estimate bin contents from 3–5 photos (experimental)","description":"Requires ai.count and access to input.itemId. Sends images to the configured OpenAI-compatible provider in two analysis calls. Supply input as a JSON string, including nullable containerDimensions and partDimensions. Reuse the Idempotency-Key only for the same request. An estimate may be null; no stock is booked. Accuracy is not validated.","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["input","images"],"properties":{"input":{"type":"string","description":"JSON-encoded BulkCountInput; see the matching schema.","contentMediaType":"application/json","contentSchema":{"$ref":"#/components/schemas/BulkCountInput"}},"images":{"type":"array","minItems":3,"maxItems":5,"items":{"type":"string","format":"binary"},"description":"Distinct views of the same unchanged bin; at most 8 MiB per image."}}}}}},"responses":{"200":{"description":"Estimate with assumptions, or no usable estimate.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkCountResult"}}}},"400":{"description":"Missing Idempotency-Key or malformed multipart body."},"402":{"description":"Monthly AI budget exceeded."},"403":{"description":"ai.count and access to the item are required."},"409":{"description":"Operation still processing or idempotency key conflicts."},"413":{"description":"Upload too large."},"422":{"description":"Invalid annotations, input or images; duplicate photos rejected."},"429":{"description":"Counting disabled or rate limit reached."},"502":{"description":"Provider returned no usable result."},"503":{"description":"Required runtime/provider or service unavailable."}}}},"/ai/count/3d":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"}],"get":{"tags":["AI"],"summary":"Check local 3D counting availability","description":"Requires ai.count and item access. Availability requires BULK_3D_ENABLED and a separately provisioned Python/GPU runtime; the standard Docker image does not include it.","parameters":[{"name":"itemId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Local runtime availability.","content":{"application/json":{"schema":{"type":"object","required":["available"],"properties":{"available":{"type":"boolean"}}}}}},"403":{"description":"ai.count and access to the item are required."},"422":{"description":"Invalid annotations, input or images; duplicate photos rejected."}}},"post":{"tags":["AI"],"summary":"Start an experimental 3D bin estimate","description":"Requires ai.count and item access. Upload 3–4 JPEG/PNG/WebP/AVIF photos, manual marks and explicit shape/packing assumptions. The first image is the top view. Runs on the configured local GPU; no paid inference API is called. Poll the returned jobId. Reuse the same key for identical retries. Deadline is ten minutes; results remain accessible for 24 hours. No stock is booked.","parameters":[{"$ref":"#/components/parameters/RequiredIdempotencyKey"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["input","images"],"properties":{"input":{"type":"string","description":"JSON-encoded Bulk3dInput; see the matching schema.","contentMediaType":"application/json","contentSchema":{"$ref":"#/components/schemas/Bulk3dInput"}},"images":{"type":"array","minItems":3,"maxItems":4,"items":{"type":"string","format":"binary"},"description":"Distinct views of the same unchanged bin; at most 8 MiB per image."}}}}}},"responses":{"202":{"description":"Durable job accepted or replayed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Bulk3dJob"}}}},"400":{"description":"Missing Idempotency-Key or malformed multipart body."},"403":{"description":"ai.count and access to the item are required."},"409":{"description":"Operation still processing or idempotency key conflicts."},"413":{"description":"Upload too large."},"422":{"description":"Invalid annotations, input or images; duplicate photos rejected."},"429":{"description":"Counting disabled or rate limit reached."},"503":{"description":"Required runtime/provider or service unavailable."}}}},"/ai/count/3d/{jobId}":{"parameters":[{"$ref":"#/components/parameters/OrganizationId"},{"name":"jobId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["AI"],"summary":"Read a 3D estimate or download its GLB","description":"Only the initiating actor in the same organization with current item access may read this job. A completed reconstruction can have estimate: null. Results expire after 24 hours; physical cleanup occurs on a subsequent submission.","parameters":[{"name":"asset","in":"query","schema":{"type":"string","enum":["model"]},"description":"Download the reconstructed GLB instead of JSON state."}],"responses":{"200":{"description":"JSON job state, or GLB when asset=model.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Bulk3dState"}},"model/gltf-binary":{"schema":{"type":"string","format":"binary"}}}},"403":{"description":"ai.count and access to the item are required."},"404":{"description":"Job not found or not owned by caller."},"409":{"description":"Model not ready."},"410":{"description":"Result expired."},"503":{"description":"Required runtime/provider or service unavailable."}}}}},"webhooks":{"inventoryEvent":{"post":{"tags":["Webhooks"],"summary":"Receive an outgoing Inventory event","security":[],"description":"This operation documents the HTTP request Inventory sends to each subscribed target; it is not an endpoint hosted by Inventory. Delivery is at least once, so receivers must deduplicate by the stable event id. Return any 2xx status to acknowledge the exact request body.","parameters":[{"name":"X-Inventory-Event-Id","in":"header","required":true,"description":"Stable event UUID; use it as the receiver's deduplication key.","schema":{"type":"string","format":"uuid"}},{"name":"X-Inventory-Event-Type","in":"header","required":true,"description":"Event name, also present in the JSON envelope.","schema":{"$ref":"#/components/schemas/WebhookOutboundEventType"}},{"name":"X-Inventory-Delivery-Id","in":"header","required":true,"description":"UUID of this endpoint-specific delivery record.","schema":{"type":"string","format":"uuid"}},{"name":"X-Inventory-Timestamp","in":"header","required":true,"description":"Unix timestamp also carried as `t` in the signature header.","schema":{"type":"string","pattern":"^[0-9]+$"}},{"name":"X-Inventory-Signature","in":"header","required":true,"description":"`t=<unix>,v1=<hex>` where `v1` is the lowercase hexadecimal HMAC-SHA256 of `<unix>.<exact raw request body>` using the endpoint signing secret. Verify the raw bytes before parsing JSON.","schema":{"type":"string","pattern":"^t=[0-9]+,v1=[a-f0-9]{64}$"},"example":"t=1786608000,v1=7d6f2dba7b8d83cd0c87bfce4c34f35621e96fe930a29d309926f7156bdb976c"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"2XX":{"description":"Event acknowledged; Inventory marks the delivery successful."},"default":{"description":"Non-2xx response; transient statuses may be retried according to the delivery policy."}}}}},"components":{"securitySchemes":{"printAgent":{"type":"http","scheme":"bearer","bearerFormat":"iprt_ token","description":"Dedicated printer credential issued once by POST /label-printers. Only valid for agent claim and acknowledgement."},"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"inv_ token"},"adminSession":{"type":"apiKey","in":"cookie","name":"authjs.session-token","description":"Authenticated Auth.js browser session cookie; each operation declares its required permission. Not restricted to administrators. HTTPS deployments use the secure-prefixed cookie variant."},"superadminSession":{"type":"apiKey","in":"cookie","name":"authjs.session-token","description":"Auth.js browser session cookie for an account whose email is listed in the deployment's `SUPERADMIN_EMAILS` environment variable. HTTPS deployments use the secure-prefixed cookie variant."},"cronSecret":{"type":"http","scheme":"bearer","bearerFormat":"NOTIFICATION_CRON_SECRET","description":"Deployment-level scheduler secret used only by the notification run endpoint."},"webhookCronSecret":{"type":"http","scheme":"bearer","bearerFormat":"WEBHOOK_CRON_SECRET","description":"Deployment-level scheduler secret used only by the outgoing webhook run endpoint."}},"parameters":{"OrganizationId":{"name":"X-Organization-ID","in":"header","required":false,"description":"Organization membership selected for this request. User-bound credentials may select any active membership; standalone tokens may only repeat their pinned organization ID.","schema":{"type":"string","format":"uuid"}},"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"description":"UUID identifying one queue operation; safe to reuse for retries.","schema":{"type":"string","format":"uuid"}},"RequiredIdempotencyKey":{"name":"Idempotency-Key","in":"header","required":true,"description":"UUID identifying this atomic operation; reuse it only to retry the exact same request.","schema":{"type":"string","format":"uuid"}},"ResourceId":{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},"ResourceReference":{"name":"id","in":"path","required":true,"description":"Resource UUID or one of the resource's organization-scoped slugs.","schema":{"type":"string","minLength":1,"maxLength":80}},"CustomFieldId":{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},"WebhookId":{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},"WebhookDeliveryId":{"name":"deliveryId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}},"responses":{"NotFound":{"description":"Resource not found"}},"schemas":{"StockPlanningItem":{"type":"object","required":["resourceId","name","subtitle","sku","quantity","unitName","minimumStock","reorderQuantity","leadTimeDays","purchaseUnitName","purchaseUnitFactor","observedDays","consumed","recentConsumed","demandDays","receipts","history"],"properties":{"resourceId":{"type":"string","format":"uuid"},"name":{"type":"string"},"subtitle":{"type":"string"},"sku":{"anyOf":[{"type":"string"},{"type":"null"}]},"quantity":{"type":"number"},"unitName":{"type":"string"},"minimumStock":{"type":"number"},"reorderQuantity":{"type":"number"},"leadTimeDays":{"type":"number"},"purchaseUnitName":{"anyOf":[{"type":"string"},{"type":"null"}]},"purchaseUnitFactor":{"anyOf":[{"type":"number"},{"type":"null"}]},"observedDays":{"type":"number"},"consumed":{"type":"number"},"recentConsumed":{"type":"number"},"demandDays":{"type":"integer"},"receipts":{"type":"array","items":{"type":"object","required":["quantity","expectedAt"],"properties":{"quantity":{"type":"number"},"expectedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}}}},"history":{"type":"array","items":{"type":"object","required":["day","quantity"],"properties":{"day":{"type":"number"},"quantity":{"type":"number"}}}}}},"SharedPrintJob":{"type":"object","required":["id","printerId","count","status","createdAt","spoolJobId"],"properties":{"id":{"type":"string","format":"uuid"},"printerId":{"type":"string","format":"uuid"},"count":{"type":"integer","minimum":1,"maximum":100},"status":{"type":"string","enum":["queued","claimed","submitted","failed","uncertain","cancelled","expired"]},"createdAt":{"type":"string","format":"date-time"},"spoolJobId":{"anyOf":[{"type":"integer"},{"type":"null"}]}},"description":"submitted confirms Windows spooler acceptance, not physical output. uncertain jobs are never automatically reprinted."},"SharedPrinter":{"type":"object","required":["id","name","tape","online","enabled"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"tape":{"type":"number"},"online":{"type":"boolean"},"enabled":{"type":"boolean"}}},"LabelWorkspace":{"type":"object","required":["revision","labels","preferences"],"properties":{"revision":{"type":"integer","minimum":0},"labels":{"type":"array","items":{"$ref":"#/components/schemas/SavedLabel"}},"preferences":{"$ref":"#/components/schemas/LabelPreferences"}}},"Bulk3dState":{"oneOf":[{"type":"object","properties":{"status":{"type":"string","enum":["queued","loading","reconstructing","analyzing"]}},"required":["status"],"additionalProperties":false},{"type":"object","properties":{"status":{"type":"string","const":"completed"},"result":{"$ref":"#/components/schemas/Bulk3dResult"}},"required":["status","result"],"additionalProperties":false},{"type":"object","properties":{"status":{"type":"string","const":"failed"},"code":{"type":"string","enum":["analysisFailed","timeout"]}},"required":["status","code"],"additionalProperties":false}]},"Bulk3dJob":{"type":"object","properties":{"jobId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"expiresAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"}},"required":["jobId","expiresAt"],"additionalProperties":false},"Bulk3dResult":{"type":"object","properties":{"method":{"type":"string","const":"bulk_3d"},"version":{"type":"string","const":"mapanything_manual_v1"},"model":{"type":"string","const":"facebook/map-anything"},"isExact":{"type":"boolean","const":false},"accuracyValidated":{"type":"boolean","const":false},"estimate":{"anyOf":[{"type":"object","properties":{"count":{"type":"integer","minimum":1,"maximum":1000000},"lowerBound":{"type":"integer","minimum":0,"maximum":1000000},"upperBound":{"type":"integer","minimum":1,"maximum":1000000}},"required":["count","lowerBound","upperBound"],"additionalProperties":false},{"type":"null"}]},"warningCodes":{"maxItems":5,"type":"array","items":{"type":"string","enum":["hiddenBottom","partShape","manualMarks","geometry","sampleSpread"]}},"imageCount":{"type":"integer","minimum":3,"maximum":4},"sampleCount":{"type":"integer","minimum":3,"maximum":20},"inferenceSeconds":{"type":"number","minimum":0,"maximum":600}},"required":["method","version","model","isExact","accuracyValidated","estimate","warningCodes","imageCount","sampleCount","inferenceSeconds"],"additionalProperties":false,"description":"Experimental estimate from reconstructed geometry and manual assumptions. estimate can be null even when a GLB is available. No validated accuracy or automatic stock booking."},"Bulk3dInput":{"type":"object","properties":{"itemId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"language":{"type":"string","enum":["de","en"]},"marks":{"type":"object","properties":{"pile":{"minItems":4,"maxItems":20,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":0,"maximum":1},{"type":"number","minimum":0,"maximum":1}]}},"table":{"minItems":3,"maxItems":3,"type":"array","items":{"type":"array","prefixItems":[{"type":"number","minimum":0,"maximum":1},{"type":"number","minimum":0,"maximum":1}]}},"edges":{"minItems":3,"maxItems":20,"type":"array","items":{"type":"array","prefixItems":[{"type":"array","prefixItems":[{"type":"number","minimum":0,"maximum":1},{"type":"number","minimum":0,"maximum":1}]},{"type":"array","prefixItems":[{"type":"number","minimum":0,"maximum":1},{"type":"number","minimum":0,"maximum":1}]}]}}},"required":["pile","table","edges"],"additionalProperties":false},"assumptions":{"type":"object","properties":{"shape":{"type":"string","enum":["ellipsoid","cuboid","triangular_prism"]},"widthRatio":{"type":"number","minimum":0.1,"maximum":2},"heightRatio":{"type":"number","minimum":0.1,"maximum":2},"packing":{"type":"number","minimum":0.1,"maximum":1},"floorOffset":{"type":"number","minimum":0,"maximum":3}},"required":["shape","widthRatio","heightRatio","packing","floorOffset"],"additionalProperties":false}},"required":["itemId","language","marks","assumptions"],"additionalProperties":false,"description":"Coordinates are normalized [0,1] in the first oriented photo. Use a simple fill polygon, three non-collinear table points outside it, and at least three representative part-length segments within the fill area. Other geometry checks apply."},"BulkCountResult":{"type":"object","properties":{"estimate":{"anyOf":[{"type":"object","properties":{"count":{"type":"integer","minimum":0,"maximum":1000000},"lowerBound":{"type":"integer","minimum":0,"maximum":1000000},"upperBound":{"type":"integer","minimum":0,"maximum":1000000}},"required":["count","lowerBound","upperBound"],"additionalProperties":false},{"type":"null"}]},"visibility":{"type":"string","enum":["mostly_visible","partial_layers","surface_only","unclear"]},"explanation":{"type":"string","minLength":1,"maxLength":1500},"assumptions":{"maxItems":6,"type":"array","items":{"type":"string","minLength":1,"maxLength":400}},"warnings":{"maxItems":6,"type":"array","items":{"type":"string","minLength":1,"maxLength":400}},"captureAdvice":{"maxItems":4,"type":"array","items":{"type":"string","minLength":1,"maxLength":400}},"method":{"type":"string","const":"bulk_visual"},"isExact":{"type":"boolean","const":false},"accuracyValidated":{"type":"boolean","const":false},"model":{"type":"string","minLength":1,"maxLength":200},"analysis":{"type":"object","properties":{"version":{"type":"string","const":"bulk_visual_v3"},"agreement":{"type":"string","enum":["overlap","divergent","insufficient","empty"]},"methods":{"minItems":2,"maxItems":2,"type":"array","items":{"type":"object","properties":{"strategy":{"type":"string","enum":["layers","volume"]},"estimate":{"anyOf":[{"type":"object","properties":{"count":{"type":"integer","minimum":0,"maximum":1000000},"lowerBound":{"type":"integer","minimum":0,"maximum":1000000},"upperBound":{"type":"integer","minimum":0,"maximum":1000000}},"required":["count","lowerBound","upperBound"],"additionalProperties":false},{"type":"null"}]},"observation":{"type":"object","properties":{"status":{"type":"string","enum":["estimated","empty","insufficient"]},"depthEvidence":{"type":"string","enum":["observed","inferred","unconstrained"]},"visibleMinimum":{"type":"integer","minimum":0,"maximum":1000000},"views":{"minItems":3,"maxItems":5,"type":"array","items":{"type":"object","properties":{"image":{"type":"integer","minimum":1,"maximum":5},"evidence":{"type":"string","minLength":1,"maxLength":400}},"required":["image","evidence"],"additionalProperties":false}},"factorA":{"anyOf":[{"type":"object","properties":{"low":{"type":"number","exclusiveMinimum":0,"maximum":1000000},"best":{"type":"number","exclusiveMinimum":0,"maximum":1000000},"high":{"type":"number","exclusiveMinimum":0,"maximum":1000000}},"required":["low","best","high"],"additionalProperties":false},{"type":"null"}]},"factorB":{"anyOf":[{"type":"object","properties":{"low":{"type":"number","exclusiveMinimum":0,"maximum":1000000},"best":{"type":"number","exclusiveMinimum":0,"maximum":1000000},"high":{"type":"number","exclusiveMinimum":0,"maximum":1000000}},"required":["low","best","high"],"additionalProperties":false},{"type":"null"}]},"volumeGeometry":{"anyOf":[{"type":"object","properties":{"lengthInItemLengths":{"type":"object","properties":{"low":{"type":"number","exclusiveMinimum":0,"maximum":1000000},"best":{"type":"number","exclusiveMinimum":0,"maximum":1000000},"high":{"type":"number","exclusiveMinimum":0,"maximum":1000000}},"required":["low","best","high"],"additionalProperties":false},"widthInItemWidths":{"type":"object","properties":{"low":{"type":"number","exclusiveMinimum":0,"maximum":1000000},"best":{"type":"number","exclusiveMinimum":0,"maximum":1000000},"high":{"type":"number","exclusiveMinimum":0,"maximum":1000000}},"required":["low","best","high"],"additionalProperties":false},"depthInItemHeights":{"type":"object","properties":{"low":{"type":"number","exclusiveMinimum":0,"maximum":1000000},"best":{"type":"number","exclusiveMinimum":0,"maximum":1000000},"high":{"type":"number","exclusiveMinimum":0,"maximum":1000000}},"required":["low","best","high"],"additionalProperties":false},"containerVolumeFraction":{"type":"object","properties":{"low":{"type":"number","exclusiveMinimum":0,"maximum":1000000},"best":{"type":"number","exclusiveMinimum":0,"maximum":1000000},"high":{"type":"number","exclusiveMinimum":0,"maximum":1000000}},"required":["low","best","high"],"additionalProperties":false},"itemShapeFraction":{"type":"object","properties":{"low":{"type":"number","exclusiveMinimum":0,"maximum":1000000},"best":{"type":"number","exclusiveMinimum":0,"maximum":1000000},"high":{"type":"number","exclusiveMinimum":0,"maximum":1000000}},"required":["low","best","high"],"additionalProperties":false},"outerEnvelopePacking":{"type":"object","properties":{"low":{"type":"number","exclusiveMinimum":0,"maximum":1000000},"best":{"type":"number","exclusiveMinimum":0,"maximum":1000000},"high":{"type":"number","exclusiveMinimum":0,"maximum":1000000}},"required":["low","best","high"],"additionalProperties":false}},"required":["lengthInItemLengths","widthInItemWidths","depthInItemHeights","containerVolumeFraction","itemShapeFraction","outerEnvelopePacking"],"additionalProperties":false},{"type":"null"}]},"explanation":{"type":"string","minLength":1,"maxLength":600},"assumptions":{"maxItems":3,"type":"array","items":{"type":"string","minLength":1,"maxLength":400}},"warnings":{"maxItems":2,"type":"array","items":{"type":"string","minLength":1,"maxLength":400}},"captureAdvice":{"maxItems":2,"type":"array","items":{"type":"string","minLength":1,"maxLength":400}}},"required":["status","depthEvidence","visibleMinimum","views","factorA","factorB","volumeGeometry","explanation","assumptions","warnings","captureAdvice"],"additionalProperties":false}},"required":["strategy","estimate","observation"],"additionalProperties":false}}},"required":["version","agreement","methods"],"additionalProperties":false}},"required":["estimate","visibility","explanation","assumptions","warnings","captureAdvice","method","isExact","accuracyValidated","model"],"additionalProperties":false,"description":"Experimental, uncalibrated estimate. estimate can be null when evidence is insufficient. The range is not a confidence interval. This response never books stock."},"BulkCountInput":{"type":"object","properties":{"itemId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"itemHint":{"type":"string","minLength":1,"maxLength":240},"language":{"type":"string","enum":["de","en"]},"containerDimensions":{"anyOf":[{"type":"object","properties":{"lengthMm":{"type":"number","exclusiveMinimum":0,"maximum":10000},"widthMm":{"type":"number","exclusiveMinimum":0,"maximum":10000},"heightMm":{"type":"number","exclusiveMinimum":0,"maximum":10000}},"required":["lengthMm","widthMm","heightMm"],"additionalProperties":false},{"type":"null"}]},"partDimensions":{"anyOf":[{"type":"object","properties":{"lengthMm":{"type":"number","exclusiveMinimum":0,"maximum":10000},"widthMm":{"type":"number","exclusiveMinimum":0,"maximum":10000},"heightMm":{"type":"number","exclusiveMinimum":0,"maximum":10000}},"required":["lengthMm","widthMm","heightMm"],"additionalProperties":false},{"type":"null"}]}},"required":["itemId","itemHint","language","containerDimensions","partDimensions"],"additionalProperties":false},"SharedPrintInput":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"printerId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"tape":{"type":"number","enum":[3.5,6,9,12,18,24]},"labels":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"string","minLength":1,"maxLength":5333334,"pattern":"^[A-Za-z0-9+/]+={0,2}$"}}},"required":["id","printerId","tape","labels"],"additionalProperties":false,"description":"id is a client-generated UUID used for idempotency. labels contains base64-encoded PT-P710BT raster labels, not images or arbitrary printer commands. All labels must use the printer tape width. At most 100 labels and 4,000,000 bytes in the combined RAW job."},"LabelWorkspaceMutation":{"oneOf":[{"type":"object","properties":{"action":{"type":"string","const":"preferences"},"preferences":{"$ref":"#/components/schemas/LabelPreferences"}},"required":["action","preferences"],"additionalProperties":false},{"type":"object","properties":{"action":{"type":"string","const":"queue"},"revision":{"type":"integer","minimum":0,"maximum":9007199254740991},"labels":{"maxItems":100,"type":"array","items":{"$ref":"#/components/schemas/SavedLabel"}}},"required":["action","revision","labels"],"additionalProperties":false}]},"LabelPreferences":{"type":"object","properties":{"setupId":{"type":"string","maxLength":100},"printTarget":{"type":"string","enum":["browser","ptouch","shared"]},"tape":{"type":"number","enum":[3.5,6,9,12,18,24]},"printer":{"type":"string","maxLength":320},"sharedPrinter":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"string","const":""}]}},"additionalProperties":false},"SavedLabel":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string","maxLength":10000},"template":{"type":"string","maxLength":10000},"tape":{"type":"number","enum":[3.5,6,9,12,18,24]},"widthMm":{"type":"number","exclusiveMinimum":0,"maximum":1000},"data":{"type":"string","maxLength":400000,"pattern":"^[A-Za-z0-9+/]+={0,2}$"},"preview":{"type":"string","maxLength":1500000,"pattern":"^data:image\\/png;base64,[A-Za-z0-9+/]+={0,2}$"},"resource":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string","maxLength":10000},"subtitle":{"type":"string","maxLength":10000},"sku":{"anyOf":[{"type":"string","maxLength":10000},{"type":"null"}]},"barcode":{"anyOf":[{"type":"string","maxLength":10000},{"type":"null"}]},"location":{"anyOf":[{"type":"string","maxLength":10000},{"type":"null"}]},"type":{"type":"string","maxLength":64},"quantity":{"type":"number"},"cover":{"anyOf":[{"type":"object","properties":{"url":{"type":"string","maxLength":8192},"altText":{"type":"string","maxLength":10000}},"required":["url","altText"]},{"type":"null"}]},"stockUnit":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string","maxLength":10000},"location":{"anyOf":[{"type":"string","maxLength":10000},{"type":"null"}]}},"required":["id","code","location"]}},"required":["id","name","sku","barcode","location","type","quantity","cover"]},"original":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"name":{"type":"string","maxLength":10000},"subtitle":{"type":"string","maxLength":10000},"sku":{"anyOf":[{"type":"string","maxLength":10000},{"type":"null"}]},"barcode":{"anyOf":[{"type":"string","maxLength":10000},{"type":"null"}]},"location":{"anyOf":[{"type":"string","maxLength":10000},{"type":"null"}]},"type":{"type":"string","maxLength":64},"quantity":{"type":"number"},"cover":{"anyOf":[{"type":"object","properties":{"url":{"type":"string","maxLength":8192},"altText":{"type":"string","maxLength":10000}},"required":["url","altText"]},{"type":"null"}]},"stockUnit":{"type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string","maxLength":10000},"location":{"anyOf":[{"type":"string","maxLength":10000},{"type":"null"}]}},"required":["id","code","location"]}},"required":["id","name","sku","barcode","location","type","quantity","cover"]},"setup":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":160},"widthMm":{"type":"number","exclusiveMinimum":0,"maximum":1000},"heightMm":{"type":"number","exclusiveMinimum":0,"maximum":1000},"elements":{"$ref":"#/components/schemas/LabelElements"},"inverted":{"type":"boolean"},"id":{"type":"string","maxLength":100},"revision":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"createdAt":{"type":"string","maxLength":10000},"updatedAt":{"type":"string","maxLength":10000}},"required":["name","widthMm","heightMm","elements","id","revision","createdAt","updatedAt"],"additionalProperties":false}},"required":["id","name","template","tape","widthMm","data","preview","resource","original","setup"]},"OrganizationSummary":{"type":"object","additionalProperties":false,"required":["id","name","slug","isReadOnly","allowNegativeStock"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":160},"slug":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"isReadOnly":{"type":"boolean"},"allowNegativeStock":{"type":"boolean"}}},"OrganizationMembership":{"type":"object","additionalProperties":false,"required":["id","name","slug","isReadOnly","allowNegativeStock","role","roleName"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":160},"slug":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Short, editable identifier used as the first Webapp URL segment."},"role":{"type":["string","null"],"pattern":"^[a-z][a-z0-9_-]{0,63}$"},"roleName":{"type":["string","null"]},"isReadOnly":{"type":"boolean"},"allowNegativeStock":{"type":"boolean","description":"Whether bulk stock balances may fall below zero in this organization."},"canManage":{"type":"boolean","description":"Present on organization-list responses; true when the current identity can administer that active organization."}}},"NotificationEventType":{"type":"string","enum":["low_stock","expiry","maintenance","return_due"]},"Notification":{"type":"object","required":["id","eventType","sourceKey","title","body","metadata","createdAt"],"properties":{"id":{"type":"string","format":"uuid"},"eventType":{"$ref":"#/components/schemas/NotificationEventType"},"resourceId":{"type":["string","null"],"format":"uuid"},"assignmentId":{"type":["string","null"],"format":"uuid"},"sourceKey":{"type":"string"},"title":{"type":"string"},"body":{"type":"string"},"href":{"type":["string","null"]},"metadata":{"type":"object","additionalProperties":true},"readAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"NotificationPreferencePatch":{"type":"object","additionalProperties":false,"properties":{"enabledEventTypes":{"type":"array","uniqueItems":true,"maxItems":4,"items":{"$ref":"#/components/schemas/NotificationEventType"}},"frequency":{"type":"string","enum":["daily","immediate"]},"digestHour":{"type":"integer","minimum":0,"maximum":23},"timezone":{"type":"string","maxLength":80},"locale":{"type":"string","enum":["en","de"]},"cooldownHours":{"type":"integer","minimum":1,"maximum":720},"lowStockThresholdPercent":{"type":"integer","minimum":1,"maximum":500},"expiryWindowDays":{"type":"integer","minimum":0,"maximum":3650},"expiryFieldKey":{"type":"string","maxLength":64,"pattern":"^[a-z][a-z0-9_]{0,63}$"},"maintenanceWindowDays":{"type":"integer","minimum":0,"maximum":3650},"maintenanceFieldKey":{"type":"string","maxLength":64,"pattern":"^[a-z][a-z0-9_]{0,63}$"},"returnDueWindowDays":{"type":"integer","minimum":0,"maximum":365},"emailEnabled":{"type":"boolean","default":false},"pushEnabled":{"type":"boolean","default":false},"slackEnabled":{"type":"boolean","default":false},"teamsEnabled":{"type":"boolean","default":false},"webhookEnabled":{"type":"boolean","default":false}}},"WooCommerceConnectionInput":{"type":"object","additionalProperties":false,"required":["storeUrl","consumerKey","consumerSecret"],"properties":{"storeUrl":{"type":"string","format":"uri","minLength":1,"maxLength":2048,"description":"Public HTTPS WooCommerce store URL, optionally including a WordPress subdirectory. Query strings and fragments are rejected.","examples":["https://shop.example.com"]},"consumerKey":{"type":"string","minLength":8,"maxLength":200,"pattern":"^ck_","writeOnly":true},"consumerSecret":{"type":"string","minLength":8,"maxLength":200,"pattern":"^cs_","writeOnly":true}}},"WooCommerceConnection":{"type":"object","additionalProperties":false,"required":["id","storeUrl","consumerKeyHint","status","syncEnabled","lastCheckedAt","lastSuccessAt","lastError","lastWebhookAt","lastSyncAt","lastSyncError","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"storeUrl":{"type":"string","format":"uri"},"consumerKeyHint":{"type":"string","description":"Redacted Consumer Key. The complete key and secret are never returned.","examples":["ck_1234…cdef"]},"status":{"type":"string","enum":["connected","error"]},"syncEnabled":{"type":"boolean"},"lastCheckedAt":{"type":["string","null"],"format":"date-time"},"lastSuccessAt":{"type":["string","null"],"format":"date-time"},"lastError":{"type":["string","null"]},"lastWebhookAt":{"type":["string","null"],"format":"date-time"},"lastSyncAt":{"type":["string","null"],"format":"date-time"},"lastSyncError":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"WooCommerceConnectionTest":{"type":"object","additionalProperties":false,"required":["productCount","checkedAt"],"properties":{"productCount":{"type":["integer","null"],"minimum":0,"description":"Product count reported by WooCommerce when available."},"checkedAt":{"type":"string","format":"date-time"}}},"WooCommerceConnectionStatusResponse":{"type":"object","additionalProperties":false,"required":["connection","sync","encryptionConfigured"],"properties":{"connection":{"oneOf":[{"$ref":"#/components/schemas/WooCommerceConnection"},{"type":"null"}]},"sync":{"oneOf":[{"$ref":"#/components/schemas/WooCommerceSyncOverview"},{"type":"null"}]},"encryptionConfigured":{"type":"boolean"}}},"WooCommerceSyncPatch":{"type":"object","additionalProperties":false,"required":["syncEnabled"],"properties":{"syncEnabled":{"type":"boolean"}}},"WooCommerceManualSyncRequest":{"oneOf":[{"type":"object","additionalProperties":false,"required":["orderId"],"properties":{"orderId":{"type":"integer","minimum":1}}},{"type":"object","additionalProperties":false,"required":["window"],"properties":{"window":{"type":"string","const":"last-7-days"}}},{"type":"object","additionalProperties":false,"maxProperties":0}]},"WooCommerceOrderLineIssue":{"type":"object","additionalProperties":false,"required":["lineItemId","sku","status","error"],"properties":{"lineItemId":{"type":"integer","minimum":1},"sku":{"type":"string"},"status":{"type":"string","enum":["unmapped","error"]},"error":{"type":["string","null"]}}},"WooCommerceOrderSync":{"type":"object","additionalProperties":false,"required":["orderId","localOrderId","orderNumber","orderStatus","status","totalLines","syncedLines","lastError","updatedAt","issues"],"properties":{"orderId":{"type":"integer","minimum":1},"localOrderId":{"type":["string","null"],"format":"uuid"},"orderNumber":{"type":"string"},"orderStatus":{"type":"string"},"status":{"type":"string","enum":["succeeded","partial","failed"]},"totalLines":{"type":"integer","minimum":0},"syncedLines":{"type":"integer","minimum":0},"lastError":{"type":["string","null"]},"updatedAt":{"type":"string","format":"date-time"},"issues":{"type":"array","items":{"$ref":"#/components/schemas/WooCommerceOrderLineIssue"}}}},"WooCommerceSyncOverview":{"type":"object","additionalProperties":false,"required":["totalOrders","issueOrders","recentOrders"],"properties":{"totalOrders":{"type":"integer","minimum":0},"issueOrders":{"type":"integer","minimum":0},"recentOrders":{"type":"array","items":{"$ref":"#/components/schemas/WooCommerceOrderSync"}}}},"WooCommerceConnectionMutationResponse":{"type":"object","additionalProperties":false,"required":["connection","test"],"properties":{"connection":{"$ref":"#/components/schemas/WooCommerceConnection"},"test":{"$ref":"#/components/schemas/WooCommerceConnectionTest"}}},"WebhookEventType":{"type":"string","description":"Stable integration event name selected when configuring an endpoint.","enum":["inventory.resource.created","inventory.resource.updated","inventory.resource.deleted","inventory.resource.merged","inventory.stock.movement.created"]},"WebhookOutboundEventType":{"type":"string","description":"Event name sent in a delivery. Test actions use a dedicated type that cannot be subscribed to.","enum":["inventory.resource.created","inventory.resource.updated","inventory.resource.deleted","inventory.resource.merged","inventory.stock.movement.created","inventory.webhook.test"]},"WebhookEndpointCreate":{"type":"object","additionalProperties":false,"required":["name","url","eventTypes"],"properties":{"name":{"type":"string","minLength":1,"maxLength":120},"url":{"type":"string","format":"uri","minLength":1,"maxLength":2048,"description":"Absolute HTTPS delivery target. Private and local networks are blocked unless the deployment explicitly opts in."},"eventTypes":{"type":"array","minItems":1,"maxItems":5,"uniqueItems":true,"items":{"$ref":"#/components/schemas/WebhookEventType"}},"enabled":{"type":"boolean","default":true}}},"WebhookEndpointPatch":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"name":{"type":"string","minLength":1,"maxLength":120},"url":{"type":"string","format":"uri","minLength":1,"maxLength":2048,"description":"Complete replacement HTTPS target; the current stored target cannot be recovered from its redacted response form."},"eventTypes":{"type":"array","minItems":1,"maxItems":5,"uniqueItems":true,"items":{"$ref":"#/components/schemas/WebhookEventType"}},"enabled":{"type":"boolean"}}},"WebhookEndpoint":{"type":"object","additionalProperties":false,"required":["id","name","target","eventTypes","enabled","failureCount","lastSuccessAt","lastFailureAt","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"target":{"type":"string","description":"Redacted delivery target. Query values and secret path segments are never returned.","examples":["https://hooks.example.com/…"]},"eventTypes":{"type":"array","uniqueItems":true,"items":{"$ref":"#/components/schemas/WebhookEventType"}},"enabled":{"type":"boolean"},"failureCount":{"type":"integer","minimum":0},"lastSuccessAt":{"type":["string","null"],"format":"date-time"},"lastFailureAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"WebhookListResponse":{"type":"object","additionalProperties":false,"required":["webhooks"],"properties":{"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}}}},"WebhookResponse":{"type":"object","additionalProperties":false,"required":["webhook"],"properties":{"webhook":{"$ref":"#/components/schemas/WebhookEndpoint"}}},"WebhookCreatedResponse":{"type":"object","additionalProperties":false,"required":["webhook","secret"],"properties":{"webhook":{"$ref":"#/components/schemas/WebhookEndpoint"},"secret":{"type":"string","description":"Signing secret disclosed once. It is encrypted at rest and cannot be retrieved later."}}},"WebhookSecretResponse":{"type":"object","additionalProperties":false,"required":["secret"],"properties":{"secret":{"type":"string","description":"Replacement signing secret disclosed once."}}},"WebhookTestResponse":{"type":"object","additionalProperties":false,"required":["eventId","deliveryId"],"properties":{"eventId":{"type":"string","format":"uuid"},"deliveryId":{"type":"string","format":"uuid"}}},"WebhookDeliveryStatus":{"type":"string","enum":["pending","processing","succeeded","failed"]},"WebhookDeliveryEvent":{"type":"object","additionalProperties":false,"required":["id","type","occurredAt"],"properties":{"id":{"type":"string","format":"uuid"},"type":{"$ref":"#/components/schemas/WebhookOutboundEventType"},"occurredAt":{"type":"string","format":"date-time"}}},"WebhookDelivery":{"type":"object","additionalProperties":false,"required":["id","status","attempts","nextAttemptAt","httpStatus","error","deliveredAt","createdAt","event"],"properties":{"id":{"type":"string","format":"uuid"},"status":{"$ref":"#/components/schemas/WebhookDeliveryStatus"},"attempts":{"type":"integer","minimum":0},"nextAttemptAt":{"type":"string","format":"date-time"},"httpStatus":{"type":["integer","null"],"minimum":100,"maximum":599},"error":{"type":["string","null"]},"deliveredAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"event":{"$ref":"#/components/schemas/WebhookDeliveryEvent"}}},"WebhookDeliveryState":{"type":"object","additionalProperties":false,"description":"Delivery state returned immediately after a manual retry; fetch the delivery list for its event summary.","required":["id","status","attempts","nextAttemptAt","httpStatus","error","deliveredAt","createdAt"],"properties":{"id":{"type":"string","format":"uuid"},"status":{"$ref":"#/components/schemas/WebhookDeliveryStatus"},"attempts":{"type":"integer","minimum":0},"nextAttemptAt":{"type":"string","format":"date-time"},"httpStatus":{"type":["integer","null"],"minimum":100,"maximum":599},"error":{"type":["string","null"]},"deliveredAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"WebhookDeliveryListResponse":{"type":"object","additionalProperties":false,"required":["deliveries"],"properties":{"deliveries":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}}}},"WebhookDeliveryResponse":{"type":"object","additionalProperties":false,"required":["delivery"],"properties":{"delivery":{"$ref":"#/components/schemas/WebhookDeliveryState"}}},"WebhookRunResponse":{"type":"object","additionalProperties":false,"required":["processed","results"],"properties":{"processed":{"type":"integer","minimum":0},"results":{"type":"array","items":{"type":"string","enum":["succeeded","failed"]}}}},"WebhookEvent":{"type":"object","additionalProperties":false,"required":["id","type","apiVersion","occurredAt","actor","data"],"properties":{"id":{"type":"string","format":"uuid","description":"Stable event identifier used by receivers for deduplication across retries."},"type":{"$ref":"#/components/schemas/WebhookOutboundEventType"},"apiVersion":{"type":"string","const":"1"},"occurredAt":{"type":"string","format":"date-time"},"actor":{"type":["string","null"],"description":"Identity responsible for the event when one is available."},"data":{"type":"object","additionalProperties":true,"description":"Event-specific snapshot: create, update, and delete events include `resource`; updates also include `changedFields`; merges include `keptResource`, `removedResource`, `keptResourceId`, and `removedResourceId`; stock movement events include the immutable `movement` snapshot; test deliveries include `test: true` and a human-readable `message`."}}},"AccessRoleKey":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_-]{0,63}$","description":"Stable lowercase identifier for a built-in or custom role.","examples":["editor","warehouse_team"]},"AppPermission":{"type":"string","description":"Granular workspace-wide capability assigned to a role.","enum":["inventory.read","inventory.create","inventory.update","inventory.delete","inventory.import","inventory.export","contacts.read","contacts.manage","stock.read","stock.manage","assignments.read","assignments.manage","counts.read","counts.manage","spatial.read","spatial.manage","orders.read","orders.manage","workflows.read","workflows.manage","labels.read","labels.manage","ai.use","settings.inventory-types.manage","settings.custom-fields.manage","settings.languages.manage","users.manage","roles.manage","sharing.manage","tokens.manage","tokens.delegate","webhooks.manage"]},"InventoryRulePermission":{"type":"string","description":"Permission that a conditional rule may grant for matching inventory items.","enum":["inventory.update","inventory.delete","stock.manage","assignments.manage","counts.manage","spatial.manage","ai.use"]},"PermissionDefinition":{"type":"object","additionalProperties":false,"required":["key","label","description"],"properties":{"key":{"$ref":"#/components/schemas/AppPermission"},"label":{"type":"string"},"description":{"type":"string"}}},"PermissionGroup":{"type":"object","additionalProperties":false,"required":["key","label","description","permissions"],"properties":{"key":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"},"permissions":{"type":"array","items":{"$ref":"#/components/schemas/PermissionDefinition"}}}},"AccessRoleInput":{"type":"object","additionalProperties":false,"required":["key","name"],"properties":{"key":{"$ref":"#/components/schemas/AccessRoleKey"},"name":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","maxLength":1000,"default":""},"permissions":{"type":"array","maxItems":30,"default":[],"items":{"$ref":"#/components/schemas/AppPermission"}}}},"AccessRolePatch":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"name":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","maxLength":1000},"permissions":{"type":"array","maxItems":30,"items":{"$ref":"#/components/schemas/AppPermission"}}}},"AccessRole":{"type":"object","additionalProperties":false,"required":["key","name","description","permissions","isSystem"],"properties":{"key":{"$ref":"#/components/schemas/AccessRoleKey"},"name":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","maxLength":1000},"permissions":{"type":"array","maxItems":30,"items":{"$ref":"#/components/schemas/AppPermission"}},"isSystem":{"type":"boolean","description":"Whether the role is built in and cannot be deleted."},"memberCount":{"type":"integer","minimum":0,"description":"Number of active users assigned to the role; included in role-list and create responses."},"createdBy":{"type":["string","null"],"maxLength":320},"updatedBy":{"type":["string","null"],"maxLength":320},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"AccessRuleCondition":{"type":"object","additionalProperties":false,"required":["field","operator"],"description":"One condition in a rule. Every condition in the same rule must match; comparisons are case-insensitive for strings.","properties":{"field":{"type":"string","pattern":"^(id|name|type|status|sku|location|serialNumber|priority|tags|categories|createdBy|customFields\\.[A-Za-z0-9_-]{1,120})$","description":"Built-in inventory field or a custom field addressed as customFields.KEY.","examples":["status","categories","customFields.department"]},"operator":{"type":"string","enum":["equals","not_equals","contains","starts_with","exists","not_exists"]},"value":{"description":"Comparison value. Required except for exists and not_exists, where it is ignored.","oneOf":[{"type":"string","maxLength":500},{"type":"number"},{"type":"boolean"},{"type":"null"}]}}},"InventoryAccessRuleInput":{"type":"object","additionalProperties":false,"required":["name","roleKey","permissions","conditions"],"description":"Additive item-specific access grant. Multiple enabled rules are ORed; all conditions inside this rule are ANDed.","properties":{"name":{"type":"string","minLength":1,"maxLength":160},"description":{"type":"string","maxLength":1000,"default":""},"roleKey":{"$ref":"#/components/schemas/AccessRoleKey"},"permissions":{"type":"array","minItems":1,"maxItems":7,"items":{"$ref":"#/components/schemas/InventoryRulePermission"}},"conditions":{"type":"array","minItems":1,"maxItems":12,"description":"Conditions combined with logical AND.","items":{"$ref":"#/components/schemas/AccessRuleCondition"}},"enabled":{"type":"boolean","default":true},"priority":{"type":"integer","minimum":0,"maximum":10000,"default":100,"description":"Display and evaluation order; lower values come first and do not override other matching rules."}},"examples":[{"name":"Update XYZ items","description":"Let members of the ABC role update items whose name contains xyz.","roleKey":"abc","permissions":["inventory.update"],"conditions":[{"field":"name","operator":"contains","value":"xyz"}],"enabled":true,"priority":100}]},"InventoryAccessRulePatch":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"name":{"type":"string","minLength":1,"maxLength":160},"description":{"type":"string","maxLength":1000},"roleKey":{"$ref":"#/components/schemas/AccessRoleKey"},"permissions":{"type":"array","minItems":1,"maxItems":7,"items":{"$ref":"#/components/schemas/InventoryRulePermission"}},"conditions":{"type":"array","minItems":1,"maxItems":12,"description":"Conditions combined with logical AND.","items":{"$ref":"#/components/schemas/AccessRuleCondition"}},"enabled":{"type":"boolean"},"priority":{"type":"integer","minimum":0,"maximum":10000}}},"InventoryAccessRule":{"type":"object","additionalProperties":false,"required":["id","name","description","roleKey","permissions","conditions","enabled","priority","createdAt","updatedAt"],"description":"Additive permission grant for matching inventory items. Rules never deny permissions already granted by a role; any matching enabled rule may grant access.","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":160},"description":{"type":"string","maxLength":1000},"roleKey":{"$ref":"#/components/schemas/AccessRoleKey"},"permissions":{"type":"array","minItems":1,"maxItems":7,"items":{"$ref":"#/components/schemas/InventoryRulePermission"}},"conditions":{"type":"array","minItems":1,"maxItems":12,"description":"Conditions combined with logical AND.","items":{"$ref":"#/components/schemas/AccessRuleCondition"}},"enabled":{"type":"boolean"},"priority":{"type":"integer","minimum":0,"maximum":10000},"createdBy":{"type":["string","null"],"maxLength":320},"updatedBy":{"type":["string","null"],"maxLength":320},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"SpatialVector3":{"type":"array","minItems":3,"maxItems":3,"items":{"type":"number","minimum":-10000,"maximum":10000},"description":"XYZ values in metres."},"SpatialDimensions":{"type":"array","minItems":3,"maxItems":3,"items":{"type":"number","minimum":0,"maximum":100}},"SpatialQuaternion":{"type":"array","minItems":4,"maxItems":4,"items":{"type":"number","minimum":-1,"maximum":1},"description":"Normalized XYZW quaternion."},"SpatialMatrix4":{"type":"array","minItems":16,"maxItems":16,"items":{"type":"number","minimum":-10000,"maximum":10000},"description":"Column-major affine 4x4 matrix."},"SpatialReferencePoint":{"type":"object","additionalProperties":false,"required":["id","localPosition","latitude","longitude"],"properties":{"id":{"type":"string","minLength":1,"maxLength":80},"label":{"type":"string","minLength":1,"maxLength":120},"localPosition":{"$ref":"#/components/schemas/SpatialVector3"},"latitude":{"type":"number","minimum":-90,"maximum":90},"longitude":{"type":"number","minimum":-180,"maximum":180},"altitude":{"type":"number","minimum":-12000,"maximum":100000}}},"SpatialGeoreference":{"type":"object","additionalProperties":false,"required":["latitude","longitude","headingDegrees","capturedAt","source"],"description":"Geographic anchor for one ARKit coordinate space. headingDegrees is the bearing of AR local -Z measured clockwise from true north; latitude/longitude/altitude identify localReferencePosition.","properties":{"latitude":{"type":"number","minimum":-90,"maximum":90},"longitude":{"type":"number","minimum":-180,"maximum":180},"altitude":{"type":"number","minimum":-12000,"maximum":100000},"headingDegrees":{"type":"number","minimum":0,"exclusiveMaximum":360},"horizontalAccuracy":{"type":"number","minimum":0,"maximum":100000},"verticalAccuracy":{"type":"number","minimum":0,"maximum":100000},"capturedAt":{"type":"string","format":"date-time"},"source":{"type":"string","enum":["gps","manual","qr-marker","app-clip","other"]},"localReferencePosition":{"allOf":[{"$ref":"#/components/schemas/SpatialVector3"}],"default":[0,0,0]},"referencePoints":{"type":"array","maxItems":64,"items":{"$ref":"#/components/schemas/SpatialReferencePoint"}},"entryMarkerCode":{"type":"string","minLength":1,"maxLength":240}}},"SpatialStructureCreate":{"type":"object","additionalProperties":false,"required":["name"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":240},"description":{"type":"string","maxLength":10000,"default":""},"georeference":{"oneOf":[{"$ref":"#/components/schemas/SpatialGeoreference"},{"type":"null"}]}}},"SpatialStructurePatch":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"name":{"type":"string","minLength":1,"maxLength":240},"description":{"type":"string","maxLength":10000},"georeference":{"oneOf":[{"$ref":"#/components/schemas/SpatialGeoreference"},{"type":"null"}]}}},"SpatialStructureSummary":{"type":"object","required":["id","name","description","floorCount","roomCount","activeScanCount","coordinateSpaceCount","bounds","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string"},"georeference":{"oneOf":[{"$ref":"#/components/schemas/SpatialGeoreference"},{"type":"null"}],"description":"Canonical building map marker, not necessarily the anchor for every room scan."},"floorCount":{"type":"integer","minimum":0},"roomCount":{"type":"integer","minimum":0},"activeScanCount":{"type":"integer","minimum":0},"coordinateSpaceCount":{"type":"integer","minimum":0},"bounds":{"oneOf":[{"type":"object","required":["min","max"],"properties":{"min":{"$ref":"#/components/schemas/SpatialVector3"},"max":{"$ref":"#/components/schemas/SpatialVector3"}}},{"type":"null"}],"description":"Local bounds only when every active scan shares one explicit coordinateSpaceId; otherwise null."},"boundsCoordinateSpaceId":{"type":["string","null"],"format":"uuid"},"boundsGeoreference":{"oneOf":[{"$ref":"#/components/schemas/SpatialGeoreference"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"RoomSceneElement":{"type":"object","additionalProperties":false,"required":["id","category","dimensions","transform","confidence"],"properties":{"id":{"type":"string","format":"uuid"},"category":{"type":"string","minLength":1,"maxLength":80},"dimensions":{"$ref":"#/components/schemas/SpatialDimensions"},"transform":{"$ref":"#/components/schemas/SpatialMatrix4"},"polygonCorners":{"type":"array","minItems":3,"maxItems":1024,"description":"Ordered RoomPlan boundary in the surface-local coordinate system; preferred over dimensions for non-rectangular floors.","items":{"$ref":"#/components/schemas/SpatialVector3"}},"confidence":{"type":"string","enum":["low","medium","high"]}}},"RoomScene":{"type":"object","additionalProperties":false,"required":["schemaVersion","coordinateSystem","units","matrixOrder","worldFromModel","webFromWorld","bounds","surfaces","objects"],"properties":{"schemaVersion":{"type":"integer","const":1},"coordinateSystem":{"type":"string","const":"arkit-right-handed-y-up"},"units":{"type":"string","const":"meter"},"matrixOrder":{"type":"string","const":"column-major"},"worldFromModel":{"$ref":"#/components/schemas/SpatialMatrix4"},"webFromWorld":{"allOf":[{"$ref":"#/components/schemas/SpatialMatrix4"}],"description":"Visualization transform shared by every scan with the same coordinateSpaceId."},"bounds":{"type":"object","additionalProperties":false,"required":["min","max"],"properties":{"min":{"$ref":"#/components/schemas/SpatialVector3"},"max":{"$ref":"#/components/schemas/SpatialVector3"}}},"surfaces":{"type":"array","maxItems":4096,"items":{"$ref":"#/components/schemas/RoomSceneElement"}},"objects":{"type":"array","maxItems":2048,"items":{"$ref":"#/components/schemas/RoomSceneElement"}}}},"RoomScanAsset":{"type":"object","required":["id","kind","name","mimeType","size","checksumSha256","url","createdAt"],"properties":{"id":{"type":"string","format":"uuid"},"kind":{"type":"string","enum":["world_map","model_usdz","structure_model","guide_image","textured_mesh","gaussian_splat"]},"name":{"type":"string"},"mimeType":{"type":"string"},"size":{"type":"integer","minimum":0},"checksumSha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"url":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"RoomScanSummary":{"type":"object","required":["id","roomResourceId","roomName","revision","status","capturedAt","createdAt","updatedAt","placementCount","assets","keyframeCount"],"properties":{"id":{"type":"string","format":"uuid"},"roomResourceId":{"type":"string","format":"uuid"},"roomName":{"type":"string"},"structureId":{"type":["string","null"],"format":"uuid"},"structureName":{"type":["string","null"]},"coordinateSpaceId":{"type":["string","null"],"format":"uuid"},"floorIdentifier":{"type":["string","null"]},"floorIndex":{"type":["integer","null"]},"roomIdentifier":{"type":["string","null"]},"layoutTransform":{"oneOf":[{"$ref":"#/components/schemas/SpatialMatrix4"},{"type":"null"}],"description":"Optional saved world-from-model transform used to arrange the room with the other rooms on its floor."},"georeference":{"oneOf":[{"$ref":"#/components/schemas/SpatialGeoreference"},{"type":"null"}]},"revision":{"type":"integer","minimum":1},"status":{"type":"string","enum":["active","superseded"]},"capturedAt":{"type":"string","format":"date-time"},"deviceModel":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"placementCount":{"type":"integer","minimum":0},"keyframeCount":{"type":"integer","minimum":0,"maximum":32,"description":"Number of calibrated reference photos. Full metadata is returned only by the room-scene detail endpoint."},"assets":{"type":"array","items":{"$ref":"#/components/schemas/RoomScanAsset"}}}},"RoomScanUploadResult":{"type":"object","additionalProperties":false,"required":["id","replayed"],"properties":{"id":{"type":"string","format":"uuid"},"replayed":{"type":"boolean"}}},"RoomLayoutTransformPatch":{"type":"object","additionalProperties":false,"required":["transform"],"properties":{"transform":{"oneOf":[{"$ref":"#/components/schemas/SpatialMatrix4"},{"type":"null"}]}}},"SpatialPlacementInput":{"type":"object","additionalProperties":false,"required":["position","orientation","confidence","method","capturedAt"],"properties":{"position":{"$ref":"#/components/schemas/SpatialVector3"},"orientation":{"$ref":"#/components/schemas/SpatialQuaternion"},"extent":{"$ref":"#/components/schemas/SpatialDimensions"},"confidence":{"type":"number","minimum":0,"maximum":1},"method":{"type":"string","enum":["scene-depth","mesh-raycast","plane-raycast","manual"]},"anchorIdentifier":{"type":"string","format":"uuid"},"capturedAt":{"type":"string","format":"date-time"},"localizationEvidence":{"$ref":"#/components/schemas/PhotoLocalizationEvidence"}}},"PhotoLocalizationEvidence":{"type":"object","additionalProperties":false,"required":["matchedKeyframeId","distance","confidence"],"properties":{"matchedKeyframeId":{"type":"string","format":"uuid"},"distance":{"type":"number","minimum":0,"maximum":1000000},"confidence":{"type":"number","minimum":0,"maximum":1},"cameraPositionError":{"type":"number","minimum":0,"maximum":100}}},"RoomCameraKeyframeInput":{"type":"object","additionalProperties":false,"required":["id","fileField","capturedAt","timestamp","cameraTransform","intrinsics","width","height","orientation","quality"],"properties":{"id":{"type":"string","format":"uuid"},"fileField":{"type":"string","description":"Must exactly equal keyframe:<id> and name one JPEG multipart part."},"capturedAt":{"type":"string","format":"date-time"},"timestamp":{"type":"number","minimum":0,"description":"ARFrame session timestamp in seconds."},"cameraTransform":{"allOf":[{"$ref":"#/components/schemas/SpatialMatrix4"}],"description":"Column-major worldFromCamera transform in the scan coordinate space."},"intrinsics":{"type":"array","minItems":9,"maxItems":9,"items":{"type":"number"},"description":"Column-major ARKit 3x3 pinhole-camera matrix for the encoded native-raster pixel dimensions. Apply orientation only when displaying the JPEG."},"width":{"type":"integer","minimum":1,"maximum":4096},"height":{"type":"integer","minimum":1,"maximum":4096},"orientation":{"type":"string","enum":["up","up-mirrored","down","down-mirrored","left-mirrored","right","right-mirrored","left"]},"quality":{"type":"number","minimum":0,"maximum":1},"featureDescriptor":{"type":["object","null"],"properties":{"format":{"type":"string","const":"vision-feature-print-v1"},"dataBase64":{"type":"string","maxLength":65536}}}}},"RoomCameraKeyframe":{"allOf":[{"type":"object","additionalProperties":false,"required":["id","capturedAt","timestamp","cameraTransform","intrinsics","width","height","orientation","quality","mimeType","size","checksumSha256","url"],"properties":{"id":{"type":"string","format":"uuid"},"capturedAt":{"type":"string","format":"date-time"},"timestamp":{"type":"number","minimum":0},"cameraTransform":{"$ref":"#/components/schemas/SpatialMatrix4"},"intrinsics":{"type":"array","minItems":9,"maxItems":9,"items":{"type":"number"}},"width":{"type":"integer","minimum":1,"maximum":4096},"height":{"type":"integer","minimum":1,"maximum":4096},"orientation":{"type":"string","enum":["up","up-mirrored","down","down-mirrored","left-mirrored","right","right-mirrored","left"]},"quality":{"type":"number","minimum":0,"maximum":1},"mimeType":{"type":"string","const":"image/jpeg"},"size":{"type":"integer","minimum":1,"maximum":6291456},"checksumSha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"url":{"type":"string"}}}]},"RoomSceneManifest":{"type":"object","required":["room","scan","placements"],"properties":{"structureId":{"type":["string","null"],"format":"uuid"},"structureName":{"type":["string","null"]},"coordinateSpaceId":{"type":["string","null"],"format":"uuid"},"floorIdentifier":{"type":["string","null"]},"floorIndex":{"type":["integer","null"]},"roomIdentifier":{"type":["string","null"]},"georeference":{"oneOf":[{"$ref":"#/components/schemas/SpatialGeoreference"},{"type":"null"}]},"room":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string"}}},"scan":{"type":"object","required":["id","revision","status","scene","capturedAt","assets","keyframes"],"properties":{"id":{"type":"string","format":"uuid"},"structureId":{"type":["string","null"],"format":"uuid"},"structureName":{"type":["string","null"]},"coordinateSpaceId":{"type":["string","null"],"format":"uuid"},"floorIdentifier":{"type":["string","null"]},"floorIndex":{"type":["integer","null"]},"roomIdentifier":{"type":["string","null"]},"layoutTransform":{"oneOf":[{"$ref":"#/components/schemas/SpatialMatrix4"},{"type":"null"}],"description":"Optional saved world-from-model transform used to arrange the room with the other rooms on its floor."},"georeference":{"oneOf":[{"$ref":"#/components/schemas/SpatialGeoreference"},{"type":"null"}]},"revision":{"type":"integer","minimum":1},"status":{"type":"string","enum":["active","superseded"]},"scene":{"$ref":"#/components/schemas/RoomScene"},"capturedAt":{"type":"string","format":"date-time"},"deviceModel":{"type":["string","null"]},"assets":{"type":"array","items":{"$ref":"#/components/schemas/RoomScanAsset"}},"keyframes":{"type":"array","maxItems":32,"items":{"$ref":"#/components/schemas/RoomCameraKeyframe"}}}},"placements":{"type":"array","items":{"type":"object","required":["id","resource","position","orientation","confidence","method","capturedAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"resource":{"type":"object","required":["id","name","type","status"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string"},"type":{"type":"string"},"status":{"type":"string"},"location":{"type":["string","null"]},"cover":{"type":["object","null"]}}},"position":{"$ref":"#/components/schemas/SpatialVector3"},"orientation":{"$ref":"#/components/schemas/SpatialQuaternion"},"extent":{"oneOf":[{"$ref":"#/components/schemas/SpatialDimensions"},{"type":"null"}]},"confidence":{"type":"number","minimum":0,"maximum":1},"method":{"type":"string","enum":["scene-depth","mesh-raycast","plane-raycast","manual"]},"anchorIdentifier":{"type":["string","null"],"format":"uuid"},"localizationEvidence":{"oneOf":[{"$ref":"#/components/schemas/PhotoLocalizationEvidence"},{"type":"null"}]},"capturedAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}},"DefinitionKey":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_-]{0,63}$"},"InventoryTypeKey":{"allOf":[{"$ref":"#/components/schemas/DefinitionKey"}],"description":"Stable key of an administrator-configurable inventory type."},"RelationTypeKey":{"allOf":[{"$ref":"#/components/schemas/DefinitionKey"}],"description":"Stable key of an administrator-configurable directed relationship type."},"InventoryTypeInput":{"type":"object","required":["key","label"],"additionalProperties":false,"properties":{"key":{"$ref":"#/components/schemas/InventoryTypeKey"},"label":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","maxLength":5000,"default":""},"color":{"type":"string","minLength":1,"maxLength":32,"default":"#635bff"},"icon":{"type":"string","minLength":1,"maxLength":80,"default":"box"},"canContain":{"type":"boolean","default":false,"description":"Records of this type can be used as parents and structured stock locations."},"spatialContainment":{"type":"boolean","default":false,"description":"Automatically derive containment from map polygons. Requires canContain."},"position":{"type":"integer","minimum":0,"maximum":100000,"default":0}}},"InventoryTypePatch":{"type":"object","minProperties":1,"additionalProperties":false,"properties":{"label":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","maxLength":5000},"color":{"type":"string","minLength":1,"maxLength":32},"icon":{"type":"string","minLength":1,"maxLength":80},"canContain":{"type":"boolean"},"spatialContainment":{"type":"boolean"},"position":{"type":"integer","minimum":0,"maximum":100000},"archived":{"type":"boolean","description":"Archive when true or restore when false."}}},"InventoryTypeDefinition":{"type":"object","required":["key","label","description","color","icon","canContain","spatialContainment","position","isSystem","createdBy","updatedBy","createdAt","updatedAt","archivedAt"],"properties":{"key":{"$ref":"#/components/schemas/InventoryTypeKey"},"label":{"type":"string"},"description":{"type":"string"},"color":{"type":"string"},"icon":{"type":"string"},"canContain":{"type":"boolean"},"spatialContainment":{"type":"boolean"},"position":{"type":"integer","minimum":0},"isSystem":{"type":"boolean"},"createdBy":{"type":["string","null"]},"updatedBy":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"archivedAt":{"type":["string","null"],"format":"date-time"}}},"RelationTypeInput":{"type":"object","required":["key","label","inverseLabel"],"additionalProperties":false,"properties":{"key":{"$ref":"#/components/schemas/RelationTypeKey"},"label":{"type":"string","minLength":1,"maxLength":120},"inverseLabel":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","maxLength":5000,"default":""},"allowManual":{"type":"boolean","default":true},"position":{"type":"integer","minimum":0,"maximum":100000,"default":0}}},"RelationTypePatch":{"type":"object","minProperties":1,"additionalProperties":false,"properties":{"label":{"type":"string","minLength":1,"maxLength":120},"inverseLabel":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","maxLength":5000},"allowManual":{"type":"boolean"},"position":{"type":"integer","minimum":0,"maximum":100000},"archived":{"type":"boolean","description":"Archive when true or restore when false."}}},"RelationTypeDefinition":{"type":"object","required":["key","label","inverseLabel","description","allowManual","spatial","position","isSystem","createdBy","updatedBy","createdAt","updatedAt","archivedAt"],"properties":{"key":{"$ref":"#/components/schemas/RelationTypeKey"},"label":{"type":"string"},"inverseLabel":{"type":"string"},"description":{"type":"string"},"allowManual":{"type":"boolean"},"spatial":{"type":"boolean","description":"Whether this built-in definition may be generated from geometry."},"position":{"type":"integer","minimum":0},"isSystem":{"type":"boolean"},"createdBy":{"type":["string","null"]},"updatedBy":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"archivedAt":{"type":["string","null"],"format":"date-time"}}},"ResourceReference":{"type":"object","required":["id","name","type","status"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"type":{"$ref":"#/components/schemas/InventoryTypeKey"},"status":{"type":"string","enum":["available","in-use","maintenance","archived"]}}},"ResourceRelationInput":{"type":"object","required":["sourceResourceId","targetResourceId","relationTypeKey"],"additionalProperties":false,"properties":{"sourceResourceId":{"type":"string","format":"uuid","description":"Directed parent or subject endpoint."},"targetResourceId":{"type":"string","format":"uuid","description":"Directed child or object endpoint."},"relationTypeKey":{"$ref":"#/components/schemas/RelationTypeKey"}}},"ResourceRelationRecord":{"type":"object","required":["id","sourceResourceId","targetResourceId","relationTypeKey","origin","sourceFeatureId","targetFeatureId","attributes","createdBy","createdAt"],"properties":{"id":{"type":"string","format":"uuid"},"sourceResourceId":{"type":"string","format":"uuid"},"targetResourceId":{"type":"string","format":"uuid"},"relationTypeKey":{"$ref":"#/components/schemas/RelationTypeKey"},"origin":{"type":"string","enum":["manual","spatial"]},"sourceFeatureId":{"type":["string","null"]},"targetFeatureId":{"type":["string","null"]},"attributes":{"type":"object","additionalProperties":true,"description":"System-managed typed relationship metadata. `variant_of` stores inherited-field overrides here."},"createdBy":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}}},"ResourceRelation":{"allOf":[{"$ref":"#/components/schemas/ResourceRelationRecord"},{"type":"object","required":["source","target","relationType"],"properties":{"source":{"oneOf":[{"$ref":"#/components/schemas/ResourceReference"},{"type":"null"}]},"target":{"oneOf":[{"$ref":"#/components/schemas/ResourceReference"},{"type":"null"}]},"relationType":{"oneOf":[{"$ref":"#/components/schemas/RelationTypeDefinition"},{"type":"null"}]}}}]},"CustomFieldOption":{"type":"object","required":["value","label"],"additionalProperties":false,"properties":{"value":{"type":"string","minLength":1,"maxLength":120,"description":"Stable value stored in customFields."},"label":{"type":"string","minLength":1,"maxLength":120},"color":{"type":"string","minLength":1,"maxLength":32}}},"CustomFieldReferenceOption":{"type":"object","required":["id","entityType","label","description","status"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"entityType":{"type":"string","enum":["inventory","stock_unit"]},"label":{"type":"string"},"description":{"type":"string"},"status":{"type":"string"}}},"CustomFieldValues":{"type":"object","maxProperties":100,"description":"Values keyed by stable custom-field definition keys. Types and required values are checked against active definitions applicable to the resource.","additionalProperties":{"oneOf":[{"type":"string","maxLength":20000},{"type":"number"},{"type":"boolean"},{"type":"array","maxItems":100,"items":{"type":"string","maxLength":120}}]}},"CustomFieldDefinitionInput":{"type":"object","required":["entityType","label","fieldType"],"additionalProperties":false,"properties":{"entityType":{"type":"string","enum":["inventory","stock_unit"],"description":"Whether values live on inventory resources or serialized stock units."},"key":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,63}$","description":"Stable API/storage identifier. Generated from label when omitted and immutable after creation."},"label":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","maxLength":5000,"default":""},"placeholder":{"type":"string","maxLength":240,"default":""},"fieldType":{"type":"string","enum":["text","textarea","number","boolean","date","datetime","select","multi_select","reference","email","url"]},"required":{"type":"boolean","default":false},"minValue":{"type":["number","null"],"default":null,"description":"Inclusive minimum for number fields; null for other field types."},"maxValue":{"type":["number","null"],"default":null,"description":"Inclusive maximum for number fields; null for other field types."},"step":{"type":["number","null"],"exclusiveMinimum":0,"default":null,"description":"Positive increment for number fields; null for other field types."},"resourceTypes":{"type":"array","maxItems":100,"uniqueItems":true,"description":"Applicable inventory types. An empty array matches every type.","items":{"$ref":"#/components/schemas/InventoryTypeKey"},"default":[]},"categories":{"type":"array","maxItems":40,"uniqueItems":true,"description":"Applicable category names, matched case-insensitively. An empty array matches every category; when resourceTypes is also set, both targets must match.","items":{"type":"string","minLength":1,"maxLength":120},"default":[]},"options":{"type":"array","maxItems":100,"description":"Required and non-empty for select and multi_select fields; empty for every other field type.","items":{"$ref":"#/components/schemas/CustomFieldOption"},"default":[]},"referenceEntityType":{"type":["string","null"],"enum":["inventory","stock_unit",null],"default":null,"description":"Required for reference fields and null for all other field types."},"referenceMultiple":{"type":"boolean","default":false,"description":"Whether a reference field stores an array of target UUIDs instead of one UUID."},"referenceResourceTypes":{"type":"array","maxItems":100,"uniqueItems":true,"items":{"$ref":"#/components/schemas/InventoryTypeKey"},"default":[],"description":"Allowed target or parent inventory types; empty matches every type."},"referenceCategories":{"type":"array","maxItems":40,"uniqueItems":true,"items":{"type":"string","minLength":1,"maxLength":120},"default":[],"description":"Allowed target or parent inventory categories; empty matches every category."},"referenceStatuses":{"type":"array","maxItems":40,"uniqueItems":true,"items":{"type":"string","minLength":1,"maxLength":32},"default":[],"description":"Allowed target statuses; empty matches every status."},"position":{"type":"integer","minimum":0,"maximum":100000,"default":0}}},"CustomFieldDefinitionPatch":{"type":"object","required":["revision"],"minProperties":2,"additionalProperties":false,"description":"The last observed revision plus a non-empty subset of mutable definition fields. Entity type and key cannot be changed.","properties":{"revision":{"type":"integer","minimum":1},"label":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","maxLength":5000},"placeholder":{"type":"string","maxLength":240},"fieldType":{"type":"string","enum":["text","textarea","number","boolean","date","datetime","select","multi_select","reference","email","url"]},"required":{"type":"boolean"},"minValue":{"type":["number","null"]},"maxValue":{"type":["number","null"]},"step":{"type":["number","null"],"exclusiveMinimum":0},"resourceTypes":{"type":"array","maxItems":100,"uniqueItems":true,"items":{"$ref":"#/components/schemas/InventoryTypeKey"}},"categories":{"type":"array","maxItems":40,"uniqueItems":true,"items":{"type":"string","minLength":1,"maxLength":120}},"options":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/CustomFieldOption"}},"referenceEntityType":{"type":["string","null"],"enum":["inventory","stock_unit",null]},"referenceMultiple":{"type":"boolean"},"referenceResourceTypes":{"type":"array","maxItems":100,"uniqueItems":true,"items":{"$ref":"#/components/schemas/InventoryTypeKey"}},"referenceCategories":{"type":"array","maxItems":40,"uniqueItems":true,"items":{"type":"string","minLength":1,"maxLength":120}},"referenceStatuses":{"type":"array","maxItems":40,"uniqueItems":true,"items":{"type":"string","minLength":1,"maxLength":32}},"position":{"type":"integer","minimum":0,"maximum":100000}}},"CustomFieldDefinition":{"type":"object","required":["id","entityType","key","label","description","placeholder","fieldType","required","minValue","maxValue","step","resourceTypes","categories","options","referenceEntityType","referenceMultiple","referenceResourceTypes","referenceCategories","referenceStatuses","position","revision","createdBy","updatedBy","createdAt","updatedAt","archivedAt"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"entityType":{"type":"string","enum":["inventory","stock_unit"]},"key":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,63}$"},"label":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","maxLength":5000},"placeholder":{"type":"string","maxLength":240},"fieldType":{"type":"string","enum":["text","textarea","number","boolean","date","datetime","select","multi_select","reference","email","url"]},"required":{"type":"boolean"},"minValue":{"type":["number","null"]},"maxValue":{"type":["number","null"]},"step":{"type":["number","null"],"exclusiveMinimum":0},"resourceTypes":{"type":"array","maxItems":100,"uniqueItems":true,"items":{"$ref":"#/components/schemas/InventoryTypeKey"}},"categories":{"type":"array","maxItems":40,"uniqueItems":true,"items":{"type":"string","minLength":1,"maxLength":120}},"options":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/CustomFieldOption"}},"referenceEntityType":{"type":["string","null"],"enum":["inventory","stock_unit",null]},"referenceMultiple":{"type":"boolean"},"referenceResourceTypes":{"type":"array","maxItems":100,"uniqueItems":true,"items":{"$ref":"#/components/schemas/InventoryTypeKey"}},"referenceCategories":{"type":"array","maxItems":40,"uniqueItems":true,"items":{"type":"string","minLength":1,"maxLength":120}},"referenceStatuses":{"type":"array","maxItems":40,"uniqueItems":true,"items":{"type":"string","minLength":1,"maxLength":32}},"position":{"type":"integer","minimum":0,"maximum":100000},"revision":{"type":"integer","minimum":1,"description":"Incremented by every update and soft deletion."},"createdBy":{"type":["string","null"],"maxLength":320},"updatedBy":{"type":["string","null"],"maxLength":320},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"archivedAt":{"type":["string","null"],"format":"date-time"}}},"LabelElement":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","const":"text"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"x":{"type":"number","minimum":0,"maximum":100},"y":{"type":"number","minimum":0,"maximum":100},"width":{"type":"number","exclusiveMinimum":0,"maximum":100},"height":{"type":"number","exclusiveMinimum":0,"maximum":100},"visible":{"type":"boolean"},"layer":{"type":"integer","minimum":0,"maximum":31},"autoWidth":{"type":"boolean"},"fontSizeMm":{"type":"number","exclusiveMinimum":0,"maximum":100},"minFontSizeMm":{"type":"number","exclusiveMinimum":0,"maximum":100},"fontFamily":{"type":"string","enum":["sans","serif","monospace","rounded","barlow-semi-condensed","inter","roboto","roboto-condensed","nunito-sans"]},"fontWeight":{"type":"integer","minimum":100,"maximum":900,"multipleOf":100},"letterSpacingEm":{"type":"number","minimum":-0.1,"maximum":1},"lineHeight":{"type":"number","minimum":0.8,"maximum":3},"align":{"type":"string","enum":["left","center","right"]},"verticalAlign":{"type":"string","enum":["top","middle","bottom"]},"textOverflow":{"type":"string","enum":["ellipsis","shrink"]},"content":{"maxItems":500,"type":"array","items":{"type":"object","properties":{"text":{"type":"string","maxLength":8000},"weight":{"type":"integer","minimum":100,"maximum":900,"multipleOf":100},"italic":{"type":"boolean"},"underline":{"type":"boolean"}},"required":["text"],"additionalProperties":false}}},"required":["type","id","x","y","width","height","visible","content"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"background"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"x":{"type":"number","minimum":0,"maximum":100},"y":{"type":"number","minimum":0,"maximum":100},"width":{"type":"number","exclusiveMinimum":0,"maximum":100},"height":{"type":"number","exclusiveMinimum":0,"maximum":100},"visible":{"type":"boolean"},"layer":{"type":"integer","minimum":0,"maximum":31},"source":{"type":"string","maxLength":3000000,"pattern":"^data:image\\/(?:png|jpeg|webp|gif|avif|svg\\+xml);base64,[a-z0-9+/=\\s]+$"},"fit":{"type":"string","enum":["cover","contain"]},"opacity":{"type":"number","minimum":0,"maximum":1}},"required":["type","x","y","width","height","visible"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"qr"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"x":{"type":"number","minimum":0,"maximum":100},"y":{"type":"number","minimum":0,"maximum":100},"width":{"type":"number","exclusiveMinimum":0,"maximum":100},"height":{"type":"number","exclusiveMinimum":0,"maximum":100},"visible":{"type":"boolean"},"layer":{"type":"integer","minimum":0,"maximum":31},"foregroundColor":{"type":"string","pattern":"^#[0-9a-f]{6}$"},"backgroundColor":{"type":"string","pattern":"^#[0-9a-f]{6}$"},"quietZoneModules":{"type":"integer","minimum":0,"maximum":4}},"required":["type","x","y","width","height","visible"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"image"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"x":{"type":"number","minimum":0,"maximum":100},"y":{"type":"number","minimum":0,"maximum":100},"width":{"type":"number","exclusiveMinimum":0,"maximum":100},"height":{"type":"number","exclusiveMinimum":0,"maximum":100},"visible":{"type":"boolean"},"layer":{"type":"integer","minimum":0,"maximum":31},"source":{"type":"string","maxLength":3000000,"pattern":"^data:image\\/(?:png|jpeg|webp|gif|avif|svg\\+xml);base64,[a-z0-9+/=\\s]+$"},"altText":{"type":"string","maxLength":300},"fit":{"type":"string","enum":["cover","contain"]},"photoOptimization":{"type":"string","enum":["auto","standard"]},"cropWhiteMargins":{"type":"boolean"},"cropTolerance":{"type":"number","minimum":0,"maximum":80},"cropPadding":{"type":"number","minimum":-10,"maximum":20}},"required":["type","x","y","width","height","visible"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"name"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"x":{"type":"number","minimum":0,"maximum":100},"y":{"type":"number","minimum":0,"maximum":100},"width":{"type":"number","exclusiveMinimum":0,"maximum":100},"height":{"type":"number","exclusiveMinimum":0,"maximum":100},"visible":{"type":"boolean"},"layer":{"type":"integer","minimum":0,"maximum":31},"autoWidth":{"type":"boolean"},"fontSizeMm":{"type":"number","exclusiveMinimum":0,"maximum":100},"minFontSizeMm":{"type":"number","exclusiveMinimum":0,"maximum":100},"fontFamily":{"type":"string","enum":["sans","serif","monospace","rounded","barlow-semi-condensed","inter","roboto","roboto-condensed","nunito-sans"]},"fontWeight":{"type":"integer","minimum":100,"maximum":900,"multipleOf":100},"letterSpacingEm":{"type":"number","minimum":-0.1,"maximum":1},"lineHeight":{"type":"number","minimum":0.8,"maximum":3},"align":{"type":"string","enum":["left","center","right"]},"verticalAlign":{"type":"string","enum":["top","middle","bottom"]},"textOverflow":{"type":"string","enum":["ellipsis","shrink"]},"content":{"maxItems":500,"type":"array","items":{"type":"object","properties":{"text":{"type":"string","maxLength":8000},"weight":{"type":"integer","minimum":100,"maximum":900,"multipleOf":100},"italic":{"type":"boolean"},"underline":{"type":"boolean"}},"required":["text"],"additionalProperties":false}}},"required":["type","x","y","width","height","visible"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"subtitle"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"x":{"type":"number","minimum":0,"maximum":100},"y":{"type":"number","minimum":0,"maximum":100},"width":{"type":"number","exclusiveMinimum":0,"maximum":100},"height":{"type":"number","exclusiveMinimum":0,"maximum":100},"visible":{"type":"boolean"},"layer":{"type":"integer","minimum":0,"maximum":31},"autoWidth":{"type":"boolean"},"fontSizeMm":{"type":"number","exclusiveMinimum":0,"maximum":100},"minFontSizeMm":{"type":"number","exclusiveMinimum":0,"maximum":100},"fontFamily":{"type":"string","enum":["sans","serif","monospace","rounded","barlow-semi-condensed","inter","roboto","roboto-condensed","nunito-sans"]},"fontWeight":{"type":"integer","minimum":100,"maximum":900,"multipleOf":100},"letterSpacingEm":{"type":"number","minimum":-0.1,"maximum":1},"lineHeight":{"type":"number","minimum":0.8,"maximum":3},"align":{"type":"string","enum":["left","center","right"]},"verticalAlign":{"type":"string","enum":["top","middle","bottom"]},"textOverflow":{"type":"string","enum":["ellipsis","shrink"]},"content":{"maxItems":500,"type":"array","items":{"type":"object","properties":{"text":{"type":"string","maxLength":8000},"weight":{"type":"integer","minimum":100,"maximum":900,"multipleOf":100},"italic":{"type":"boolean"},"underline":{"type":"boolean"}},"required":["text"],"additionalProperties":false}}},"required":["type","x","y","width","height","visible"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"identifier"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"x":{"type":"number","minimum":0,"maximum":100},"y":{"type":"number","minimum":0,"maximum":100},"width":{"type":"number","exclusiveMinimum":0,"maximum":100},"height":{"type":"number","exclusiveMinimum":0,"maximum":100},"visible":{"type":"boolean"},"layer":{"type":"integer","minimum":0,"maximum":31},"autoWidth":{"type":"boolean"},"fontSizeMm":{"type":"number","exclusiveMinimum":0,"maximum":100},"minFontSizeMm":{"type":"number","exclusiveMinimum":0,"maximum":100},"fontFamily":{"type":"string","enum":["sans","serif","monospace","rounded","barlow-semi-condensed","inter","roboto","roboto-condensed","nunito-sans"]},"fontWeight":{"type":"integer","minimum":100,"maximum":900,"multipleOf":100},"letterSpacingEm":{"type":"number","minimum":-0.1,"maximum":1},"lineHeight":{"type":"number","minimum":0.8,"maximum":3},"align":{"type":"string","enum":["left","center","right"]},"verticalAlign":{"type":"string","enum":["top","middle","bottom"]},"textOverflow":{"type":"string","enum":["ellipsis","shrink"]},"content":{"maxItems":500,"type":"array","items":{"type":"object","properties":{"text":{"type":"string","maxLength":8000},"weight":{"type":"integer","minimum":100,"maximum":900,"multipleOf":100},"italic":{"type":"boolean"},"underline":{"type":"boolean"}},"required":["text"],"additionalProperties":false}}},"required":["type","x","y","width","height","visible"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"barcode"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"x":{"type":"number","minimum":0,"maximum":100},"y":{"type":"number","minimum":0,"maximum":100},"width":{"type":"number","exclusiveMinimum":0,"maximum":100},"height":{"type":"number","exclusiveMinimum":0,"maximum":100},"visible":{"type":"boolean"},"layer":{"type":"integer","minimum":0,"maximum":31}},"required":["type","x","y","width","height","visible"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"url"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"x":{"type":"number","minimum":0,"maximum":100},"y":{"type":"number","minimum":0,"maximum":100},"width":{"type":"number","exclusiveMinimum":0,"maximum":100},"height":{"type":"number","exclusiveMinimum":0,"maximum":100},"visible":{"type":"boolean"},"layer":{"type":"integer","minimum":0,"maximum":31},"autoWidth":{"type":"boolean"},"fontSizeMm":{"type":"number","exclusiveMinimum":0,"maximum":100},"minFontSizeMm":{"type":"number","exclusiveMinimum":0,"maximum":100},"fontFamily":{"type":"string","enum":["sans","serif","monospace","rounded","barlow-semi-condensed","inter","roboto","roboto-condensed","nunito-sans"]},"fontWeight":{"type":"integer","minimum":100,"maximum":900,"multipleOf":100},"letterSpacingEm":{"type":"number","minimum":-0.1,"maximum":1},"lineHeight":{"type":"number","minimum":0.8,"maximum":3},"align":{"type":"string","enum":["left","center","right"]},"verticalAlign":{"type":"string","enum":["top","middle","bottom"]},"textOverflow":{"type":"string","enum":["ellipsis","shrink"]},"content":{"maxItems":500,"type":"array","items":{"type":"object","properties":{"text":{"type":"string","maxLength":8000},"weight":{"type":"integer","minimum":100,"maximum":900,"multipleOf":100},"italic":{"type":"boolean"},"underline":{"type":"boolean"}},"required":["text"],"additionalProperties":false}}},"required":["type","x","y","width","height","visible"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","const":"location"},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"x":{"type":"number","minimum":0,"maximum":100},"y":{"type":"number","minimum":0,"maximum":100},"width":{"type":"number","exclusiveMinimum":0,"maximum":100},"height":{"type":"number","exclusiveMinimum":0,"maximum":100},"visible":{"type":"boolean"},"layer":{"type":"integer","minimum":0,"maximum":31},"autoWidth":{"type":"boolean"},"fontSizeMm":{"type":"number","exclusiveMinimum":0,"maximum":100},"minFontSizeMm":{"type":"number","exclusiveMinimum":0,"maximum":100},"fontFamily":{"type":"string","enum":["sans","serif","monospace","rounded","barlow-semi-condensed","inter","roboto","roboto-condensed","nunito-sans"]},"fontWeight":{"type":"integer","minimum":100,"maximum":900,"multipleOf":100},"letterSpacingEm":{"type":"number","minimum":-0.1,"maximum":1},"lineHeight":{"type":"number","minimum":0.8,"maximum":3},"align":{"type":"string","enum":["left","center","right"]},"verticalAlign":{"type":"string","enum":["top","middle","bottom"]},"textOverflow":{"type":"string","enum":["ellipsis","shrink"]},"content":{"maxItems":500,"type":"array","items":{"type":"object","properties":{"text":{"type":"string","maxLength":8000},"weight":{"type":"integer","minimum":100,"maximum":900,"multipleOf":100},"italic":{"type":"boolean"},"underline":{"type":"boolean"}},"required":["text"],"additionalProperties":false}}},"required":["type","x","y","width","height","visible"],"additionalProperties":false}],"description":"Normalized percentage box; x + width and y + height must not exceed 100. Text content totals at most 8000 characters. Optional IDs distinguish multiple elements of the same type."},"LabelElements":{"maxItems":32,"type":"array","items":{"$ref":"#/components/schemas/LabelElement"},"description":"Up to 32 elements with unique identities (id, or type for legacy elements). Visible images must not overlap visible QR codes. At most one text element may use autoWidth to control the physical label length."},"LabelSetupInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":160},"widthMm":{"type":"number","exclusiveMinimum":0,"maximum":1000},"heightMm":{"type":"number","exclusiveMinimum":0,"maximum":1000},"elements":{"$ref":"#/components/schemas/LabelElements"},"inverted":{"type":"boolean"}},"required":["name","widthMm","heightMm","elements"],"additionalProperties":false},"LabelSetupPatch":{"type":"object","properties":{"revision":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"name":{"type":"string","minLength":1,"maxLength":160},"widthMm":{"type":"number","exclusiveMinimum":0,"maximum":1000},"heightMm":{"type":"number","exclusiveMinimum":0,"maximum":1000},"elements":{"$ref":"#/components/schemas/LabelElements"},"inverted":{"type":"boolean"}},"required":["revision"],"additionalProperties":false,"description":"Supply the last observed revision and at least one changed property. A stale revision returns 409."},"LabelSetup":{"type":"object","required":["id","name","widthMm","heightMm","elements","revision","createdAt","updatedAt"],"additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":160},"widthMm":{"type":"number","exclusiveMinimum":0,"maximum":1000},"heightMm":{"type":"number","exclusiveMinimum":0,"maximum":1000},"elements":{"$ref":"#/components/schemas/LabelElements"},"revision":{"type":"integer","minimum":1,"description":"Incremented by every successful update."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"inverted":{"type":"boolean"}}},"InventoryCount":{"type":"object","required":["count","confidence","detectedItem","isExact","explanation","warnings","markers","model"],"properties":{"count":{"type":"integer","minimum":0,"maximum":1000000},"confidence":{"type":"number","minimum":0,"maximum":1},"detectedItem":{"type":"string","minLength":1,"maxLength":240},"isExact":{"type":"boolean","description":"True only when every counted instance is individually visible without meaningful ambiguity. The current zero-shot SAM 3 provider returns false so clients require review."},"explanation":{"type":"string","minLength":1,"maxLength":1000},"warnings":{"type":"array","maxItems":10,"items":{"type":"string","minLength":1,"maxLength":240}},"markers":{"type":"array","description":"One bounding-box center per counted item on a 0...1000 image grid, measured from the top-left corner of the orientation-corrected full image.","items":{"type":"object","additionalProperties":false,"required":["x","y"],"properties":{"x":{"type":"integer","minimum":0,"maximum":1000},"y":{"type":"integer","minimum":0,"maximum":1000}}}},"model":{"type":"string"}}},"InventoryRecognitionObservation":{"type":"object","additionalProperties":false,"required":["label","category","brand","model","color","material","visibleText","searchTerms","confidence"],"properties":{"label":{"type":"string","minLength":1,"maxLength":160},"category":{"type":"string","minLength":1,"maxLength":160},"brand":{"type":["string","null"],"minLength":1,"maxLength":160},"model":{"type":["string","null"],"minLength":1,"maxLength":160},"color":{"type":["string","null"],"minLength":1,"maxLength":120},"material":{"type":["string","null"],"minLength":1,"maxLength":120},"visibleText":{"type":"array","maxItems":20,"items":{"type":"string","minLength":1,"maxLength":160}},"searchTerms":{"type":"array","minItems":1,"maxItems":30,"items":{"type":"string","minLength":1,"maxLength":160}},"confidence":{"type":"number","minimum":0,"maximum":1}}},"InventoryRecognitionMatch":{"type":"object","additionalProperties":false,"required":["resourceId","confidence","reason","evidence","resource"],"properties":{"resourceId":{"type":"string","format":"uuid"},"resourceIds":{"type":"array","maxItems":24,"uniqueItems":true,"description":"Configured targets; older clients may omit this to use resourceId as the only target.","items":{"type":"string","format":"uuid"}},"targetSelectionMode":{"type":"string","enum":["all","radio","checkbox"],"default":"all"},"allowVariantSelection":{"type":"boolean","default":false},"confidence":{"type":"number","minimum":0,"maximum":1},"reason":{"type":"string","minLength":1,"maxLength":600},"evidence":{"type":"array","maxItems":8,"items":{"type":"string","minLength":1,"maxLength":240}},"resource":{"$ref":"#/components/schemas/Resource"}}},"InventoryRecognitionResult":{"type":"object","additionalProperties":false,"required":["detected","matches","isConfident","model","catalog"],"properties":{"detected":{"oneOf":[{"$ref":"#/components/schemas/InventoryRecognitionObservation"},{"type":"null"}]},"matches":{"type":"array","maxItems":5,"items":{"$ref":"#/components/schemas/InventoryRecognitionMatch"}},"isConfident":{"type":"boolean","description":"True only when the leading provider score is strong and sufficiently separated from the runner-up; the match remains advisory."},"model":{"type":["string","null"]},"catalog":{"type":"object","additionalProperties":false,"required":["considered","truncated"],"properties":{"considered":{"type":"integer","minimum":0,"maximum":5000},"truncated":{"type":"boolean","description":"True when metadata matches or the image-bearing visual fallback exceeded the bounded comparison catalog; clients should present the result as non-exhaustive."}}}}},"InventoryCountJob":{"type":"object","additionalProperties":false,"required":["status","jobToken","expiresAt"],"properties":{"status":{"type":"string","enum":["processing"]},"jobToken":{"type":"string","minLength":1,"maxLength":4096},"expiresAt":{"type":"string","format":"date-time"},"message":{"type":"string"}}},"ImageGenerationModel":{"type":"object","required":["id","provider","model","label"],"additionalProperties":false,"properties":{"id":{"type":"string","maxLength":240,"example":"google:gemini-3.1-flash-image"},"provider":{"type":"string","enum":["openai","google"]},"model":{"type":"string","maxLength":233,"example":"gemini-3.1-flash-image"},"label":{"type":"string","maxLength":260,"example":"Nano Banana 2"}}},"InventoryCountModel":{"type":"object","required":["id","provider","model","label","description"],"additionalProperties":false,"properties":{"id":{"type":"string","enum":["grounding-dino","yolo-world","sam-2","sam-3"]},"provider":{"type":"string","enum":["replicate"]},"model":{"type":"string","maxLength":240},"label":{"type":"string","maxLength":260},"description":{"type":"string","maxLength":500}}},"BomComponentInput":{"type":"object","required":["resourceId","quantityPerAssembly"],"additionalProperties":false,"properties":{"resourceId":{"type":"string","format":"uuid"},"resourceIds":{"type":"array","maxItems":24,"uniqueItems":true,"items":{"type":"string","format":"uuid"}},"targetSelectionMode":{"type":"string","enum":["all","radio","checkbox"]},"allowVariantSelection":{"type":"boolean"},"slotKey":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[A-Za-z0-9_-]+$","description":"Stable logical BOM slot. Omit only for backward-compatible matching or creation."},"quantityPerAssembly":{"type":"integer","minimum":1},"position":{"type":"integer","minimum":0},"note":{"type":"string","maxLength":20000}}},"BomCover":{"type":"object","required":["url","altText"],"additionalProperties":false,"properties":{"url":{"type":"string"},"altText":{"type":"string"}}},"BomComponent":{"allOf":[{"$ref":"#/components/schemas/BomComponentInput"},{"type":"object","required":["id","slotKey","origin","name","availableQuantity","trackingMode","cover","availableUnits","choices"],"properties":{"id":{"type":"string","format":"uuid"},"slotKey":{"type":"string","minLength":1,"maxLength":80},"origin":{"type":"string","enum":["local","inherited","override","variant"],"description":"Whether this effective row is local, unchanged from the primary, replaces a primary slot, or exists only on the variant."},"name":{"type":"string"},"sku":{"type":["string","null"]},"availableQuantity":{"type":"integer","minimum":0},"trackingMode":{"type":"string","enum":["bulk","serialized"]},"cover":{"oneOf":[{"$ref":"#/components/schemas/BomCover"},{"type":"null"}]},"availableUnits":{"type":"array","items":{"type":"object","required":["id","code","location"],"properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"location":{"type":["string","null"]}}}},"choices":{"type":"array","minItems":1,"description":"The BOM component itself followed by readable direct first-class variants that may be consumed for this slot during a build.","items":{"type":"object","required":["resourceId","name","sku","availableQuantity","trackingMode","cover","availableUnits","isPrimary"],"properties":{"resourceId":{"type":"string","format":"uuid"},"name":{"type":"string"},"sku":{"type":["string","null"]},"availableQuantity":{"type":"integer"},"trackingMode":{"type":"string","enum":["bulk","serialized"]},"cover":{"oneOf":[{"$ref":"#/components/schemas/BomCover"},{"type":"null"}]},"availableUnits":{"type":"array","items":{"type":"object","required":["id","code","location"],"properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"location":{"type":["string","null"]}}}},"isPrimary":{"type":"boolean"}}}}}}]},"BomParent":{"type":"object","required":["id","slotKey","resourceId","name","type","status","quantityPerAssembly","position","note","origin"],"additionalProperties":false,"properties":{"id":{"type":"string","description":"Stored BOM row id or a stable inherited-row identifier."},"slotKey":{"type":"string","minLength":1,"maxLength":80},"resourceId":{"type":"string","format":"uuid"},"name":{"type":"string"},"type":{"type":"string"},"status":{"type":"string"},"quantityPerAssembly":{"type":"integer","minimum":1},"position":{"type":"integer","minimum":0},"note":{"type":"string"},"origin":{"type":"string","enum":["local","inherited","override","variant"]}}},"BomDetail":{"type":"object","required":["resource","components","buildableQuantity","inheritance"],"properties":{"resource":{"type":"object","required":["id","name","quantity","trackingMode"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"quantity":{"type":"integer"},"trackingMode":{"type":"string","enum":["bulk","serialized"]}}},"components":{"type":"array","items":{"$ref":"#/components/schemas/BomComponent"}},"buildableQuantity":{"type":"integer","minimum":0},"inheritance":{"oneOf":[{"type":"object","required":["primaryResourceId","primaryName","overrideCount"],"properties":{"primaryResourceId":{"type":"string","format":"uuid"},"primaryName":{"type":"string"},"overrideCount":{"type":"integer","minimum":0,"description":"Stored removals, replacements, and variant-only slots."}}},{"type":"null"}]}}},"AssemblyOutputConfiguration":{"type":"object","minProperties":1,"maxProperties":100,"description":"Complete selection of variable BOM slots for a finished product. Each value must be the slot's component or an active member of its component family. Mutually exclusive with outputResourceId and componentResourceSelections. Reuses a matching finished article or creates just this configuration atomically with the build. Existing manual recipe overrides are preserved. No Cartesian product is stored.","propertyNames":{"pattern":"^[A-Za-z0-9_-]{1,80}$"},"additionalProperties":{"type":"string","format":"uuid"}},"AssemblyBuildInput":{"type":"object","required":["quantity"],"additionalProperties":false,"properties":{"outputResourceId":{"type":"string","format":"uuid","description":"Finished item to credit. Must be the requested item or a direct variant. Required when the requested item has finished variants or variable component slots unless outputConfiguration is supplied; componentResourceSelections never infer the output. Explicitly use the primary ID for unassigned output. When building a variant directly, its ID is the default output. Missing or conflicting output selections return 422."},"outputConfiguration":{"$ref":"#/components/schemas/AssemblyOutputConfiguration"},"quantity":{"type":"integer","minimum":1,"maximum":1000},"occurredAt":{"type":"string","format":"date-time"},"location":{"type":["string","null"],"maxLength":240},"note":{"type":"string","maxLength":20000},"componentResourceSelections":{"type":"object","description":"Maps stable BOM slot keys to either that slot's component resource or an active member of its first-class component family. The selected resource is consumed and snapshotted in build history. When the output is a finished variant, selections must match its complete effective BOM; conflicting substitutions return 422 before any stock is booked.","propertyNames":{"pattern":"^[A-Za-z0-9_-]{1,80}$"},"additionalProperties":{"type":"string","format":"uuid"}},"componentUnitIds":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string","format":"uuid"}}},"outputUnitCodes":{"type":"array","items":{"type":"string","maxLength":180}}}},"AssemblyBuild":{"type":"object","required":["id","assemblyResourceId","quantity","occurredAt","createdAt","components","outputUnits"],"properties":{"id":{"type":"string","format":"uuid"},"assemblyResourceId":{"type":"string","format":"uuid"},"quantity":{"type":"integer","minimum":1},"occurredAt":{"type":"string","format":"date-time"},"location":{"type":["string","null"]},"note":{"type":"string"},"materialCosts":{"type":"object","additionalProperties":{"type":"integer","minimum":0},"description":"Actual consumed material costs in cents, grouped by ISO currency."},"unpricedComponentQuantity":{"type":"integer","minimum":0},"costEstimated":{"type":"boolean"},"createdBy":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"components":{"type":"array","items":{"type":"object","required":["resourceId","name","sku","quantityPerAssembly","quantityConsumed","componentUnits","stockMovementIds","outputUnitIds","costs","unpricedQuantity","costEstimated"],"properties":{"resourceId":{"type":["string","null"],"format":"uuid"},"name":{"type":"string"},"sku":{"type":["string","null"]},"quantityPerAssembly":{"type":"integer","minimum":1},"quantityConsumed":{"type":"integer","minimum":1},"costs":{"type":"object","additionalProperties":{"type":"integer","minimum":0}},"unpricedQuantity":{"type":"integer","minimum":0},"costEstimated":{"type":"boolean"},"componentUnits":{"type":"array","items":{"type":"object","required":["id","code","location","status","outputUnitId"],"properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"location":{"type":["string","null"]},"status":{"type":"string"},"outputUnitId":{"type":["string","null"],"format":"uuid"}}}},"stockMovementIds":{"type":"array","items":{"type":"string","format":"uuid"}},"outputUnitIds":{"type":"array","items":{"type":"string","format":"uuid"}}}}},"outputUnits":{"type":"array","items":{"$ref":"#/components/schemas/StockUnit"}}}},"PurchaseOrderLineInput":{"type":"object","required":["resourceId"],"oneOf":[{"required":["orderedQuantity"]},{"required":["purchaseQuantity"]}],"additionalProperties":false,"properties":{"resourceId":{"type":"string","format":"uuid"},"orderedQuantity":{"type":"integer","minimum":1,"description":"Quantity in base stock units. Mutually exclusive with purchaseQuantity."},"purchaseQuantity":{"type":"integer","minimum":1,"description":"Quantity in the configured purchase unit. Mutually exclusive with orderedQuantity."},"expectedAt":{"type":["string","null"],"format":"date-time"},"note":{"type":"string","maxLength":20000},"unitPriceCents":{"type":["integer","null"],"minimum":0,"maximum":2000000000},"priceCurrency":{"type":["string","null"],"minLength":3,"maxLength":3}}},"PurchaseOrderInput":{"type":"object","required":["lines"],"additionalProperties":false,"properties":{"reference":{"type":["string","null"],"maxLength":160},"contactId":{"type":["string","null"],"format":"uuid"},"supplier":{"type":"string","maxLength":240},"status":{"type":"string","enum":["draft","ordered"]},"orderedAt":{"type":"string","format":"date-time"},"expectedAt":{"type":["string","null"],"format":"date-time"},"note":{"type":"string","maxLength":20000},"lines":{"type":"array","minItems":1,"maxItems":100,"items":{"$ref":"#/components/schemas/PurchaseOrderLineInput"}}}},"PurchaseOrderLine":{"allOf":[{"$ref":"#/components/schemas/PurchaseOrderLineInput"},{"type":"object","required":["id","resourceName","resourceCurrency","baseUnitName","orderedQuantity","receivedQuantity","openQuantity","purchaseUnitName","purchaseUnitFactor","orderedPurchaseQuantity","receivedPurchaseQuantity","openPurchaseQuantity","trackingMode","totalPriceCents"],"properties":{"id":{"type":"string","format":"uuid"},"resourceName":{"type":"string"},"resourceSku":{"type":["string","null"]},"resourceCurrency":{"type":"string","minLength":3,"maxLength":3},"baseUnitName":{"type":"string"},"purchaseUnitName":{"type":["string","null"]},"purchaseUnitFactor":{"type":"integer","minimum":1},"orderedPurchaseQuantity":{"type":["integer","null"],"minimum":0},"receivedPurchaseQuantity":{"type":["integer","null"],"minimum":0},"openPurchaseQuantity":{"type":["integer","null"],"minimum":0},"receivedQuantity":{"type":"integer","minimum":0},"openQuantity":{"type":"integer","minimum":0},"trackingMode":{"type":"string","enum":["bulk","serialized"]},"totalPriceCents":{"type":["integer","null"],"minimum":0}}}]},"PurchaseOrder":{"type":"object","required":["id","supplier","status","orderedAt","lines","totalOrdered","totalReceived","totalOpen"],"properties":{"id":{"type":"string","format":"uuid"},"reference":{"type":["string","null"]},"supplier":{"type":"string"},"status":{"type":"string","enum":["draft","ordered","partially-received","received","cancelled"]},"orderedAt":{"type":"string","format":"date-time"},"expectedAt":{"type":["string","null"],"format":"date-time"},"note":{"type":"string"},"createdBy":{"type":["string","null"]},"lines":{"type":"array","items":{"$ref":"#/components/schemas/PurchaseOrderLine"}},"totalOrdered":{"type":"integer","minimum":0},"totalReceived":{"type":"integer","minimum":0},"totalOpen":{"type":"integer","minimum":0}}},"OrderType":{"type":"string","enum":["purchase","sale","loan"]},"OrderStatus":{"type":"string","enum":["draft","ordered","partially-received","received","confirmed","partially-fulfilled","fulfilled","reserved","partially-issued","issued","partially-returned","returned","overdue","cancelled"]},"OrderLineInput":{"type":"object","additionalProperties":false,"required":["resourceId","quantity"],"properties":{"resourceId":{"type":"string","format":"uuid"},"quantity":{"type":"integer","minimum":1,"maximum":2000000000},"expectedAt":{"type":["string","null"],"format":"date-time"},"note":{"type":"string","maxLength":20000},"unitPriceCents":{"type":["integer","null"],"minimum":0,"maximum":2000000000},"priceCurrency":{"type":["string","null"],"minLength":3,"maxLength":3}}},"OrderInput":{"type":"object","additionalProperties":false,"required":["type","contactId","lines"],"properties":{"type":{"$ref":"#/components/schemas/OrderType"},"contactId":{"type":"string","format":"uuid"},"reference":{"type":["string","null"],"maxLength":160},"status":{"$ref":"#/components/schemas/OrderStatus"},"orderedAt":{"type":"string","format":"date-time"},"expectedAt":{"type":["string","null"],"format":"date-time","description":"Required return due date for loans."},"note":{"type":"string","maxLength":20000},"lines":{"type":"array","minItems":1,"maxItems":100,"items":{"$ref":"#/components/schemas/OrderLineInput"}}}},"OrderPatch":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"contactId":{"type":"string","format":"uuid"},"reference":{"type":["string","null"],"maxLength":160},"status":{"$ref":"#/components/schemas/OrderStatus"},"orderedAt":{"type":"string","format":"date-time"},"expectedAt":{"type":["string","null"],"format":"date-time"},"note":{"type":"string","maxLength":20000}}},"OrderLine":{"allOf":[{"$ref":"#/components/schemas/OrderLineInput"},{"type":"object","required":["id","orderId","resourceName","fulfilledQuantity","returnedQuantity","openQuantity","reservedQuantity","openReservationQuantity","openReturnQuantity","trackingMode","unitName","units"],"properties":{"id":{"type":"string","format":"uuid"},"orderId":{"type":"string","format":"uuid"},"resourceName":{"type":"string"},"resourceSku":{"type":["string","null"]},"fulfilledQuantity":{"type":"integer","minimum":0},"returnedQuantity":{"type":"integer","minimum":0},"openQuantity":{"type":"integer","minimum":0},"reservedQuantity":{"type":"integer","minimum":0},"openReservationQuantity":{"type":"integer","minimum":0},"openReturnQuantity":{"type":"integer","minimum":0},"totalPriceCents":{"type":["integer","null"],"minimum":0},"trackingMode":{"type":"string","enum":["bulk","serialized"]},"unitName":{"type":"string"},"units":{"type":"array","items":{"$ref":"#/components/schemas/OrderLineUnit"}}}}]},"Order":{"type":"object","required":["id","type","contactName","status","orderedAt","lines","shipments","totalQuantity","totalFulfilled","totalReturned","totalReserved"],"properties":{"id":{"type":"string","format":"uuid"},"type":{"$ref":"#/components/schemas/OrderType"},"contactId":{"type":["string","null"],"format":"uuid"},"contactName":{"type":"string"},"reference":{"type":["string","null"]},"status":{"$ref":"#/components/schemas/OrderStatus"},"orderedAt":{"type":"string","format":"date-time"},"expectedAt":{"type":["string","null"],"format":"date-time"},"note":{"type":"string"},"lines":{"type":"array","items":{"$ref":"#/components/schemas/OrderLine"}},"shipments":{"type":"array","items":{"$ref":"#/components/schemas/Shipment"}},"totalQuantity":{"type":"integer","minimum":0},"totalFulfilled":{"type":"integer","minimum":0},"totalReturned":{"type":"integer","minimum":0},"totalReserved":{"type":"integer","minimum":0}}},"ShipmentStatus":{"type":"string","enum":["draft","ready","shipped","in_transit","delivered","exception","returned","cancelled"]},"ShipmentLineInput":{"type":"object","additionalProperties":false,"required":["orderLineId","quantity"],"properties":{"orderLineId":{"type":"string","format":"uuid"},"quantity":{"type":"integer","minimum":1,"maximum":2000000000},"unitIds":{"type":"array","maxItems":100,"uniqueItems":true,"description":"Concrete stock-unit ids; required one-for-one for serialized lines and forbidden for bulk lines.","items":{"type":"string","format":"uuid"}}}},"ShipmentInput":{"type":"object","additionalProperties":false,"required":["carrierCode","lines"],"properties":{"carrierCode":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,39}$"},"service":{"type":["string","null"],"minLength":1,"maxLength":120},"trackingNumber":{"type":["string","null"],"minLength":1,"maxLength":180},"trackingUrl":{"type":["string","null"],"format":"uri","maxLength":2048,"description":"HTTPS only. Known carriers receive a default URL when omitted."},"status":{"type":"string","enum":["draft","ready"],"default":"draft"},"note":{"type":"string","maxLength":20000},"lines":{"type":"array","minItems":1,"maxItems":100,"items":{"$ref":"#/components/schemas/ShipmentLineInput"}}}},"ShipmentPatch":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"carrierCode":{"type":"string","pattern":"^[a-z0-9][a-z0-9_-]{0,39}$"},"service":{"type":["string","null"],"minLength":1,"maxLength":120},"trackingNumber":{"type":["string","null"],"minLength":1,"maxLength":180},"trackingUrl":{"type":["string","null"],"format":"uri","maxLength":2048,"description":"HTTPS only."},"status":{"$ref":"#/components/schemas/ShipmentStatus"},"occurredAt":{"type":"string","format":"date-time","description":"Effective status timestamp; requires status."},"note":{"type":"string","maxLength":20000},"eventNote":{"type":"string","maxLength":2000}}},"ShipmentUnit":{"type":"object","required":["orderLineUnitId","stockUnitId","code"],"properties":{"orderLineUnitId":{"type":"string","format":"uuid"},"stockUnitId":{"type":"string","format":"uuid"},"code":{"type":"string","maxLength":180}}},"ShipmentLine":{"type":"object","required":["id","orderLineId","resourceId","resourceName","quantity","units"],"properties":{"id":{"type":"string","format":"uuid"},"orderLineId":{"type":"string","format":"uuid"},"resourceId":{"type":"string","format":"uuid"},"resourceName":{"type":"string"},"quantity":{"type":"integer","minimum":1},"units":{"type":"array","items":{"$ref":"#/components/schemas/ShipmentUnit"}}}},"ShipmentEvent":{"type":"object","required":["id","fromStatus","toStatus","note","actor","occurredAt"],"properties":{"id":{"type":"string","format":"uuid"},"fromStatus":{"anyOf":[{"$ref":"#/components/schemas/ShipmentStatus"},{"type":"null"}]},"toStatus":{"$ref":"#/components/schemas/ShipmentStatus"},"note":{"type":"string"},"actor":{"type":["string","null"]},"occurredAt":{"type":"string","format":"date-time"}}},"Shipment":{"type":"object","required":["id","orderId","carrierCode","service","trackingNumber","trackingUrl","status","shippedAt","deliveredAt","note","createdBy","updatedBy","createdAt","updatedAt","lines","events","totalQuantity"],"properties":{"id":{"type":"string","format":"uuid"},"orderId":{"type":"string","format":"uuid"},"carrierCode":{"type":"string"},"service":{"type":["string","null"]},"trackingNumber":{"type":["string","null"]},"trackingUrl":{"type":["string","null"],"format":"uri"},"status":{"$ref":"#/components/schemas/ShipmentStatus"},"shippedAt":{"type":["string","null"],"format":"date-time"},"deliveredAt":{"type":["string","null"],"format":"date-time"},"note":{"type":"string"},"createdBy":{"type":["string","null"]},"updatedBy":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"lines":{"type":"array","items":{"$ref":"#/components/schemas/ShipmentLine"}},"events":{"type":"array","items":{"$ref":"#/components/schemas/ShipmentEvent"}},"totalQuantity":{"type":"integer","minimum":1}}},"OrderLineMovementInput":{"type":"object","additionalProperties":false,"required":["action","quantity"],"properties":{"action":{"type":"string","enum":["issue","return"]},"quantity":{"type":"integer","minimum":1,"maximum":2000000000},"occurredAt":{"type":"string","format":"date-time"},"location":{"type":["string","null"],"maxLength":240},"note":{"type":"string","maxLength":20000}}},"OrderLineUnit":{"type":"object","required":["id","stockUnitId","code","status","stockStatus","reservedAt","fulfilledAt","returnedAt"],"properties":{"id":{"type":"string","format":"uuid"},"stockUnitId":{"type":"string","format":"uuid"},"code":{"type":"string","maxLength":180},"status":{"type":"string","enum":["reserved","fulfilled","returned"]},"stockStatus":{"type":"string","enum":["available","reserved","in-use","maintenance","consumed","lost","retired"]},"reservedAt":{"type":"string","format":"date-time"},"fulfilledAt":{"type":["string","null"],"format":"date-time"},"returnedAt":{"type":["string","null"],"format":"date-time"}}},"SerializedOrderLineUnits":{"type":"object","required":["line","availableUnits","assignments"],"properties":{"line":{"type":"object","required":["id","resourceId","resourceName","quantity","fulfilledQuantity","returnedQuantity"],"properties":{"id":{"type":"string","format":"uuid"},"resourceId":{"type":"string","format":"uuid"},"resourceName":{"type":"string"},"quantity":{"type":"integer","minimum":1},"fulfilledQuantity":{"type":"integer","minimum":0},"returnedQuantity":{"type":"integer","minimum":0}}},"availableUnits":{"type":"array","items":{"type":"object","required":["id","code","status","location"],"properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string","maxLength":180},"status":{"type":"string","const":"available"},"location":{"type":["string","null"],"maxLength":240}}}},"assignments":{"type":"array","items":{"$ref":"#/components/schemas/OrderLineUnit"}}}},"OrderLineUnitActionInput":{"type":"object","additionalProperties":false,"required":["action","unitIds"],"properties":{"action":{"type":"string","enum":["reserve","release","issue","return"]},"unitIds":{"type":"array","minItems":1,"maxItems":100,"uniqueItems":true,"items":{"type":"string","format":"uuid"}},"occurredAt":{"type":"string","format":"date-time"},"note":{"type":"string","maxLength":20000}}},"PurchaseReceiptInput":{"type":"object","oneOf":[{"required":["quantity"]},{"required":["purchaseQuantity"]}],"additionalProperties":false,"properties":{"quantity":{"type":"integer","minimum":1,"maximum":1000,"description":"Receipt quantity in base stock units."},"purchaseQuantity":{"type":"integer","minimum":1,"maximum":1000000,"description":"Receipt quantity in the purchase unit snapshotted on the order line."},"receivedAt":{"type":"string","format":"date-time"},"location":{"type":["string","null"],"maxLength":240},"note":{"type":"string","maxLength":20000},"unitCodes":{"type":"array","items":{"type":"string","maxLength":180}}}},"NativeLoginResponse":{"type":"object","required":["token","user","scopes","expiresAt","organization","organizations"],"properties":{"token":{"type":"string","description":"Opaque secret returned only once."},"user":{"type":"object","required":["id","name","email","role"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string","format":"email"},"role":{"$ref":"#/components/schemas/AccessRoleKey"}}},"scopes":{"type":"array","items":{"type":"string","enum":["read","write","ai"]}},"expiresAt":{"type":"string","format":"date-time"},"organization":{"$ref":"#/components/schemas/OrganizationMembership"},"organizations":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/OrganizationMembership"}}}},"Pagination":{"type":"object","required":["page","pageSize","total","pages"],"properties":{"page":{"type":"integer"},"pageSize":{"type":"integer"},"total":{"type":"integer"},"pages":{"type":"integer"}}},"CsvImportResponse":{"type":"object","required":["importId","summary","rows"],"properties":{"importId":{"type":"string","format":"uuid","description":"The request Idempotency-Key."},"summary":{"type":"object","required":["total","created","replayed","failed"],"properties":{"total":{"type":"integer","minimum":1,"maximum":1000},"created":{"type":"integer","minimum":0},"replayed":{"type":"integer","minimum":0},"failed":{"type":"integer","minimum":0}}},"rows":{"type":"array","minItems":1,"maxItems":1000,"items":{"type":"object","required":["line","status"],"properties":{"line":{"type":"integer","minimum":2,"description":"One-based source line where the CSV row begins."},"status":{"type":"string","enum":["created","replayed","error"]},"resource":{"type":"object","description":"Present for created and replayed rows.","required":["id","name","sku"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"sku":{"type":["string","null"]}}},"error":{"type":"string","description":"Present for rows with status error."},"details":{"type":"array","items":{"type":"string"}}}}}}},"Media":{"type":"object","required":["id","resourceId","url","name","mimeType","kind","position","source"],"properties":{"id":{"type":"string","format":"uuid"},"resourceId":{"type":"string","format":"uuid"},"url":{"type":"string"},"name":{"type":"string"},"mimeType":{"type":"string"},"kind":{"type":"string","enum":["image","video","document","model","unknown"]},"position":{"type":"integer"},"source":{"type":"string","enum":["upload","ai"]},"altText":{"type":"string"}}},"ScanWorkflowExtraction":{"oneOf":[{"type":"object","required":["mode"],"additionalProperties":false,"properties":{"mode":{"type":"string","const":"full"}}},{"type":"object","required":["mode","parameter"],"additionalProperties":false,"properties":{"mode":{"type":"string","const":"url-query"},"parameter":{"type":"string","minLength":1,"maxLength":80},"sourceOrigin":{"type":"string","maxLength":300,"description":"Optional exact URL origin; the server never fetches the URL."},"sourcePath":{"type":"string","pattern":"^/[^?#]*$","maxLength":500}}},{"type":"object","required":["mode","prefix"],"additionalProperties":false,"properties":{"mode":{"type":"string","const":"prefix"},"prefix":{"type":"string","minLength":1,"maxLength":160}}},{"type":"object","required":["mode","pattern","group"],"additionalProperties":false,"properties":{"mode":{"type":"string","const":"regex"},"pattern":{"type":"string","minLength":1,"maxLength":500},"flags":{"type":"string","maxLength":4,"default":""},"group":{"type":"string","minLength":1,"maxLength":64}}}]},"ScanCodeType":{"type":"string","enum":["qr_code","data_matrix","aztec","pdf417","code_128","code_93","code_39","codabar","ean_13","ean_8","upc_a","upc_e","itf"]},"ScanExtractionSuggestion":{"type":"object","required":["suggestion","model"],"properties":{"suggestion":{"type":"object","required":["pattern","flags","group","explanation"],"properties":{"pattern":{"type":"string"},"flags":{"type":"string"},"group":{"type":"string"},"explanation":{"type":"string"}}},"model":{"type":"string"}}},"ScanWorkflowFixedProperty":{"type":"object","required":["key","label","value"],"additionalProperties":false,"properties":{"key":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[A-Za-z0-9_.-]+$"},"label":{"type":"string","minLength":1,"maxLength":120},"value":{"type":"string","maxLength":240},"storage":{"type":"string","enum":["custom-field","metadata","execution"],"default":"metadata"}}},"ScanWorkflowExtractedField":{"type":"object","required":["key","label","extraction"],"additionalProperties":false,"properties":{"key":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[A-Za-z0-9_.-]+$"},"label":{"type":"string","minLength":1,"maxLength":120},"extraction":{"$ref":"#/components/schemas/ScanWorkflowExtraction"},"storage":{"type":"string","enum":["custom-field","metadata","execution"],"default":"custom-field"}}},"ScanWorkflowOperation":{"oneOf":[{"type":"object","required":["type"],"additionalProperties":false,"properties":{"type":{"type":"string","const":"unit"}}},{"type":"object","required":["type","delta"],"additionalProperties":false,"properties":{"type":{"type":"string","const":"stock-adjustment"},"delta":{"type":"integer","minimum":-1000000,"maximum":1000000,"not":{"const":0}}}},{"type":"object","required":["type","quantity"],"additionalProperties":false,"properties":{"type":{"type":"string","const":"assembly-build"},"quantity":{"type":"integer","minimum":1,"maximum":1000}}}]},"ScanWorkflowOption":{"type":"object","required":["value","label"],"additionalProperties":false,"properties":{"value":{"type":"string","minLength":1,"maxLength":120},"label":{"type":"string","minLength":1,"maxLength":120},"color":{"type":"string","minLength":1,"maxLength":32}}},"ActionChainValue":{"oneOf":[{"type":"object","properties":{"source":{"type":"string","const":"literal"},"value":{"anyOf":[{"type":"string","maxLength":20000},{"type":"number"},{"type":"boolean"},{"type":"null"}]}},"required":["source","value"],"additionalProperties":false},{"type":"object","properties":{"source":{"type":"string","const":"scan"},"field":{"type":"string","enum":["identifier","raw"]}},"required":["source","field"],"additionalProperties":false},{"type":"object","properties":{"source":{"type":"string","const":"input"},"key":{"type":"string","pattern":"^[A-Za-z0-9_.-]{1,80}$"}},"required":["source","key"],"additionalProperties":false},{"type":"object","properties":{"source":{"type":"string","const":"result"},"actionId":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,80}$"},"path":{"type":"string","pattern":"^(resourceId|unitId|code|found|status|quantity|metadata\\.[A-Za-z0-9_.-]{1,80}|customFields\\.[A-Za-z0-9_.-]{1,80})$"}},"required":["source","actionId","path"],"additionalProperties":false}]},"ActionChainConditions":{"type":"object","properties":{"mode":{"type":"string","enum":["all","any"]},"rules":{"minItems":1,"maxItems":8,"type":"array","items":{"type":"object","properties":{"left":{"$ref":"#/components/schemas/ActionChainValue"},"operator":{"type":"string","enum":["equals","not-equals","exists","missing","gt","gte","lt","lte"]},"right":{"$ref":"#/components/schemas/ActionChainValue"}},"required":["left","operator"],"additionalProperties":false}}},"required":["mode","rules"],"additionalProperties":false},"ActionChainTarget":{"oneOf":[{"type":"object","properties":{"source":{"type":"string","const":"selected"}},"required":["source"],"additionalProperties":false},{"type":"object","properties":{"source":{"type":"string","const":"resource"},"resourceId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["source","resourceId"],"additionalProperties":false},{"type":"object","properties":{"source":{"type":"string","const":"result"},"actionId":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,80}$"}},"required":["source","actionId"],"additionalProperties":false}]},"ActionChainAction":{"oneOf":[{"type":"object","properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,80}$"},"label":{"type":"string","minLength":1,"maxLength":160},"enabled":{"default":true,"type":"boolean"},"when":{"default":null,"anyOf":[{"$ref":"#/components/schemas/ActionChainConditions"},{"type":"null"}]},"target":{"$ref":"#/components/schemas/ActionChainTarget"},"code":{"$ref":"#/components/schemas/ActionChainValue","default":{"source":"scan","field":"identifier"}},"type":{"type":"string","const":"find-unit"},"allowMissing":{"default":false,"type":"boolean"}},"required":["id","label","target","type"],"additionalProperties":false},{"type":"object","properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,80}$"},"label":{"type":"string","minLength":1,"maxLength":160},"enabled":{"default":true,"type":"boolean"},"when":{"default":null,"anyOf":[{"$ref":"#/components/schemas/ActionChainConditions"},{"type":"null"}]},"target":{"$ref":"#/components/schemas/ActionChainTarget"},"code":{"$ref":"#/components/schemas/ActionChainValue","default":{"source":"scan","field":"identifier"}},"properties":{"default":[],"maxItems":24,"type":"array","items":{"type":"object","properties":{"key":{"type":"string","pattern":"^[A-Za-z0-9_.-]{1,80}$"},"storage":{"type":"string","enum":["metadata","custom-field"]},"value":{"$ref":"#/components/schemas/ActionChainValue"}},"required":["key","storage","value"],"additionalProperties":false}},"applyFlowValues":{"default":false,"type":"boolean"},"type":{"type":"string","const":"unit"},"mode":{"type":"string","enum":["create","update","upsert"]},"status":{"default":null,"anyOf":[{"type":"string","enum":["available","reserved","in-use","maintenance","consumed","lost","retired"]},{"type":"null"}]}},"required":["id","label","target","type","mode"],"additionalProperties":false},{"type":"object","properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,80}$"},"label":{"type":"string","minLength":1,"maxLength":160},"enabled":{"default":true,"type":"boolean"},"when":{"default":null,"anyOf":[{"$ref":"#/components/schemas/ActionChainConditions"},{"type":"null"}]},"target":{"$ref":"#/components/schemas/ActionChainTarget"},"code":{"$ref":"#/components/schemas/ActionChainValue","default":{"source":"scan","field":"identifier"}},"properties":{"default":[],"maxItems":24,"type":"array","items":{"type":"object","properties":{"key":{"type":"string","pattern":"^[A-Za-z0-9_.-]{1,80}$"},"storage":{"type":"string","enum":["metadata","custom-field"]},"value":{"$ref":"#/components/schemas/ActionChainValue"}},"required":["key","storage","value"],"additionalProperties":false}},"applyFlowValues":{"default":false,"type":"boolean"},"type":{"type":"string","const":"assembly-build"},"quantity":{"$ref":"#/components/schemas/ActionChainValue"},"components":{"default":[],"maxItems":40,"type":"array","items":{"type":"object","properties":{"slotKey":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,80}$"},"resource":{"$ref":"#/components/schemas/ActionChainValue"},"unitFromAction":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,80}$"},"choice":{"type":"object","properties":{"inputKey":{"type":"string","pattern":"^[A-Za-z0-9_.-]{1,80}$"},"resources":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":120},"additionalProperties":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},"required":["inputKey","resources"],"additionalProperties":false}},"required":["slotKey"],"additionalProperties":false}}},"required":["id","label","target","type","quantity"],"additionalProperties":false},{"type":"object","properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,80}$"},"label":{"type":"string","minLength":1,"maxLength":160},"enabled":{"default":true,"type":"boolean"},"when":{"default":null,"anyOf":[{"$ref":"#/components/schemas/ActionChainConditions"},{"type":"null"}]},"type":{"type":"string","const":"stock-adjustment"},"target":{"$ref":"#/components/schemas/ActionChainTarget"},"delta":{"$ref":"#/components/schemas/ActionChainValue"},"factor":{"default":1,"anyOf":[{"type":"number","const":1},{"type":"number","const":-1}]}},"required":["id","label","type","target","delta"],"additionalProperties":false},{"type":"object","properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,80}$"},"label":{"type":"string","minLength":1,"maxLength":160},"enabled":{"default":true,"type":"boolean"},"when":{"default":null,"anyOf":[{"$ref":"#/components/schemas/ActionChainConditions"},{"type":"null"}]},"target":{"$ref":"#/components/schemas/ActionChainTarget"},"code":{"$ref":"#/components/schemas/ActionChainValue","default":{"source":"scan","field":"identifier"}},"type":{"type":"string","const":"set-location"},"location":{"$ref":"#/components/schemas/ActionChainValue"},"structured":{"default":true,"type":"boolean"}},"required":["id","label","target","type","location"],"additionalProperties":false},{"type":"object","properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,80}$"},"label":{"type":"string","minLength":1,"maxLength":160},"enabled":{"default":true,"type":"boolean"},"when":{"default":null,"anyOf":[{"$ref":"#/components/schemas/ActionChainConditions"},{"type":"null"}]},"type":{"type":"string","const":"assert"},"check":{"$ref":"#/components/schemas/ActionChainConditions"},"message":{"type":"string","minLength":1,"maxLength":500}},"required":["id","label","type","check","message"],"additionalProperties":false},{"type":"object","properties":{"id":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,80}$"},"label":{"type":"string","minLength":1,"maxLength":160},"enabled":{"default":true,"type":"boolean"},"when":{"default":null,"anyOf":[{"$ref":"#/components/schemas/ActionChainConditions"},{"type":"null"}]},"type":{"type":"string","const":"webhook"},"eventName":{"type":"string","minLength":1,"maxLength":120},"properties":{"default":[],"maxItems":24,"type":"array","items":{"type":"object","properties":{"key":{"type":"string","pattern":"^[A-Za-z0-9_-]{1,80}$"},"value":{"$ref":"#/components/schemas/ActionChainValue"}},"required":["key","value"],"additionalProperties":false}}},"required":["id","label","type","eventName"],"additionalProperties":false}]},"ActionChainRunInput":{"type":"object","properties":{"workflowId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"code":{"type":"string","minLength":1,"maxLength":2048},"codeType":{"type":["string","null"],"enum":["qr_code","data_matrix","aztec","pdf417","code_128","code_93","code_39","codabar","ean_13","ean_8","upc_a","upc_e","itf",null]},"selectedResourceIds":{"default":[],"maxItems":24,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"inputs":{"default":{},"type":"object","propertyNames":{"type":"string","maxLength":80},"additionalProperties":{"anyOf":[{"type":"string","maxLength":20000},{"type":"number"},{"type":"boolean"},{"maxItems":12,"type":"array","items":{"type":"string","maxLength":2048}}]}},"expectedPlanHash":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["workflowId","code"],"additionalProperties":false},"ActionChainRunReport":{"type":"object","properties":{"workflowId":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"revision":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"identifier":{"type":"string"},"planHash":{"type":"string","pattern":"^[a-f0-9]{64}$"},"replayed":{"type":"boolean"},"steps":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"},"skipped":{"type":"boolean"},"target":{"anyOf":[{"type":"string"},{"type":"null"}]},"eventName":{"type":"string"},"code":{"type":"string"},"quantityBefore":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"quantityAfter":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"statusBefore":{"anyOf":[{"type":"string"},{"type":"null"}]},"statusAfter":{"anyOf":[{"type":"string"},{"type":"null"}]},"locationBefore":{"anyOf":[{"type":"string"},{"type":"null"}]},"locationAfter":{"anyOf":[{"type":"string"},{"type":"null"}]},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"customFields":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"components":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"quantity":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"codes":{"type":"array","items":{"type":"string"}}},"required":["name","quantity","codes"]}}},"required":["id","label","type","skipped","target"]}}},"required":["workflowId","revision","identifier","planHash","steps"]},"ScanWorkflowInputField":{"type":"object","required":["key","label","required"],"additionalProperties":false,"properties":{"visibleWhen":{"anyOf":[{"$ref":"#/components/schemas/ActionChainConditions"},{"type":"null"}],"description":"May depend only on scan values and earlier visible inputs. Hidden values are ignored, including required fields."},"key":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[A-Za-z0-9_.-]+$"},"label":{"type":"string","minLength":1,"maxLength":120},"required":{"type":"boolean"},"type":{"type":"string","enum":["text","textarea","number","checkbox","select","radio","media","file"],"default":"select"},"storage":{"type":"string","enum":["custom-field","metadata","execution"],"default":"metadata"},"placeholder":{"type":"string","maxLength":240,"default":""},"options":{"type":"array","maxItems":40,"default":[],"items":{"$ref":"#/components/schemas/ScanWorkflowOption"}}}},"ScanWorkflowInput":{"type":"object","required":["name","resourceId","extraction","identifierPropertyKey"],"properties":{"actions":{"type":"array","maxItems":24,"default":[],"description":"Ordered action list. Empty preserves the legacy operation. Results may reference only earlier actions. At least one action must be enabled.","items":{"$ref":"#/components/schemas/ActionChainAction"}},"oncePerCode":{"type":"boolean","default":false,"description":"Deduplicate workflow + extracted identifier + selected target set, even with a new execution key."},"name":{"type":"string","minLength":1,"maxLength":160},"description":{"type":"string","maxLength":5000,"default":""},"enabled":{"type":"boolean","default":true},"resourceId":{"type":"string","format":"uuid"},"codeTypes":{"type":"array","minItems":1,"uniqueItems":true,"default":["qr_code","data_matrix","aztec","pdf417","code_128","code_93","code_39","codabar","ean_13","ean_8","upc_a","upc_e","itf"],"items":{"$ref":"#/components/schemas/ScanCodeType"}},"publicTriggerEnabled":{"type":"boolean","default":false},"publicTriggerCode":{"type":["string","null"],"minLength":1,"maxLength":2048,"description":"Optional fixed code used by the public URL; when null the public form asks for a code."},"quantityInputKey":{"type":["string","null"],"minLength":1,"maxLength":80,"pattern":"^[A-Za-z0-9_.-]+$","description":"Required number input whose positive integer value replaces the configured operation magnitude."},"extraction":{"$ref":"#/components/schemas/ScanWorkflowExtraction"},"identifierPropertyKey":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[A-Za-z0-9_.-]+$"},"identifierStorage":{"type":"string","enum":["custom-field","metadata","execution"],"default":"metadata"},"extractedFields":{"type":"array","maxItems":24,"default":[],"items":{"$ref":"#/components/schemas/ScanWorkflowExtractedField"}},"operation":{"allOf":[{"$ref":"#/components/schemas/ScanWorkflowOperation"}],"default":{"type":"unit"}},"createMissingUnit":{"type":"boolean","default":false},"unitStatus":{"oneOf":[{"type":"string","enum":["available","reserved","in-use","maintenance","consumed","lost","retired"]},{"type":"null"}]},"fixedProperties":{"type":"array","maxItems":24,"items":{"$ref":"#/components/schemas/ScanWorkflowFixedProperty"}},"inputFields":{"type":"array","maxItems":24,"items":{"$ref":"#/components/schemas/ScanWorkflowInputField"}},"triggerWebhook":{"type":"boolean","default":false},"webhookEventName":{"type":"string","minLength":1,"maxLength":120,"default":"inventory.action.executed"}}},"ScanWorkflowPatch":{"type":"object","required":["revision"],"minProperties":2,"additionalProperties":false,"description":"Current revision plus at least one writable ScanWorkflowInput property.","properties":{"actions":{"type":"array","maxItems":24,"default":[],"description":"Ordered action list. Empty preserves the legacy operation. Results may reference only earlier actions. At least one action must be enabled.","items":{"$ref":"#/components/schemas/ActionChainAction"}},"oncePerCode":{"type":"boolean","default":false,"description":"Deduplicate workflow + extracted identifier + selected target set, even with a new execution key."},"revision":{"type":"integer","minimum":1},"name":{"type":"string","minLength":1,"maxLength":160},"description":{"type":"string","maxLength":5000},"enabled":{"type":"boolean"},"resourceId":{"type":"string","format":"uuid"},"codeTypes":{"type":"array","minItems":1,"uniqueItems":true,"items":{"$ref":"#/components/schemas/ScanCodeType"}},"publicTriggerEnabled":{"type":"boolean"},"publicTriggerCode":{"type":["string","null"],"minLength":1,"maxLength":2048},"quantityInputKey":{"type":["string","null"],"minLength":1,"maxLength":80,"pattern":"^[A-Za-z0-9_.-]+$"},"extraction":{"$ref":"#/components/schemas/ScanWorkflowExtraction"},"identifierPropertyKey":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[A-Za-z0-9_.-]+$"},"identifierStorage":{"type":"string","enum":["custom-field","metadata","execution"]},"extractedFields":{"type":"array","maxItems":24,"items":{"$ref":"#/components/schemas/ScanWorkflowExtractedField"}},"operation":{"$ref":"#/components/schemas/ScanWorkflowOperation"},"createMissingUnit":{"type":"boolean"},"unitStatus":{"oneOf":[{"type":"string","enum":["available","reserved","in-use","maintenance","consumed","lost","retired"]},{"type":"null"}]},"fixedProperties":{"type":"array","maxItems":24,"items":{"$ref":"#/components/schemas/ScanWorkflowFixedProperty"}},"inputFields":{"type":"array","maxItems":24,"items":{"$ref":"#/components/schemas/ScanWorkflowInputField"}},"triggerWebhook":{"type":"boolean"},"webhookEventName":{"type":"string","minLength":1,"maxLength":120}}},"ScanWorkflow":{"allOf":[{"$ref":"#/components/schemas/ScanWorkflowInput"},{"type":"object","required":["id","name","description","enabled","resourceId","resourceIds","targetSelectionMode","allowVariantSelection","codeTypes","publicTriggerEnabled","publicTriggerId","publicTriggerCode","quantityInputKey","revision","extraction","identifierPropertyKey","identifierStorage","extractedFields","operation","createMissingUnit","unitStatus","fixedProperties","inputFields","triggerWebhook","webhookEventName","createdBy","updatedBy","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"publicTriggerId":{"type":"string","format":"uuid","description":"Random bearer identifier used in the public action URL."},"revision":{"type":"integer","minimum":1},"createdBy":{"type":["string","null"]},"updatedBy":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}]},"ScanWorkflowTargetOption":{"type":"object","additionalProperties":false,"required":["id","name","quantity","trackingMode","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"quantity":{"type":"integer"},"trackingMode":{"type":"string","enum":["bulk","serialized"]},"updatedAt":{"type":"string","format":"date-time"}}},"ScanWorkflowTargetGroup":{"type":"object","additionalProperties":false,"required":["resourceId","name","options"],"properties":{"resourceId":{"type":"string","format":"uuid"},"name":{"type":"string"},"options":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/ScanWorkflowTargetOption"}}}},"StockScanExpectedTarget":{"type":"object","additionalProperties":false,"required":["resourceId","resourceUpdatedAt","unitId","unitUpdatedAt"],"properties":{"resourceId":{"type":"string","format":"uuid"},"resourceUpdatedAt":{"type":"string","format":"date-time"},"unitId":{"type":["string","null"],"format":"uuid"},"unitUpdatedAt":{"type":["string","null"],"format":"date-time"}}},"PublicActionFlow":{"type":"object","additionalProperties":false,"required":["triggerId","name","description","resourceName","targetSelectionMode","allowVariantSelection","targetGroups","requiresCode","identifierLabel","quantityInputKey","inputFields","operation"],"properties":{"triggerId":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string"},"resourceName":{"type":"string"},"targetSelectionMode":{"type":"string","enum":["all","radio","checkbox"]},"allowVariantSelection":{"type":"boolean"},"targetGroups":{"type":"array","items":{"$ref":"#/components/schemas/ScanWorkflowTargetGroup"}},"requiresCode":{"type":"boolean"},"identifierLabel":{"type":"string"},"quantityInputKey":{"type":["string","null"]},"inputFields":{"type":"array","items":{"$ref":"#/components/schemas/ScanWorkflowInputField"}},"operation":{"oneOf":[{"type":"object","required":["type"],"additionalProperties":false,"properties":{"type":{"type":"string","const":"unit"}}},{"type":"object","required":["type","direction","quantity"],"additionalProperties":false,"properties":{"type":{"type":"string","const":"stock-adjustment"},"direction":{"type":"string","enum":["in","out"]},"quantity":{"type":"integer","minimum":1}}},{"type":"object","required":["type","quantity"],"additionalProperties":false,"properties":{"type":{"type":"string","const":"assembly-build"},"quantity":{"type":"integer","minimum":1}}}]}}},"PublicActionFlowExecutionInput":{"type":"object","additionalProperties":false,"properties":{"code":{"type":"string","minLength":1,"maxLength":2048},"selectedResourceIds":{"type":"array","maxItems":24,"uniqueItems":true,"items":{"type":"string","format":"uuid"}},"inputs":{"type":"object","default":{},"maxProperties":24,"propertyNames":{"minLength":1,"maxLength":80},"additionalProperties":{"oneOf":[{"type":"string","maxLength":20000},{"type":"number"},{"type":"boolean"},{"type":"array","maxItems":12,"items":{"type":"string","maxLength":2048}}]}}}},"StockScanResolution":{"type":"object","required":["workflow","resource","resources","targetGroups","selectedResourceIds","expectedTargets","identifier","operation","unit","willCreate","fields","fixedProperties","metadataPreview","customFieldsPreview","executionPreview","statusBefore","statusAfter","quantityBefore","quantityAfter","delta","expectedResourceUpdatedAt","expectedUnitId","expectedUnitUpdatedAt"],"additionalProperties":false,"properties":{"workflow":{"$ref":"#/components/schemas/ScanWorkflow"},"resource":{"type":"object","required":["id","name","quantity","trackingMode"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"quantity":{"type":"integer"},"trackingMode":{"type":"string","enum":["bulk","serialized"]}}},"resources":{"type":"array","items":{"$ref":"#/components/schemas/ScanWorkflowTargetOption"}},"targetGroups":{"type":"array","items":{"$ref":"#/components/schemas/ScanWorkflowTargetGroup"}},"selectedResourceIds":{"type":"array","uniqueItems":true,"items":{"type":"string","format":"uuid"}},"expectedTargets":{"type":"array","items":{"$ref":"#/components/schemas/StockScanExpectedTarget"}},"identifier":{"type":"string","minLength":1,"maxLength":180},"operation":{"$ref":"#/components/schemas/ScanWorkflowOperation"},"unit":{"oneOf":[{"$ref":"#/components/schemas/StockUnit"},{"type":"null"}]},"willCreate":{"type":"boolean"},"statusBefore":{"oneOf":[{"type":"string","enum":["available","reserved","in-use","maintenance","consumed","lost","retired"]},{"type":"null"}]},"statusAfter":{"oneOf":[{"type":"string","enum":["available","reserved","in-use","maintenance","consumed","lost","retired"]},{"type":"null"}]},"quantityBefore":{"type":"integer"},"quantityAfter":{"type":"integer"},"delta":{"type":"integer"},"expectedResourceUpdatedAt":{"type":"string","format":"date-time","description":"Resource version captured by resolve; execute rejects a stale quantity preview."},"expectedUnitId":{"description":"Unit captured by resolve, or null when no matching unit existed. Both unit guard fields must be null or non-null together.","oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"expectedUnitUpdatedAt":{"description":"Unit version captured by resolve, or null when no matching unit existed. Both unit guard fields must be null or non-null together.","oneOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"fields":{"type":"array","maxItems":24,"items":{"$ref":"#/components/schemas/ScanWorkflowInputField"}},"fixedProperties":{"type":"array","maxItems":24,"items":{"$ref":"#/components/schemas/ScanWorkflowFixedProperty"}},"metadataPreview":{"type":"object","additionalProperties":true},"customFieldsPreview":{"type":"object","additionalProperties":true},"executionPreview":{"type":"object","additionalProperties":true}}},"StockScanExecutionInput":{"type":"object","required":["workflowId","revision","code","expectedResourceUpdatedAt","expectedUnitId","expectedUnitUpdatedAt"],"additionalProperties":false,"properties":{"expectedPlanHash":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"Required for action chains. Prefer the dedicated action-chains endpoints."},"workflowId":{"type":"string","format":"uuid"},"revision":{"type":"integer","minimum":1},"code":{"type":"string","minLength":1,"maxLength":2048},"codeType":{"oneOf":[{"$ref":"#/components/schemas/ScanCodeType"},{"type":"null"}]},"expectedResourceUpdatedAt":{"type":"string","format":"date-time","description":"Copy exactly from the resolve response."},"expectedUnitId":{"description":"Copy exactly from resolve; must be null together with expectedUnitUpdatedAt or non-null together with it.","oneOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"expectedUnitUpdatedAt":{"description":"Copy exactly from resolve; must be null together with expectedUnitId or non-null together with it.","oneOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"selectedResourceIds":{"type":"array","maxItems":24,"uniqueItems":true,"items":{"type":"string","format":"uuid"}},"expectedTargets":{"type":"array","maxItems":24,"items":{"$ref":"#/components/schemas/StockScanExpectedTarget"}},"inputs":{"type":"object","default":{},"description":"Operator-provided workflow fields. May be omitted when the workflow has no input fields.","maxProperties":24,"propertyNames":{"minLength":1,"maxLength":80},"additionalProperties":{"oneOf":[{"type":"string","maxLength":20000},{"type":"number"},{"type":"boolean"},{"type":"array","maxItems":12,"items":{"type":"string","maxLength":2048}}]}}}},"StockScanExecution":{"type":"object","required":["workflowId","revision","operation","resource","unit","movement","created","metadataBefore","metadataAfter"],"additionalProperties":true,"properties":{"workflowId":{"type":"string","format":"uuid"},"revision":{"type":"integer","minimum":1},"resource":{"type":"object","required":["id","name","quantity"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"quantity":{"type":"integer"}}},"operation":{"$ref":"#/components/schemas/ScanWorkflowOperation"},"unit":{"oneOf":[{"$ref":"#/components/schemas/StockUnit"},{"type":"null"}]},"movement":{"oneOf":[{"$ref":"#/components/schemas/StockMovement"},{"type":"null"}]},"created":{"type":"boolean"},"metadataBefore":{"oneOf":[{"type":"object","additionalProperties":true},{"type":"null"}]},"metadataAfter":{"type":"object","additionalProperties":true}}},"StockLocationResource":{"type":"object","required":["id","name","type","status"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"type":{"$ref":"#/components/schemas/InventoryTypeKey"},"status":{"type":"string","enum":["available","in-use","maintenance","archived"]}}},"StockLocationBalance":{"type":"object","required":["locationResourceId","name","type","quantity"],"properties":{"locationResourceId":{"type":"string","format":"uuid"},"name":{"type":"string"},"type":{"$ref":"#/components/schemas/InventoryTypeKey"},"quantity":{"type":"integer"}}},"StockLocationBreakdown":{"type":"object","required":["resource","trackingMode","assignedQuantity","unassignedQuantity","locations"],"properties":{"resource":{"type":"object","required":["id","name","quantity","trackingMode"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"quantity":{"type":"integer"},"trackingMode":{"type":["string","null"],"enum":["bulk","serialized",null]}}},"trackingMode":{"type":"string","enum":["bulk","serialized"]},"assignedQuantity":{"type":"integer"},"unassignedQuantity":{"type":"integer"},"locations":{"type":"array","items":{"$ref":"#/components/schemas/StockLocationBalance"}}}},"StockLocationsResponse":{"type":"object","required":["breakdown","availableLocations"],"properties":{"breakdown":{"$ref":"#/components/schemas/StockLocationBreakdown"},"availableLocations":{"type":"array","items":{"$ref":"#/components/schemas/StockLocationResource"}}}},"InventoryCyclePolicyInput":{"type":"object","required":["intervalDays"],"additionalProperties":false,"properties":{"intervalDays":{"type":"integer","minimum":1,"maximum":3650},"enabled":{"type":"boolean","default":true}}},"InventoryCyclePolicy":{"type":"object","required":["resourceId","intervalDays","enabled","nextDueAt","lastCompletedAt","createdBy","updatedBy","createdAt","updatedAt"],"properties":{"resourceId":{"type":"string","format":"uuid"},"intervalDays":{"type":"integer","minimum":1,"maximum":3650},"enabled":{"type":"boolean"},"nextDueAt":{"type":"string","format":"date-time"},"lastCompletedAt":{"type":["string","null"],"format":"date-time"},"createdBy":{"type":["string","null"]},"updatedBy":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"InventoryCountInput":{"type":"object","required":["countedQuantity"],"additionalProperties":false,"properties":{"countedQuantity":{"type":"integer","minimum":0,"maximum":2000000000,"description":"For serialized tracking this must match current availability after individual units have been reviewed or corrected."},"locationResourceId":{"type":["string","null"],"format":"uuid","description":"Reconcile only this structured stock location when provided."},"countedAt":{"type":"string","format":"date-time"},"note":{"type":"string","maxLength":20000}}},"InventoryCountRecord":{"type":"object","required":["id","resourceId","locationResourceId","expectedQuantity","countedQuantity","variance","countedAt","note","movementId","idempotencyKey","createdBy","createdAt"],"properties":{"id":{"type":"string","format":"uuid"},"resourceId":{"type":"string","format":"uuid"},"locationResourceId":{"type":["string","null"],"format":"uuid"},"expectedQuantity":{"type":"integer","minimum":0},"countedQuantity":{"type":"integer","minimum":0},"variance":{"type":"integer"},"countedAt":{"type":"string","format":"date-time"},"note":{"type":"string"},"movementId":{"type":["string","null"],"format":"uuid"},"idempotencyKey":{"type":["string","null"],"format":"uuid"},"createdBy":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}}},"InventoryCountMutation":{"type":"object","required":["count","replayed"],"properties":{"count":{"$ref":"#/components/schemas/InventoryCountRecord"},"movementId":{"type":"string","format":"uuid","description":"Present when the count is newly recorded; replayed counts retain the movement id inside count."},"replayed":{"type":"boolean"}}},"InventoryCycle":{"type":"object","required":["resource","policy","history"],"properties":{"resource":{"type":"object","required":["id","name","quantity","trackingMode"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"quantity":{"type":"integer"},"trackingMode":{"type":"string","enum":["bulk","serialized"]}}},"policy":{"oneOf":[{"$ref":"#/components/schemas/InventoryCyclePolicy"},{"type":"null"}]},"history":{"type":"array","maxItems":25,"items":{"$ref":"#/components/schemas/InventoryCountRecord"}}}},"DueInventoryCycle":{"type":"object","required":["resourceId","name","type","quantity","intervalDays","nextDueAt","lastCompletedAt"],"properties":{"resourceId":{"type":"string","format":"uuid"},"name":{"type":"string"},"type":{"$ref":"#/components/schemas/InventoryTypeKey"},"quantity":{"type":"integer"},"intervalDays":{"type":"integer","minimum":1,"maximum":3650},"nextDueAt":{"type":"string","format":"date-time"},"lastCompletedAt":{"type":["string","null"],"format":"date-time"}}},"InternalRequestStatus":{"type":"string","enum":["submitted","approved","rejected","fulfilled","cancelled"]},"InternalRequestCreate":{"type":"object","required":["startsAt","dueAt","lines"],"additionalProperties":false,"properties":{"deliveryResourceId":{"type":["string","null"],"format":"uuid"},"startsAt":{"type":"string","format":"date-time"},"dueAt":{"type":"string","format":"date-time"},"note":{"type":"string","maxLength":20000},"lines":{"type":"array","minItems":1,"maxItems":50,"items":{"type":"object","required":["resourceId","quantity"],"additionalProperties":false,"properties":{"resourceId":{"type":"string","format":"uuid"},"quantity":{"type":"integer","minimum":1,"maximum":2000000000},"note":{"type":"string","maxLength":20000}}}}}},"InternalRequestAction":{"type":"object","required":["action"],"additionalProperties":false,"properties":{"action":{"type":"string","enum":["approve","reject","cancel","fulfill"]},"note":{"type":"string","maxLength":20000}}},"InternalRequestLine":{"type":"object","required":["id","resource","quantity","note","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"resource":{"type":"object","required":["id","name","sku","status","currentQuantity","trackingMode"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"sku":{"type":["string","null"]},"status":{"type":"string"},"currentQuantity":{"type":"integer"},"trackingMode":{"type":"string","enum":["bulk","serialized"]}}},"quantity":{"type":"integer","minimum":1},"note":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"InternalRequestEvent":{"type":"object","required":["id","type","actor","note","occurredAt"],"properties":{"id":{"type":"string","format":"uuid"},"type":{"$ref":"#/components/schemas/InternalRequestStatus"},"actor":{"type":"string"},"note":{"type":"string"},"occurredAt":{"type":"string","format":"date-time"}}},"InternalRequest":{"type":"object","required":["id","reference","status","requester","delivery","startsAt","dueAt","note","decisionNote","decidedBy","decidedAt","fulfilledBy","fulfilledAt","createdBy","createdAt","updatedAt","canCancel","lines","events"],"properties":{"id":{"type":"string","format":"uuid"},"reference":{"type":"string","example":"REQ-A1B2C3D4"},"status":{"$ref":"#/components/schemas/InternalRequestStatus"},"requester":{"type":"object","required":["userId","name","email"],"properties":{"userId":{"type":["string","null"],"format":"uuid"},"name":{"type":"string"},"email":{"type":["string","null"],"format":"email"}}},"delivery":{"oneOf":[{"type":"object","required":["resourceId","name"],"properties":{"resourceId":{"type":"string","format":"uuid"},"name":{"type":"string"}}},{"type":"null"}]},"startsAt":{"type":"string","format":"date-time"},"dueAt":{"type":"string","format":"date-time"},"note":{"type":"string"},"decisionNote":{"type":"string"},"decidedBy":{"type":["string","null"]},"decidedAt":{"type":["string","null"],"format":"date-time"},"fulfilledBy":{"type":["string","null"]},"fulfilledAt":{"type":["string","null"],"format":"date-time"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"canCancel":{"type":"boolean"},"lines":{"type":"array","items":{"$ref":"#/components/schemas/InternalRequestLine"}},"events":{"type":"array","items":{"$ref":"#/components/schemas/InternalRequestEvent"}}}},"InternalRequestMutation":{"type":"object","required":["request"],"properties":{"request":{"$ref":"#/components/schemas/InternalRequest"}}},"ReservationCalendarEntry":{"type":"object","required":["id","source","sourceId","reference","status","title","subtitle","resourceId","quantity","startsAt","dueAt"],"properties":{"id":{"type":"string"},"source":{"type":"string","enum":["internal-request","reservation"]},"sourceId":{"type":"string","format":"uuid"},"reference":{"type":["string","null"]},"status":{"type":"string","enum":["submitted","approved","fulfilled","reserved"]},"title":{"type":"string"},"subtitle":{"type":"string"},"resourceId":{"type":"string","format":"uuid"},"quantity":{"type":"integer","minimum":1},"startsAt":{"type":"string","format":"date-time"},"dueAt":{"type":["string","null"],"format":"date-time"}}},"ReservationCalendar":{"type":"object","required":["entries","range"],"properties":{"entries":{"type":"array","items":{"$ref":"#/components/schemas/ReservationCalendarEntry"}},"range":{"type":"object","required":["from","to"],"properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"}}}}},"InventoryAssignmentRecipientInput":{"oneOf":[{"type":"object","required":["type","userId"],"additionalProperties":false,"properties":{"type":{"type":"string","const":"user"},"userId":{"type":"string","format":"uuid"}}},{"type":"object","required":["type","resourceId"],"additionalProperties":false,"properties":{"type":{"type":"string","const":"resource"},"resourceId":{"type":"string","format":"uuid"}}},{"type":"object","required":["type","label"],"additionalProperties":false,"properties":{"type":{"type":"string","const":"label"},"label":{"type":"string","minLength":1,"maxLength":240}}}],"discriminator":{"propertyName":"type"}},"InventoryAssignmentInput":{"type":"object","required":["kind","recipient"],"additionalProperties":false,"properties":{"kind":{"type":"string","enum":["checkout","assignment","reservation"]},"quantity":{"type":"integer","minimum":1,"maximum":2000000000,"default":1},"stockUnitId":{"type":["string","null"],"format":"uuid","description":"Required for serialized stock and omitted for bulk stock."},"recipient":{"$ref":"#/components/schemas/InventoryAssignmentRecipientInput"},"startsAt":{"type":"string","format":"date-time"},"dueAt":{"type":["string","null"],"format":"date-time"},"note":{"type":"string","maxLength":20000}}},"InventoryAssignmentCompletion":{"type":"object","required":["status"],"additionalProperties":false,"properties":{"status":{"type":"string","enum":["returned","cancelled"]},"completedAt":{"type":"string","format":"date-time"},"note":{"type":"string","maxLength":20000}}},"InventoryReservationCheckout":{"type":"object","required":["action"],"additionalProperties":false,"properties":{"action":{"type":"string","const":"checkout"},"stockUnitId":{"type":["string","null"],"format":"uuid","description":"Required when the reserved item uses serialized tracking."},"checkedOutAt":{"type":"string","format":"date-time"},"note":{"type":"string","maxLength":20000}}},"LendingSettings":{"type":"object","required":["enabled","approvalRequired","defaultDurationDays","maxDurationDays"],"additionalProperties":false,"properties":{"enabled":{"type":"boolean"},"approvalRequired":{"type":"boolean"},"defaultDurationDays":{"type":"integer","minimum":1,"maximum":3650},"maxDurationDays":{"type":"integer","minimum":1,"maximum":3650}}},"InventoryAssignment":{"type":"object","required":["id","resourceId","stockUnitId","kind","status","stockApplied","overdue","quantity","assignee","stockUnit","startsAt","dueAt","completedAt","note","createdBy","completedBy","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"resourceId":{"type":"string","format":"uuid"},"stockUnitId":{"type":["string","null"],"format":"uuid"},"kind":{"type":"string","enum":["checkout","assignment","reservation"]},"status":{"type":"string","enum":["active","returned","cancelled"]},"stockApplied":{"type":"boolean"},"overdue":{"type":"boolean","description":"Derived from an active checkout whose due date has passed."},"quantity":{"type":"integer","minimum":1},"assignee":{"type":"object","required":["type","id","label","detail"],"properties":{"type":{"type":"string","enum":["user","resource","label"]},"id":{"type":["string","null"],"format":"uuid"},"label":{"type":"string"},"detail":{"type":["string","null"]}}},"stockUnit":{"oneOf":[{"type":"object","required":["id","code","status"],"properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"status":{"type":["string","null"]}}},{"type":"null"}]},"startsAt":{"type":"string","format":"date-time"},"dueAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"note":{"type":"string"},"createdBy":{"type":["string","null"]},"completedBy":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"InventoryAssignmentMutation":{"type":"object","required":["assignment","resource","movement"],"properties":{"assignment":{"$ref":"#/components/schemas/InventoryAssignment"},"resource":{"type":"object","required":["id","name","quantity"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"quantity":{"type":"integer"}}},"movement":{"$ref":"#/components/schemas/StockMovement"}}},"InventoryAssignmentList":{"type":"object","required":["resource","trackingMode","lending","availability","recipients","availableUnits","assignments"],"properties":{"resource":{"type":"object","required":["id","name","quantity"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"quantity":{"type":"integer"}}},"trackingMode":{"type":"string","enum":["bulk","serialized"]},"lending":{"$ref":"#/components/schemas/LendingSettings"},"availability":{"type":"object","required":["availableQuantity","activeQuantity","reservedQuantity"],"properties":{"availableQuantity":{"type":"integer"},"activeQuantity":{"type":"integer","minimum":0},"reservedQuantity":{"type":"integer","minimum":0}}},"recipients":{"type":"object","required":["users"],"properties":{"users":{"type":"array","maxItems":500,"items":{"type":"object","required":["id","name","email"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string","format":"email"}}}}}},"availableUnits":{"type":"array","maxItems":500,"items":{"type":"object","required":["id","code","status","location"],"properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"status":{"type":"string","enum":["available"]},"location":{"type":["string","null"]}}}},"assignments":{"type":"array","maxItems":200,"items":{"$ref":"#/components/schemas/InventoryAssignment"}}}},"StockConfigInput":{"type":"object","properties":{"trackingMode":{"type":"string","enum":["bulk","serialized"]},"minimumStock":{"type":"integer","minimum":0},"reorderQuantity":{"type":"integer","minimum":0},"leadTimeDays":{"type":"integer","minimum":0},"unitName":{"type":"string","minLength":1,"maxLength":80},"purchaseUnitName":{"type":["string","null"],"minLength":1,"maxLength":80},"purchaseUnitFactor":{"type":["integer","null"],"minimum":1,"maximum":2000000000}}},"ContactFields":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":240},"company":{"type":["string","null"],"maxLength":240},"roles":{"type":"array","minItems":1,"uniqueItems":true,"items":{"type":"string","enum":["customer","supplier"]}},"email":{"type":["string","null"],"format":"email","maxLength":320},"phone":{"type":["string","null"],"maxLength":80},"website":{"type":["string","null"],"format":"uri","maxLength":2048},"customerNumber":{"type":["string","null"],"maxLength":80},"supplierNumber":{"type":["string","null"],"maxLength":80},"taxId":{"type":["string","null"],"maxLength":80},"addressLine1":{"type":["string","null"],"maxLength":240},"addressLine2":{"type":["string","null"],"maxLength":240},"postalCode":{"type":["string","null"],"maxLength":32},"city":{"type":["string","null"],"maxLength":120},"state":{"type":["string","null"],"maxLength":120},"countryCode":{"type":["string","null"],"pattern":"^[A-Z]{2}$"},"tags":{"type":"array","maxItems":50,"uniqueItems":true,"items":{"type":"string","minLength":1,"maxLength":80}},"notes":{"type":"string","maxLength":20000},"resourceIds":{"type":"array","maxItems":500,"uniqueItems":true,"items":{"type":"string","format":"uuid"}}}},"ContactInput":{"allOf":[{"$ref":"#/components/schemas/ContactFields"},{"type":"object","required":["name","roles"]}]},"ContactPatch":{"allOf":[{"$ref":"#/components/schemas/ContactFields"},{"type":"object","minProperties":1}]},"Contact":{"allOf":[{"$ref":"#/components/schemas/ContactFields"},{"type":"object","required":["id","name","roles","tags","notes","archivedAt","createdAt","updatedAt","resources","movementCount","commentCount"],"properties":{"id":{"type":"string","format":"uuid"},"archivedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"resources":{"type":"array","items":{"type":"object","required":["id","name","sku","type"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"sku":{"type":["string","null"]},"type":{"type":"string"}}}},"movementCount":{"type":"integer","minimum":0},"commentCount":{"type":"integer","minimum":0}}}]},"CommentInput":{"type":"object","additionalProperties":false,"required":["body"],"properties":{"body":{"type":"string","minLength":1,"maxLength":10000}}},"ContactComment":{"type":"object","required":["id","contactId","body","authorName","createdAt","updatedAt","canEdit"],"properties":{"id":{"type":"string","format":"uuid"},"contactId":{"type":"string","format":"uuid"},"body":{"type":"string","minLength":1,"maxLength":10000},"authorName":{"type":"string","minLength":1,"maxLength":160},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"canEdit":{"type":"boolean"}}},"StockConfig":{"allOf":[{"$ref":"#/components/schemas/StockConfigInput"},{"type":"object","required":["trackingMode","minimumStock","reorderQuantity","leadTimeDays","unitName","purchaseUnitName","purchaseUnitFactor"]}]},"StockForecast":{"type":"object","required":["averageDailyUsage","daysUntilStockout","predictedStockoutAt","isBelowMinimum","suggestedReorderQuantity"],"properties":{"averageDailyUsage":{"type":["number","null"],"minimum":0},"daysUntilStockout":{"type":["number","null"],"minimum":0},"predictedStockoutAt":{"type":["string","null"],"format":"date-time"},"isBelowMinimum":{"type":"boolean"},"suggestedReorderQuantity":{"type":"integer","minimum":0}}},"StockMovementInput":{"type":"object","required":["delta","type"],"additionalProperties":false,"properties":{"delta":{"type":"integer","minimum":-2000000000,"maximum":2000000000,"description":"Positive receipts and negative issues. Structured transfers require zero because the global balance does not change."},"quantity":{"type":"integer","minimum":0,"maximum":2000000000,"description":"Required and positive for a structured transfer; otherwise it must equal the absolute delta when provided."},"type":{"type":"string","enum":["receipt","issue","adjustment","return","waste","transfer"]},"reason":{"type":["string","null"],"maxLength":240},"note":{"type":"string","maxLength":20000},"location":{"type":["string","null"],"maxLength":240},"fromLocationResourceId":{"type":["string","null"],"format":"uuid","description":"Structured source location for an issue or transfer."},"toLocationResourceId":{"type":["string","null"],"format":"uuid","description":"Structured destination location for a receipt or transfer."},"contactId":{"type":["string","null"],"format":"uuid","description":"Active customer or supplier associated with this movement."},"occurredAt":{"type":"string","format":"date-time"},"totalPriceCents":{"type":["integer","null"],"minimum":-2000000000,"maximum":2000000000,"description":"Signed transaction value; negative values can represent outbound revenue. Inbound prices must be nonnegative."},"priceCurrency":{"type":["string","null"],"minLength":3,"maxLength":3}}},"StockMovement":{"type":"object","required":["id","resourceId","contactId","delta","quantity","balanceAfter","fromLocationBalanceAfter","toLocationBalanceAfter","type","note","location","fromLocationResourceId","toLocationResourceId","occurredAt","createdAt","createdBy"],"properties":{"id":{"type":"string","format":"uuid"},"resourceId":{"type":"string","format":"uuid"},"contactId":{"type":["string","null"],"format":"uuid"},"unitId":{"type":["string","null"],"format":"uuid"},"assemblyBuildId":{"type":["string","null"],"format":"uuid"},"purchaseReceiptId":{"type":["string","null"],"format":"uuid"},"delta":{"type":"integer"},"quantity":{"type":"integer","minimum":0},"totalPriceCents":{"type":["integer","null"],"minimum":-2000000000},"priceCurrency":{"type":["string","null"]},"costCents":{"type":["integer","null"],"minimum":0},"costCurrency":{"type":["string","null"]},"costEstimated":{"type":"boolean"},"balanceAfter":{"type":"integer"},"fromLocationBalanceAfter":{"type":["integer","null"]},"toLocationBalanceAfter":{"type":["integer","null"]},"type":{"type":"string","description":"Includes client booking types plus system audit types such as opening_balance, inventory-count, assignment-checkout, assignment-return, unit-created, unit-status, and merge."},"reason":{"type":["string","null"]},"note":{"type":"string"},"location":{"type":["string","null"]},"fromLocationResourceId":{"type":["string","null"],"format":"uuid"},"toLocationResourceId":{"type":["string","null"],"format":"uuid"},"occurredAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"createdBy":{"type":["string","null"]}}},"StockUnitInput":{"type":"object","properties":{"count":{"type":"integer","minimum":1,"maximum":100,"default":1},"code":{"type":"string","maxLength":180},"codes":{"type":"array","maxItems":100,"items":{"type":"string","maxLength":180}},"location":{"type":["string","null"],"maxLength":240},"locationResourceId":{"type":["string","null"],"format":"uuid"},"metadata":{"type":"object","additionalProperties":true},"customFields":{"$ref":"#/components/schemas/CustomFieldValues"},"acquiredAt":{"type":"string","format":"date-time"},"totalPriceCents":{"type":["integer","null"],"minimum":0,"maximum":2000000000},"priceCurrency":{"type":["string","null"],"minLength":3,"maxLength":3}}},"StockUnitPatch":{"type":"object","properties":{"code":{"type":"string","minLength":1,"maxLength":180,"description":"Editable identifier unique within this item. Leading and trailing whitespace is removed. The unit UUID and its QR links remain unchanged."},"status":{"type":"string","enum":["available","reserved","in-use","maintenance","consumed","lost","retired"]},"location":{"type":["string","null"],"maxLength":240},"locationResourceId":{"type":["string","null"],"format":"uuid"},"metadata":{"type":"object","additionalProperties":true},"customFields":{"$ref":"#/components/schemas/CustomFieldValues"},"occurredAt":{"type":"string","format":"date-time"},"reason":{"type":["string","null"],"maxLength":240},"note":{"type":"string","maxLength":20000},"totalPriceCents":{"type":["integer","null"],"minimum":-2000000000,"maximum":2000000000,"description":"Signed transaction value; negative values can represent outbound revenue. Inbound prices must be nonnegative."},"priceCurrency":{"type":["string","null"],"minLength":3,"maxLength":3}}},"StockUnit":{"allOf":[{"$ref":"#/components/schemas/StockUnitPatch"},{"type":"object","required":["id","resourceId","code","status","location","locationResourceId","metadata","customFields","acquiredAt","lastMovedAt","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid"},"resourceId":{"type":"string","format":"uuid"},"code":{"type":"string"},"acquisitionCostCents":{"type":["integer","null"],"minimum":0},"costCurrency":{"type":["string","null"]},"acquiredAt":{"type":"string","format":"date-time"},"lastMovedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}]},"StockOverviewCover":{"type":"object","required":["url","altText"],"properties":{"url":{"type":"string"},"altText":{"type":"string"}}},"StockOverviewItem":{"type":"object","required":["resourceId","variantOfResourceId","name","type","cover","quantity","onOrder","projectedQuantity","minimumStock","trackingMode","reorderSuggested","unitName"],"properties":{"resourceId":{"type":"string","format":"uuid"},"variantOfResourceId":{"type":["string","null"],"format":"uuid"},"name":{"type":"string"},"type":{"type":"string"},"cover":{"oneOf":[{"$ref":"#/components/schemas/StockOverviewCover"},{"type":"null"}]},"quantity":{"type":"integer"},"onOrder":{"type":"integer","minimum":0},"projectedQuantity":{"type":"integer"},"nextExpectedAt":{"type":["string","null"],"format":"date-time"},"minimumStock":{"type":"integer","minimum":0},"trackingMode":{"type":"string","enum":["bulk","serialized"]},"averageDailyUsage":{"type":["number","null"],"minimum":0},"daysUntilStockout":{"type":["number","null"],"minimum":0},"predictedStockoutAt":{"type":["string","null"],"format":"date-time"},"reorderSuggested":{"type":"boolean"},"unitName":{"type":"string"}}},"StockDetail":{"type":"object","required":["resource","family","config","forecast","procurement","movements","units"],"properties":{"family":{"description":"Individual variant balances and their total including unassigned primary stock, read from the same database snapshot.","$ref":"#/components/schemas/ResourceFamily"},"resource":{"type":"object","required":["id","name","type","categories","quantity"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"type":{"$ref":"#/components/schemas/InventoryTypeKey"},"categories":{"type":"array","items":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"color":{"type":"string"}}}},"quantity":{"type":"integer","description":"This item’s own stock. For the family total use family.summary.totalQuantity."}}},"config":{"$ref":"#/components/schemas/StockConfig"},"forecast":{"$ref":"#/components/schemas/StockForecast"},"procurement":{"type":"object","required":["onOrder","projectedQuantity","nextExpectedAt","openLines"],"properties":{"onOrder":{"type":"integer","minimum":0},"projectedQuantity":{"type":"integer"},"nextExpectedAt":{"type":["string","null"],"format":"date-time"},"openLines":{"type":"array","items":{"type":"object","required":["lineId","orderId","supplier","orderedQuantity","receivedQuantity","openQuantity"],"properties":{"lineId":{"type":"string","format":"uuid"},"orderId":{"type":"string","format":"uuid"},"reference":{"type":["string","null"]},"supplier":{"type":"string"},"orderedQuantity":{"type":"integer","minimum":1},"receivedQuantity":{"type":"integer","minimum":0},"openQuantity":{"type":"integer","minimum":1},"expectedAt":{"type":["string","null"],"format":"date-time"}}}}}},"movements":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/StockMovement"}},"units":{"type":"array","items":{"$ref":"#/components/schemas/StockUnit"}}}},"ResourceInput":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":240},"slugs":{"type":"array","maxItems":20,"uniqueItems":true,"items":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"description":"Ordered organization-scoped URL slugs. The first value is the standard slug; remaining values are aliases. Values are normalized to lowercase; `new` and UUID-shaped values are reserved."},"description":{"type":"string","maxLength":20000},"type":{"$ref":"#/components/schemas/InventoryTypeKey"},"status":{"type":"string","enum":["available","in-use","maintenance","archived"]},"sku":{"type":["string","null"],"maxLength":80},"barcode":{"type":["string","null"],"maxLength":180},"quantity":{"type":"integer","minimum":0,"description":"Opening quantity; later changes use stock movements."},"location":{"type":["string","null"]},"serialNumber":{"type":["string","null"]},"valueCents":{"type":["integer","null"],"minimum":0},"currency":{"type":"string","minLength":3,"maxLength":3},"priority":{"type":"integer","minimum":1,"maximum":5},"tags":{"type":"array","items":{"type":"string"}},"categories":{"type":"array","items":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"color":{"type":"string"}}}},"relatedResourceIds":{"type":"array","maxItems":100,"items":{"type":"string","format":"uuid"},"description":"Legacy undirected related-item ids. Prefer typed resource relationships for new integrations."},"gpsLatitude":{"type":["number","null"],"minimum":-90,"maximum":90},"gpsLongitude":{"type":["number","null"],"minimum":-180,"maximum":180},"gpsAltitude":{"type":["number","null"]},"mapFeatures":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ResourceMapFeature"}},"notes":{"type":"string"},"customFields":{"$ref":"#/components/schemas/CustomFieldValues"},"subtitle":{"type":"string","maxLength":240,"description":"Optional subtitle used by label templates. Empty string clears it."}}},"ResourcePatch":{"type":"object","description":"Any subset of the writable resource fields.","properties":{"name":{"type":"string","minLength":1,"maxLength":240},"slugs":{"type":"array","maxItems":20,"uniqueItems":true,"items":{"type":"string","minLength":1,"maxLength":80,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"description":"Replaces the ordered URL slugs for this resource. The first value becomes the standard slug; remaining values are aliases."},"description":{"type":"string","maxLength":20000},"type":{"$ref":"#/components/schemas/InventoryTypeKey"},"status":{"type":"string","enum":["available","in-use","maintenance","archived"]},"sku":{"type":["string","null"],"maxLength":80},"barcode":{"type":["string","null"],"maxLength":180},"location":{"type":["string","null"]},"serialNumber":{"type":["string","null"]},"valueCents":{"type":["integer","null"],"minimum":0},"currency":{"type":"string","minLength":3,"maxLength":3},"priority":{"type":"integer","minimum":1,"maximum":5},"tags":{"type":"array","items":{"type":"string"}},"categories":{"type":"array","items":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"color":{"type":"string"}}}},"relatedResourceIds":{"type":"array","maxItems":100,"items":{"type":"string","format":"uuid"},"description":"Legacy undirected related-item ids. Prefer typed resource relationships for new integrations."},"gpsLatitude":{"type":["number","null"],"minimum":-90,"maximum":90},"gpsLongitude":{"type":["number","null"],"minimum":-180,"maximum":180},"gpsAltitude":{"type":["number","null"]},"mapFeatures":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/ResourceMapFeature"}},"notes":{"type":"string"},"customFields":{"$ref":"#/components/schemas/CustomFieldValues"},"subtitle":{"type":"string","maxLength":240,"description":"Optional subtitle used by label templates. Empty string clears it."}}},"ResourceFamilyVariantInput":{"type":"object","additionalProperties":false,"required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":240},"sku":{"type":["string","null"],"maxLength":80},"barcode":{"type":["string","null"],"maxLength":180}}},"ResourceFamilyExistingVariantInput":{"type":"object","additionalProperties":false,"required":["existingResourceId"],"properties":{"existingResourceId":{"type":"string","format":"uuid","description":"Existing standalone inventory item to connect as the child variant while preserving its operational records."}}},"ResourceVariantDetachResult":{"type":"object","required":["resourceId","materializedBomLineCount"],"properties":{"resourceId":{"type":"string","format":"uuid"},"materializedBomLineCount":{"type":"integer","minimum":0}}},"ResourceFamilyMember":{"type":"object","required":["id","name","type","status","sku","barcode","quantity","trackingMode","updatedAt","overriddenFields"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"type":{"$ref":"#/components/schemas/InventoryTypeKey"},"status":{"type":"string","enum":["available","in-use","maintenance","archived"]},"sku":{"type":["string","null"]},"barcode":{"type":["string","null"]},"quantity":{"type":"integer"},"trackingMode":{"type":"string","enum":["bulk","serialized"]},"updatedAt":{"type":"string","format":"date-time"},"overriddenFields":{"type":"array","items":{"type":"string","enum":["description","type","valueCents","currency","priority","tags","categories","customFields","notes"]}}}},"ResourceFamily":{"type":"object","required":["role","currentResourceId","primary","variants","optionGroupCount","summary"],"properties":{"role":{"type":"string","enum":["primary","variant"]},"currentResourceId":{"type":"string","format":"uuid"},"primary":{"$ref":"#/components/schemas/ResourceFamilyMember"},"variants":{"type":"array","items":{"$ref":"#/components/schemas/ResourceFamilyMember"}},"optionGroupCount":{"type":"integer","minimum":0},"summary":{"type":"object","required":["totalQuantity","primaryQuantity","variantQuantity","variantCount","serializedVariantCount"],"properties":{"totalQuantity":{"type":"integer"},"primaryQuantity":{"type":"integer"},"variantQuantity":{"type":"integer"},"variantCount":{"type":"integer","minimum":0},"serializedVariantCount":{"type":"integer","minimum":0}}}}},"ResourceOptionValueInput":{"type":"object","additionalProperties":false,"required":["label","code","isDefault"],"properties":{"label":{"type":"string","minLength":1,"maxLength":120},"code":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9_-]{0,39}$"},"componentResourceId":{"type":["string","null"],"format":"uuid"},"isDefault":{"type":"boolean"},"position":{"type":"integer","minimum":0}}},"ResourceOptionGroupInput":{"type":"object","additionalProperties":false,"required":["key","name","values"],"properties":{"key":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,63}$"},"name":{"type":"string","minLength":1,"maxLength":120},"bomSlotKey":{"type":["string","null"],"maxLength":80},"position":{"type":"integer","minimum":0},"values":{"type":"array","minItems":2,"maxItems":8,"items":{"$ref":"#/components/schemas/ResourceOptionValueInput"}}}},"ResourceOptionValue":{"allOf":[{"$ref":"#/components/schemas/ResourceOptionValueInput"},{"type":"object","required":["id","componentName","position"],"properties":{"id":{"type":"string","format":"uuid"},"componentName":{"type":["string","null"]}}}]},"ResourceOptionGroup":{"type":"object","required":["id","key","name","bomSlotKey","position","values"],"properties":{"id":{"type":"string","format":"uuid"},"key":{"type":"string"},"name":{"type":"string"},"bomSlotKey":{"type":["string","null"]},"position":{"type":"integer","minimum":0},"values":{"type":"array","items":{"$ref":"#/components/schemas/ResourceOptionValue"}}}},"ResourceOptions":{"type":"object","required":["role","currentResourceId","primary","groups","configurations","currentSelection","bomSlots","combinationCount","generatedVariantCount","familyVariantCount","definitionsLocked"],"properties":{"role":{"type":"string","enum":["primary","variant"]},"currentResourceId":{"type":"string","format":"uuid"},"primary":{"type":"object","required":["id","name","sku"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"sku":{"type":["string","null"]}}},"groups":{"type":"array","items":{"$ref":"#/components/schemas/ResourceOptionGroup"}},"configurations":{"type":"array","description":"Materialized configurations whose inventory items the caller may read.","items":{"type":"object","required":["resourceId","resourceName","resourceSku","isPrimary","signature","selection"],"properties":{"resourceId":{"type":"string","format":"uuid"},"resourceName":{"type":"string"},"resourceSku":{"type":["string","null"]},"isPrimary":{"type":"boolean"},"signature":{"type":"string"},"selection":{"type":"array","items":{"type":"object","required":["groupId","groupName","valueId","valueLabel"],"properties":{"groupId":{"type":"string","format":"uuid"},"groupName":{"type":"string"},"valueId":{"type":"string","format":"uuid"},"valueLabel":{"type":"string"}}}}}}},"currentSelection":{"type":"array","items":{"type":"object","required":["groupId","groupName","valueId","valueLabel"],"properties":{"groupId":{"type":"string","format":"uuid"},"groupName":{"type":"string"},"valueId":{"type":"string","format":"uuid"},"valueLabel":{"type":"string"}}}},"bomSlots":{"type":"array","items":{"type":"object","required":["slotKey","position","componentResourceId","componentName"],"properties":{"slotKey":{"type":"string"},"position":{"type":"integer","minimum":0},"componentResourceId":{"type":"string","format":"uuid"},"componentName":{"type":"string"}}}},"combinationCount":{"type":"integer","minimum":0,"maximum":100},"generatedVariantCount":{"type":"integer","minimum":0},"familyVariantCount":{"type":"integer","minimum":0},"definitionsLocked":{"type":"boolean"}}},"ResourceOptionGenerationResult":{"type":"object","required":["primaryResourceId","generatedVariantCount","variants"],"properties":{"primaryResourceId":{"type":"string","format":"uuid"},"generatedVariantCount":{"type":"integer","minimum":1,"maximum":99},"variants":{"type":"array","items":{"type":"object","required":["id","name","sku"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"sku":{"type":["string","null"]}}}}}},"ResourceMapFeature":{"type":"object","required":["id","type","layer","description","coordinates"],"properties":{"id":{"type":"string","minLength":1,"maxLength":80},"type":{"type":"string","enum":["point","polygon"]},"layer":{"type":"string","minLength":1,"maxLength":80},"description":{"type":"string","maxLength":5000},"coordinates":{"description":"A [longitude, latitude] pair for points or a closed ring of pairs for polygons.","oneOf":[{"type":"array","minItems":2,"maxItems":2,"items":{"type":"number"}},{"type":"array","minItems":4,"maxItems":500,"items":{"type":"array","minItems":2,"maxItems":2,"items":{"type":"number"}}}]}}},"Resource":{"allOf":[{"$ref":"#/components/schemas/ResourceInput"},{"type":"object","required":["id","slugs","customFields","createdAt","updatedAt","media"],"properties":{"id":{"type":"string","format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"media":{"type":"array","items":{"$ref":"#/components/schemas/Media"}},"cover":{"oneOf":[{"$ref":"#/components/schemas/Media"},{"type":"null"}]}}}]}}}}