Compute Dynamic Beverage Nutrition Facts for the exact drink a customer ordered โ from your POS, kiosk, or ordering app. The engine runs in the browser today; a hosted REST API is on the way.
What you can build
Drop in engine.js and call window.BevFacts โ compute, round, declare, and render labels with zero network calls.
Encode a whole drink into a shareable link or QR code. Scannable by any phone, resolvable with no backend.
Compute and persist labels server-side, render PNG/SVG, and pull vendor recipe tables over HTTP.
Subscribe to cup.returned and label.created events with signed, replay-protected payloads.
Publish and consume base recipes, milks, syrups, and toppings as machine-readable JSON.
The browser surfaces need no credentials โ keep API keys server-side, exactly where they belong.
Quickstart
The engine is a single static file with no dependencies. Everything below runs on this very page โ open your console and try it.
<script src="engine.js"></script>
<script>
// Base recipe + the modifiers the customer ordered
const order = {
drinkName: "Caramel Latte",
calories: 250, sugars: 33, addedSugars: 28, caffeine: 150,
totalFat: 7, satFat: 4.5, sodium: 170, totalCarb: 35, protein: 10,
sweetness: 100, pumps: 3, shots: 2 // +3 syrup pumps, +2 espresso shots
};
const facts = BevFacts.compute(order); // unrounded, as-ordered
const declared = BevFacts.declare(facts); // 21 CFR 101.9 rounded strings
const warnings = BevFacts.warnings(facts); // e.g. ["added_sugars_over_100pct_dv"]
const link = BevFacts.link(order); // shareable deep link / QR target
</script>
Live playground
Edit the order JSON and press Run. This calls the real window.BevFacts API loaded on this page โ the same code your integration would ship.
Order (JSON)
Result
Rendered label
Reference
window.BevFacts API| Member | Signature | Returns |
|---|---|---|
version | string | Spec version, e.g. "1.0-draft" |
DV | object | Daily-value table (added sugars 50, sodium 2300, โฆ) |
PRESETS | array | Example base recipes |
compute(order) | (state) โ nutrients | Unrounded as-ordered vector (sweetness, pumps, shots applied) |
declare(nutrients) | (nutrients) โ strings | FDA-rounded declaration strings + %DV |
warnings(nutrients) | (nutrients) โ string[] | Machine-readable warning flags |
round | {calories, fat, โฆ} | The individual 21 CFR 101.9 rounding functions |
labelHTML(order) | (state) โ string | Inner HTML of a ready-to-style Nutrition Facts label |
link(order) | (state) โ string | A deep-link URL encoding the whole order |
Draft ยท hosted API
The wire format is specified and stable enough to build against; endpoints are not yet hosted. Full details โ auth, idempotency, pagination, webhooks, and errors โ live in Part 5 of the spec.
| Endpoint | Purpose |
|---|---|
POST /v1/labels | Compute & optionally render a label (PNG / SVG / JSON) |
GET /v1/labels/{id} | Retrieve a computed label document by id or hash |
GET /v1/presets | List a vendor's published base recipes |
GET /v1/cups/{id} | Deposit / return state for a reusable cup |
POST /v1/cups/{id}/return | Record a return scan; emit cup.returned |
curl https://api.bevfacts.example/v1/labels \
-H "Authorization: Bearer bf_live_โฆ" \
-H "Content-Type: application/json" \
-d '{ "drink": { "name": "Caramel Latte", "servingSize": { "amount": 16, "unit": "fl_oz", "ml": 473 } },
"base": { "calories": 250, "sugars_g": 33, "addedSugars_g": 28, "caffeine_mg": 150 },
"modifiers": [ { "type": "syrup_pump", "count": 3 }, { "type": "espresso_shot", "count": 2 } ],
"render": ["png", "json"] }'
Want the hosted API, webhooks, or an SDK for your stack?
The REST surface, event signatures, and cup-return lifecycle are specified in the open. Follow along or weigh in via GitHub, or read the full API specification.