Blizzfull API

Start integrating with Claude

Read a restaurant's menu, keep it in sync, and put orders into its kitchen.

Open in ClaudeOpen in Codex

Claude opens with the prompt below. In Codex, Claude Code or any other agent, paste it.

The prompt
Help me integrate with the Blizzfull API: read a restaurant's menu, keep it in sync, and put orders into its kitchen.

Read the whole reference first. It is one Markdown file: https://blizzfull.com/llms-full.txt
The OpenAPI 3.1.1 document: https://blizzfull.com/developer/openapi.json

Then ask me what I'm building (menu sync, placing pickup orders, or a point-of-sale integration that picks up and accepts orders) and in which language, and write it against the sandbox first.
Every request sends the X-Blizzfull-API-User and X-Blizzfull-API-Token headers. My keys come from my Blizzfull contact.
Base URL
https://apiv2.blizzfull.com
Auth
Two headers
Spec
OpenAPI 3.1.1, version 2.8.0
Calls
21

Getting started

The Blizzfull API connects point-of-sale systems, ordering partners and AI agents to Blizzfull restaurants.

Getting access

Every request sends an API user and token. Ask your Blizzfull contact for a key; you get a sandbox key first. There are two kinds:

  • Ordering key, for a partner that places orders for one restaurant, such as an AI phone agent. It reads that restaurant's storefront and menu feed, places orders, and reads back the orders it placed. Nothing else: not the restaurant's other orders, its settings or its reports.
  • Restaurant key, for point-of-sale and menu integrations. It belongs to one restaurant (or to a partner's restaurants) and can be narrowed to the calls it needs.

Conventions

  • Base URL: https://apiv2.blizzfull.com.
  • Envelope: a successful response is {"response": ...}.
  • Errors: a refusal is the HTTP status with {"response": "<what to fix>"}. A failure inside the order or menu engine is HTTP 400 with {"type": "exception", "message": ..., "code": ...}.
  • Money: orders (StandardOrder) use integer cents. Menus use dollars: numbers when you send them, decimal strings in the feed.
  • Time: ISO 8601, UTC.
  • IDs: Blizzfull's IDs. A menu import uses your own IDs, and Blizzfull remembers the mapping.
  • Rate limits: 30 requests a minute per key and from each IP address, and 30 order or menu creations every 5 minutes per key. Over a limit you get HTTP 429 with Retry-After: wait that long, then send the request again (an order with the same tempID).
  • Compatibility: fields are added without notice; ignore the ones you don't use.

Machine-readable

This document and its schemas are served from https://apiv2.blizzfull.com/schema/: openapi.json, standard-order.schema.json, menu-feed.schema.json and blizzfullMenuSchema.json (JSON Schema 2020-12).

Authentication

Send both headers with every request. A key belongs to one restaurant, or to a partner's restaurants.

Server: https://apiv2.blizzfull.com (Production)

Every request: Get the live menu

curl
curl -G "https://apiv2.blizzfull.com/items/getFullMenu" \
  -d "restaurantID=$RESTAURANT_ID" \
  -d "locationID=1" \
  -H "X-Blizzfull-API-User: $BLIZZFULL_API_USER" \
  -H "X-Blizzfull-API-Token: $BLIZZFULL_API_TOKEN"
JavaScript
const query = new URLSearchParams({
  restaurantID: process.env.RESTAURANT_ID,
  locationID: '1',
});
const res = await fetch(`https://apiv2.blizzfull.com/items/getFullMenu?${query}`, {
  headers: {
    'X-Blizzfull-API-User': process.env.BLIZZFULL_API_USER,
    'X-Blizzfull-API-Token': process.env.BLIZZFULL_API_TOKEN,
  },
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const { response } = await res.json();
Python
import os

import requests

res = requests.get(
    "https://apiv2.blizzfull.com/items/getFullMenu",
    headers={
        "X-Blizzfull-API-User": os.environ["BLIZZFULL_API_USER"],
        "X-Blizzfull-API-Token": os.environ["BLIZZFULL_API_TOKEN"],
    },
    params={"restaurantID": os.environ["RESTAURANT_ID"], "locationID": 1},
    timeout=30,
)
res.raise_for_status()
response = res.json()["response"]
A refusal · 401
{
  "response": "Unauthorized"
}

Restaurant

The restaurant's storefront: where it is, when it takes pickup orders and how long they take.

Get the storefront

GET /restaurants/{restaurantId}

What your callers need to know about the restaurant: where it is, its phone number, when it takes pickup orders, how long they take, and its sales tax rate.

Placing an order does not check these. Check takingOrders, closedUntil and hoursDataPickup before you offer pickup, and quote busyModePickupTime while busyMode is on (otherwise pickupTime).

Parameters

Responses

  • 200

    The storefront.

    • responseobjectRequired

      What a caller needs to know about the restaurant, at the location you order for. An ordering key gets exactly these fields.

      • idstringRequired

        The Blizzfull restaurant ID.

      • namestringRequired

        The restaurant's name.

      • The restaurant's description, as its website shows it. May be empty.

      • phonestringRequired

        The restaurant's phone number, digits only.

      • Street address. May be empty.

      • citystring

        City.

      • statestring

        Two-letter state code.

      • zipstring

        ZIP code.

      • Where the restaurant is.

      • timeZonestringRequired

        IANA time zone. Hours and times below are in it.

        Example
        "America/Los_Angeles"
      • taxRatenumberRequired

        Sales tax, as a percentage (8.25 is 8.25%). Blizzfull adds it to every order.

        Example
        8.25
      • takingOrdersstringRequired

        "1" while the restaurant takes online orders; "0" when it has turned them off.

        One of
        "0" "1"
      • closedUntilintegerRequired

        Unix seconds: the restaurant has paused online orders until then. 0 or a time already past means it has not.

      • hoursDataPickuparrayRequired

        Pickup hours: [weekly, dates]. weekly has seven entries, Sunday first; each is a list of [open, close] pairs in minutes after local midnight ([[660, 1260]] is 11 AM to 9 PM), and an empty list is closed. dates is [], or an object keyed MM/DD whose hours replace the weekly ones on that date.

        Length
        Exactly 2 items
      • pickupTimestringRequired

        The usual minutes until a pickup order is ready, as a decimal string.

        Example
        "15"
      • busyModeboolean

        True while the restaurant is busy and quoting longer times.

      • While busyMode is on, the minutes it quotes for pickup (0 when not set: use pickupTime).

      • What to tell the customer about picking up. May be empty.

  • 401

    The API user or token is missing or wrong.

    { "response": string }

    Example {"response":"Unauthorized"}

  • 403

    The key may not make this call, or not for this restaurant or order.

    { "response": string }

  • 429

    Over the rate limit. Wait Retry-After seconds.

    { "response": string }

    Header Retry-After integer Seconds to wait.

Operation ID getStorefront

Example request

curl
curl "https://apiv2.blizzfull.com/restaurants/$RESTAURANT_ID" \
  -H "X-Blizzfull-API-User: $BLIZZFULL_API_USER" \
  -H "X-Blizzfull-API-Token: $BLIZZFULL_API_TOKEN"
JavaScript
const res = await fetch(`https://apiv2.blizzfull.com/restaurants/${process.env.RESTAURANT_ID}`, {
  headers: {
    'X-Blizzfull-API-User': process.env.BLIZZFULL_API_USER,
    'X-Blizzfull-API-Token': process.env.BLIZZFULL_API_TOKEN,
  },
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const { response } = await res.json();
Python
import os

import requests

res = requests.get(
    f"https://apiv2.blizzfull.com/restaurants/{os.environ['RESTAURANT_ID']}",
    headers={
        "X-Blizzfull-API-User": os.environ["BLIZZFULL_API_USER"],
        "X-Blizzfull-API-Token": os.environ["BLIZZFULL_API_TOKEN"],
    },
    timeout=30,
)
res.raise_for_status()
response = res.json()["response"]
Example response · 200
{
  "response": {
    "id": "1234",
    "name": "Example Wings",
    "description": "Fresh wings and tenders, breaded to order.",
    "phone": "5555550100",
    "streetAddress": "100 Main Street",
    "city": "Bakersfield",
    "state": "CA",
    "zip": "93306",
    "geoLocation": {
      "latitude": 35.3926,
      "longitude": -118.9663
    },
    "timeZone": "America/Los_Angeles",
    "taxRate": 8.25,
    "takingOrders": "1",
    "closedUntil": 0,
    "hoursDataPickup": [
      [
        [
          [
            660,
            1260
          ]
        ],
        [
          [
            660,
            1260
          ]
        ],
        [
          [
            660,
            1260
          ]
        ],
        [
          [
            660,
            1260
          ]
        ],
        [
          [
            660,
            1260
          ]
        ],
        [
          [
            660,
            1320
          ]
        ],
        [
          [
            660,
            1320
          ]
        ]
      ],
      []
    ],
    "pickupTime": "15",
    "busyMode": false,
    "busyModePickupTime": 25,
    "pickupInstructions": ""
  }
}

Orders

Place orders into a restaurant and read them back as StandardOrder.

Place an order

POST /orders

Needs an ordering key. Places a pickup order at your key's restaurant, exactly as you send it: your lines, choices and prices are the order. Blizzfull adds tax, submits it to the restaurant like any online order (their tablet, printers and point of sale take it from there), and returns it as a StandardOrder with the order number and total.

The customer pays at pickup. The order shows in the restaurant's reports as a phone order.

Retries are safe: send a tempID. If a request times out, send the same body again; an order already placed with that tempID in the last 24 hours comes back (HTTP 200) instead of a second one being made.

Building lines: take each item's id, size id and choices from the menu feed. totalPrice is the line's total in cents (item, size and options, times quantity) and becomes the line's price. Every line needs its name and totalPrice, so an item the menu no longer has is still recorded as the caller ordered it.

Refused, not dropped (HTTP 412): payments (transactions), extraCharges, a line's customPrice or taxExempt, rewards and gift cards, and an item from another restaurant's menu. Any field not listed below is ignored.

The response's customer is the name and phone you sent; there is no customer account behind it.

Request body application/json · required

A pickup order, in StandardOrder's shape. Only these fields are read.

  • tempIDstring

    Your reference for this order, 1 to 8 letters, digits, - or _, unique per order. Makes retries safe.

    Pattern
    ^[A-Za-z0-9_-]{1,8}$
  • typestringRequired
    One of
    "PICKUP"
  • isFutureboolean

    True for an order scheduled for fulfillmentTime. Leave out for as soon as possible.

  • fulfillmentTimestring (date-time)

    When the customer will pick up, with an offset. Read only when isFuture is true.

  • Alternative to isFuture + fulfillmentTime: the pickup time in Unix seconds. 0 means as soon as possible.

  • customerobjectRequired

    The caller. The order is a guest order: this name and phone stay on it and are never matched to, created as or saved on a Blizzfull customer account.

    • namestring

      Required (or firstName): staff call it out at pickup and it prints on the ticket. Split into first and last name at the first space.

    • firstNamestring
    • lastNamestring
    • phonestringRequired

      The callback number; at least 10 digits, any formatting.

      Example
      "(661) 555-0177"
    • phoneExtstring
  • notestring

    Instructions for the whole order.

  • itemsobject[]Required
    Length
    At least 1 item
    • idobjectRequired
      • internalintegerRequired

        The item's id from the menu feed.

    • namestringRequired

      The item's name, as the caller ordered it.

    • quantityinteger
      Default
      1
      Range
      At least 1
    • totalPriceintegerRequired

      The line total in cents: item, size and options, times quantity.

      Range
      More than 0
    • sizeobject
      • idobject
        • internalstring | integer

          The size's id from the menu feed.

    • The caller's choices, as StandardOrder's OptionGroupSelection: each group's optionGroupId with its selections (optionItemId, selected), and sub-options one level deep. List what differs from the menu's defaults. Anything else in this list is refused (412).

    • notestring

      Instructions for this line.

  • discountsobject[]

    Order-level discounts. Their amounts are added up and taken off the order (never below zero); names are not kept.

Responses

  • 200

    A retry with a tempID already used: the order the first request placed.

    { "response": { "order": StandardOrder } }

  • 201

    Placed.

    { "response": { "order": StandardOrder } }

  • 400

    The order engine couldn't take the order, for example a choice that isn't on the item.

    { "type": "exception", "message": string, "code": integer, "trace": null, "request": string }

  • 401

    The API user or token is missing or wrong.

    { "response": string }

    Example {"response":"Unauthorized"}

  • 403

    The key may not make this call, or not for this restaurant or order.

    { "response": string }

  • 412

    Refused: the message names the field to fix.

    { "response": string }

    Example {"response":"items[0].totalPrice must be the line total in cents"}

  • 429

    Over the rate limit. Wait Retry-After seconds.

    { "response": string }

    Header Retry-After integer Seconds to wait.

Operation ID createOrder

Example request

curl
curl "https://apiv2.blizzfull.com/orders" \
  -H "X-Blizzfull-API-User: $BLIZZFULL_API_USER" \
  -H "X-Blizzfull-API-Token: $BLIZZFULL_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tempID": "kp1001",
    "type": "PICKUP",
    "isFuture": true,
    "fulfillmentTime": "2026-10-28T19:30:00-07:00",
    "customer": {
      "name": "Dana Rivera",
      "phone": "(661) 555-0177"
    },
    "note": "Called in by phone",
    "items": [
      {
        "id": {
          "internal": 166519
        },
        "name": "Hungry Combo",
        "quantity": 1,
        "totalPrice": 1650,
        "optionSelections": [
          {
            "optionGroupId": "216385",
            "selections": [
              {
                "optionItemId": "441415",
                "selected": 1
              }
            ]
          },
          {
            "optionGroupId": "216386",
            "selections": [
              {
                "optionItemId": "441417",
                "selected": 1
              }
            ]
          }
        ],
        "note": "Sauce on the side"
      }
    ]
  }'
JavaScript
const res = await fetch('https://apiv2.blizzfull.com/orders', {
  method: 'POST',
  headers: {
    'X-Blizzfull-API-User': process.env.BLIZZFULL_API_USER,
    'X-Blizzfull-API-Token': process.env.BLIZZFULL_API_TOKEN,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "tempID": "kp1001",
    "type": "PICKUP",
    "isFuture": true,
    "fulfillmentTime": "2026-10-28T19:30:00-07:00",
    "customer": {
      "name": "Dana Rivera",
      "phone": "(661) 555-0177"
    },
    "note": "Called in by phone",
    "items": [
      {
        "id": {
          "internal": 166519
        },
        "name": "Hungry Combo",
        "quantity": 1,
        "totalPrice": 1650,
        "optionSelections": [
          {
            "optionGroupId": "216385",
            "selections": [
              {
                "optionItemId": "441415",
                "selected": 1
              }
            ]
          },
          {
            "optionGroupId": "216386",
            "selections": [
              {
                "optionItemId": "441417",
                "selected": 1
              }
            ]
          }
        ],
        "note": "Sauce on the side"
      }
    ]
  }),
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const { response } = await res.json();
Python
import os

import requests

res = requests.post(
    "https://apiv2.blizzfull.com/orders",
    headers={
        "X-Blizzfull-API-User": os.environ["BLIZZFULL_API_USER"],
        "X-Blizzfull-API-Token": os.environ["BLIZZFULL_API_TOKEN"],
    },
    json={
        "tempID": "kp1001",
        "type": "PICKUP",
        "isFuture": True,
        "fulfillmentTime": "2026-10-28T19:30:00-07:00",
        "customer": {
            "name": "Dana Rivera",
            "phone": "(661) 555-0177",
        },
        "note": "Called in by phone",
        "items": [
            {
                "id": {
                    "internal": 166519,
                },
                "name": "Hungry Combo",
                "quantity": 1,
                "totalPrice": 1650,
                "optionSelections": [
                    {
                        "optionGroupId": "216385",
                        "selections": [
                            {
                                "optionItemId": "441415",
                                "selected": 1,
                            },
                        ],
                    },
                    {
                        "optionGroupId": "216386",
                        "selections": [
                            {
                                "optionItemId": "441417",
                                "selected": 1,
                            },
                        ],
                    },
                ],
                "note": "Sauce on the side",
            },
        ],
    },
    timeout=30,
)
res.raise_for_status()
response = res.json()["response"]
Example response · 201
{
  "response": {
    "order": {
      "id": {
        "internal": "2303306",
        "external": null
      },
      "status": "SUBMITTED",
      "type": "PICKUP",
      "sourcePlatform": "phone",
      "isFuture": true,
      "pickupTime": "2026-10-29T02:30:00+00:00",
      "fulfillmentTime": "2026-10-29T02:30:00+00:00",
      "taxRate": "8.2500",
      "processingVia": "manual",
      "merchant": {
        "name": "Example Wings",
        "id": {
          "internal": "1234",
          "external": null
        },
        "timezone": "America/Los_Angeles"
      },
      "customer": {
        "id": "",
        "name": "Dana Rivera",
        "phone": "+16615550177",
        "phoneExt": ""
      },
      "items": [
        {
          "quantity": 1,
          "orderItemID": 1,
          "id": {
            "internal": 166519,
            "external": null
          },
          "name": "Hungry Combo",
          "note": "Sauce on the side",
          "unitPrice": 1650,
          "totalPrice": 1650,
          "taxRate": 8.25,
          "optionSelections": [
            {
              "optionGroupId": "216385",
              "selections": [
                {
                  "optionItemId": "441415",
                  "selected": 1
                }
              ]
            },
            {
              "optionGroupId": "216386",
              "selections": [
                {
                  "optionItemId": "441417",
                  "selected": 1
                }
              ]
            }
          ]
        }
      ],
      "totals": {
        "subtotal": 1650,
        "tip": 0,
        "extraCharge": 0,
        "deliveryFee": 0,
        "tax": 136,
        "dspWithheldTax": 0,
        "total": 1786,
        "discount": 0,
        "paid": 0,
        "balanceOwed": 1786
      },
      "transactions": []
    }
  }
}

Get an order

GET /orders/{orderId}/getWithRestaurantStd

One order as a StandardOrder, with the restaurant details a receipt needs. Use it to check an order's status (SUBMITTED, ACCEPTED, FULFILLED, CANCELED) and ready time.

An ordering key reads only the orders it placed, without the payment staff take at pickup (transactions is empty; totals still shows what is paid and owed). A restaurant key reads any order at its restaurant.

Parameters

  • orderIdpathstringRequired

    The order number (id.internal), or ex-<n> for a marketplace order.

    Pattern
    ^(ex-)?[1-9][0-9]*$

Responses

  • 200

    The order.

  • 401

    The API user or token is missing or wrong.

    { "response": string }

    Example {"response":"Unauthorized"}

  • 403

    The key may not make this call, or not for this restaurant or order.

    { "response": string }

  • 429

    Over the rate limit. Wait Retry-After seconds.

    { "response": string }

    Header Retry-After integer Seconds to wait.

Operation ID getOrder

Example request

curl
curl "https://apiv2.blizzfull.com/orders/$ORDER_ID/getWithRestaurantStd" \
  -H "X-Blizzfull-API-User: $BLIZZFULL_API_USER" \
  -H "X-Blizzfull-API-Token: $BLIZZFULL_API_TOKEN"
JavaScript
const res = await fetch(`https://apiv2.blizzfull.com/orders/${process.env.ORDER_ID}/getWithRestaurantStd`, {
  headers: {
    'X-Blizzfull-API-User': process.env.BLIZZFULL_API_USER,
    'X-Blizzfull-API-Token': process.env.BLIZZFULL_API_TOKEN,
  },
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const { response } = await res.json();
Python
import os

import requests

res = requests.get(
    f"https://apiv2.blizzfull.com/orders/{os.environ['ORDER_ID']}/getWithRestaurantStd",
    headers={
        "X-Blizzfull-API-User": os.environ["BLIZZFULL_API_USER"],
        "X-Blizzfull-API-Token": os.environ["BLIZZFULL_API_TOKEN"],
    },
    timeout=30,
)
res.raise_for_status()
response = res.json()["response"]

Point of sale

For point-of-sale partners: pick up new orders, marketplace orders included, and run them through to done.

Also for this group: Send your point of sale's menu (POST /menu/importExternalPOSMenu/{posName}, under Menu); Get an order in your ticket format (GET /orders/{orderId}, under Order feed).

List orders by day

GET /orders

A restaurant's Blizzfull orders by the day they were placed, in any status, newest first: for order history, and for catching up after your system was down. Orders come in Blizzfull's internal format, as /orders/poll gives them without posToMap. Marketplace orders have their own list, /orders/marketplace.

Parameters

  • restaurantIDqueryintegerRequired

    The restaurant's ID.

    Range
    At least 1
  • dateFilterquerystringRequired

    <first day>,<last day>: the restaurant's own days, both included.

    Example
    "2026-11-01,2026-11-03"
    Pattern
    ^[0-9]{4}-[0-9]{2}-[0-9]{2},[0-9]{4}-[0-9]{2}-[0-9]{2}$
  • statusFilterquerystring

    notopen is every placed order.

    One of
    "notopen" "submitted" "closed" "canceled"
    Default
    "notopen"
  • offsetqueryinteger
    Default
    0
    Range
    At least 0
  • limitqueryinteger
    Default
    100
    Range
    At least 1

Responses

  • 200

    One page of orders.

    • responseobjectRequired

      One page of orders.

      • resultobject[]Required
        • idstringRequired
          Pattern
          ^(ex-)?[1-9][0-9]*$
        • statusstringRequired
      • totalFoundinteger | stringRequired

        How many orders match, on every page.

  • 401

    The API user or token is missing or wrong.

    { "response": string }

    Example {"response":"Unauthorized"}

  • 403

    The key may not make this call, or not for this restaurant or order.

    { "response": string }

  • 412

    dateFilter is missing.

    { "response": string }

    Example {"response":"dateFilter required"}

  • 429

    Over the rate limit. Wait Retry-After seconds.

    { "response": string }

    Header Retry-After integer Seconds to wait.

Operation ID listOrders

Example request

curl
curl -G "https://apiv2.blizzfull.com/orders" \
  -d "restaurantID=$RESTAURANT_ID" \
  -d "dateFilter=2026-11-01,2026-11-03" \
  -H "X-Blizzfull-API-User: $BLIZZFULL_API_USER" \
  -H "X-Blizzfull-API-Token: $BLIZZFULL_API_TOKEN"
JavaScript
const query = new URLSearchParams({
  restaurantID: process.env.RESTAURANT_ID,
  dateFilter: '2026-11-01,2026-11-03',
});
const res = await fetch(`https://apiv2.blizzfull.com/orders?${query}`, {
  headers: {
    'X-Blizzfull-API-User': process.env.BLIZZFULL_API_USER,
    'X-Blizzfull-API-Token': process.env.BLIZZFULL_API_TOKEN,
  },
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const { response } = await res.json();
Python
import os

import requests

res = requests.get(
    "https://apiv2.blizzfull.com/orders",
    headers={
        "X-Blizzfull-API-User": os.environ["BLIZZFULL_API_USER"],
        "X-Blizzfull-API-Token": os.environ["BLIZZFULL_API_TOKEN"],
    },
    params={"restaurantID": os.environ["RESTAURANT_ID"], "dateFilter": "2026-11-01,2026-11-03"},
    timeout=30,
)
res.raise_for_status()
response = res.json()["response"]

Pick up new orders

GET /orders/poll

Orders submitted (or accepted) since a time you give, for a point of sale to take into its own ticket flow. Poll every few seconds with the time of the newest order you have.

Orders come in Blizzfull's internal order format; with posToMap, each is transformed into your integration's ticket format.

Parameters

  • orderListquerystringRequired

    <unix seconds>,<0|1>: orders submitted after that time, or with ,1, orders accepted after it.

    Example
    "1793142409,0"
    Pattern
    ^[0-9]+(,[01])?$
  • posToMapquerystring

    Your integration's name: returns each order in your ticket format, using the restaurant's item mapping.

  • 1 also returns marketplace orders Blizzfull relays, when they arrive. Requires posToMap. /orders/marketplace lists them by day, and the order feed says when one changes.

    One of
    0 1
  • returnRawqueryinteger

    1 returns the order list itself, without the response.orderList.data wrapping.

    One of
    0 1

Responses

  • 200

    The new orders; orderList is absent when there are none.

    { "response": { "orderList": { "data": [object] } } }

  • 401

    The API user or token is missing or wrong.

    { "response": string }

    Example {"response":"Unauthorized"}

  • 404

    posToMap names an integration the restaurant doesn't have.

    { "response": string }

  • 412

    Refused: the message names the field to fix.

    { "response": string }

    Example {"response":"items[0].totalPrice must be the line total in cents"}

  • 429

    Over the rate limit. Wait Retry-After seconds.

    { "response": string }

    Header Retry-After integer Seconds to wait.

Operation ID pollOrders

Example request

curl
curl -G "https://apiv2.blizzfull.com/orders/poll" \
  -d "orderList=1793142409,0" \
  -H "X-Blizzfull-API-User: $BLIZZFULL_API_USER" \
  -H "X-Blizzfull-API-Token: $BLIZZFULL_API_TOKEN"
JavaScript
const query = new URLSearchParams({
  orderList: '1793142409,0',
});
const res = await fetch(`https://apiv2.blizzfull.com/orders/poll?${query}`, {
  headers: {
    'X-Blizzfull-API-User': process.env.BLIZZFULL_API_USER,
    'X-Blizzfull-API-Token': process.env.BLIZZFULL_API_TOKEN,
  },
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const { response } = await res.json();
Python
import os

import requests

res = requests.get(
    "https://apiv2.blizzfull.com/orders/poll",
    headers={
        "X-Blizzfull-API-User": os.environ["BLIZZFULL_API_USER"],
        "X-Blizzfull-API-Token": os.environ["BLIZZFULL_API_TOKEN"],
    },
    params={"orderList": "1793142409,0"},
    timeout=30,
)
res.raise_for_status()
response = res.json()["response"]

Accept an order

POST /orders/{orderId}/accept

Confirms an order on the restaurant's behalf with a ready time. The customer is told it was accepted, and a delivery order's courier is booked. Accepting an accepted order changes nothing, so two systems watching one restaurant can't accept it twice.

A marketplace order is the marketplace's to accept, and it usually arrives accepted. Here, this call only says your system has it: a ready time isn't used, and it answers status instead of the times below. One the marketplace canceled, or that is done, answers 409.

Parameters

  • orderIdpathstringRequired

    The order number (id.internal), or ex-<n> for a marketplace order.

    Pattern
    ^(ex-)?[1-9][0-9]*$

Request body application/x-www-form-urlencoded

  • readyTimeinteger

    Minutes until the order is ready. 0 uses the restaurant's default.

  • etastring

    When a delivery courier should pick up, ISO 8601 UTC.

  • busyModeinteger

    1 turns the restaurant's busy mode on, -1 turns it off, 0 (or left out) leaves it as it is.

    One of
    -1 0 1
  • 1 starts a scheduled order now instead of at its scheduled time.

    One of
    0 1
  • 1 accepts a delivery order without booking a courier.

    One of
    0 1

Responses

  • 200

    Accepted.

  • 401

    The API user or token is missing or wrong.

    { "response": string }

    Example {"response":"Unauthorized"}

  • 403

    The key may not make this call, or not for this restaurant or order.

    { "response": string }

  • 409

    A marketplace order that was canceled or is done.

    { "response": string }

    Example {"response":"This marketplace order is canceled."}

  • 429

    Over the rate limit. Wait Retry-After seconds.

    { "response": string }

    Header Retry-After integer Seconds to wait.

Operation ID acceptOrder

Example request

curl
curl "https://apiv2.blizzfull.com/orders/$ORDER_ID/accept" \
  -H "X-Blizzfull-API-User: $BLIZZFULL_API_USER" \
  -H "X-Blizzfull-API-Token: $BLIZZFULL_API_TOKEN" \
  --data-urlencode "readyTime=20"
JavaScript
const res = await fetch(`https://apiv2.blizzfull.com/orders/${process.env.ORDER_ID}/accept`, {
  method: 'POST',
  headers: {
    'X-Blizzfull-API-User': process.env.BLIZZFULL_API_USER,
    'X-Blizzfull-API-Token': process.env.BLIZZFULL_API_TOKEN,
  },
  body: new URLSearchParams({
    "readyTime": 20
  }),
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const { response } = await res.json();
Python
import os

import requests

res = requests.post(
    f"https://apiv2.blizzfull.com/orders/{os.environ['ORDER_ID']}/accept",
    headers={
        "X-Blizzfull-API-User": os.environ["BLIZZFULL_API_USER"],
        "X-Blizzfull-API-Token": os.environ["BLIZZFULL_API_TOKEN"],
    },
    data={
        "readyTime": 20,
    },
    timeout=30,
)
res.raise_for_status()
response = res.json()["response"]

List marketplace orders by day

GET /orders/marketplace

A restaurant's marketplace orders (DoorDash, Uber Eats and the others Blizzfull relays) by the day they arrived, newest first: for catching up after your system was down, and for history. /orders/poll gives the new ones as they come, and the order feed says when one changes.

A marketplace takes its own payment and refunds its own guests. It accepted the order before Blizzfull received it, so these orders usually arrive accepted.

Parameters

  • dateFilterquerystringRequired

    <first day>,<last day>: the restaurant's own days, both included, 31 days at most.

    Example
    "2026-11-01,2026-11-03"
    Pattern
    ^[0-9]{4}-[0-9]{2}-[0-9]{2},[0-9]{4}-[0-9]{2}-[0-9]{2}$
  • statusFilterquerystring

    notopen is all of them.

    One of
    "notopen" "SUBMITTED" "ACCEPTED" "FULFILLED" "CANCELED"
    Default
    "notopen"
  • posToMapquerystring

    Your integration's name, as for /orders/poll: each order comes with your item IDs on its lines.

  • restaurantIDqueryinteger

    For a key that serves several restaurants: which one.

    Range
    At least 1
  • offsetqueryinteger
    Default
    0
    Range
    At least 0
  • limitqueryinteger
    Default
    50
    Range
    1 to 100

Responses

  • 200

    One page of marketplace orders, each in the same format as /orders/poll.

    • responseobjectRequired

      One page of orders.

      • resultobject[]Required
        • idstringRequired
          Pattern
          ^(ex-)?[1-9][0-9]*$
        • statusstringRequired
      • totalFoundinteger | stringRequired

        How many orders match, on every page.

  • 401

    The API user or token is missing or wrong.

    { "response": string }

    Example {"response":"Unauthorized"}

  • 403

    The key may not make this call, or not for this restaurant or order.

    { "response": string }

  • 404

    posToMap names an integration the restaurant doesn't have.

    { "response": string }

  • 412

    dateFilter or statusFilter is not valid, or the key serves several restaurants and restaurantID is missing.

    { "response": string }

    Example {"response":"dateFilter must be <first day>,<last day> as YYYY-MM-DD"}

  • 429

    Over the rate limit. Wait Retry-After seconds.

    { "response": string }

    Header Retry-After integer Seconds to wait.

Operation ID listMarketplaceOrders

Example request

curl
curl -G "https://apiv2.blizzfull.com/orders/marketplace" \
  -d "dateFilter=2026-11-01,2026-11-03" \
  -H "X-Blizzfull-API-User: $BLIZZFULL_API_USER" \
  -H "X-Blizzfull-API-Token: $BLIZZFULL_API_TOKEN"
JavaScript
const query = new URLSearchParams({
  dateFilter: '2026-11-01,2026-11-03',
});
const res = await fetch(`https://apiv2.blizzfull.com/orders/marketplace?${query}`, {
  headers: {
    'X-Blizzfull-API-User': process.env.BLIZZFULL_API_USER,
    'X-Blizzfull-API-Token': process.env.BLIZZFULL_API_TOKEN,
  },
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const { response } = await res.json();
Python
import os

import requests

res = requests.get(
    "https://apiv2.blizzfull.com/orders/marketplace",
    headers={
        "X-Blizzfull-API-User": os.environ["BLIZZFULL_API_USER"],
        "X-Blizzfull-API-Token": os.environ["BLIZZFULL_API_TOKEN"],
    },
    params={"dateFilter": "2026-11-01,2026-11-03"},
    timeout=30,
)
res.raise_for_status()
response = res.json()["response"]
Example response · 200
{
  "response": {
    "result": [
      {
        "id": "ex-284417",
        "status": "accepted"
      }
    ],
    "totalFound": 1
  }
}

Say where an order is now

POST /orders/{orderId}/status

Moves an accepted order on from your kitchen.

  • READY: a pickup or dine-in order closes, and the customer is told it's ready. A delivery order doesn't change, so the customer isn't told it's on its way while it's still in the kitchen. A marketplace is told its order is ready for pickup.
  • OUT_FOR_DELIVERY: a delivery order closes, and the customer is told it's on its way. Anything else answers 409: a pickup doesn't go out, and a marketplace runs its own deliveries.
  • FULFILLED: the order closes, if it hasn't yet. A marketplace is told its order is done.

The customer gets a text when the restaurant has switched on ready texts. Repeating a status changes nothing. Your order feed says ORDER_COMPLETED when an order closes.

Parameters

  • orderIdpathstringRequired

    The order number (id.internal), or ex-<n> for a marketplace order.

    Pattern
    ^(ex-)?[1-9][0-9]*$

Request body application/json · required

  • statusstringRequired
    One of
    "READY" "OUT_FOR_DELIVERY" "FULFILLED"

Responses

  • 200

    The order's status now.

    • responseobjectRequired
      • statusstringRequired

        The order's status now, as StandardOrder names it.

        One of
        "ACCEPTED" "FULFILLED" "CANCELED"
      • lastModifiedintegerRequired

        Unix seconds.

  • 401

    The API user or token is missing or wrong.

    { "response": string }

    Example {"response":"Unauthorized"}

  • 403

    The key may not make this call, or not for this restaurant or order.

    { "response": string }

  • 409

    The order isn't accepted yet, was canceled, or can't take this status.

    { "response": string }

    Example {"response":"Accept the order first."}

  • 412

    status is not one of these.

    { "response": string }

  • 429

    Over the rate limit. Wait Retry-After seconds.

    { "response": string }

    Header Retry-After integer Seconds to wait.

  • 502

    A marketplace order: the marketplace didn't confirm it, so nothing changed. Send it again.

    { "response": string }

Operation ID setOrderStatus

Example request

curl
curl "https://apiv2.blizzfull.com/orders/$ORDER_ID/status" \
  -H "X-Blizzfull-API-User: $BLIZZFULL_API_USER" \
  -H "X-Blizzfull-API-Token: $BLIZZFULL_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "READY"
  }'
JavaScript
const res = await fetch(`https://apiv2.blizzfull.com/orders/${process.env.ORDER_ID}/status`, {
  method: 'POST',
  headers: {
    'X-Blizzfull-API-User': process.env.BLIZZFULL_API_USER,
    'X-Blizzfull-API-Token': process.env.BLIZZFULL_API_TOKEN,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "status": "READY"
  }),
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const { response } = await res.json();
Python
import os

import requests

res = requests.post(
    f"https://apiv2.blizzfull.com/orders/{os.environ['ORDER_ID']}/status",
    headers={
        "X-Blizzfull-API-User": os.environ["BLIZZFULL_API_USER"],
        "X-Blizzfull-API-Token": os.environ["BLIZZFULL_API_TOKEN"],
    },
    json={
        "status": "READY",
    },
    timeout=30,
)
res.raise_for_status()
response = res.json()["response"]
Example response · 200
{
  "response": {
    "status": "FULFILLED",
    "lastModified": 1793742138
  }
}

Cancel an order

POST /orders/{orderId}/cancel

Cancels an order and gives back everything paid, on the payments made. The customer is emailed when the order has their email, a booked courier is canceled, and your order feed says ORDER_CANCELED.

A marketplace order is canceled at the marketplace, which refunds its guest. Your feed says EXTERNAL_ORDER_UPDATED.

Parameters

  • orderIdpathstringRequired

    The order number (id.internal), or ex-<n> for a marketplace order.

    Pattern
    ^(ex-)?[1-9][0-9]*$

Request body application/json · required

  • reasonstringRequired

    Kept on the order.

  • cancelTypeinteger

    1 refunds what was paid. 2 cancels without refunding.

    One of
    1 2
    Default
    1

Responses

  • 200

    The order's status now.

    • responseobjectRequired
      • statusstringRequired

        The order's status now, as StandardOrder names it.

        One of
        "ACCEPTED" "FULFILLED" "CANCELED"
      • lastModifiedintegerRequired

        Unix seconds.

  • 400

    The order engine couldn't take the order, for example a choice that isn't on the item.

    { "type": "exception", "message": string, "code": integer, "trace": null, "request": string }

  • 401

    The API user or token is missing or wrong.

    { "response": string }

    Example {"response":"Unauthorized"}

  • 403

    The key may not make this call, or not for this restaurant or order.

    { "response": string }

  • 409

    The order was already canceled, or was never placed.

    { "response": string }

    Example {"response":"This order was already canceled."}

  • 412

    reason is missing.

    { "response": string }

    Example {"response":"reason required"}

  • 429

    Over the rate limit. Wait Retry-After seconds.

    { "response": string }

    Header Retry-After integer Seconds to wait.

  • 502

    A marketplace order: the marketplace didn't confirm it, so nothing changed. Send it again.

    { "response": string }

Operation ID cancelOrder

Example request

curl
curl "https://apiv2.blizzfull.com/orders/$ORDER_ID/cancel" \
  -H "X-Blizzfull-API-User: $BLIZZFULL_API_USER" \
  -H "X-Blizzfull-API-Token: $BLIZZFULL_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "Customer called to cancel"
  }'
JavaScript
const res = await fetch(`https://apiv2.blizzfull.com/orders/${process.env.ORDER_ID}/cancel`, {
  method: 'POST',
  headers: {
    'X-Blizzfull-API-User': process.env.BLIZZFULL_API_USER,
    'X-Blizzfull-API-Token': process.env.BLIZZFULL_API_TOKEN,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "reason": "Customer called to cancel"
  }),
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const { response } = await res.json();
Python
import os

import requests

res = requests.post(
    f"https://apiv2.blizzfull.com/orders/{os.environ['ORDER_ID']}/cancel",
    headers={
        "X-Blizzfull-API-User": os.environ["BLIZZFULL_API_USER"],
        "X-Blizzfull-API-Token": os.environ["BLIZZFULL_API_TOKEN"],
    },
    json={
        "reason": "Customer called to cancel",
    },
    timeout=30,
)
res.raise_for_status()
response = res.json()["response"]
Example response · 200
{
  "response": {
    "status": "CANCELED",
    "lastModified": 1793742138
  }
}

Give part of an order back

POST /orders/{orderId}/refund

Changes the order, then gives the difference back on the payments made, newest first, so the order stays balanced:

  • items take lines off, or part of a line's quantity.
  • amount comes off as a discount, in cents and tax included, to within a cent.

A card still held before capture is charged less. Any other card is refunded on its original charge. Cash is recorded, and the answer's cash says what to hand back. To give back everything, cancel the order. A marketplace refunds its own orders, so a marketplace order answers 409.

Your order feed says ORDER_UPDATED.

Parameters

  • orderIdpathstringRequired

    The order number (id.internal).

    Pattern
    ^[1-9][0-9]*$

Request body application/json · required

  • reasonstringRequired

    Kept in the order's log.

  • itemsobject[]
    • orderItemIDintegerRequired

      The line's orderItemID.

    • quantityintegerRequired

      How many to take off. All of them removes the line.

      Range
      At least 1
  • amountinteger

    Cents to give back, tax included.

    Range
    At least 1

Responses

  • 200

    What went back.

    • responseobjectRequired
      • refundedintegerRequired

        Cents given back now.

      • cashintegerRequired

        Of those, the cents paid in cash: hand them back at the counter.

      • pendingintegerRequired

        Cents still to go back.

      • willRetrybooleanRequired

        Blizzfull retries pending later (a card that hasn't settled, within 12 hours). When false and pending is above 0, the restaurant's staff settle it from the order in their dashboard.

      • lastModifiedintegerRequired

        Unix seconds.

  • 400

    The order engine couldn't take the order, for example a choice that isn't on the item.

    { "type": "exception", "message": string, "code": integer, "trace": null, "request": string }

  • 401

    The API user or token is missing or wrong.

    { "response": string }

    Example {"response":"Unauthorized"}

  • 403

    The key may not make this call, or not for this restaurant or order.

    { "response": string }

  • 409

    The order was canceled or was never placed, or it is a marketplace order.

    { "response": string }

    Example {"response":"A marketplace refunds its own orders."}

  • 412

    reason, items or amount isn't valid, or amount is more than was paid.

    { "response": string }

    Example {"response":"Send items or amount. To refund everything, cancel the order."}

  • 429

    Over the rate limit. Wait Retry-After seconds.

    { "response": string }

    Header Retry-After integer Seconds to wait.

Operation ID refundOrder

Example request

curl
curl "https://apiv2.blizzfull.com/orders/$ORDER_ID/refund" \
  -H "X-Blizzfull-API-User: $BLIZZFULL_API_USER" \
  -H "X-Blizzfull-API-Token: $BLIZZFULL_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "Out of wings",
    "items": [
      {
        "orderItemID": 1,
        "quantity": 1
      }
    ]
  }'
JavaScript
const res = await fetch(`https://apiv2.blizzfull.com/orders/${process.env.ORDER_ID}/refund`, {
  method: 'POST',
  headers: {
    'X-Blizzfull-API-User': process.env.BLIZZFULL_API_USER,
    'X-Blizzfull-API-Token': process.env.BLIZZFULL_API_TOKEN,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "reason": "Out of wings",
    "items": [
      {
        "orderItemID": 1,
        "quantity": 1
      }
    ]
  }),
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const { response } = await res.json();
Python
import os

import requests

res = requests.post(
    f"https://apiv2.blizzfull.com/orders/{os.environ['ORDER_ID']}/refund",
    headers={
        "X-Blizzfull-API-User": os.environ["BLIZZFULL_API_USER"],
        "X-Blizzfull-API-Token": os.environ["BLIZZFULL_API_TOKEN"],
    },
    json={
        "reason": "Out of wings",
        "items": [
            {
                "orderItemID": 1,
                "quantity": 1,
            },
        ],
    },
    timeout=30,
)
res.raise_for_status()
response = res.json()["response"]
Example response · 200
{
  "response": {
    "refunded": 300,
    "cash": 0,
    "pending": 0,
    "willRetry": false,
    "lastModified": 1793742138
  }
}

Store

For point-of-sale partners: pause ordering, set busy mode, and turn third-party ordering on and off.

Read whether the restaurant is taking orders

GET /restaurants/{restaurantId}/ordering

Whether ordering is paused, and whether busy mode is on. The restaurant's hours are separate: orderingEnabled is true when nothing is paused, even while the restaurant is closed.

Parameters

  • restaurantIdpathintegerRequired

    The restaurant's ID.

    Range
    At least 1

Responses

  • 200

    The state of ordering.

    • responseobjectRequired
      • takingOrdersbooleanRequired

        False while ordering is paused until someone turns it back on.

      • closedUntilinteger | nullRequired

        While ordering is paused until a time: that time, in Unix seconds.

      • orderingEnabledbooleanRequired

        Whether customers can order now, hours aside: takingOrders, and no pause running.

      • busyModeobjectRequired
        • onbooleanRequired
        • pickupMinutesintegerRequired

          Quoted for pickup while busy mode is on.

        • deliveryMinutesintegerRequired

          Quoted for delivery while busy mode is on.

      • pickupMinutesintegerRequired

        The usual pickup quote.

      • deliveryMinutesobjectRequired

        The usual delivery quote.

        • minintegerRequired
        • maxintegerRequired
  • 401

    The API user or token is missing or wrong.

    { "response": string }

    Example {"response":"Unauthorized"}

  • 403

    The key may not make this call, or not for this restaurant or order.

    { "response": string }

  • 429

    Over the rate limit. Wait Retry-After seconds.

    { "response": string }

    Header Retry-After integer Seconds to wait.

Operation ID getOrdering

Example request

curl
curl "https://apiv2.blizzfull.com/restaurants/$RESTAURANT_ID/ordering" \
  -H "X-Blizzfull-API-User: $BLIZZFULL_API_USER" \
  -H "X-Blizzfull-API-Token: $BLIZZFULL_API_TOKEN"
JavaScript
const res = await fetch(`https://apiv2.blizzfull.com/restaurants/${process.env.RESTAURANT_ID}/ordering`, {
  headers: {
    'X-Blizzfull-API-User': process.env.BLIZZFULL_API_USER,
    'X-Blizzfull-API-Token': process.env.BLIZZFULL_API_TOKEN,
  },
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const { response } = await res.json();
Python
import os

import requests

res = requests.get(
    f"https://apiv2.blizzfull.com/restaurants/{os.environ['RESTAURANT_ID']}/ordering",
    headers={
        "X-Blizzfull-API-User": os.environ["BLIZZFULL_API_USER"],
        "X-Blizzfull-API-Token": os.environ["BLIZZFULL_API_TOKEN"],
    },
    timeout=30,
)
res.raise_for_status()
response = res.json()["response"]
Example response · 200
{
  "response": {
    "takingOrders": true,
    "closedUntil": null,
    "orderingEnabled": true,
    "busyMode": {
      "on": false,
      "pickupMinutes": 40,
      "deliveryMinutes": 70
    },
    "pickupMinutes": 20,
    "deliveryMinutes": {
      "min": 30,
      "max": 45
    }
  }
}

Pause ordering, or set busy mode

POST /restaurants/{restaurantId}/ordering

Stops or slows online orders right away, without waiting for an order to accept. Send what you want to change.

Where the restaurant syncs its pauses to the marketplaces, a pause and its end reach them too: every marketplace pauses and resumes with Blizzfull ordering. /restaurants/{restaurantId}/marketplaces pauses them on their own.

Parameters

  • restaurantIdpathintegerRequired

    The restaurant's ID.

    Range
    At least 1

Request body application/json · required

  • False pauses ordering until it is turned back on. True takes orders again, and ends a timed pause.

  • closedUntilinteger | "restOfDay" | null

    Pauses ordering until this time, in Unix seconds, or "restOfDay" until the restaurant next opens tomorrow or later. Null ends a timed pause.

  • busyModeobject

    Longer quoted times. It ends when you turn it off, or overnight.

    • onbooleanRequired
    • The pickup quote while busy (not extra minutes). Required the first time.

      Range
      1 to 255
    • The delivery quote while busy.

      Range
      1 to 255

Responses

  • 200

    The state of ordering now.

    • responseobjectRequired
      • takingOrdersbooleanRequired

        False while ordering is paused until someone turns it back on.

      • closedUntilinteger | nullRequired

        While ordering is paused until a time: that time, in Unix seconds.

      • orderingEnabledbooleanRequired

        Whether customers can order now, hours aside: takingOrders, and no pause running.

      • busyModeobjectRequired
        • onbooleanRequired
        • pickupMinutesintegerRequired

          Quoted for pickup while busy mode is on.

        • deliveryMinutesintegerRequired

          Quoted for delivery while busy mode is on.

      • pickupMinutesintegerRequired

        The usual pickup quote.

      • deliveryMinutesobjectRequired

        The usual delivery quote.

        • minintegerRequired
        • maxintegerRequired
  • 401

    The API user or token is missing or wrong.

    { "response": string }

    Example {"response":"Unauthorized"}

  • 403

    The key may not make this call, or not for this restaurant or order.

    { "response": string }

  • 409

    restOfDay, and the restaurant's hours don't say when it opens next. Send a time.

    { "response": string }

    Example {"response":"The restaurant's hours don't say when it opens next. Send closedUntil as a time."}

  • 412

    A value is not valid. The message says which.

    { "response": string }

    Example {"response":"takingOrders is true or false"}

  • 429

    Over the rate limit. Wait Retry-After seconds.

    { "response": string }

    Header Retry-After integer Seconds to wait.

Operation ID setOrdering

Example request

curl
curl "https://apiv2.blizzfull.com/restaurants/$RESTAURANT_ID/ordering" \
  -H "X-Blizzfull-API-User: $BLIZZFULL_API_USER" \
  -H "X-Blizzfull-API-Token: $BLIZZFULL_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "takingOrders": false
  }'
JavaScript
const res = await fetch(`https://apiv2.blizzfull.com/restaurants/${process.env.RESTAURANT_ID}/ordering`, {
  method: 'POST',
  headers: {
    'X-Blizzfull-API-User': process.env.BLIZZFULL_API_USER,
    'X-Blizzfull-API-Token': process.env.BLIZZFULL_API_TOKEN,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "takingOrders": false
  }),
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const { response } = await res.json();
Python
import os

import requests

res = requests.post(
    f"https://apiv2.blizzfull.com/restaurants/{os.environ['RESTAURANT_ID']}/ordering",
    headers={
        "X-Blizzfull-API-User": os.environ["BLIZZFULL_API_USER"],
        "X-Blizzfull-API-Token": os.environ["BLIZZFULL_API_TOKEN"],
    },
    json={
        "takingOrders": False,
    },
    timeout=30,
)
res.raise_for_status()
response = res.json()["response"]

Read third-party ordering

GET /restaurants/{restaurantId}/marketplaces

The marketplaces (DoorDash, Uber Eats and the others) that order at the restaurant's locations, and which are paused. This is what Blizzfull last sent them: a pause made on a marketplace's own tablet doesn't show here.

Parameters

  • restaurantIdpathintegerRequired

    The restaurant's ID.

    Range
    At least 1

Responses

  • 200

    Each location and its marketplaces.

    • responseobjectRequired
      • locationsobject[]Required
        • idstringRequired

          What location takes.

        • namestringRequired
        • connectedbooleanRequired

          Whether the marketplaces connection is live at this location.

        • marketplacesobject[]Required

          The marketplaces this location took an order from in the last 90 days, or that were paused or reported on.

          • marketplacestringRequired

            What marketplace takes, and what an order calls sourcePlatform.

            Example
            "doordash"
          • namestringRequired
            Example
            "DoorDash"
          • pausedbooleanRequired
          • pausedUntilinteger | nullRequired

            When it comes back on its own, in Unix seconds. Null while paused means until you resume it.

          • changedAtinteger | nullRequired

            When it was last paused or resumed, in Unix seconds.

  • 401

    The API user or token is missing or wrong.

    { "response": string }

    Example {"response":"Unauthorized"}

  • 403

    The key may not make this call, or not for this restaurant or order.

    { "response": string }

  • 404

    The restaurant doesn't take marketplace orders through Blizzfull.

    { "response": string }

  • 429

    Over the rate limit. Wait Retry-After seconds.

    { "response": string }

    Header Retry-After integer Seconds to wait.

Operation ID getMarketplaces

Example request

curl
curl "https://apiv2.blizzfull.com/restaurants/$RESTAURANT_ID/marketplaces" \
  -H "X-Blizzfull-API-User: $BLIZZFULL_API_USER" \
  -H "X-Blizzfull-API-Token: $BLIZZFULL_API_TOKEN"
JavaScript
const res = await fetch(`https://apiv2.blizzfull.com/restaurants/${process.env.RESTAURANT_ID}/marketplaces`, {
  headers: {
    'X-Blizzfull-API-User': process.env.BLIZZFULL_API_USER,
    'X-Blizzfull-API-Token': process.env.BLIZZFULL_API_TOKEN,
  },
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const { response } = await res.json();
Python
import os

import requests

res = requests.get(
    f"https://apiv2.blizzfull.com/restaurants/{os.environ['RESTAURANT_ID']}/marketplaces",
    headers={
        "X-Blizzfull-API-User": os.environ["BLIZZFULL_API_USER"],
        "X-Blizzfull-API-Token": os.environ["BLIZZFULL_API_TOKEN"],
    },
    timeout=30,
)
res.raise_for_status()
response = res.json()["response"]
Example response · 200
{
  "response": {
    "locations": [
      {
        "id": "1234",
        "name": "Kin Da",
        "connected": true,
        "marketplaces": [
          {
            "marketplace": "doordash",
            "name": "DoorDash",
            "paused": true,
            "pausedUntil": 1793742138,
            "changedAt": 1793738538
          },
          {
            "marketplace": "uber",
            "name": "Uber Eats",
            "paused": false,
            "pausedUntil": null,
            "changedAt": null
          }
        ]
      }
    ]
  }
}

Turn third-party ordering off or on

POST /restaurants/{restaurantId}/marketplaces

Pauses or resumes one marketplace, or all of them, at one location or all of them. Blizzfull ordering carries on.

Where the restaurant syncs its pauses to the marketplaces, pausing and resuming all of Blizzfull ordering (/restaurants/{restaurantId}/ordering) also resumes every marketplace paused here.

Parameters

  • restaurantIdpathintegerRequired

    The restaurant's ID.

    Range
    At least 1

Request body application/json · required

  • pausedbooleanRequired
  • Left out: all of them.

    One of
    "doordash" "uber" "grubhub" "jet" "deliveroo" "skipthedishes" "flipdish" "chownow"
  • untilinteger

    For a pause: when it comes back on its own, in Unix seconds. Left out: until you resume it.

  • locationstring

    One location's id, for a restaurant with virtual brands. Left out: all of them.

Responses

  • 200

    Each location and its marketplaces now.

    • responseobjectRequired
      • locationsobject[]Required
        • idstringRequired

          What location takes.

        • namestringRequired
        • connectedbooleanRequired

          Whether the marketplaces connection is live at this location.

        • marketplacesobject[]Required

          The marketplaces this location took an order from in the last 90 days, or that were paused or reported on.

          • marketplacestringRequired

            What marketplace takes, and what an order calls sourcePlatform.

            Example
            "doordash"
          • namestringRequired
            Example
            "DoorDash"
          • pausedbooleanRequired
          • pausedUntilinteger | nullRequired

            When it comes back on its own, in Unix seconds. Null while paused means until you resume it.

          • changedAtinteger | nullRequired

            When it was last paused or resumed, in Unix seconds.

  • 401

    The API user or token is missing or wrong.

    { "response": string }

    Example {"response":"Unauthorized"}

  • 403

    The key may not make this call, or not for this restaurant or order.

    { "response": string }

  • 404

    The restaurant doesn't take marketplace orders through Blizzfull.

    { "response": string }

  • 412

    A value is not valid. The message says which.

    { "response": string }

    Example {"response":"paused is required: true or false"}

  • 429

    Over the rate limit. Wait Retry-After seconds.

    { "response": string }

    Header Retry-After integer Seconds to wait.

  • 502

    The marketplace connection didn't confirm the change at a location. Send it again. The message names any location it went through at.

    { "response": string }

    Example {"response":"The marketplace connection didn't confirm the change at location 1234. Send it again."}

Operation ID setMarketplaces

Example request

curl
curl "https://apiv2.blizzfull.com/restaurants/$RESTAURANT_ID/marketplaces" \
  -H "X-Blizzfull-API-User: $BLIZZFULL_API_USER" \
  -H "X-Blizzfull-API-Token: $BLIZZFULL_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "paused": true,
    "marketplace": "uber",
    "until": 1793742138
  }'
JavaScript
const res = await fetch(`https://apiv2.blizzfull.com/restaurants/${process.env.RESTAURANT_ID}/marketplaces`, {
  method: 'POST',
  headers: {
    'X-Blizzfull-API-User': process.env.BLIZZFULL_API_USER,
    'X-Blizzfull-API-Token': process.env.BLIZZFULL_API_TOKEN,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "paused": true,
    "marketplace": "uber",
    "until": 1793742138
  }),
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const { response } = await res.json();
Python
import os

import requests

res = requests.post(
    f"https://apiv2.blizzfull.com/restaurants/{os.environ['RESTAURANT_ID']}/marketplaces",
    headers={
        "X-Blizzfull-API-User": os.environ["BLIZZFULL_API_USER"],
        "X-Blizzfull-API-Token": os.environ["BLIZZFULL_API_TOKEN"],
    },
    json={
        "paused": True,
        "marketplace": "uber",
        "until": 1793742138,
    },
    timeout=30,
)
res.raise_for_status()
response = res.json()["response"]

Order feed

For point-of-sale partners: every order at your restaurant the moment it changes, over a websocket.

Connect to the order feed

GET /pubsub/token

Hear about every order at your restaurant the moment it changes, instead of polling for it. Blizzfull sends each change to your point of sale on an Ably websocket channel, and you fetch the order it names.

Connect with an Ably client library:

  • Auth URL: this call, https://apiv2.blizzfull.com/pubsub/token, with your API user and token as authHeaders. A key that serves several restaurants adds restaurantID in authParams. The library gets a token (good for 24 hours) and a new one before it expires.
  • Channel: restaurant.{restaurantId}.pos. The token can subscribe to it and nothing else.

Each message's name is its event, and its data.payload names the order (the other fields are for tracing):

  • ORDER_SUBMITTED: a new order.
  • ORDER_ACCEPTED: the order was accepted, with etaMinutes when a ready time was given.
  • ORDER_UPDATED: the order changed.
  • ORDER_COMPLETED: the order is ready.
  • ORDER_CANCELED: the order was canceled, with reason when there is one.
  • EXTERNAL_ORDER_RECEIVED, EXTERNAL_ORDER_UPDATED: a marketplace order Blizzfull relays, named by externalOrderId.
  • OPEN_ORDER_SUBMITTED, OPEN_ORDER_CLOSED: a table check guests order from a QR code: a round went to the kitchen, or the check was paid.

An order event's payload has orderId, restaurantId and status, and usually submittedTime and lastModified (Unix seconds) and surface (where the order was placed, such as web or phone).

{
  "v": 1,
  "topic": "restaurant.1234.pos",
  "event": "ORDER_SUBMITTED",
  "ts": 1793575105425,
  "seq": 12,
  "actor": {"id": "system", "role": "system"},
  "correlation": "3f2b8c1e-7d4a-4e9b-a1c5-0d6e8f9a2b47",
  "payload": {
    "orderId": 6550001,
    "restaurantId": 1234,
    "status": "submitted",
    "submittedTime": 1793575105,
    "lastModified": 1793575105,
    "surface": "web"
  }
}

On every message, get the order (GET /orders/{orderId}, or GET /orders/ex-{externalOrderId} for a marketplace order) and do what it needs.

  • Answering: the feed only tells you. Hearing about an order doesn't pick it up or accept it: call /orders/{orderId}/accept and /orders/{orderId}/status as usual.
  • Missed messages: Ably delivers what you missed when it reconnects within two minutes, and nothing older. After longer, or at startup, catch up with /orders and /orders/marketplace, then follow the feed. Keep polling /orders/poll slowly, about once a minute, as a safety net.
  • More than one system: every connection gets every message, so a new system can watch alongside an old one. Decide in your own software which one accepts. Accepting twice changes nothing.
  • Staying connected: the Ably library sends its own heartbeats and reconnects. You send nothing.

The order feed has to be switched on for your restaurant, or this call answers 403: ask your Blizzfull contact. To test, place orders on your sandbox restaurant.

Parameters

  • restaurantIDqueryinteger

    Only for a key that serves several restaurants: the restaurant to listen to.

Responses

  • 200

    An Ably token, as Ably's libraries expect from an auth URL: not wrapped in response.

    • tokenstringRequired

      The token.

    • keyNamestringRequired

      The Ably key that issued it.

    • issuedintegerRequired

      When it was issued, in Unix milliseconds.

    • expiresintegerRequired

      When it expires, in Unix milliseconds: 24 hours after issued.

    • capabilitystringRequired

      What it allows, as JSON: subscribing to your restaurant's channel.

    • clientIdstring

      apiuser: and your API user's ID.

  • 401

    The API user or token is missing or wrong.

    { "response": string }

    Example {"response":"Unauthorized"}

  • 403

    The key may not make this call, or the order feed is not switched on for its restaurant.

    { "response": string }

    Example {"response":"The order feed is not switched on for this restaurant."}

  • 429

    Over the rate limit. Wait Retry-After seconds.

    { "response": string }

    Header Retry-After integer Seconds to wait.

Operation ID getOrderFeedToken

Example request

curl
curl "https://apiv2.blizzfull.com/pubsub/token" \
  -H "X-Blizzfull-API-User: $BLIZZFULL_API_USER" \
  -H "X-Blizzfull-API-Token: $BLIZZFULL_API_TOKEN"
JavaScript
const res = await fetch('https://apiv2.blizzfull.com/pubsub/token', {
  headers: {
    'X-Blizzfull-API-User': process.env.BLIZZFULL_API_USER,
    'X-Blizzfull-API-Token': process.env.BLIZZFULL_API_TOKEN,
  },
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const { response } = await res.json();
Python
import os

import requests

res = requests.get(
    "https://apiv2.blizzfull.com/pubsub/token",
    headers={
        "X-Blizzfull-API-User": os.environ["BLIZZFULL_API_USER"],
        "X-Blizzfull-API-Token": os.environ["BLIZZFULL_API_TOKEN"],
    },
    timeout=30,
)
res.raise_for_status()
response = res.json()["response"]
Example response · 200
{
  "token": "xVLyHw.EXAMPLE-TOKEN",
  "keyName": "xVLyHw.EXAMPLE",
  "issued": 1793568068468,
  "expires": 1793654468468,
  "capability": "{\"restaurant.1234.pos\":[\"subscribe\"]}",
  "clientId": "apiuser:42"
}

Get an order in your ticket format

GET /orders/{orderId}

The order a message names, in your ticket format (the same format /orders/poll returns with posToMap), with your item IDs on its lines. For a marketplace order, use ex- and the message's externalOrderId: /orders/ex-284417.

For a table check, send the kitchen every line whose orderItemID you haven't sent, and close the check when status is closed. Line numbers only grow and are never reused, so getting the same order twice changes nothing. Keep each line's orderItemID on your own check, so a restart doesn't send a line twice.

Parameters

  • orderIdpathstringRequired

    The message's orderId, or ex- and its externalOrderId for a marketplace order.

    Pattern
    ^(ex-)?[1-9][0-9]*$
  • posToMapquerystringRequired

    Your integration's name, as for /orders/poll: the order comes in your ticket format, using the restaurant's item mapping.

Responses

  • 200

    The order (shortened here: it has every field your poll's orders have).

    • responseobjectRequired

      An order in your ticket format: the same format /orders/poll returns with posToMap, so it has more fields than these.

      • idstringRequired

        The order number: the message's orderId, or ex-<n> for a marketplace order.

        Pattern
        ^(ex-)?[1-9][0-9]*$
      • statusstringRequired

        submitted when it is new, closed once it is ready (a table check: once it is paid), canceled, or open while a table check is still ordering. A marketplace order is submitted, accepted, fulfilled or canceled.

        Example
        "submitted"
      • acceptedboolean

        Whether the restaurant has accepted it.

      • typestring

        How it is served, such as take-out, delivery or for-here.

        Example
        "take-out"
      • tableIDstring

        The table, for a table check; empty otherwise.

      • itemsobject[]Required

        The order's lines (for a table check, every line the table has sent).

        • orderItemIDintegerRequired

          The line's number in the order. Numbers only grow and are never reused.

          Range
          At least 1
        • itemIDinteger | stringRequired

          Blizzfull's item ID.

        • externalIDstring | integer | null

          Your item ID, from the restaurant's item mapping; null when the item isn't mapped.

        • externalSizeIDstring | integer | null

          Your size ID, when the size is mapped.

        • namestringRequired

          The item's name.

        • quantityintegerRequired

          How many.

          Range
          At least 1
        • The guest's note for the kitchen.

        • The guest's choices with your option IDs: one list for each option group.

          • externalIDstring | integer | null

            Your option ID.

          • selinteger | string

            The selection, as in your poll's orders: a number, or a string for an option sold by amount.

          • subOptionsobject[]

            Choices made inside this choice.

            • externalIDstring | integer | null

              Your option ID.

            • selinteger | string

              The selection, as in your poll's orders: a number, or a string for an option sold by amount.

  • 401

    The API user or token is missing or wrong.

    { "response": string }

    Example {"response":"Unauthorized"}

  • 403

    The key may not make this call, or not for this restaurant or order.

    { "response": string }

  • 412

    posToMap names an integration the restaurant doesn't have.

    { "response": string }

  • 429

    Over the rate limit. Wait Retry-After seconds.

    { "response": string }

    Header Retry-After integer Seconds to wait.

Operation ID getOrderTicket

Example request

curl
curl -G "https://apiv2.blizzfull.com/orders/$ORDER_ID" \
  -d "posToMap=$POS_TO_MAP" \
  -H "X-Blizzfull-API-User: $BLIZZFULL_API_USER" \
  -H "X-Blizzfull-API-Token: $BLIZZFULL_API_TOKEN"
JavaScript
const query = new URLSearchParams({
  posToMap: process.env.POS_TO_MAP,
});
const res = await fetch(`https://apiv2.blizzfull.com/orders/${process.env.ORDER_ID}?${query}`, {
  headers: {
    'X-Blizzfull-API-User': process.env.BLIZZFULL_API_USER,
    'X-Blizzfull-API-Token': process.env.BLIZZFULL_API_TOKEN,
  },
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
const { response } = await res.json();
Python
import os

import requests

res = requests.get(
    f"https://apiv2.blizzfull.com/orders/{os.environ['ORDER_ID']}",
    headers={
        "X-Blizzfull-API-User": os.environ["BLIZZFULL_API_USER"],
        "X-Blizzfull-API-Token": os.environ["BLIZZFULL_API_TOKEN"],
    },
    params={"posToMap": os.environ["POS_TO_MAP"]},
    timeout=30,
)
res.raise_for_status()
response = res.json()["response"]
Example response · 200
{
  "response": {
    "id": "6550001",
    "status": "submitted",
    "accepted": false,
    "type": "take-out",
    "tableID": "",
    "items": [
      {
        "orderItemID": 1,
        "itemID": 166519,
        "externalID": "HC-01",
        "externalSizeID": null,
        "name": "Hungry Combo",
        "quantity": 2,
        "specialInstructions": "Sauce on the side",
        "externalOptionMapMask": [
          [
            {
              "externalID": "STYLE-WINGS",
              "sel": 1
            }
          ],
          [
            {
              "externalID": "FLAVOR-LEMON-PEPPER",
              "sel": 1
            }
          ]
        ]
      }
    ]
  }
}

Schemas

The documents the calls send and return, field by field.

Machine-readable

Questions about the API? engineering@blizzfull.com. API changes are in the patch notes.

A mom-and-pop should never lose to a chain on anything.

With Blizzfull, it doesn’t have to.

Developer

2,500+ restaurants served24/7 support(213) 529-3956