{
  "openapi": "3.0.3",
  "info": {
    "title": "Odoo CE POS External Orders",
    "version": "1.1.0",
    "description": "Cashier-confirmed incoming orders. JSON REST, not Odoo JSON-RPC. Authentication scopes each connector to one POS and its own orders. UTC date strings. API v1 has no outbound webhooks. v1.1: read-only company directories, native prices and existing partner/pricelist selection. Each key still targets one POS; shops/warehouses list only its company. Contacts include shared contacts."
  },
  "servers": [
    {
      "url": "https://{host}/api/ce/pos/v1",
      "description": "Use the HTTPS hostname assigned to your company. Replace the example before connecting.",
      "variables": {
        "host": {
          "default": "your-odoo.example",
          "description": "Your company Odoo hostname; no protocol or path."
        }
      }
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/ping": {
      "get": {
        "summary": "Check connection",
        "operationId": "Check_connection",
        "responses": {
          "401": {
            "description": "Missing, invalid or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Order absent in this integration",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Wrong method",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or order already processed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "200": {
            "description": "Authenticated connection",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "api_version": {
                      "type": "string"
                    },
                    "integration": {
                      "type": "string"
                    },
                    "pos_config_id": {
                      "type": "integer"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "capabilities": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "fulfillment": {
                      "type": "string"
                    },
                    "outbound_webhooks": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "api_version",
                    "integration",
                    "pos_config_id",
                    "currency",
                    "capabilities",
                    "fulfillment",
                    "outbound_webhooks"
                  ],
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/products": {
      "get": {
        "operationId": "listProducts",
        "summary": "Read products",
        "parameters": [
          {
            "name": "after_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 2147483647,
              "default": 0
            },
            "description": "Ascending ID cursor; retain filters on every page."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 100
            },
            "description": "Maximum page size."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Substring search. Contacts: name/phone/email; products: name/SKU/barcode; others: name."
          },
          {
            "name": "partner_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 2147483647
            },
            "description": "Existing allowed contact. Optional."
          },
          {
            "name": "pricelist_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 2147483647
            },
            "description": "Explicit available POS pricelist. Optional."
          }
        ],
        "responses": {
          "401": {
            "description": "Missing/invalid/revoked Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Invalid parameters or unavailable IDs",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "200": {
            "description": "ID-ordered page. Null cursor ends the full scan. No deletion/change feed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductPage"
                }
              }
            }
          }
        }
      }
    },
    "/orders": {
      "post": {
        "summary": "Create incoming order",
        "operationId": "Create_incoming_order",
        "responses": {
          "401": {
            "description": "Missing, invalid or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Order absent in this integration",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Wrong method",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or order already processed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "201": {
            "description": "Created, pending cashier review",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResponse"
                }
              }
            }
          },
          "200": {
            "description": "Identical request replayed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResponse"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateOrder"
              }
            }
          }
        }
      }
    },
    "/orders/{external_id}": {
      "get": {
        "summary": "Get own order status",
        "operationId": "Get_own_order_status",
        "responses": {
          "401": {
            "description": "Missing, invalid or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Order absent in this integration",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Wrong method",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or order already processed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "200": {
            "description": "Current status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResponse"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "external_id",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{1,128}$",
              "example": "crm-2026-000123"
            }
          }
        ]
      }
    },
    "/orders/{external_id}/cancel": {
      "post": {
        "summary": "Cancel pending order",
        "operationId": "Cancel_pending_order",
        "responses": {
          "401": {
            "description": "Missing, invalid or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Order absent in this integration",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "405": {
            "description": "Wrong method",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or order already processed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "200": {
            "description": "Cancelled or already cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResponse"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 2000,
                    "minLength": 1
                  }
                },
                "required": [
                  "reason"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "in": "path",
            "name": "external_id",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9._:-]{1,128}$",
              "example": "crm-2026-000123"
            }
          }
        ]
      }
    },
    "/contacts": {
      "get": {
        "operationId": "listContacts",
        "summary": "Read contacts",
        "parameters": [
          {
            "name": "after_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 2147483647,
              "default": 0
            },
            "description": "Ascending ID cursor; retain filters on every page."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 100
            },
            "description": "Maximum page size."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Substring search. Contacts: name/phone/email; products: name/SKU/barcode; others: name."
          }
        ],
        "responses": {
          "401": {
            "description": "Missing/invalid/revoked Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Invalid parameters or unavailable IDs",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "200": {
            "description": "ID-ordered page. Null cursor ends the full scan. No deletion/change feed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactPage"
                }
              }
            }
          }
        }
      }
    },
    "/categories": {
      "get": {
        "operationId": "listCategorys",
        "summary": "Read categories",
        "parameters": [
          {
            "name": "after_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 2147483647,
              "default": 0
            },
            "description": "Ascending ID cursor; retain filters on every page."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 100
            },
            "description": "Maximum page size."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Substring search. Contacts: name/phone/email; products: name/SKU/barcode; others: name."
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "pos",
                "product"
              ],
              "default": "pos"
            },
            "description": "Separate namespaces for POS and product category IDs. Includes ancestors."
          }
        ],
        "responses": {
          "401": {
            "description": "Missing/invalid/revoked Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Invalid parameters or unavailable IDs",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "200": {
            "description": "ID-ordered page. Null cursor ends the full scan. No deletion/change feed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CategoryPage"
                }
              }
            }
          }
        }
      }
    },
    "/pricelists": {
      "get": {
        "operationId": "listPricelists",
        "summary": "Read pricelists",
        "parameters": [
          {
            "name": "after_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 2147483647,
              "default": 0
            },
            "description": "Ascending ID cursor; retain filters on every page."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 100
            },
            "description": "Maximum page size."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Substring search. Contacts: name/phone/email; products: name/SKU/barcode; others: name."
          }
        ],
        "responses": {
          "401": {
            "description": "Missing/invalid/revoked Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Invalid parameters or unavailable IDs",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "200": {
            "description": "ID-ordered page. Null cursor ends the full scan. No deletion/change feed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PricelistPage"
                }
              }
            }
          }
        }
      }
    },
    "/shops": {
      "get": {
        "operationId": "listShops",
        "summary": "Read shops",
        "parameters": [
          {
            "name": "after_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 2147483647,
              "default": 0
            },
            "description": "Ascending ID cursor; retain filters on every page."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 100
            },
            "description": "Maximum page size."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Substring search. Contacts: name/phone/email; products: name/SKU/barcode; others: name."
          }
        ],
        "responses": {
          "401": {
            "description": "Missing/invalid/revoked Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Invalid parameters or unavailable IDs",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "200": {
            "description": "ID-ordered page. Null cursor ends the full scan. No deletion/change feed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShopPage"
                }
              }
            }
          }
        }
      }
    },
    "/warehouses": {
      "get": {
        "operationId": "listWarehouses",
        "summary": "Read warehouses",
        "parameters": [
          {
            "name": "after_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 2147483647,
              "default": 0
            },
            "description": "Ascending ID cursor; retain filters on every page."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 100
            },
            "description": "Maximum page size."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Substring search. Contacts: name/phone/email; products: name/SKU/barcode; others: name."
          }
        ],
        "responses": {
          "401": {
            "description": "Missing/invalid/revoked Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Invalid parameters or unavailable IDs",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "200": {
            "description": "ID-ordered page. Null cursor ends the full scan. No deletion/change feed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WarehousePage"
                }
              }
            }
          }
        }
      }
    },
    "/prices": {
      "post": {
        "operationId": "quotePrices",
        "summary": "Calculate native Odoo prices; no order, reservation or fixed price commitment",
        "description": "Uses current quantity rules, allowed partner/pricelist, fiscal position and company tax rounding. Works with closed shift. Recalculated at cashier acceptance; payment/cash rounding is later. Repeated products remain separate lines.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PriceRequest"
              }
            }
          }
        },
        "responses": {
          "401": {
            "description": "Missing/invalid/revoked Bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Invalid parameters or unavailable IDs",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "200": {
            "description": "Current estimate in POS currency",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PriceQuote"
                }
              }
            }
          }
        }
      }
    },
    "/products/{product_id}/combo": {
      "get": {
        "operationId": "getComboOptions",
        "summary": "Native combo groups, item IDs and attributes",
        "description": "Requires pos_external_orders 20.0.2.0.0 and ce_mobile_api 20.0.17.0.0. Check ping capabilities for native_combos. Uses the same scoped Bearer key as other directories. Cashier selects lots and serials at checkout.",
        "parameters": [
          {
            "in": "path",
            "name": "product_id",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Choices and native group limits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComboOptions"
                }
              }
            }
          },
          "401": {
            "description": "Valid Bearer token required"
          },
          "403": {
            "description": "Access denied"
          },
          "422": {
            "description": "Unavailable product, invalid options or module not installed"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "ceo_<integration id>_<secret>; generate in External Orders > Connections"
      }
    },
    "schemas": {
      "InputLine": {
        "type": "object",
        "properties": {
          "product_id": {
            "type": "integer",
            "minimum": 1
          },
          "qty": {
            "type": "number",
            "exclusiveMinimum": true,
            "minimum": 0,
            "maximum": 1000000
          },
          "combo_selections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ComboSelection"
            },
            "minItems": 1,
            "maxItems": 200,
            "description": "Required only for combo products. No prices, taxes, lot IDs or serial names accepted from CRM."
          }
        },
        "required": [
          "product_id",
          "qty"
        ],
        "additionalProperties": false,
        "description": "Ordinary product: product_id and qty. Combo: also combo_selections. Native Odoo enforces group limits and attribute combinations."
      },
      "Customer": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 200
          },
          "phone": {
            "type": "string",
            "maxLength": 80
          },
          "email": {
            "type": "string",
            "maxLength": 254
          },
          "address": {
            "type": "string",
            "maxLength": 1000
          }
        },
        "additionalProperties": false
      },
      "CreateOrder": {
        "type": "object",
        "properties": {
          "external_id": {
            "type": "string",
            "pattern": "^[A-Za-z0-9._:-]{1,128}$",
            "example": "crm-2026-000123"
          },
          "lines": {
            "type": "array",
            "minItems": 1,
            "maxItems": 100,
            "items": {
              "$ref": "#/components/schemas/InputLine"
            }
          },
          "customer": {
            "$ref": "#/components/schemas/Customer"
          },
          "note": {
            "type": "string",
            "maxLength": 2000
          },
          "partner_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          },
          "pricelist_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          }
        },
        "required": [
          "external_id",
          "lines"
        ],
        "additionalProperties": false
      },
      "Order": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "external_id": {
            "type": "string",
            "pattern": "^[A-Za-z0-9._:-]{1,128}$",
            "example": "crm-2026-000123"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "accepted",
              "completed",
              "rejected",
              "cancelled",
              "cancelled_in_pos"
            ]
          },
          "created_at": {
            "type": "string"
          },
          "decided_at": {
            "type": "string",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "nullable": true
          },
          "pos_order_id": {
            "type": "integer",
            "nullable": true
          },
          "pos_order_uuid": {
            "type": "string",
            "nullable": true
          },
          "currency": {
            "type": "string"
          },
          "amount_total": {
            "type": "number",
            "nullable": true
          },
          "lines": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "product_id": {
                  "type": "integer"
                },
                "name": {
                  "type": "string"
                },
                "qty": {
                  "type": "number"
                },
                "uom": {
                  "type": "string"
                },
                "combo_selections": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ComboSelection"
                  },
                  "minItems": 1,
                  "maxItems": 200,
                  "description": "Required only for combo products. No prices, taxes, lot IDs or serial names accepted from CRM."
                }
              },
              "required": [
                "product_id",
                "name",
                "qty",
                "uom"
              ],
              "additionalProperties": false
            }
          },
          "partner_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          },
          "pricelist_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          }
        },
        "required": [
          "id",
          "external_id",
          "status",
          "created_at",
          "decided_at",
          "reason",
          "pos_order_id",
          "pos_order_uuid",
          "currency",
          "amount_total",
          "lines",
          "partner_id",
          "pricelist_id"
        ],
        "additionalProperties": false
      },
      "OrderResponse": {
        "type": "object",
        "properties": {
          "order": {
            "$ref": "#/components/schemas/Order"
          },
          "replayed": {
            "type": "boolean"
          }
        },
        "required": [
          "order"
        ],
        "additionalProperties": false
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "message"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": false
      },
      "PriceLine": {
        "type": "object",
        "properties": {
          "product_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
          },
          "qty": {
            "type": "number"
          },
          "uom_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
          },
          "price_unit": {
            "type": "number",
            "description": "Native Odoo line unit price; may include tax. Use subtotal_included/amount_total for payable amounts."
          },
          "subtotal_excluded": {
            "type": "number"
          },
          "subtotal_included": {
            "type": "number"
          },
          "tax_amount": {
            "type": "number"
          },
          "tax_ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 1,
              "maximum": 2147483647
            }
          },
          "combo_lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ComboPriceLine"
            },
            "description": "Native component allocation. Parent totals already include these amounts: do not add them again."
          }
        },
        "required": [
          "product_id",
          "qty",
          "uom_id",
          "price_unit",
          "subtotal_excluded",
          "subtotal_included",
          "tax_amount",
          "tax_ids"
        ],
        "additionalProperties": false
      },
      "PriceRequest": {
        "type": "object",
        "properties": {
          "lines": {
            "type": "array",
            "minItems": 1,
            "maxItems": 100,
            "items": {
              "$ref": "#/components/schemas/InputLine"
            }
          },
          "partner_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          },
          "pricelist_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          }
        },
        "required": [
          "lines"
        ],
        "additionalProperties": false
      },
      "PriceQuote": {
        "type": "object",
        "properties": {
          "partner_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          },
          "pricelist_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          },
          "fiscal_position_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          },
          "currency": {
            "type": "string"
          },
          "currency_rounding": {
            "type": "number"
          },
          "calculated_at": {
            "type": "string"
          },
          "estimate": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "pos_config_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PriceLine"
            }
          },
          "amount_untaxed": {
            "type": "number"
          },
          "amount_tax": {
            "type": "number"
          },
          "amount_total": {
            "type": "number"
          }
        },
        "required": [
          "partner_id",
          "pricelist_id",
          "fiscal_position_id",
          "currency",
          "currency_rounding",
          "calculated_at",
          "estimate",
          "pos_config_id",
          "lines",
          "amount_untaxed",
          "amount_tax",
          "amount_total"
        ],
        "additionalProperties": false
      },
      "Contact": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
          },
          "name": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "phone": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "is_company": {
            "type": "boolean"
          },
          "parent_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          },
          "type": {
            "type": "string",
            "enum": [
              "contact",
              "invoice",
              "delivery",
              "other"
            ]
          },
          "street": {
            "type": "string",
            "nullable": true
          },
          "street2": {
            "type": "string",
            "nullable": true
          },
          "city": {
            "type": "string",
            "nullable": true
          },
          "zip": {
            "type": "string",
            "nullable": true
          },
          "state": {
            "type": "string",
            "nullable": true
          },
          "country_code": {
            "type": "string",
            "nullable": true
          },
          "vat": {
            "type": "string",
            "nullable": true
          },
          "pricelist_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          }
        },
        "required": [
          "id",
          "name",
          "updated_at",
          "phone",
          "email",
          "is_company",
          "parent_id",
          "type",
          "street",
          "street2",
          "city",
          "zip",
          "state",
          "country_code",
          "vat",
          "pricelist_id"
        ],
        "additionalProperties": false
      },
      "Product": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
          },
          "name": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "sku": {
            "type": "string",
            "nullable": true
          },
          "barcode": {
            "type": "string",
            "nullable": true
          },
          "uom": {
            "type": "string"
          },
          "uom_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
          },
          "uom_rounding": {
            "type": "number"
          },
          "product_category_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          },
          "pos_category_ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 1,
              "maximum": 2147483647
            }
          },
          "price": {
            "$ref": "#/components/schemas/CatalogPrice"
          },
          "type": {
            "type": "string"
          },
          "selection_required": {
            "type": "boolean"
          },
          "combo_url": {
            "type": "string",
            "description": "Authenticated URL of group and item choices."
          },
          "tracking": {
            "type": "string",
            "enum": [
              "none",
              "lot",
              "serial"
            ],
            "description": "Available with ce_mobile_api 20.0.25; normal products only."
          },
          "tracking_at_checkout": {
            "type": "boolean",
            "description": "Cashier must select stock lots or serial numbers at fulfillment; CRM sends only product_id and qty."
          }
        },
        "required": [
          "id",
          "name",
          "updated_at",
          "sku",
          "barcode",
          "uom",
          "uom_id",
          "uom_rounding",
          "product_category_id",
          "pos_category_ids",
          "price"
        ],
        "additionalProperties": false
      },
      "Category": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
          },
          "name": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "pos",
              "product"
            ]
          },
          "parent_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          }
        },
        "required": [
          "id",
          "name",
          "updated_at",
          "type",
          "parent_id"
        ],
        "additionalProperties": false
      },
      "Pricelist": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
          },
          "name": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "currency": {
            "type": "string"
          },
          "currency_rounding": {
            "type": "number"
          },
          "is_default": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "name",
          "updated_at",
          "currency",
          "currency_rounding",
          "is_default"
        ],
        "additionalProperties": false
      },
      "Shop": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
          },
          "name": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "company_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
          },
          "currency": {
            "type": "string"
          },
          "warehouse_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          },
          "source_location_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          },
          "accepts_orders_with_this_key": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "name",
          "updated_at",
          "company_id",
          "currency",
          "warehouse_id",
          "source_location_id",
          "accepts_orders_with_this_key"
        ],
        "additionalProperties": false
      },
      "Warehouse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
          },
          "name": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "company_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
          },
          "stock_location_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
          },
          "stock_location_name": {
            "type": "string"
          },
          "view_location_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
          }
        },
        "required": [
          "id",
          "name",
          "updated_at",
          "code",
          "company_id",
          "stock_location_id",
          "stock_location_name",
          "view_location_id"
        ],
        "additionalProperties": false
      },
      "ContactPage": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Contact"
            }
          },
          "next_after_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          }
        },
        "required": [
          "items",
          "next_after_id"
        ],
        "additionalProperties": false
      },
      "ProductPage": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Product"
            }
          },
          "next_after_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          },
          "partner_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          },
          "pricelist_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          },
          "fiscal_position_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          },
          "currency": {
            "type": "string"
          },
          "currency_rounding": {
            "type": "number"
          },
          "calculated_at": {
            "type": "string"
          },
          "estimate": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "price_quantity": {
            "type": "integer",
            "enum": [
              1
            ]
          }
        },
        "required": [
          "items",
          "next_after_id",
          "partner_id",
          "pricelist_id",
          "fiscal_position_id",
          "currency",
          "currency_rounding",
          "calculated_at",
          "estimate",
          "price_quantity"
        ],
        "additionalProperties": false
      },
      "CategoryPage": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Category"
            }
          },
          "next_after_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          }
        },
        "required": [
          "items",
          "next_after_id"
        ],
        "additionalProperties": false
      },
      "PricelistPage": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Pricelist"
            }
          },
          "next_after_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          }
        },
        "required": [
          "items",
          "next_after_id"
        ],
        "additionalProperties": false
      },
      "ShopPage": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Shop"
            }
          },
          "next_after_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          }
        },
        "required": [
          "items",
          "next_after_id"
        ],
        "additionalProperties": false
      },
      "WarehousePage": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Warehouse"
            }
          },
          "next_after_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647,
            "nullable": true
          }
        },
        "required": [
          "items",
          "next_after_id"
        ],
        "additionalProperties": false
      },
      "ComboSelection": {
        "type": "object",
        "required": [
          "item_id",
          "qty"
        ],
        "additionalProperties": false,
        "properties": {
          "item_id": {
            "type": "integer",
            "minimum": 1
          },
          "qty": {
            "type": "integer",
            "minimum": 1,
            "description": "Quantity of this choice per one bundle."
          },
          "attribute_value_ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 1
            },
            "uniqueItems": true,
            "maxItems": 100
          },
          "custom_values": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "minLength": 1,
              "maxLength": 1000
            },
            "description": "Selected custom attribute value ID as string -> text."
          }
        }
      },
      "CatalogPrice": {
        "type": "object",
        "properties": {
          "product_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
          },
          "qty": {
            "type": "number"
          },
          "uom_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
          },
          "price_unit": {
            "type": "number",
            "description": "Native Odoo line unit price; may include tax. Use subtotal_included/amount_total for payable amounts."
          },
          "subtotal_excluded": {
            "type": "number"
          },
          "subtotal_included": {
            "type": "number"
          },
          "tax_amount": {
            "type": "number"
          },
          "tax_ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 1,
              "maximum": 2147483647
            }
          }
        },
        "required": [
          "product_id",
          "qty",
          "uom_id",
          "price_unit",
          "subtotal_excluded",
          "subtotal_included",
          "tax_amount",
          "tax_ids"
        ],
        "additionalProperties": false,
        "nullable": true,
        "description": "Null for a combo: select its composition and POST /prices for the full amount."
      },
      "ComboPriceLine": {
        "type": "object",
        "properties": {
          "product_id": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
          },
          "qty": {
            "type": "number"
          },
          "price_unit": {
            "type": "number",
            "description": "Native Odoo line unit price; may include tax. Use subtotal_included/amount_total for payable amounts."
          },
          "subtotal_excluded": {
            "type": "number"
          },
          "subtotal_included": {
            "type": "number"
          },
          "tax_amount": {
            "type": "number"
          },
          "tax_ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 1,
              "maximum": 2147483647
            }
          },
          "combo_item_id": {
            "type": "integer",
            "minimum": 1
          }
        },
        "required": [
          "product_id",
          "qty",
          "price_unit",
          "subtotal_excluded",
          "subtotal_included",
          "tax_amount",
          "tax_ids",
          "combo_item_id"
        ],
        "additionalProperties": false
      },
      "ComboOptions": {
        "type": "object",
        "required": [
          "version",
          "product_id",
          "name",
          "currency",
          "currency_rounding",
          "groups"
        ],
        "additionalProperties": false,
        "properties": {
          "version": {
            "type": "integer",
            "enum": [
              1
            ]
          },
          "product_id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "currency": {
            "type": "string"
          },
          "currency_rounding": {
            "type": "number"
          },
          "groups": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "name",
                "qty_free",
                "qty_max",
                "is_upsell",
                "base_price",
                "items"
              ],
              "additionalProperties": false,
              "properties": {
                "id": {
                  "type": "integer"
                },
                "name": {
                  "type": "string"
                },
                "qty_free": {
                  "type": "integer"
                },
                "qty_max": {
                  "type": "integer"
                },
                "is_upsell": {
                  "type": "boolean"
                },
                "base_price": {
                  "type": "number"
                },
                "items": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "id",
                      "product_id",
                      "name",
                      "extra_price",
                      "uom_id",
                      "uom_name",
                      "tracking",
                      "attributes"
                    ],
                    "additionalProperties": false,
                    "properties": {
                      "id": {
                        "type": "integer"
                      },
                      "product_id": {
                        "type": "integer"
                      },
                      "name": {
                        "type": "string"
                      },
                      "extra_price": {
                        "type": "number"
                      },
                      "uom_id": {
                        "type": "integer"
                      },
                      "uom_name": {
                        "type": "string"
                      },
                      "tracking": {
                        "oneOf": [
                          {
                            "type": "string",
                            "enum": [
                              "none",
                              "lot",
                              "serial"
                            ]
                          },
                          {
                            "type": "boolean",
                            "enum": [
                              false
                            ]
                          }
                        ]
                      },
                      "attributes": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "required": [
                            "attribute_id",
                            "name",
                            "variant_mode",
                            "values"
                          ],
                          "additionalProperties": false,
                          "properties": {
                            "attribute_id": {
                              "type": "integer"
                            },
                            "name": {
                              "type": "string"
                            },
                            "variant_mode": {
                              "type": "string"
                            },
                            "values": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "required": [
                                  "id",
                                  "name",
                                  "custom",
                                  "price_extra"
                                ],
                                "additionalProperties": false,
                                "properties": {
                                  "id": {
                                    "type": "integer"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "custom": {
                                    "type": "boolean"
                                  },
                                  "price_extra": {
                                    "type": "number"
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
