API Reference

🧭 Onboarding sequence

The Onboarding sequence shows the order in which you create KitchenHub objects for a new location of your customer, from the access token to the first order. Each step produces a value or a state that the next step needs, and names the equivalent action in the Admin Dashboard where one exists.

The examples reuse the same identifiers throughout: location_id location-test212, store_id store-test212, provider_id doordash_pos, integration_id integration-test212.

For the entity model behind location and store, see 📍 Locations & Stores API.


🔐 Preparation

Run these two steps once per customer account.

Get an access token

Requires: client_id and client_secret issued by KitchenHub.

Endpoint:

POST https://api.kitchenhub.app/v2/auth/token/

Request Body:

{
  "client_id": "kh_client_7f21a9",
  "client_secret": "kh_secret_4c8e2b"
}

You receive an access token and a refresh token in the response. The access token stays valid for 30 minutes. Send it as Authorization: Bearer <access token> in every API request below.

Reference: Create pair tokens

Set up the webhooks

Requires: access_token, and an HTTPS endpoint on your side that accepts POST.

Register the webhooks before you create the location.

Endpoint:

POST https://api.kitchenhub.app/v2/webhooks/

Request Body:

{
  "url": "https://partner.example.com/kitchenhub/events",
  "version": 2,
  "webhook_type": "Order",
  "filters": {},
  "authorization_headers": {}
}

You receive the created webhook in the response.

📘

One webhook per event type, not one per location

KitchenHub sends the events of every store to the same endpoint, so route them by store_id on your side.

For the event types, the versions each one accepts and the payload of each one, see 🪝 Webhooks API.

Reference: Create webhook


📍 Step 1. Create the location

Requires: access_token, and the street address of the venue.

When the location is not in America/New_York, pass location_timezone. KitchenHub applies America/New_York when the field is absent.

❗

Set the timezone explicitly

A wrong timezone shifts the working hours and the scheduled orders of the location by the offset between the two zones.

Endpoint:

POST https://api.kitchenhub.app/v2/locations/

Request Body:

{
  "location_name": "Downtown Restaurant",
  "location_street": "123 Main St",
  "location_city": "New York",
  "location_state": "NY",
  "location_zipcode": "10001",
  "location_country": "US",
  "location_timezone": "America/New_York",
  "partner_location_id": "partner-location-001",
  "restaurant_delivery_time": 30
}

You receive the created location in the response. Take id from it and use it as location_id to create the store.

Reference: Create location

Create the location in the Admin Dashboard

Go to the Locations section and add the location with the New button.

To read the location and its id afterwards, call Get location list.


🏪 Step 2. Create the store

Requires: access_token, and location_id from step 1.

Endpoint:

POST https://api.kitchenhub.app/v2/stores/

Request Body:

{
  "location_id": "location-test212",
  "store_name": "Main Brand",
  "partner_store_id": "partner-store-001",
  "auto_accept_enabled": false,
  "auto_accept_cooking_time": 20,
  "auto_complete_enabled": true,
  "restaurant_delivery_time": 30
}

You receive the created store in the response. Take id from it and use it as store_id in the following steps.

Reference: Create store

Create the store in the Admin Dashboard

Expand the location you created and click Add store. In the store settings you set the auto-accept mode and the other store settings.

To read the store_id afterwards, call Get list of stores.


📄 Step 3. Upload the menu to KitchenHub

Requires: access_token, and store_id from step 2.

Uploading the menu before you connect a provider is good practice: you check the menu in KitchenHub first, and some providers require a menu for the connection. Until the menu arrives, the integration account of such a provider stays in waiting_menu.

Endpoint:

PUT https://api.kitchenhub.app/v2/stores/store-test212/menu/

Request Body:

{
  "menu": {
    "partner_id": "menu-001",
    "name": "Main Menu",
    "description": null,
    "media_url": null,
    "partner_categories": ["cat-beverages"]
  },
  "categories": [
    {
      "partner_id": "cat-beverages",
      "title": "Beverages",
      "description": null,
      "is_deactivated": false,
      "partner_items": ["item-cola"],
      "partner_availability": null
    }
  ],
  "items": [
    {
      "partner_id": "item-cola",
      "name": "Can of Soda",
      "description": null,
      "is_deactivated": false,
      "price": 3.35,
      "is_alcohol": false,
      "partner_modifiers": [],
      "partner_availability": null
    }
  ],
  "modifiers": [],
  "options": [],
  "availabilities": []
}

The call is asynchronous. You receive a confirmation that the update started, not the result of the update.

For the menu model, field limits and image requirements, see 📄 Menu API.

Reference: Update Menu for Store


👀 Step 4. Verify the menu and send a test order in the Admin Dashboard

Open the store in the Admin Dashboard and go to Settings → Menu → Preview. The preview shows the items, their images, their modifiers and their prices as the marketplace receives them.

Send a test order from Settings → Menu → Preview. The test order shows that your endpoint receives the Order notification and that your service writes the status back.

To accept, cancel or complete the test order, call Change order status.


📦 Step 5. List the providers

Skip this step when you connect the provider through the Admin Dashboard.

Requires: access_token.

Endpoint:

GET https://api.kitchenhub.app/v2/providers/

The endpoint returns the providers and the capabilities of each one.

Reference: Get information about all integration


🔗 Step 6. Create the integration account

Requires: access_token, store_id from step 2, provider_id from step 5, and a redirect URL on your side.

Endpoint:

POST https://api.kitchenhub.app/v2/integration_accounts/

Request Body:

{
  "provider_id": "doordash_pos",
  "store_id": "store-test212",
  "redirect_url": "https://partner.example.com/kitchenhub/connected"
}

You receive integration_account_id and url in the response. url points to the connector page.

Reference: Create integration accounts

Connect the provider in the Admin Dashboard

Go to the Providers section, click Add more and pick the provider.

To read the integration_id once you finish the connection in step 7, call Get all your integration accounts.


🧾 Step 7. Open the connector page for the restaurant

Requires: url from step 6, and the provider credentials held by the restaurant owner or manager.

Open the url in the browser of the restaurant owner or manager. They fill in their credentials or authorize access and submit the form. KitchenHub finalizes the connection in the background.

The browser lands on the redirect URL you passed in step 6, or on the dashboard when you started from the dashboard.

Each provider runs its own connection flow. Some establish the integration immediately; others take several days.


🔄 Step 8. Get the integration status

Requires: access_token, and integration_id from step 6.

Wait for the notification on your webhook, or poll until the account reports connected.

Endpoint:

GET https://api.kitchenhub.app/v2/integration_accounts/integration-test212/

You receive the integration account with its connection status, which is one of waiting_menu, in_progress, waiting, connected, rejected, disabled.

Reference: Get your integration account


🕐 Step 9. Set the working hours

Requires: access_token, and integration_id from step 6.

Before you push the working hours, poll the menu upload status until the provider reports completed, or wait for the MenuIntegrationStatus notification on your webhook.

Endpoint:

PUT https://api.kitchenhub.app/v2/integration_accounts/integration-test212/working_hours/

Request Body:

{
  "working_hours": [
    {
      "days": ["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY"],
      "time_slots": [{ "start_time": "09:00", "end_time": "22:00" }]
    },
    {
      "days": ["SATURDAY", "SUNDAY"],
      "time_slots": [{ "start_time": "10:00", "end_time": "23:00" }]
    }
  ],
  "working_hours_overrides": [
    {
      "service_type": "PICKUP",
      "overrides": [
        {
          "days": ["SATURDAY", "SUNDAY"],
          "time_slots": [{ "start_time": "10:00", "end_time": "20:00" }]
        }
      ]
    }
  ]
}

You receive the stored working hours in the response.

References: Get menu upload status description, Create integration account working hours

Set the working hours in the Admin Dashboard

Set them in the Working hours section.


📅 Step 10. Set the closing days

Requires: access_token, integration_id from step 6, and the complete list of dates the store stays closed.

Send the complete list on every call. KitchenHub removes the closing days stored on the account that are absent from the list.

Endpoint:

PUT https://api.kitchenhub.app/v2/integration_accounts/integration-test212/closing_days/

Request Body:

{
  "days": ["2026-12-25", "2027-01-01"]
}

You receive the stored closing days in the response.

Reference: Create integration account closing days

Set the closing days in the Admin Dashboard

Set them in the Closing days section.


🛒 Step 11. Send an end-to-end test order from the provider

Requires: an integration in connected, and access to the provider account of the restaurant.

Place a test order on the provider side for the store you onboarded.

Your endpoint receives the Order notification. To accept, cancel or complete the order, call Change order status.


⏸️ Step 12. Pause the store

Requires: access_token, and integration_id from step 6.

The store now takes orders. To pause it, set its online status to false. A paused store does not accept orders.

Endpoint:

PUT https://api.kitchenhub.app/v2/integration_accounts/integration-test212/status/

Request Body:

{
  "online": false
}

For a pause longer than a week or two, we recommend disconnecting the integration instead.

References: Update integration online status, Delete your integration account