Fetch Store Catalog from the GonnaOrder API

GonnaOrder supports a wide range of pre-configured POS integrations. However, you can also integrate with custom POS and back-office partners using the GonnaOrder API, ensuring seamless integration with the desired POS/back-office partner. In this guide, we focus on how to fetch the GonnaOrder catalog of a store from the admin side of the GonnaOrder API. It covers two admin endpoints that you may call without query parameters. You can also add level query parameter when calling the catalog from the API.

  1. GET /api/v1/user/stores/{storeId}/catalog
    (two parameters: storeId in the path, with level as a query parameter)

  2. GET /api/v1/user/stores/{storeId}/catalog/{catalogId}/categories/name
    (three parameters: storeId and catalogId in the path, level as a query parameter)

Both endpoints accept an optional level query parameter that lets you choose which part of the catalog hierarchy is returned. The default behavior (when level is omitted) returns the parent-only catalog. Adding the level parameter on each call lets you switch between a flat parent-only view, a child-only view, and the complete nested catalog tree, all in a single API call.


On this Page


Understanding the Catalog Hierarchy

A GonnaOrder offer can be:

  • PARENT — The main sellable product that appears on the customer’s main menu (e.g., Pepperoni Pizza).
  • VARIANT — a sized or styled variation of a parent offer, such as a small/medium/large pizza.
  • CHILD — an option-group item that belongs to a parent or a variant, such as toppings or extras.
  • COMBO — a meal deal which includes multiple combination of offers. For example, a burger combo can have multi-choice burgers, fries, and drinks).
  • GIFT_CARD / GIFT_CARD_VARIANT. These are gift card offers and their related variants.

As initially stated, you can use the admin catalog endpoint to return parent-level offers without the option group items. Also, if you want a section of the catalog offers, you can use the level parameter to return specific catalog level on demand, without having to combine multiple calls.


Authentication and Base URLs

All admin endpoints require Bearer token authentication, the same one already used by existing integrations:

Environment Base URL
Production https://admin.gonnaorder.com
Staging https://admin.wannaorder.net

Conventions Used in This Documentation

  1. All examples assume storeId = 12345 and, where applicable, catalogId = 678.
  2. level is case-sensitive and must be sent in upper case (for example FULL, not full or Full).
  3. An invalid value returns HTTP 400 Bad Request.
  4. Sample Response used are illustrative; field names match the JSON returned by the production API.

API 1. Fetch the Full Catalog of a Store

If you wish to fetch the entire store catalog from the admin side, this option comes in handy. This two-parameter endpoint allows you to read the complete product list for a store and decide between a parent-only view, a child-only view, or the full nested tree.

Endpoint

GET /api/v1/user/stores/{storeId}/catalog

Request parameters

Parameter Type / Location Required Description
storeId long, path Yes The numeric identifier of the store whose catalog you want to fetch.
level string, query No Section of the catalog to be returned. Accepted values: PARENT, CHILD, FULL.
When level omitted the endpoint defaults to PARENT.

Behaviour by Level Value

Level What is returned Typical use case
PARENT (default) Parent-level offers only. Option-group items (CHILD offers) are not fetched.
VARIANT, COMBO, GIFT_CARD and GIFT_CARD_VARIANT offers are returned.
Lightweight sync of the main product list, when option groups are imported separately.
CHILD Only the CHILD offers and the child categories that contain them are fetched. The parent category tree and parent-level offers are not part of the response. Refresh of option-group items only (for example, after a price change on toppings).
FULL The complete catalog tree. CHILD offers are nested under their
PARENT and VARIANT offers, exactly as the customer storefront receives the catalog.
One-shot import of the full menu into a POS or back-office system.

Example Without the level Parameter

Here is an example of an API call without the level parameter.

GET /api/v1/user/stores/12345/catalog
Authorization: Bearer <token>

This call returns parent-level offers, organized in their parent categories. CHILD offers are not present in the response. This is identical to calling the endpoint with level=PARENT explicitly.


Example, level = PARENT

GET /api/v1/user/stores/12345/catalog?level=PARENT
Authorization: Bearer <token>

This call will deliver the same response as the call without the level query parameter. You can use this form when you want to make the intent explicit in your code.

Response shape (illustrative)

{
  "id": 678,
  "name": "Default catalog",
  "categories": [
    {
      "id": 1001,
      "name": "Pizzas",
      "offers": [
        {
          "id": 5001,
          "name": "Margherita",
          "hierarchyLevel": "PARENT",
          "price": 8.50
        },
        {
          "id": 5002,
          "name": "Pepperoni",
          "hierarchyLevel": "PARENT",
          "price": 9.50
        },
        {
          "id": 5003,
          "name": "Margherita L",
          "hierarchyLevel": "VARIANT",
          "parentId": 5001,
          "price": 11.00
        }
      ]
    },
    {
      "id": 1002,
      "name": "Drinks",
      "offers": [
        {
          "id": 5101,
          "name": "Cola 33cl",
          "hierarchyLevel": "PARENT",
          "price": 2.00
        }
      ]
    }
  ]
}

Example, level = CHILD

GET /api/v1/user/stores/12345/catalog?level=CHILD
Authorization: Bearer <token>

This API call returns only the option-group items (CHILD offers) and the child categories that contain them. Therefore, parent offers and the parent category tree are not included.

Response shape (illustrative)

{
  "id": 678,
  "name": "Default catalog",
  "categories": [
    {
      "id": 2001,
      "name": "Pizza Toppings",
      "hierarchyLevel": "ITEM_GROUP",
      "offers": [
        {
          "id": 6001,
          "name": "Extra Cheese",
          "hierarchyLevel": "CHILD",
          "price": 1.00
        },
        {
          "id": 6002,
          "name": "Mushrooms",
          "hierarchyLevel": "CHILD",
          "price": 0.80
        },
        {
          "id": 6003,
          "name": "Olives",
          "hierarchyLevel": "CHILD",
          "price": 0.80
           }
      ]
    }
  ]
}

Example, level = FULL

As the name suggests, this API call returns the complete catalog tree (PARENT and CHILD). CHILD offers are nested under their parent and variant offers. This is the most convenient form for a POS that needs to import the whole menu in one call.

Here is how to make this API call:

GET /api/v1/user/stores/12345/catalog?level=FULL
Authorization: Bearer <token>

Sample Response (illustrative)

Here is how the response will look like:

{
  "id": 678,
  "name": "Default catalog",
  "categories": [
    {
      "id": 1001,
      "name": "Pizzas",
      "offers": [
        {
          "id": 5001,
          "name": "Margherita",
          "hierarchyLevel": "PARENT",
          "price": 8.50,
          "optionGroups": [
            {
              "id": 2001,
              "name": "Pizza Toppings",
              "offers": [
                {
                  "id": 6001,
                  "name": "Extra Cheese",
                  "hierarchyLevel": "CHILD",
                  "price": 1.00
                },
                {
                  "id": 6002,
                  "name": "Mushrooms",
                  "hierarchyLevel": "CHILD",
                  "price": 0.80
                },
                {
                  "id": 6003,
                  "name": "Olives",
                  "hierarchyLevel": "CHILD",
                  "price": 0.80
                }
              ]
            }
          ]
        },
        {
          "id": 5003,
          "name": "Margherita L",
          "hierarchyLevel": "VARIANT",
          "parentId": 5001,
          "price": 11.00,
          "optionGroups": [
            {
              "id": 2001,
              "name": "Pizza Toppings",
              "offers": [
                /* same children as parent */
              ]
            }
          ]
        }
      ]
    },
    {
      "id": 1002,
      "name": "Drinks",
      "offers": [
        {
          "id": 5101,
          "name": "Cola 33cl",
          "hierarchyLevel": "PARENT",
          "price": 2.00,
          "optionGroups": [
            {
              "id": 2002,
              "name": "Drink Size",
              "offers": [
                {
                  "id": 6101,
                  "name": "33 cl",
                  "hierarchyLevel": "CHILD",
                  "price": 0.00
                },
                {
                  "id": 6102,
                  "name": "50 cl",
                  "hierarchyLevel": "CHILD",
                  "price": 0.50
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

Key Notes to Remember When Using API 1

  • Stores with zero CHILD offers respond successfully under level=CHILD with an empty list of child categories.
  • Under level=FULL, responses may be equivalent to level=PARENT if no child offers exist.
  • VARIANT offers that themselves carry option groups correctly nest CHILD offers under both the parent and the variant.
  • Lower-case or mixed-case values such as level=full are rejected with HTTP 400.
  • Unknown values such as level=BANANA are rejected with HTTP 400.

API 2. Fetch Category Names for a Catalog

Unlike fetching the entire catalog, this three-parameter endpoint allows you to fetch specific categories from the API. Therefore, it returns the list of categories of a catalog (names and identifiers, no offers). Use this endpoint call when you want a quick directory of what is in the catalog without downloading the entire offer payload.

Endpoint

GET /api/v1/user/stores/{storeId}/catalog/{catalogId}/categories/name

Request parameters

Parameter Type / Location Required Description
storeId long, path Yes The numeric identifier of the store.
catalogId long, path Yes The numeric identifier of the catalog inside the store.
level string, query No Hierarchy level of the categories to return. Most integrations use PARENT or CHILD. When omitted, all categories are returned, regardless of hierarchy level.

Behavior by level Value

Level What is returned
Omitted All category names in the catalog are returned, regardless of hierarchy level.
PARENT Only parent categories (those that hold parent-level offers such as products, pizzas, drinks).
CHILD Only child categories (those that hold option-group items such as toppings, sizes, sides).

The endpoint also accepts other values from the internal hierarchy enum, such as:

  • TOP
  • VARIANT
  • COMBO
  • GIFT_CARD
  • GIFT_CARD_VARIANT
  • ITEM_GROUP
  • RULE
  • RULE_DELIVERY_FEE
  • PRODUCT

For a POS sync, PARENT and CHILD are the values you will need to make the API call.

Example, Omitting level

This API call returns every category name in the entire catalog.

GET /api/v1/user/stores/12345/catalog/678/categories/name

Authorization: Bearer <token>

Sample Response (illustrative)

[
  {
    "id": 1001,
    "name": "Pizzas",
    "hierarchyLevel": "PARENT"
  },
  {
    "id": 1002,
    "name": "Drinks",
    "hierarchyLevel": "PARENT"
  },
  {
    "id": 2001,
    "name": "Pizza Toppings",
    "hierarchyLevel": "ITEM_GROUP"
  },
  {
    "id": 2002,
    "name": "Drink Size",
    "hierarchyLevel": "ITEM_GROUP"
  }
]

Example, level = PARENT

This API call returns only the categories that hold parent-level offers. Therefore, it is good for building a navigation menu in a POS UI.

GET /api/v1/user/stores/12345/catalog/678/categories/name?level=PARENT

Authorization: Bearer <token>

Sample Response (illustrative)

[
  {
    "id": 1001,
    "name": "Pizzas",
    "hierarchyLevel": "PARENT"
  },
  {
    "id": 1002,
    "name": "Drinks",
    "hierarchyLevel": "PARENT"
  }
]

Example, level = CHILD

This API cal returns only the option-group categories. Useful if you want to enumerate the option groups available in a catalog, separately from the products.

GET /api/v1/user/stores/12345/catalog/678/categories/name?level=CHILD

Authorization: Bearer <token>

Sample Response (illustrative)

[
  {
    "id": 2001,
    "name": "Pizza Toppings",
    "hierarchyLevel": "ITEM_GROUP"
  },
  {
    "id": 2002,
    "name": "Drink Size",
    "hierarchyLevel": "ITEM_GROUP"
  }
]

Key Notes to Remember When Using API 2

  • Like API 1, level is case-sensitive. Therefore, lower-case or mixed-case values are rejected with
    HTTP 400.
  • A catalog with zero categories at the requested level returns an empty array (HTTP 200) rather than
    404.
  • If the catalogId does not belong to the supplied storeId, the call returns HTTP 404.

Recommended Usage for a POS Integration

Most POS integrations are best served by a single full-catalog import, followed by targeted refreshes. Here are some recommendations when using fetching catalog from the GonnaOrder API:

  • Use GET /api/v1/user/stores/{storeId}/catalog?level=FULL for the initial catalog sync or after major catalog updates.
  • Use GET /api/v1/user/stores/{storeId}/catalog?level=PARENT for fast price or availability refreshes.
  • Use GET /api/v1/user/stores/{storeId}/catalog?level=CHILD when refreshing option-group items only.
  • Use GET /api/v1/user/stores/{storeId}/catalog/{catalogId}/categories/name?level=PARENT to render a category navigation menu on the POS UI.

Common Error Responses

HTTP status Meaning Resolution
400 Bad Request Invalid level value Resend using supported upper-case values
401 Unauthorized Missing or expired Bearer token Refresh the access token and retry
403 Forbidden API user has no access to the store Verify store assignment
404 Not Found Store or catalog not found or catalog does not belong to the store. Verify storeId and catalogId
5xx Server-side error Retry with exponential backoff. Contact GonnaOrder support if the error persists.

Backwards compatibility

The level parameter is optional on both endpoints. Omitting it does not affect the response of the existing integrations. You can adopt the level parameter incrementally, endpoint by endpoint and call site by call site, with no coordination window required.