Search in documentation
ctrl+4K
Modules
Authentication
Merchant
Catalog
Order
Events
Logistics
Shipping
Review
Financial
Solutions

How it works

The Catalog API organizes your menu into three levels: catalog, category, and item. Items have add-ons and can have different pricing and availability per sales channel (context).This guide shows when to call each endpoint. For hands-on examples, see Introduction. For the complete reference, see Endpoints.
Every integration follows six steps:
  1. Authenticate — Get an accessToken. See Authentication.
  2. List catalogsGET /catalogs. Every store already has at least one.
  3. Create categoriesPOST /categories groups items (sandwiches, drinks, desserts).
  4. Create itemsPUT /items sends item, products, option groups, and options in one call.
  5. Update price and statusPATCH /items/price and PATCH /items/status for individual changes.
  6. Track batch operationsGET /batch/{batchId} for asynchronous patches.
Complete catalog architecture showing merchants, catalogs, categories, items, and modifiersProduct structure example showing item and its components
Every item has two states:
  • AVAILABLE — Customers can purchase.
  • UNAVAILABLE — Item paused. Does not appear in the app until it returns to AVAILABLE.
Use PATCH /items/status to toggle states without resending the complete item.
The change you want to make determines the endpoint:
ChangeEndpointNotes
Create or rewrite a complete itemPUT /itemsSends item, products, groups, and options in one call. Idempotent.
Change item pricePATCH /items/priceChanges only item price. Supports batch.
Change add-on pricePATCH /options/priceChanges only add-on (option) price. Supports batch.
Pause or reactivate an itemPATCH /items/statusChanges only status. Supports batch.
Pause an add-on optionPATCH /options/statusAffects a single option.
Pause all options in a groupPATCH /optionGroups/statusAffects the entire group.
Adjust inventoryPOST /inventorySets the maximum sellable quantity.
Remember: PUT /items replaces the complete item — omitted fields are removed. Use PATCH for individual changes.
PUT /items is idempotent: calling twice with the same payload does not create duplicates. The second call overwrites the first, simplifying retries on transient failures.
PUT /catalog/v2.0/merchants/{merchantId}/items
{
  "item": {
    "id": "burger-001",
    "type": "DEFAULT",
    "categoryId": "appetizers",
    "status": "AVAILABLE",
    "price": {"value": 25.00}
  },
  "products": [
    {
      "id": "burger-prod-001",
      "name": "X-Burger"
    }
  ],
  "optionGroups": [],
  "options": []
}
Use the same PUT /items with optionGroups and options filled in:
{
  "item": { /* ... */ },
  "products": [ /* ... */ ],
  "optionGroups": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440010",
      "name": "Choose a drink",
      "min": 0,
      "max": 1,
      "optionIds": ["550e8400-e29b-41d4-a716-446655440020", "550e8400-e29b-41d4-a716-446655440021"]
    }
  ],
  "options": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440020",
      "productId": "550e8400-e29b-41d4-a716-446655440002",
      "price": {"value": 8.00}
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440021",
      "productId": "550e8400-e29b-41d4-a716-446655440003",
      "price": {"value": 12.00}
    }
  ]
}
PATCH /catalog/v2.0/merchants/{merchantId}/items/price
{
  "prices": [
    {"productId": "burger-prod-001", "price": 26.50},
    {"productId": "burger-prod-002", "price": 28.00}
  ]
}
The response returns a batchId. Track it with GET /batch/{batchId}:
GET /catalog/v2.0/merchants/{merchantId}/batch/{batchId}
{
  "batchId": "batch-123",
  "status": "COMPLETED",
  "successCount": 95,
  "failureCount": 5
}
Batch patches run asynchronously. Check GET /batch/{batchId} until the status is COMPLETED before assuming changes are applied.
Offer the same item across different channels (Delivery, Digital Menu, Dine-in) with distinct prices and statuses. Use contextModifiers instead of duplicating items:
{
  "item": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "price": {"value": 25.00},
    "status": "AVAILABLE",
    "contextModifiers": [
      {
        "catalogContext": "WHITELABEL",
        "price": {"value": 28.00},
        "status": "UNAVAILABLE"
      }
    ]
  }
}
Values in contextModifiers override root values only in that context. Available contexts:
  • DEFAULT — Delivery
  • WHITELABEL — Digital Menu
  • INDOOR — Dine-in
For stores with completely distinct catalogs per channel, use PUT /multisetup/items. See Multi-menu.
Choose the topic most relevant to your integration:
Was this page helpful?
Rate your experience in the new Developer portal: