Ready2order Product API

Products are the items sold at the point of sale. Each product belongs to a product group and carries a price, a VAT rate, and a set of optional features such as stock tracking, variations, and ingredients. **Identifiers** A product supports three optional identifiers alongside its system `product_id`: - `product_itemnumber`: the merchant's own article number, used on labels, in exports, and for stock lookups - `product_barcode`: EAN or barcode for scanning at the POS - `product_externalReference`: for integrators to store their own system's ID, so you can map between your records and ready2order without storing `product_id` on your side **Pricing and VAT** `product_price` is the base price. Set `product_priceIncludesVat` to `true` (the default) if that figure is gross, or `false` if it is net. A VAT rate is required on creation — supply either `product_vat` as a percentage or `product_vat_id` referencing a [VAT rate](#tag/Vat-Rate). Customers and customer categories can have individual price overrides managed via the [per-customer prices](#operation/productGetAllCustomerProductPrices) and [per-category prices](#operation/productGetAllCustomerCategoryProductPrices) endpoints. **Custom price and quantity** Set `product_customPrice: true` to let the cashier enter the price manually at checkout, which is useful for open-price items. `product_customQuantity: true` does the same for the quantity. **Stock** Stock tracking is optional and configured per product. Set `product_stock_enabled: true`, then use `product_stock_value` for the current quantity, `product_stock_safetyStock` for the minimum threshold, and `product_stock_reorderLevel` for the point at which the system alerts about low inventory. Use the [get stock](#operation/productGetStock) and [update stock](#operation/productUpdateStock) endpoints to read or update stock figures without touching other product fields. **Product type** `product_type` is mainly relevant in gastro mode, where it drives printer routing (e.g. kitchen vs. bar). Available values: `standard`, `food`, `drink`, `extra`, `sidedish`, `variation`, `ingredient`. For standard retail products, use `standard`. **Variations and ingredients** Variations (selectable add-ons or modifications) and ingredients (component tracking for recipes and partial-unit sales) are enabled per product with `product_variations_enabled` and `product_ingredients_enabled`. Both require the corresponding feature to be active on the account. **Keeping a catalogue in sync** The recommended approach is to subscribe to [webhooks](#tag/Webhook) for `product.created` and `product.updated` events. This avoids polling and ensures your system is updated in near real-time without unnecessary requests. If webhooks are not an option, use the `updatedAfter` query parameter on [list products](#operation/productGetAll) to fetch only products changed since a given timestamp. Use [batch create](#operation/productCreateBatch) to create multiple products in one request.

OpenAPI Specification

ready2order-product-api-openapi.yml Raw ↑
openapi: 3.0.0
info:
  title: ready2order Public Account Token Product API
  contact:
    name: support@ready2order.com
  license:
    name: proprietary
  version: R2-2026.30.2
  description: "# First Steps\n\n## Authorization\n\nThe ready2order API uses a three-token flow to grant your integration access to a ready2order account. Your integration identifies itself with a Developer Token, requests permission from the account owner, and receives a long-lived Account Token to use for all subsequent requests.\n\nEvery API request to account data must include:\n\n```http\nAuthorization: Bearer <ACCOUNT_TOKEN>\n```\n\n| Token | Scope | Lifetime |\n|-------|-------|----------|\n| **Developer Token** | Identifies your integration | Permanent |\n| **Grant Access Token** | One-time permission request | 10 minutes |\n| **Account Token** | Access to a ready2order account | Until revoked |\n\n---\n\n## Setup\n\nThis is a one-time process per account you want to integrate with.\n\n### Step 1 — Get your Developer Token\n\nRegister at [https://api.ready2order.com](https://api.ready2order.com). Your Developer Token will be emailed to you.\n\nStore it securely — it identifies your integration across all accounts.\n\n---\n\n### Step 2 — Request a Grant Access Token\n\nCall this endpoint using your Developer Token:\n\n```http\nPOST /v1/developerToken/grantAccessToken\nAuthorization: Bearer <DEVELOPER_TOKEN>\n```\n\n```json\n{\n  \"callbackUri\": \"https://your-app.com/callback\"\n}\n```\n\n`callbackUri` is optional but strongly recommended (see Step 3).\n\n**Response:**\n\n```json\n{\n  \"grantAccessToken\": \"...\",\n  \"grantAccessUri\": \"https://app.ready2order.com/...\"\n}\n```\n\n---\n\n### Step 3 — Account owner approves access\n\nRedirect the account owner to the `grantAccessUri`. They will log in to their ready2order account and click **Approve**.\n\n**With `callbackUri`** — after approval, ready2order redirects the account owner back to your URL:\n\n```\nhttps://your-app.com/callback?accountToken=<ACCOUNT_TOKEN>&grantAccessToken=<GRANT_ACCESS_TOKEN>&status=approved\n```\n\nThe `accountToken` in that redirect is what you store and use for all future requests.\n\n**Without `callbackUri`** — poll for the result instead:\n\n```http\nGET /v1/developerToken/grantAccessToken/{grantAccessToken}\nAuthorization: Bearer <DEVELOPER_TOKEN>\n```\n\nThe response will include `accountToken` once the account owner has approved.\n\n> The Grant Access Token expires after **10 minutes**. If the account owner does not approve in time, repeat Step 2 to generate a new one.\n\n---\n\n## Training Mode\n\nSome resources support a training mode that keeps test transactions separate from live data. It is handy for staff training and demos where test sales should not show up in reports or fiscal records.\n\nWhen a cashier puts the POS into training mode, all transactions in that session are flagged as training records and kept separate from live data. On the API side, the `trainingMode` field on a resource tells you whether it is a training record, and most list endpoints accept a `trainingMode` query parameter to filter by it.\n\n---\n\n## Error Responses\n\n| Status | Likely cause |\n|--------|-------------|\n| `401 Unauthorized` | Wrong token type, or `Authorization` header missing |\n| `403 Forbidden` | Developer Token used where Account Token is required (or vice versa) |\n| `429 Too Many Requests` | Rate limit exceeded — max 60 requests per minute per Account Token |\n"
servers:
- url: https://api.ready2order.com/v1
tags:
- name: Product
  description: "<!-- markdownlint-disable MD041 MD051 github-internal-links relative-links -- tag description snippet, not a standalone document; the tag name serves as the heading in the API docs -->\nProducts are the items sold at the point of sale. Each product belongs to a product group and carries a price, a VAT rate, and a set of optional features such as stock tracking, variations, and ingredients.\n\n**Identifiers**\n\nA product supports three optional identifiers alongside its system `product_id`:\n\n- `product_itemnumber`: the merchant's own article number, used on labels, in exports, and for stock lookups\n- `product_barcode`: EAN or barcode for scanning at the POS\n- `product_externalReference`: for integrators to store their own system's ID, so you can map between your records and ready2order without storing `product_id` on your side\n\n**Pricing and VAT**\n\n`product_price` is the base price. Set `product_priceIncludesVat` to `true` (the default) if that figure is gross, or `false` if it is net. A VAT rate is required on creation — supply either `product_vat` as a percentage or `product_vat_id` referencing a [VAT rate](#tag/Vat-Rate).\n\nCustomers and customer categories can have individual price overrides managed via the [per-customer prices](#operation/productGetAllCustomerProductPrices) and [per-category prices](#operation/productGetAllCustomerCategoryProductPrices) endpoints.\n\n**Custom price and quantity**\n\nSet `product_customPrice: true` to let the cashier enter the price manually at checkout, which is useful for open-price items. `product_customQuantity: true` does the same for the quantity.\n\n**Stock**\n\nStock tracking is optional and configured per product. Set `product_stock_enabled: true`, then use `product_stock_value` for the current quantity, `product_stock_safetyStock` for the minimum threshold, and `product_stock_reorderLevel` for the point at which the system alerts about low inventory. Use the [get stock](#operation/productGetStock) and [update stock](#operation/productUpdateStock) endpoints to read or update stock figures without touching other product fields.\n\n**Product type**\n\n`product_type` is mainly relevant in gastro mode, where it drives printer routing (e.g. kitchen vs. bar). Available values: `standard`, `food`, `drink`, `extra`, `sidedish`, `variation`, `ingredient`. For standard retail products, use `standard`.\n\n**Variations and ingredients**\n\nVariations (selectable add-ons or modifications) and ingredients (component tracking for recipes and partial-unit sales) are enabled per product with `product_variations_enabled` and `product_ingredients_enabled`. Both require the corresponding feature to be active on the account.\n\n**Keeping a catalogue in sync**\n\nThe recommended approach is to subscribe to [webhooks](#tag/Webhook) for `product.created` and `product.updated` events. This avoids polling and ensures your system is updated in near real-time without unnecessary requests.\n\nIf webhooks are not an option, use the `updatedAfter` query parameter on [list products](#operation/productGetAll) to fetch only products changed since a given timestamp. Use [batch create](#operation/productCreateBatch) to create multiple products in one request.\n    "
paths:
  /products/batch:
    post:
      tags:
      - Product
      summary: Create products in bulk
      description: Creates multiple products in a single request. Returns a result for each item along with a count of how many succeeded and how many failed.
      operationId: productCreateBatch
      requestBody:
        content:
          application/json:
            schema:
              required:
              - items
              properties:
                items:
                  type: array
                  items:
                    properties:
                      productgroup_id:
                        description: Product group id
                        type: integer
                        example: 1
                      product_name:
                        description: Product name
                        type: string
                        example: Coca cola
                      product_price:
                        description: Product price
                        type: string
                        example: 124.25
                      product_vat:
                        description: VAT-Rate in decimals. Provide either product_vat or product_vat_id
                        type: string
                        example: 10.5
                      product_vat_id:
                        description: ID of VAT-rate (see /vat-rates). Provide either product_vat or product_vat_id
                        type: integer
                        example: 1234
                      product_itemnumber:
                        description: Item number
                        type: string
                        example: x-123
                      product_externalReference:
                        description: External reference
                        type: string
                        example: xxx-123
                      product_barcode:
                        description: Barcode
                        type: string
                        example: '12345678'
                      product_description:
                        description: Optional description
                        type: string
                        example: lorem ipsum dolor sit amet
                      product_priceIncludesVat:
                        description: Whether price is provided included or excluding VAT
                        type: boolean
                        example: false
                      product_active:
                        description: Is product active
                        type: boolean
                        example: true
                      product_discountable:
                        description: Is product discountable
                        type: boolean
                        example: true
                      product_stock_enabled:
                        description: Is stock for product enabled
                        type: boolean
                        example: true
                      product_stock_value:
                        description: Product stock value
                        type: string
                        example: 10.5
                      product_stock_reorderLevel:
                        description: Product stock reorder level
                        type: string
                        example: 2.5
                      product_stock_safetyStock:
                        description: Product stock safety level
                        type: string
                        example: 5.1
                      product_stock_unit:
                        description: Product stock unit
                        type: string
                        example: Kg
                      product_sortIndex:
                        description: Product sort index
                        type: integer
                        example: 5
                      product_type:
                        description: In case of adding new sidedishes or extras you need to provide the product_type. For example, if you're adding 'Fries' as a side you need to provide 'food'.
                        type: string
                        example: food, drink or default
                      product_accountingCode:
                        description: Product accounting code
                        type: string
                        example: XY124
                      product_accountingCodeName:
                        description: Accounting code name
                        type: string
                        example: code-name-x
                      product_alternativeNameOnReceipts:
                        description: Product alternative name on receipts
                        type: string
                        example: XXX Cola
                      product_alternativeNameInPos:
                        description: An alternative name shown on the POS screen instead of the regular product name. Useful when the shelf name differs from what staff should see at checkout.
                        type: string
                        example: POS Cola
                      product_ingredients_enabled:
                        description: Enables ingredients for this product. Ingredients are used for recipe-based costing and partial-unit sales. Requires the ingredients feature to be active on the account.
                        type: boolean
                        example: true
                      product_variations_enabled:
                        description: Enables variations for this product. Variations are selectable add-ons or modifications the cashier can apply at checkout. Requires the variations feature to be active on the account.
                        type: boolean
                        example: true
                      product_customPrice:
                        description: Allows the cashier to enter the price freely at checkout instead of using the product's configured price. Useful for open-price items or when the price varies per transaction.
                        type: boolean
                        example: true
                      product_customQuantity:
                        description: Allows the cashier to enter the quantity freely at checkout instead of incrementing by whole units.
                        type: boolean
                        example: true
                      product_soldOut:
                        description: Is product sold out
                        type: boolean
                        example: false
                      product_expressMode:
                        description: Enables express checkout for this product in the POS. When a cashier taps the product button, a bill is created and closed immediately — skipping the cart entirely. Useful for single-item, fixed-price sales such as a prepaid coffee or a parking ticket.
                        type: boolean
                        example: true
                      product_highlight:
                        description: Highlights the product line on printed receipts and order tickets — the line is printed in red with a distinct fill character between the product name and price. Red colour output requires a printer that supports it.
                        type: boolean
                        example: true
                      product_sideDishOrder:
                        description: Presents the sidedish list for this product in a fixed order. Only relevant when the product has sidedishes configured.
                        type: boolean
                        example: true
                      product_fav:
                        description: Marks the product as a favourite in the POS, making it appear in the favourites section for quicker access.
                        type: boolean
                        example: true
                    type: object
              type: object
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                properties:
                  product_id:
                    type: integer
                    example: 9999
                  product_externalReference:
                    type: string
                  product_itemnumber:
                    type: string
                  product_barcode:
                    type: string
                  product_name:
                    type: string
                  product_description:
                    type: string
                  product_price:
                    type: string
                    example: 0
                  product_priceIncludesVat:
                    type: boolean
                    example: false
                  product_vat:
                    type: string
                    example: 0
                  product_vat_id:
                    type: integer
                    example: 9999
                  product_customPrice:
                    type: boolean
                    example: false
                  product_customQuantity:
                    type: boolean
                    example: false
                  product_fav:
                    type: boolean
                    example: false
                  product_highlight:
                    type: boolean
                    example: false
                  product_expressMode:
                    type: boolean
                    example: false
                  product_stock_enabled:
                    type: boolean
                    example: false
                  product_ingredients_enabled:
                    type: boolean
                    example: false
                  product_variations_enabled:
                    type: boolean
                    example: false
                  product_stock_value:
                    type: string
                    example: 0
                  product_stock_unit:
                    type: string
                  product_stock_reorderLevel:
                    type: string
                    example: 0
                  product_stock_safetyStock:
                    type: string
                    example: 0
                  product_sortIndex:
                    type: integer
                    example: 9999
                  product_soldOut:
                    type: boolean
                    example: false
                  product_sideDishOrder:
                    type: boolean
                    example: false
                  product_discountable:
                    type: boolean
                    example: false
                  product_accountingCode:
                    type: string
                  product_colorClass:
                    type: string
                  productgroup_id:
                    type: integer
                    example: 9999
                  product_type_id:
                    type: integer
                    example: 9999
                  product_type:
                    type: string
                  product_created_at:
                    type: string
                  product_updated_at:
                    type: string
                  product_alternativeNameOnReceipts:
                    type: string
                  product_alternativeNameInPos:
                    type: string
                  productgroup:
                    properties:
                      productgroup_id:
                        type: integer
                        example: 9999
                      productgroup_name:
                        type: string
                      productgroup_description:
                        type: string
                      productgroup_shortcut:
                        type: string
                      productgroup_active:
                        type: boolean
                        example: false
                      productgroup_sortIndex:
                        type: integer
                        example: 9999
                      productgroup_created_at:
                        type: string
                      productgroup_updated_at:
                        type: string
                      productgroup_type_id:
                        type: integer
                        example: 9999
                    type: object
                  productvariation:
                    type: array
                    items:
                      properties:
                        variation_id:
                          type: integer
                          example: 9999
                        variation_name:
                          type: string
                        variation_price:
                          type: string
                        variation_stock:
                          type: string
                          example: 0
                      type: object
                  productingredient:
                    type: array
                    items:
                      properties:
                        ingredient_id:
                          type: integer
                          example: 9999
                        ingredient_name:
                          type: string
                        ingredient_unit:
                          type: string
                        ingredient_quantity:
                          type: string
                          example: 0
                      type: object
                  images:
                    type: array
                    items:
                      properties:
                        image_id:
                          type: integer
                          example: 9999
                        image_url:
                          type: string
                      type: object
                type: object
        '400':
          description: Bad Request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
      security:
      - Bearer: []
  /products/batch/stock:
    post:
      tags:
      - Product
      summary: Update stock in bulk
      description: Updates stock for multiple products in one request. Each item can be identified by either `product_id` or `product_itemNumber`.
      operationId: productUpdateStockInBatch
      requestBody:
        content:
          application/json:
            schema:
              required:
              - products
              properties:
                products:
                  description: List of products
                  type: array
                  items:
                    properties:
                      product_stock:
                        type: string
                      product_id:
                        type: string
                      product_itemNumber:
                        type: string
                    type: object
                  example: List of products
              type: object
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                properties:
                  updatedIds:
                    properties:
                      id:
                        type: integer
                        example: 1
                    type: object
                  updatedItemNumbers:
                    properties:
                      number:
                        type: integer
                        example: 1
                    type: object
                type: object
        '400':
          description: Bad Request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
      security:
      - Bearer: []
  /products:
    get:
      tags:
      - Product
      summary: List products
      description: Returns a paginated list of products. Filter by product group, name, barcode, or item number. Use `updatedAfter` to fetch only products changed since a given timestamp.
      operationId: productGetAll
      parameters:
      - name: page
        in: query
        description: Page you want to display
        required: false
        schema:
          type: integer
          example: 1
      - name: limit
        in: query
        description: Items per page
        required: false
        schema:
          type: integer
          example: 25
      - name: productgroup_id
        in: query
        description: get all products for this productgroup_id
        required: false
        schema:
          type: integer
          example: 1
      - name: itemNumber
        in: query
        description: search for a product with the given product_itemNumber
        required: false
        schema:
          type: string
          example: x-123
      - name: name
        in: query
        description: search for a product with the given product_name
        required: false
        schema:
          type: string
          example: coca cola
      - name: barcode
        in: query
        description: search for a product with the given product_barcode
        required: false
        schema:
          type: string
          example: '1234567890'
      - name: q
        in: query
        description: search for a product by keywords
        required: false
        schema:
          type: string
          example: keyword
      - name: includeProductGroup
        in: query
        description: include product group information
        required: false
        schema:
          type: boolean
          example: false
      - name: includeProductVariations
        in: query
        description: include product variations information
        required: false
        schema:
          type: boolean
          example: false
      - name: includeProductIngredients
        in: query
        description: include product variations information
        required: false
        schema:
          type: boolean
          example: false
      - name: updatedAfter
        in: query
        description: Only return list of products which have been updated after a given timestamp
        required: false
        schema:
          type: string
          example: '2021-12-29 04:18:00'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  properties:
                    product_id:
                      type: integer
                      example: 1234
                    product_externalReference:
                      type: string
                      example: ref-1234
                    product_itemnumber:
                      type: string
                      example: 1
                    product_barcode:
                      type: string
                      example: x400467508233
                    product_name:
                      type: string
                      example: coca cola
                    product_description:
                      type: string
                      example: coca cola - non-alcoholic drink
                    product_price:
                      type: string
                      example: 10.5
                    product_priceIncludesVat:
                      type: boolean
                      example: false
                    product_vat:
                      type: string
                      example: 2
                    product_vat_id:
                      type: integer
                      example: 2
                    product_customPrice:
                      type: boolean
                      example: true
                    product_customQuantity:
                      type: boolean
                      example: true
                    product_fav:
                      type: boolean
                      example: true
                    product_highlight:
                      type: boolean
                      example: true
                    product_expressMode:
                      type: boolean
                      example: true
                    product_stock_enabled:
                      type: boolean
                      example: true
                    product_ingredients_enabled:
                      type: boolean
                      example: true
                    product_variations_enabled:
                      type: boolean
                      example: true
                    product_stock_value:
                      type: string
                      example: 100
                    product_stock_unit:
                      type: string
                      example: kg
                    product_stock_reorderLevel:
                      type: string
                      example: 10
                    product_stock_safetyStock:
                      type: string
                      example: 20
                    product_sortIndex:
                      type: integer
                      example: 5
                    product_soldOut:
                      type: boolean
                      example: true
                    product_sideDishOrder:
                      type: boolean
                      example: true
                    product_discountable:
                      type: boolean
                      example: true
                    product_accountingCode:
                      type: string
                      example: 1000123
                    product_colorClass:
                      type: string
                      example: bgGreenYellow
                    productgroup_id:
                      type: integer
                      example: 1
                    product_type_id:
                      type: integer
                      example: 1
                    product_type:
                      type: string
                      example: standard
                    product_created_at:
                      type: string
                      example: '2019-01-01 11:11:11'
                    product_updated_at:
                      type: string
                      example: '2019-01-01 11:11:11'
                    product_alternativeNameOnReceipts:
                      type: string
                      example: xxx cola
                    product_alternativeNameInPos:
                      type: string
                      example: yyy cola
                    productgroup:
                      properties:
                        productgroup_id:
                          type: integer
                          example: 1
                        productgroup_name:
                          type: string
                        productgroup_description:
                          type: string
                        productgroup_shortcut:
                          type: string
                        productgroup_active:
                          type: boolean
                          example: false
                        productgroup_sortIndex:
                          type: integer
                          example: 9999
                        productgroup_created_at:
                          type: string
                        productgroup_updated_at:
                          type: string
                        productgroup_type_id:
                          type: integer
                          example: 9999
                      type: object
                    productvariation:
                      type: array
                      items:
                        properties:
                          variation_id:
                            type: integer
                            example: 1
                          variation_name:
                            type: string
                            example: schnitzel with chips and mayo
                          variation_price:
                            type: string
                            example: 15.2
                          variation_stock:
                            type: string
                            example: 10
                        type: object
                    productingredient:
                      type: array
                      items:
                        properties:
                          ingredient_id:
                            type: integer
                            example: 1
                          ingredient_name:
                            type: string
                            example: pork meat
                          ingredient_unit:
                            type: string
                            example: Kg
                          ingredient_quantity:
                            type: string
                            example: 0
                        type: object
                    images:
                      type: array
                      items:
                        properties:
                          image_id:
                            type: integer
                            example: 1
                          image_url:
                            type: string
                            example: https://cdn.ready2order.at/live/static/cache/images/{hash}.png
                        type: object
                  type: object
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
      security:
      - Bearer: []
    post:
      tags:
      - Product
      summary: Create a product
      description: Creates a new product.
      operationId: productCreate
      requestBody:
        content:
          application/json:
            schema:
              required:
              - product_name
              - product_price
              properties:
                productgroup_id:
                  description: Product group id
                  type: inte

# --- truncated at 32 KB (90 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/ready2order/refs/heads/main/openapi/ready2order-product-api-openapi.yml