Developers

Your kitchen, over HTTPS.

Everything ChefOS knows about a kitchen — recipes, costs, stock, counts, orders, sales, variance — is readable with an API key, and the moments that matter arrive as signed webhooks. No SDK to install; any language that can make an HTTPS request will do.

Authentication

A manager or owner creates a key under Integrations → API & webhooks in the sidebar. The key is shown once. Send it as a bearer token:

curl https://www.chefrys.com/recipes \
  -H "Authorization: Bearer cos_0123456789abcdef…"

A key acts for one kitchen with a chef's access: every operational read and write, but never people, billing, exports or the audit log. Revoke it at any time from the same screen; every request it made is in the kitchen's activity log under the key's name.

Endpoints most integrations use

Method · pathWhat it returns or does
GET /recipesEvery recipe with cost, price, food-cost % and completeness.
GET /recipes/{id}/rollupOne recipe in full: ingredients in grams, sub-recipes, steps, allergens, batch and portion cost.
GET /ingredientsThe ingredient library with prices per gram, yields and categories.
GET /suppliersSupplier items: pack, pack price, code.
GET /inventory/fullStock on hand with values and pars.
GET /count/sheet?date=YYYY-MM-DD · POST /countThe count sheet in shelf units, and saving counts ({date, lines:[{id, entries:[{key, qty}]}]}).
GET /variance?from=&to=Period variance between two counts: opening + purchases − closing vs ideal, in grams and dollars.
GET /menu-engineering?range=30&by=categoryStars, plowhorses, puzzles and dogs with margin and popularity.
GET /sales · GET /sales/pendingSales history, and POS names not yet linked to a recipe.
GET /order · GET /orders · POST /orders/placeThe suggested order sheet, placed orders, and placing one.
GET /invoicesInvoices on file with their lines.
GET /price-watchSupplier price moves of the last 30 days and the dishes they hit.
GET /prep · GET /planToday's prep list and the production plan.
POST /messageSend a document (multipart files[]) or text for reading — the same path as the composer; uses credits.

Responses are JSON. Dates are YYYY-MM-DD; weights are grams; money is US dollars. Errors carry {"detail": "…"} with the usual status codes; a key that cannot do something gets 403.

Webhooks

Register an HTTPS URL under the same screen and pick the events. Each delivery is a JSON POST:

{
  "event": "count.finalized",
  "kitchen": "the_bistro",
  "ts": 1789300000.123,
  "data": {"date": "2026-09-13", "items": 212, "value": 18342.10, "by": "marco"}
}
EventWhendata
count.finalizedA count is locked for a date.date, items, value, by
order.placedOrder sheet lines become purchase orders.orders: [{id, supplier, lines, total}]
order.sentA purchase order is emailed to the supplier.id, supplier, to, lines
price.alertA supplier price moved enough to change plate costs.ingredient, pct, old_pack_price, new_pack_price, dishes
invoice.receivedAn invoice was read and its purchases booked.supplier, number, date, total, lines
sales.syncedSales arrived from a connected POS.source, days, rows, matched, unmatched
webhook.testYou pressed Test.hello

Verify every delivery. The header X-ChefOS-Signature is sha256= followed by the hex HMAC-SHA256 of the raw request body, keyed with the webhook's secret (shown once when you create it). Reject anything that does not match. Respond with a 2xx within eight seconds; ChefOS retries once, and pauses a webhook after twenty consecutive failures.

# Python
import hmac, hashlib
expected = "sha256=" + hmac.new(SECRET.encode(), request_body_bytes, hashlib.sha256).hexdigest()
ok = hmac.compare_digest(expected, request.headers["X-ChefOS-Signature"])

Limits and fair use

Keys share the kitchen's daily allowance of AI actions and its credit balance when they send documents or questions. Plain reads are not metered. Be gentle: a few requests a second is fine; a scraper is not. Questions: chefrys.com/talk.