{"openapi":"3.1.0","info":{"title":"MI AI Manifest API","version":"3.14.3","description":"REST API for MI AI Manifest — logistics management platform with pallets, shipments, containers, billing, and AI chat."},"servers":[{"url":"https://manifestdev.miglobal.com.mx","description":"Development"},{"url":"https://manifest.miglobal.com.mx","description":"Production"}],"tags":[{"name":"Auth","description":"Authentication & session management"},{"name":"Users","description":"User CRUD and preferences"},{"name":"Pallets","description":"Pallet lifecycle management"},{"name":"Shipments","description":"Shipment CRUD, multi-stop, fleet"},{"name":"Containers","description":"Container management"},{"name":"Customers","description":"Customer accounts & contacts"},{"name":"Billing","description":"Bills, payments, disputes"},{"name":"Improvements","description":"Bug reports & feature requests"},{"name":"Photos","description":"Entity photo upload & management"},{"name":"TLI","description":"AI chat (TLI) threads & messages"},{"name":"Documentation","description":"In-app documentation pages"},{"name":"External API v1","description":"Public-facing API for partner/internal/customer apps. Auth via Bearer <key_id>.<secret>."}],"paths":{"/api/v1/auth/login":{"post":{"tags":["Auth"],"summary":"Login","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["username","password"],"properties":{"username":{"type":"string"},"password":{"type":"string"}}}}}},"responses":{"200":{"description":"Session created, user object returned"},"401":{"description":"Invalid credentials"}}}},"/api/v1/auth/me":{"get":{"tags":["Auth"],"summary":"Get current session user","responses":{"200":{"description":"Current user object"},"401":{"description":"Not authenticated"}}}},"/api/v1/auth/logout":{"post":{"tags":["Auth"],"summary":"Logout","responses":{"200":{"description":"Session destroyed"}}}},"/api/v1/users":{"get":{"tags":["Users"],"summary":"List all users (admin only)","responses":{"200":{"description":"Array of user objects"}}},"post":{"tags":["Users"],"summary":"Create user (admin only)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["username","password","fullName","role"],"properties":{"username":{"type":"string"},"password":{"type":"string"},"fullName":{"type":"string"},"role":{"type":"string","enum":["admin","supervisor","logistics","customer","user"]}}}}}},"responses":{"201":{"description":"User created"}}}},"/api/v1/users/{id}":{"get":{"tags":["Users"],"summary":"Get user by ID","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"User object"}}},"put":{"tags":["Users"],"summary":"Update user (admin only)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"User updated"}}},"delete":{"tags":["Users"],"summary":"Delete user (admin only)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"User deleted"}}}},"/api/v1/users/{id}/language":{"put":{"tags":["Users"],"summary":"Update language preference","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"language":{"type":"string","enum":["en","es-MX"]}}}}}},"responses":{"200":{"description":"Language updated"}}}},"/api/v1/column-preferences/{gridName}":{"get":{"tags":["Users"],"summary":"Get column preferences for a grid","parameters":[{"name":"gridName","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Column preferences object"}}},"put":{"tags":["Users"],"summary":"Save column preferences for a grid","parameters":[{"name":"gridName","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Preferences saved"}}}},"/api/v1/pallets":{"get":{"tags":["Pallets"],"summary":"List pallets (filtered by role)","responses":{"200":{"description":"Array of pallets"}}},"post":{"tags":["Pallets"],"summary":"Create pallet","responses":{"201":{"description":"Pallet created"}}}},"/api/v1/pallets/{id}":{"get":{"tags":["Pallets"],"summary":"Get pallet by ID","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Pallet object with items"}}},"put":{"tags":["Pallets"],"summary":"Update pallet","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Pallet updated"}}},"delete":{"tags":["Pallets"],"summary":"Delete pallet (supervisor+)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Pallet deleted"}}}},"/api/v1/pallets/{id}/status":{"put":{"tags":["Pallets"],"summary":"Update pallet status","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["active","saved","printed","shipped","crossdock"]}}}}}},"responses":{"200":{"description":"Status updated"}}}},"/api/v1/pallets/{id}/expected-items":{"get":{"tags":["Receive"],"summary":"List expected items on a pallet (for scan-to-verify)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Array of scanned_items with palletStatus + receivedAt fields"}}}},"/api/v1/shipments/{id}/expected-items":{"get":{"tags":["Receive"],"summary":"List expected items on a shipment (joined through pallets)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Array of scanned_items with palletStatus + receivedAt fields"}}}},"/api/v1/scan-receive/item":{"post":{"tags":["Receive"],"summary":"Confirm receipt of one serial (verify semantics — no on-the-fly creation)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["serialNumber","warehouseId"],"properties":{"shipmentId":{"type":"string"},"palletId":{"type":"string"},"serialNumber":{"type":"string"},"make":{"type":"string"},"model":{"type":"string"},"warehouseId":{"type":"string"}}}}}},"responses":{"200":{"description":"Item confirmed; returns updated item + progress counters"},"409":{"description":"not_found_in_scope | already_received | ambiguous_match"}}}},"/api/v1/scan-receive/complete":{"post":{"tags":["Receive"],"summary":"Finalize scan-verified receive — runs crossdock for each pallet in scope","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["warehouseId","receivingType"],"properties":{"shipmentId":{"type":"string"},"palletId":{"type":"string"},"warehouseId":{"type":"string"},"receivingType":{"type":"string","enum":["crossdock","final"]},"allowMissing":{"type":"boolean","default":true}}}}}},"responses":{"200":{"description":"Summary: palletsReceived, itemsConfirmed, itemsMissing"},"409":{"description":"incomplete_receive when allowMissing=false and items remain unscanned"}}}},"/api/v1/scan-receive/bulk-lookup":{"post":{"tags":["Receive"],"summary":"Bulk receive: resolve a scanned serial to its existing item + shipment-scope flag","description":"Used by the In-bulk by-serial flow. Returns { item, inScope } — inScope=true if the serial belongs to the shipment, false if it was found elsewhere in the system (misrouted).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["shipmentId","serialNumber"],"properties":{"shipmentId":{"type":"string"},"serialNumber":{"type":"string"},"make":{"type":"string"},"model":{"type":"string"}}}}}},"responses":{"200":{"description":"{ item, inScope } — item resolved"},"409":{"description":"ambiguous_match | not_found_anywhere"}}}},"/api/v1/scan-receive/bulk-repallet":{"post":{"tags":["Receive"],"summary":"Bulk receive: re-palletize a batch of existing serials onto one new destination pallet","description":"Creates a new pallet (crossdock or final) at the destination warehouse and moves the given existing scanned_items onto it by updating pallet_id only — all other fields preserved. Emptied origin pallets are closed out of the shipment.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["shipmentId","itemIds","warehouseId"],"properties":{"shipmentId":{"type":"string"},"itemIds":{"type":"array","items":{"type":"string"}},"warehouseId":{"type":"string"},"isCrossdock":{"type":"boolean","description":"true → new pallet status 'crossdock' (re-shippable); false → 'saved' (final inventory)"},"container":{"type":"string"},"notes":{"type":"string"}}}}}},"responses":{"200":{"description":"{ pallet, moved, failed[] } — new pallet created"},"400":{"description":"missing_scope / missing_warehouse / missing_items / no_items"}}}},"/api/v1/scan-receive/loose":{"post":{"tags":["Loose Items"],"summary":"Receive a serial as a loose item (no pallet required)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["serialNumber","make","model","warehouseId"],"properties":{"serialNumber":{"type":"string"},"make":{"type":"string"},"model":{"type":"string"},"sku":{"type":"string"},"description":{"type":"string"},"lpn":{"type":"string"},"qty":{"type":"integer"},"containerId":{"type":"string","description":"Provide containerId XOR shipmentId"},"shipmentId":{"type":"string","description":"Provide containerId XOR shipmentId"},"warehouseId":{"type":"string"}}}}}},"responses":{"200":{"description":"Loose item created, history row inserted"},"400":{"description":"missing_required / missing_anchor / both_anchors / missing_warehouse"},"409":{"description":"duplicate_in_anchor / duplicate_serial (caught by unique constraints)"}}}},"/api/v1/loose-items":{"get":{"tags":["Loose Items"],"summary":"List loose items (palletId IS NULL) with filters","parameters":[{"name":"containerId","in":"query","schema":{"type":"string"}},{"name":"shipmentId","in":"query","schema":{"type":"string"}},{"name":"warehouseId","in":"query","schema":{"type":"string"}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","schema":{"type":"integer","default":200}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Array of loose items joined to container/shipment labels"}}}},"/api/v1/loose-items/bulk-assign":{"post":{"tags":["Loose Items"],"summary":"Assign loose items to an existing pallet","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["itemIds","palletId"],"properties":{"itemIds":{"type":"array","items":{"type":"string"}},"palletId":{"type":"string"}}}}}},"responses":{"200":{"description":"{ assigned, failed: [{itemId, reason}] }"}}}},"/api/v1/loose-items/create-pallet-from":{"post":{"tags":["Loose Items"],"summary":"Create a new pallet and assign selected loose items to it","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["itemIds","warehouseId"],"properties":{"itemIds":{"type":"array","items":{"type":"string"}},"warehouseId":{"type":"string"},"customerId":{"type":"integer"},"shipmentId":{"type":"string"},"container":{"type":"string"},"notes":{"type":"string"}}}}}},"responses":{"200":{"description":"{ pallet, assigned, failed: [{itemId, reason}] }"}}}},"/api/v1/pallets/{id}/item-history":{"get":{"tags":["Loose Items"],"summary":"Movement history for items on this pallet (current + former)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Array of scanned_item_history rows ordered by performed_at DESC"}}}},"/api/v1/scanned-items/{id}/history":{"get":{"tags":["Loose Items"],"summary":"Movement chain for one scanned item","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Array of scanned_item_history rows ordered by performed_at ASC"}}}},"/api/v1/shipments":{"get":{"tags":["Shipments"],"summary":"List shipments","responses":{"200":{"description":"Array of shipments"}}},"post":{"tags":["Shipments"],"summary":"Create shipment","responses":{"201":{"description":"Shipment created"}}}},"/api/v1/shipments/{id}":{"get":{"tags":["Shipments"],"summary":"Get shipment by ID","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Shipment with stops, pallets, documents"}}},"put":{"tags":["Shipments"],"summary":"Update shipment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Shipment updated"}}},"delete":{"tags":["Shipments"],"summary":"Delete shipment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Shipment deleted"}}}},"/api/v1/shipments/{id}/information-requests":{"get":{"tags":["Shipments"],"summary":"List information requests for a shipment (internal staff only)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Array of information requests (subject, requestedText, status, requester/provider)"}}},"post":{"tags":["Shipments"],"summary":"Request missing information on a shipment (emails the internal team)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Information request created (status=requested)"}}}},"/api/v1/shipments/information-requests/{requestId}/provide":{"patch":{"tags":["Shipments"],"summary":"Provide the requested information (status→provided; emails the requester if they left an email)","parameters":[{"name":"requestId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Information request marked provided"}}}},"/api/v1/containers":{"get":{"tags":["Containers"],"summary":"List containers","responses":{"200":{"description":"Array of containers"}}},"post":{"tags":["Containers"],"summary":"Create container","responses":{"201":{"description":"Container created"}}}},"/api/v1/containers/{id}":{"get":{"tags":["Containers"],"summary":"Get container by ID","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Container with items and documents"}}}},"/api/v1/customers":{"get":{"tags":["Customers"],"summary":"List customers","responses":{"200":{"description":"Array of customers"}}},"post":{"tags":["Customers"],"summary":"Create customer","responses":{"201":{"description":"Customer created"}}}},"/api/v1/bills":{"get":{"tags":["Billing"],"summary":"List bills","responses":{"200":{"description":"Array of bills"}}},"post":{"tags":["Billing"],"summary":"Create bill","responses":{"201":{"description":"Bill created"}}}},"/api/v1/improvements":{"get":{"tags":["Improvements"],"summary":"List improvements (bugs & features)","responses":{"200":{"description":"Array of improvements"}}},"post":{"tags":["Improvements"],"summary":"Create improvement","responses":{"201":{"description":"Improvement created"}}}},"/api/v1/improvements/{id}":{"get":{"tags":["Improvements"],"summary":"Get improvement by ID","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Improvement with attachments and comments"}}},"patch":{"tags":["Improvements"],"summary":"Update improvement","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Improvement updated"}}}},"/api/v1/photos/upload":{"post":{"tags":["Photos"],"summary":"Upload entity photo","description":"Multipart upload. Accepts JPEG, PNG, HEIC. Server compresses with Sharp and generates thumbnail.","responses":{"200":{"description":"Photo uploaded with presigned URLs"}}}},"/api/v1/tli/threads":{"get":{"tags":["TLI"],"summary":"List AI chat threads","responses":{"200":{"description":"Array of threads"}}},"post":{"tags":["TLI"],"summary":"Create AI chat thread","responses":{"201":{"description":"Thread created"}}}},"/api/v1/tli/chat/stream":{"post":{"tags":["TLI"],"summary":"Send message and stream AI response (SSE)","description":"Server-Sent Events stream. Events: connected, text, tool_use, tool_result, complete, error.","responses":{"200":{"description":"SSE stream"}}}},"/api/v1/documentation/pages":{"get":{"tags":["Documentation"],"summary":"List documentation pages","responses":{"200":{"description":"Array of documentation pages"}}}},"/api/v1/debug/status":{"get":{"tags":["Auth"],"summary":"Health check","responses":{"200":{"description":"Server status object"}}}},"/api/v1/external/health":{"get":{"tags":["External API v1"],"security":[],"summary":"API liveness check (no auth required)","responses":{"200":{"description":"{ status: 'ok', timestamp }"}}}},"/api/v1/external/version":{"get":{"tags":["External API v1"],"security":[],"summary":"API + server version metadata","responses":{"200":{"description":"version info"}}}},"/api/v1/external/whoami":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Identify the current API key","responses":{"200":{"description":"key_id, scope, customer_id, permissions, rate_limit_tier"},"401":{"description":"Missing or invalid Bearer token"}}}},"/api/v1/external/shipments":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"List shipments (cursor-paginated)","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":25,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"Opaque cursor from prior page's pagination.next_cursor"},{"name":"status","in":"query","schema":{"type":"string"}},{"name":"bol_number","in":"query","schema":{"type":"string"}},{"name":"carrier","in":"query","schema":{"type":"string"}},{"name":"from_date","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"to_date","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"customer_id","in":"query","schema":{"type":"integer"},"description":"Partner/internal keys only; ignored for customer-scoped keys"}],"responses":{"200":{"description":"Page of shipments with pagination metadata"},"401":{"description":"Auth failure"},"403":{"description":"Missing shipments:read permission"},"429":{"description":"Rate limit exceeded"}}}},"/api/v1/external/shipments/{id}":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Get a single shipment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Shipment"},"404":{"description":"Not found or out of scope"}}}},"/api/v1/external/shipments/by-bol/{bolNumber}":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Lookup shipment by BOL number","parameters":[{"name":"bolNumber","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Shipment"},"404":{"description":"Not found"}}}},"/api/v1/external/shipments/{id}/pallets":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Pallets + scanned items for a shipment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Pallets with items"}}}},"/api/v1/external/shipments/{id}/items":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Flat list of items across all pallets in a shipment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Items"}}}},"/api/v1/external/items/by-serial/{serialNumber}":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Look up items by serial number (fully denormalized)","description":"Returns every record reachable from items with this serial number: pallet, shipment (with BOL + shipment_number), every stop on multi-stop shipments, the customer record, the user who scanned it in, order links, UPC → product master with harmonized code, and GPS trackers attached to the shipment. `documents[]` is included only when the API key also has `documents:read`; otherwise the field is omitted (not null).\n\n**Multiplicity:** The response is **always a paginated list**, not a single object. Serials are unique per `(make, model)` combination — not globally — so the same serial may legitimately exist for different products. Use `?make=` and `?model=` to disambiguate when you know the product family.\n\n**Empty result:** Unknown serials return HTTP 200 with `{ \"data\": [], \"pagination\": { has_more: false, ... } }` — not 404. 404 is reserved for resources the caller doesn't have permission to see (customer-scope violations).\n\n**Customer scoping:** customer-scoped keys see only items on shipments belonging to their bound `customer_id`. Partner/internal keys see everything; they can pass `?customer_id=N` to filter.\n\n**Heavy fields opt-in:** `?include=photos`, `?include=history`, `?include=bills`, `?include=fleet`, or `?include=all`. Default omits these to keep the response fast.","parameters":[{"name":"serialNumber","in":"path","required":true,"schema":{"type":"string"},"example":"1D2481178"},{"name":"make","in":"query","schema":{"type":"string"},"description":"Disambiguate when the same serial exists for multiple makes","example":"Dell"},{"name":"model","in":"query","schema":{"type":"string"},"example":"Inspiron 15"},{"name":"limit","in":"query","schema":{"type":"integer","default":25,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"Opaque cursor from prior page's pagination.next_cursor"},{"name":"include","in":"query","schema":{"type":"string","enum":["photos","history","bills","fleet","all"]},"description":"Comma-separated list. Adds heavy fields to the response."},{"name":"customer_id","in":"query","schema":{"type":"integer"},"description":"Partner/internal keys only; ignored for customer-scoped keys"}],"responses":{"200":{"description":"Page of fully-enriched items. Each row contains: item core fields + scanned_by user + pallet + shipment (with shipment_number, bol_number, full route + ETA) + stops + customer + order links + product master + trackers + (conditional) documents.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ItemListResponse"}}}},"401":{"description":"Unauthorized — missing or invalid bearer token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Missing items:read permission","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded — see X-RateLimit-* headers + Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/external/items/by-upc/{upc}":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Look up items by UPC (fully denormalized)","description":"Returns every reachable record from items matching this UPC. Same response shape as `/items/by-serial`. UPCs are not unique on `scanned_items` — the response is always a paginated list. Customer-scoped keys see only their items.","parameters":[{"name":"upc","in":"path","required":true,"schema":{"type":"string"},"example":"012345678905"},{"name":"limit","in":"query","schema":{"type":"integer","default":25,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"include","in":"query","schema":{"type":"string","enum":["photos","history","bills","fleet","all"]}},{"name":"customer_id","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Page of enriched items","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ItemListResponse"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Missing items:read"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Rate limited"}}}},"/api/v1/external/items/by-lpn/{lpn}":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Look up items by LPN (License Plate Number, fully denormalized)","description":"Same response shape as `/items/by-serial`. LPNs are typically unique in practice but not enforced at the DB layer — returns a paginated list.","parameters":[{"name":"lpn","in":"path","required":true,"schema":{"type":"string"},"example":"LPN-99887766"},{"name":"limit","in":"query","schema":{"type":"integer","default":25,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"include","in":"query","schema":{"type":"string","enum":["photos","history","bills","fleet","all"]}},{"name":"customer_id","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Page of enriched items","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ItemListResponse"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Missing items:read"}}}},"/api/v1/external/items/by-sku/{sku}":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Look up items by SKU (fully denormalized)","description":"Same response shape as `/items/by-serial`. SKUs are not unique — returns a paginated list.","parameters":[{"name":"sku","in":"path","required":true,"schema":{"type":"string"},"example":"DELL-INSP-15"},{"name":"limit","in":"query","schema":{"type":"integer","default":25,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"include","in":"query","schema":{"type":"string","enum":["photos","history","bills","fleet","all"]}},{"name":"customer_id","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Page of enriched items","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ItemListResponse"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Missing items:read"}}}},"/api/v1/external/items/by-order/{orderId}":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Look up items by external order ID (fully denormalized)","description":"Returns all items linked to this Bin Manager / external order ID. Useful for tracing every serial against a customer purchase order across whatever shipments it ended up on.","parameters":[{"name":"orderId","in":"path","required":true,"schema":{"type":"string"},"example":"PO-2026-04129"},{"name":"line_number","in":"query","schema":{"type":"integer"},"description":"Filter to a specific order line (zero-based index)"},{"name":"limit","in":"query","schema":{"type":"integer","default":25,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"include","in":"query","schema":{"type":"string","enum":["photos","history","bills","fleet","all"]}},{"name":"customer_id","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Page of enriched items","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ItemListResponse"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Missing items:read"}}}},"/api/v1/external/items":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Flexible item search (fully denormalized)","description":"Combine any of the filters below. **At least one filter is required** — calling with no filter returns 400 to prevent full-table scans. Same response shape as the `by-*` endpoints.","parameters":[{"name":"serial","in":"query","schema":{"type":"string"}},{"name":"upc","in":"query","schema":{"type":"string"}},{"name":"lpn","in":"query","schema":{"type":"string"}},{"name":"sku","in":"query","schema":{"type":"string"}},{"name":"make","in":"query","schema":{"type":"string"}},{"name":"model","in":"query","schema":{"type":"string"}},{"name":"order_id","in":"query","schema":{"type":"string"}},{"name":"line_number","in":"query","schema":{"type":"integer"}},{"name":"customer_id","in":"query","schema":{"type":"integer"},"description":"Partner/internal keys only"},{"name":"limit","in":"query","schema":{"type":"integer","default":25,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"include","in":"query","schema":{"type":"string","enum":["photos","history","bills","fleet","all"]}}],"responses":{"200":{"description":"Page of enriched items","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ItemListResponse"}}}},"400":{"description":"validation_failed — at least one filter is required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Missing items:read"}}}},"/api/v1/external/products/by-upc/{upc}":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Resolve UPC to product master (make / model / description / harmonized code)","description":"Single-record lookup against the `upc_codes` reference table joined with `product_makes` and `product_models`. Returns the canonical product metadata for the UPC — useful for interpreting raw UPC scans, populating product dropdowns in integrating apps, and getting the harmonized (HTS) code for customs declarations. Not customer-scoped — this is shared master data.","parameters":[{"name":"upc","in":"path","required":true,"schema":{"type":"string"},"example":"012345678905"}],"responses":{"200":{"description":"Product record","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductResponse"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}},"description":"Missing products:read"},"404":{"description":"UPC not in product master","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/external/shipments/{id}/stops":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Stops for a multi-stop shipment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Stops"}}}},"/api/v1/external/shipments/{id}/stops/{stopId}":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Single stop detail","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"stopId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Stop"},"404":{"description":"Not found"}}}},"/api/v1/external/shipments/{id}/trackers":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"GPS/AirTag tracker tags linked to shipment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Trackers"}}}},"/api/v1/external/shipments/{id}/documents":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"List BOL/POD documents (with proxied download URLs)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Documents"}}}},"/api/v1/external/shipments/{id}/documents/{docId}/download":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Download a shipment document (proxied from MinIO)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"docId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"PDF stream","content":{"application/pdf":{}}}}}},"/api/v1/external/shipments/{id}/status":{"patch":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Update shipment status (write_status permission)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["created","in_transit","delivered","cancelled","loaded"]},"delivered_at":{"type":"string","format":"date-time"},"notes":{"type":"string","maxLength":500}}}}}},"responses":{"200":{"description":"Updated"},"403":{"description":"Missing write_status"}}}},"/api/v1/external/shipments/{id}/stops/{stopId}/status":{"patch":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Update per-stop status","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"stopId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Updated"}}}},"/api/v1/external/shipments/{id}/stops/{stopId}/pod":{"post":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Upload proof-of-delivery PDF for a stop (documents:write)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"stopId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"201":{"description":"POD stored"}}}},"/api/v1/external/customers":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"List customers (partner/internal scope only)","responses":{"200":{"description":"Customer list"},"403":{"description":"customer-scoped keys forbidden"}}}},"/api/v1/external/webhooks":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"List webhook subscriptions for this API key","responses":{"200":{"description":"Webhooks"}}},"post":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Create a webhook subscription (webhooks:manage)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","events"],"properties":{"url":{"type":"string","format":"uri","description":"HTTPS URL only"},"events":{"type":"array","items":{"type":"string"},"minItems":1},"description":{"type":"string"}}}}}},"responses":{"201":{"description":"Webhook created — secret returned ONCE"}}}},"/api/v1/external/webhooks/{id}":{"delete":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Delete a webhook subscription","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted"}}}},"/api/v1/external/webhooks/{id}/deliveries":{"get":{"tags":["External API v1"],"security":[{"bearerApiKey":[]}],"summary":"Recent webhook delivery attempts","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deliveries"}}}}},"components":{"securitySchemes":{"session":{"type":"apiKey","in":"cookie","name":"connect.sid","description":"Session cookie set by POST /api/auth/login (for internal app endpoints)."},"bearerApiKey":{"type":"http","scheme":"bearer","bearerFormat":"<key_id>.<secret>","description":"External API v1 bearer token. Issue keys via Settings > API Keys & External API (admin only)."}},"schemas":{"ApiError":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string","example":"Resource not found"},"details":{"type":"object","nullable":true,"description":"Optional structured details (e.g., validation field errors)"}},"required":["code","message"]}},"required":["error"]},"PaginationMeta":{"type":"object","properties":{"next_cursor":{"type":"string","nullable":true,"description":"Opaque cursor for the next page; null if no more pages","example":"eyJjcmVhdGVkQXQiOiIyMDI2LTAxLTAxVDAwOjAwOjAwLjAwMFoiLCJpZCI6ImFiYy0xMjMifQ"},"has_more":{"type":"boolean"},"limit":{"type":"integer","example":25}},"required":["next_cursor","has_more","limit"]},"ScannedByUser":{"type":"object","nullable":true,"properties":{"id":{"type":"string","format":"uuid"},"username":{"type":"string"},"full_name":{"type":"string"},"role":{"type":"string","enum":["admin","supervisor","logistics","user","customer"]}}},"PalletStopAssignment":{"type":"object","nullable":true,"properties":{"stop_id":{"type":"string","format":"uuid"},"assigned_at":{"type":"string","format":"date-time"},"delivery_status":{"type":"string","enum":["assigned","loaded","delivered","returned","damaged"]},"delivered_at":{"type":"string","format":"date-time","nullable":true},"receiver_name":{"type":"string","nullable":true},"signature_url":{"type":"string","nullable":true}}},"PalletInfo":{"type":"object","nullable":true,"properties":{"id":{"type":"string","description":"Pallet identifier (e.g. PLT-001234)"},"status":{"type":"string","enum":["active","saved","printed","shipped","crossdock"]},"container":{"type":"string","nullable":true},"warehouse_id":{"type":"string","nullable":true},"ownership_type":{"type":"string","enum":["customer","mit_owned"]},"total_items":{"type":"integer"},"shipped_at":{"type":"string","format":"date-time","nullable":true},"last_modified":{"type":"string","format":"date-time"},"is_virtual":{"type":"boolean"},"pictures_completed":{"type":"boolean"},"original_shipment_id":{"type":"string","nullable":true,"description":"For crossdock pallets: the prior shipment id"},"stop_assignment":{"$ref":"#/components/schemas/PalletStopAssignment"},"created_by":{"type":"string","format":"uuid"}}},"ShipmentInfo":{"type":"object","nullable":true,"properties":{"id":{"type":"string","format":"uuid"},"shipment_number":{"type":"integer","example":10000123},"status":{"type":"string","example":"in_transit"},"bol_number":{"type":"string","nullable":true},"carrier_name":{"type":"string","nullable":true},"carrier_type":{"type":"string","example":"LTL"},"from_location":{"type":"string"},"customer_id":{"type":"integer","nullable":true},"customer_address_id":{"type":"integer","nullable":true},"to_customer_name":{"type":"string"},"to_address":{"type":"string"},"to_city":{"type":"string"},"to_state":{"type":"string"},"to_zip":{"type":"string"},"to_country":{"type":"string"},"pickup_date":{"type":"string","format":"date-time"},"eta":{"type":"string","format":"date-time"},"delivered_at":{"type":"string","format":"date-time","nullable":true},"gps_tracking_url":{"type":"string","nullable":true},"is_multi_stop":{"type":"boolean"},"total_stops":{"type":"integer","nullable":true},"current_stop":{"type":"integer","nullable":true},"seal_number":{"type":"string","nullable":true},"has_no_pallets":{"type":"boolean"},"notes":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"ShipmentStop":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"shipment_id":{"type":"string","format":"uuid"},"stop_sequence":{"type":"integer"},"stop_type":{"type":"string","enum":["warehouse","final_delivery"]},"customer_id":{"type":"integer","nullable":true},"customer_address_id":{"type":"integer","nullable":true},"to_customer_name":{"type":"string","nullable":true},"to_address":{"type":"string","nullable":true},"to_city":{"type":"string","nullable":true},"to_state":{"type":"string","nullable":true},"to_zip":{"type":"string","nullable":true},"to_country":{"type":"string","nullable":true},"scheduled_date":{"type":"string","format":"date-time","nullable":true},"actual_arrival":{"type":"string","format":"date-time","nullable":true},"actual_departure":{"type":"string","format":"date-time","nullable":true},"appointment_date":{"type":"string","format":"date-time","nullable":true},"status":{"type":"string","enum":["pending","in_transit","arrived","unloading","delivered","skipped","cancelled"]},"delivered_at":{"type":"string","format":"date-time","nullable":true},"pod_file_url":{"type":"string","nullable":true},"notes":{"type":"string","nullable":true},"is_destination_for_this_pallet":{"type":"boolean","description":"True when this stop is where the item's pallet is being delivered"}}},"CustomerInfo":{"type":"object","nullable":true,"properties":{"id":{"type":"integer"},"company_name":{"type":"string"},"country":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"primary_contact_name":{"type":"string","nullable":true},"primary_contact_email":{"type":"string","nullable":true},"primary_contact_phone":{"type":"string","nullable":true},"preferred_language":{"type":"string","enum":["en","es-MX","zh-CN"]}}},"OrderInfo":{"type":"object","nullable":true,"description":"Order context. Only populated when the item has an order_id.","properties":{"order_id":{"type":"string"},"order_line_number":{"type":"integer","nullable":true},"linked_shipments":{"type":"array","description":"Every shipment this order has been split across (an order can span multiple shipments).","items":{"type":"object","properties":{"shipment_id":{"type":"string","format":"uuid"},"customer_id":{"type":"integer","nullable":true},"customer_name":{"type":"string","nullable":true},"units_ordered":{"type":"integer","nullable":true},"units_delivered":{"type":"integer","nullable":true},"units_in_shipment":{"type":"integer","nullable":true}}}}}},"ProductMaster":{"type":"object","nullable":true,"description":"Resolved against the upc_codes / product_makes / product_models tables. Only populated when the item has a UPC that exists in the product master.","properties":{"upc":{"type":"string"},"make":{"type":"string","nullable":true},"model":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"harmonized_code":{"type":"string","nullable":true,"description":"HTS / customs classification code"},"make_id":{"type":"string","format":"uuid","nullable":true},"model_id":{"type":"string","format":"uuid","nullable":true}}},"ShipmentTracker":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tag_type":{"type":"string","enum":["apple_airtag","samsung_tag","generic_tag"]},"tag_id":{"type":"string"},"pallet_id":{"type":"string"},"notes":{"type":"string","nullable":true,"description":"Where the tracker is placed within the pallet"},"created_at":{"type":"string","format":"date-time"}}},"ShipmentDocumentRef":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["bol","pod"]},"file_name":{"type":"string"},"uploaded_at":{"type":"string","format":"date-time"},"uploaded_by":{"type":"string","format":"uuid"},"download_url":{"type":"string","description":"Relative path. Fetch with the same bearer token; MinIO/S3 URL never exposed."}}},"EnrichedItem":{"type":"object","description":"Fully denormalized item record. Every block is reachable from this item — no follow-up API calls required for context.","properties":{"id":{"type":"string","format":"uuid"},"serial_number":{"type":"string"},"make":{"type":"string"},"model":{"type":"string"},"sku":{"type":"string","nullable":true},"upc":{"type":"string","nullable":true},"lpn":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"qty":{"type":"integer","nullable":true,"default":1},"supplier_id":{"type":"string","nullable":true},"external_pallet_id":{"type":"string","nullable":true,"description":"Bin Manager / import-system pallet reference"},"source_type":{"type":"string","enum":["manual","import","bin_manager"],"default":"manual"},"order_id":{"type":"string","nullable":true,"description":"External order id (Bin Manager); null for manually scanned items"},"order_line_number":{"type":"integer","nullable":true},"scanned_at":{"type":"string","format":"date-time"},"scanned_by":{"$ref":"#/components/schemas/ScannedByUser"},"pallet":{"$ref":"#/components/schemas/PalletInfo"},"shipment":{"$ref":"#/components/schemas/ShipmentInfo"},"stops":{"type":"array","items":{"$ref":"#/components/schemas/ShipmentStop"}},"customer":{"$ref":"#/components/schemas/CustomerInfo"},"order":{"$ref":"#/components/schemas/OrderInfo"},"product":{"$ref":"#/components/schemas/ProductMaster"},"trackers":{"type":"array","items":{"$ref":"#/components/schemas/ShipmentTracker"}},"documents":{"type":"array","description":"Present only if the API key also has documents:read. Field is omitted entirely otherwise (not null).","items":{"$ref":"#/components/schemas/ShipmentDocumentRef"}},"photos":{"type":"array","description":"Opt-in. Add ?include=photos or ?include=all to populate.","items":{"type":"object"}},"shipment_status_history":{"type":"array","description":"Opt-in. Add ?include=history or ?include=all.","items":{"type":"object"}},"stop_status_history":{"type":"array","description":"Opt-in. Add ?include=history or ?include=all.","items":{"type":"object"}}},"required":["id","serial_number","make","model","scanned_at"]},"ItemListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/EnrichedItem"}},"pagination":{"$ref":"#/components/schemas/PaginationMeta"}},"required":["data","pagination"],"example":{"data":[{"id":"scanned-item-uuid","serial_number":"ABC123","make":"Dell","model":"Inspiron 15","sku":"DELL-INSP-15","upc":"012345678905","lpn":"LPN-99887766","description":"Refurbished laptop","qty":1,"supplier_id":null,"external_pallet_id":null,"source_type":"manual","order_id":"PO-2026-04129","order_line_number":3,"scanned_at":"2026-05-13T19:14:03Z","scanned_by":{"id":"user-uuid","username":"warehouse_op_1","full_name":"Maria Lopez","role":"user"},"pallet":{"id":"PLT-001039","status":"shipped","container":"CNT-1015","warehouse_id":"wh-uuid","ownership_type":"customer","total_items":18,"shipped_at":"2026-05-12T15:00:00Z","last_modified":"2026-05-12T15:00:00Z","is_virtual":false,"pictures_completed":true,"original_shipment_id":null,"stop_assignment":{"stop_id":"stop-uuid","assigned_at":"2026-05-12T10:00:00Z","delivery_status":"assigned","delivered_at":null,"receiver_name":null,"signature_url":null},"created_by":"user-uuid"},"shipment":{"id":"shipment-uuid","shipment_number":10000123,"status":"in_transit","bol_number":"BOL-77231","carrier_name":"ACME Logistics","carrier_type":"LTL","from_location":"TJ","customer_id":42,"customer_address_id":7,"to_customer_name":"Acme Wholesale","to_address":"100 Industrial Blvd","to_city":"Phoenix","to_state":"AZ","to_zip":"85001","to_country":"US","pickup_date":"2026-05-12T08:00:00Z","eta":"2026-05-15T17:00:00Z","delivered_at":null,"gps_tracking_url":"https://example.com/track/abc","is_multi_stop":true,"total_stops":3,"current_stop":1,"seal_number":"SEAL-12345","has_no_pallets":false,"notes":null,"created_at":"2026-05-12T07:30:00Z"},"stops":[{"id":"stop-uuid","shipment_id":"shipment-uuid","stop_sequence":1,"stop_type":"warehouse","to_city":"Phoenix","to_state":"AZ","scheduled_date":"2026-05-14T09:00:00Z","status":"pending","is_destination_for_this_pallet":true}],"customer":{"id":42,"company_name":"Acme Wholesale","country":"US","city":"Phoenix","state":"AZ","primary_contact_email":"ops@acme.example","preferred_language":"en"},"order":{"order_id":"PO-2026-04129","order_line_number":3,"linked_shipments":[{"shipment_id":"shipment-uuid","customer_id":42,"customer_name":"Acme Wholesale","units_ordered":100,"units_delivered":18,"units_in_shipment":18}]},"product":{"upc":"012345678905","make":"Dell","model":"Inspiron 15","description":"Refurbished laptop","harmonized_code":"8471.30.0100","make_id":"make-uuid","model_id":"model-uuid"},"trackers":[{"id":"tracker-uuid","tag_type":"apple_airtag","tag_id":"AIR-001","pallet_id":"PLT-001039","notes":"Inside pallet, top center","created_at":"2026-05-12T10:00:00Z"}],"documents":[{"id":"doc-uuid","type":"bol","file_name":"BOL_77231.pdf","uploaded_at":"2026-05-12T14:55:00Z","uploaded_by":"user-uuid","download_url":"/api/v1/external/shipments/shipment-uuid/documents/doc-uuid/download"}]}],"pagination":{"next_cursor":"eyJjcmVhdGVkQXQiOiIyMDI2LTAxLTAxVDAwOjAwOjAwLjAwMFoiLCJpZCI6ImFiYy0xMjMifQ","has_more":true,"limit":25}}},"ProductResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"upc":{"type":"string"},"make":{"type":"string","nullable":true},"make_id":{"type":"string","format":"uuid"},"model":{"type":"string","nullable":true},"model_id":{"type":"string","format":"uuid"},"model_description":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"harmonized_code":{"type":"string","nullable":true},"is_active":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"}},"required":["upc"]}},"required":["data"],"example":{"data":{"upc":"012345678905","make":"Dell","make_id":"make-uuid","model":"Inspiron 15","model_id":"model-uuid","model_description":"15-inch refurbished laptop","description":"Inspiron 15 series","harmonized_code":"8471.30.0100","is_active":true,"created_at":"2025-01-15T12:00:00Z"}}}}},"security":[{"session":[]}]}