DADI Menu — Developer API Documentation
Version: 1.0 Last updated: 2026-08-27 Maintained by: iKRATES (https://ikrates.com) Audience: Fantasy Ikoyi engineering team and other approved partners
Overview
The DADI by KRATES menu is a rotating selection of dishes from iKRATES resident chefs. This document describes two ways for a partner site (e.g. Fantasy Ikoyi) to surface the live DADI menu:
| Option | What it is | Best for |
| --- | --- | --- |
| A — Embed Widget | A drop-in <iframe> that renders the styled menu and links back to iKRATES to order. | Fastest integration, no styling work, always up to date. |
| B — JSON API | A public GET endpoint returning the full menu as structured JSON. | Full control over layout, theming, and copy on the partner site. |
Both options are public and read-only. No authentication, API key, or account is required. Only public menu fields are exposed — no owner emails, private listing data, or access codes are ever returned.
Option A — Embed Widget (iframe)
The fastest way to show the DADI menu on your site. The widget is a headerless, fully-styled page that renders the live menu (grouped by chef and section), with each item's "order" button linking back to iKRATES to complete the purchase.
Endpoint
https://ikrates.com/embed/dadi-menu
Embed snippet
Drop this anywhere in your page where you want the menu to appear:
<iframe
src="https://ikrates.com/embed/dadi-menu"
title="DADI by KRATES Menu"
style="width:100%; max-width:720px; height:1400px; border:0; border-radius:12px;"
loading="lazy"
allow="fullscreen"
></iframe>
Recommended sizing
- Width:
100%withmax-width: 720px(the widget is designed for a single-column, mobile-friendly layout). - Height: The content height varies with the number of menu items. Start at 1400px and adjust to fit. If your site supports
ResizeObserver-based dynamic iframe resizing, you may omit a fixed height and resize from the parent — otherwise a fixed height with internal scroll is the simplest approach. - Border / radius: Optional;
border-radius: 12pxmatches the widget's internal card styling.
Notes
- The widget is self-contained — it loads its own fonts, styles, and data. You do not need to add any CSS or scripts.
- All "order" actions open iKRATES (
https://ikrates.com/dadi-menu) in a new tab. - The widget refreshes its data on every page load, so it always reflects the current resident chefs and menu items.
- It is safe to embed on any public page; no CORS configuration is needed for an iframe.
Option B — JSON API
For partners who want full control over the rendering, the JSON API returns the complete DADI menu as structured data.
Endpoint
GET https://ikrates.com/functions/get-dadi-menu
Request
| Property | Value |
| --- | --- |
| Method | GET |
| Auth | None (public) |
| Query params | None |
| Request body | None |
| CORS | Access-Control-Allow-Origin: * (callable from any origin) |
An OPTIONS preflight is supported and returns 204 No Content with the CORS headers.
Response
200 OK — application/json
{
"chefs": [
{
"id": "abc123",
"business_name": "Chef Example Kitchen",
"category": "Chef",
"bio": "Short biography of the chef.",
"city": "Lagos",
"image": "https://.../chef-photo.jpg",
"menu": [
{
"name": "Jollof Rice",
"category": "Main Meal",
"price": 4500,
"description": "Smoky party-style jollof.",
"dietary": "Contains: rice, pepper",
"image": "https://.../dish.jpg"
}
],
"packages": [
{
"name": "Weekly Lunch Package",
"category": "Main Meal",
"price": 30000,
"description": "5 lunches delivered weekly.",
"image": "https://.../package.jpg",
"frequency": "five_weekly",
"min_plates": 5,
"max_plates": 20,
"delivery_cost": 2000,
"options": [
{ "name": "Jollof Rice", "qty": 3 },
{ "name": "Egusi Soup", "qty": 2 }
]
}
]
}
],
"sections": [
{
"name": "Breakfast",
"items": [
{
"name": "Akara & Pap",
"category": "Breakfast",
"price": 2000,
"description": "Fresh bean cakes with pap.",
"dietary": "Vegan",
"image": "https://.../akara.jpg",
"chef": "Chef Example Kitchen",
"chef_id": "abc123"
}
]
}
],
"generated_at": "2026-08-27T08:00:00.000Z"
}
Response schema
Top level
| Field | Type | Description |
| --- | --- | --- |
| chefs | Chef[] | Resident chefs who have at least one DADI-enabled menu item or package. |
| sections | Section[] | All menu items flattened and grouped by section, in a fixed order: Breakfast → Main Meal → Dessert → Beverages & Drinks. Each item is enriched with its chef and chef_id. Use this for a simple single-list view. |
| generated_at | string (ISO 8601) | Timestamp the response was generated. |
Chef
| Field | Type | Description |
| --- | --- | --- |
| id | string | iKRATES professional record id. Use to build a link to the chef's profile: https://ikrates.com/professionals/{id}. |
| business_name | string | Display name of the chef/business. |
| category | string | Professional category (e.g. Chef, Private Chef, Caterer). |
| bio | string | Short biography. May be empty. |
| city | string | City the chef is based in. May be empty. |
| image | string | Profile/cover image URL. May be empty. |
| menu | MenuItem[] | DADI-enabled single dishes (excludes packages). |
| packages | Package[] | DADI-enabled weekly meal packages. |
MenuItem
| Field | Type | Description |
| --- | --- | --- |
| name | string | Dish name. |
| category | string | DADI section: Breakfast, Main Meal, Dessert, or Beverages & Drinks. Falls back to the item's general category if unset. |
| price | number | Price in NGN (Nigerian Naira, major units). Uses the DADI-specific price if set, otherwise the standard menu price. |
| description | string | Dish description. May be empty. |
| dietary | string | Dietary notes / allergen info. May be empty. |
| image | string | Dish image URL. May be empty. |
Package
| Field | Type | Description |
| --- | --- | --- |
| name | string | Package name. |
| category | string | DADI section. |
| price | number | Package price in NGN. |
| description | string | Package description. May be empty. |
| image | string | Package image URL. May be empty. |
| frequency | string | Delivery cadence: any, daily, five_weekly, weekly_bulk, or twice_weekly. |
| min_plates | number | Minimum plates per order. |
| max_plates | number | Maximum plates per order (0 = no limit). |
| delivery_cost | number | Delivery cost per delivery in NGN. |
| options | object[] | Composing dishes, each { name, qty }. |
Section
| Field | Type | Description |
| --- | --- | --- |
| name | string | Section name (Breakfast, Main Meal, Dessert, Beverages & Drinks). |
| items | object[] | Menu items in this section. Each item has all MenuItem fields plus chef (business name) and chef_id. |
Example — fetch and render (JavaScript)
<div id="dadi-menu">Loading menu…</div>
<script>
fetch("https://ikrates.com/functions/get-dadi-menu")
.then((res) => res.json())
.then((data) => {
const container = document.getElementById("dadi-menu");
const orderUrl = "https://ikrates.com/dadi-menu";
const html = (data.sections || [])
.map((section) => {
const items = section.items
.map((item) => `
<div style="display:flex;gap:12px;padding:12px 0;border-bottom:1px solid #eee">
${item.image ? `<img src="${item.image}" alt="${item.name}" style="width:64px;height:64px;border-radius:8px;object-fit:cover"/>` : ""}
<div style="flex:1">
<strong>${item.name}</strong>
${item.description ? `<div style="font-size:13px;color:#666">${item.description}</div>` : ""}
<div style="font-size:12px;color:#999">by ${item.chef}</div>
</div>
<div style="text-align:right">
<div style="font-weight:bold">₦${item.price.toLocaleString()}</div>
<a href="${orderUrl}" target="_blank" rel="noopener" style="font-size:12px">Order →</a>
</div>
</div>`)
.join("");
return `<h3>${section.name}</h3>${items}`;
})
.join("");
container.innerHTML = html || "<p>No menu items available right now.</p>";
})
.catch((err) => {
document.getElementById("dadi-menu").innerHTML =
"<p>Unable to load the DADI menu. Please try again later.</p>";
console.error("DADI menu error:", err);
});
</script>
Example — curl
curl https://ikrates.com/functions/get-dadi-menu
Error responses
| Status | When | Body |
| --- | --- | --- |
| 200 | Success | { chefs, sections, generated_at } |
| 500 | Server error | { "error": "<message>" } |
If no resident chefs have published DADI menus yet, the API returns 200 with empty arrays: { "chefs": [], "sections": [] }.
Data scope & security
- The API and widget expose public menu fields only: dish name, category, price, description, dietary notes, image, and the chef's public profile fields (name, category, bio, city, image).
- Never exposed: owner email addresses, private listing access codes (WiFi, door, alarm), booking data, or any internal identifiers beyond the public chef
id. - Only chefs who are accepted DADI residents and have at least one DADI-enabled, non-draft menu item appear in the response.
- All ordering, payment, and account actions happen on iKRATES — the partner surface is display-only. Item "order" links point to
https://ikrates.com/dadi-menu.
Caching & refresh guidance
- The menu changes only when resident chefs add, edit, or disable DADI items — typically a few times per week.
- A 5–15 minute client-side cache (e.g.
Cache-Controlor an in-memory TTL) is recommended to reduce load while keeping the menu reasonably fresh. - The response includes a
generated_attimestamp you can use as a cache key or staleness indicator. - Do not poll more frequently than once per minute.
Linking back to iKRATES
| Destination | URL |
| --- | --- |
| Full DADI menu (order page) | https://ikrates.com/dadi-menu |
| A specific chef's profile | https://ikrates.com/professionals/{chef_id} |
When in doubt, link any "order" / "view" action to the main DADI menu URL above.
Support
For integration questions, schema changes, or to report an issue, contact the iKRATES team via the Support page at https://ikrates.com/support.
This document describes the public DADI menu integration as of the date above. The response schema is additive only — new fields may be added over time, but existing fields will not be removed or renamed without notice.