menu-MENAmenu-MENA
HomePricingBlogContact UsGet Started
The API access page in the menu-MENA admin panel, showing a masked API key field with copy and regenerate buttons, a live curl example, and a quick-reference list of the four public API endpoints.

Connecting Your Menu Data to Other Tools: The Public API

Platform & Tech

By menu-MENA Team

Published on September 24, 2026


A guest's order lands in your WhatsApp and on your Orders board. That covers the people running the restaurant. It doesn't cover an agency managing the account for a client, or a POS vendor trying to bridge menu-MENA into their own system without asking staff to re-type anything. For that, menu-MENA ships a small REST API: four GET endpoints, one key, plain JSON.

Getting a key

Go to Admin → API access. The page is owner-only: a manager who lands there gets redirected straight back to the dashboard, no key ever renders for them. Hit Generate API key and you get one starting with mcx_live_, shown in a read-only field with a copy icon next to it. Below that sits a live curl example with your actual key already dropped in, so you can paste it into a terminal and get a real response on the first try instead of guessing at the header format.

If you ever need to cut off an old integration, hit Regenerate. The previous key stops working the instant you do, which is worth remembering before you swap keys in production: update the integration first, then regenerate, not the other way around.

Four endpoints, all reads

  • GET /api/public/v1/me returns your tenant id, slug, name, and plan. It's the connection-test call, the one a Zapier "test trigger" step or a health check would hit first.
  • GET /api/public/v1/menu returns the same categories and items your public menu page renders, in the same structure the admin panel edits.
  • GET /api/public/v1/orders?since=<ms>&limit=<n> returns order records.
  • GET /api/public/v1/reservations?since=<ms>&limit=<n> returns reservation records, with the same query shape.

Every response is wrapped in { "data": ... }. There's nothing to write, only to read: none of the four endpoints accept POST, PUT, or DELETE. If your integration needs to push a menu change or create an order from outside the admin panel, this version doesn't do that.

Reading orders without missing one

/orders and /reservations are built as polling sources, the pattern Zapier calls a Polling Trigger: you call on an interval, since there's no webhook yet. Call without since and you get the most recent limit records (25 by default, 100 max), newest first, a sample of what's there. Call with since set to the newest createdAt you've already seen, and you get everything after it, oldest first this time, so you can walk forward without gaps.

That ordering flip on the second call isn't an accident. Fetch newest-first and cut it off at limit, and a burst of orders between two polls, a lunch rush, say, could push older-but-still-unseen records past the page and out of the response. Ascending order with a > filter on createdAt means nothing between polls gets skipped, only delayed by one more call.

An order record carries status, channel, lines (item, quantity, unit price), meta (dine-in or takeaway, table number), totalPrice, totalQty, and currency. It also carries taxAmount, discountAmount, and couponCode, each nullable. Those three exist so you can reconcile the total against the line items yourself: a coupon order's lines sum to more than totalPrice, and a VAT-inclusive tenant's tax portion isn't visible anywhere else in the payload. status matches what your team sees on the Orders board itself, an order logged before that board existed still reports as new, not some old internal label your integration would have to special-case.

Rate limits and errors

Sixty requests a minute per API key. Go over it and you get a 429. There's a second limiter underneath that one, keyed by IP address instead of by key, that catches a stream of bad Bearer tokens before they ever touch the database, so a broken integration retrying an invalid key in a loop can't run up your reads. A missing or wrong key returns 401 with { "error": { "message": "..." } }, in that shape every time.

What's not here yet

No writes. No webhooks, polling only. And no live Zapier app: the REST surface above is engineering-complete and exactly what a Zapier "New Order" or "New Reservation" trigger would be built on, but publishing an actual app to Zapier's directory is a separate step nobody's taken yet. If you're integrating today, you're calling the API directly.

Who this is actually for

Most restaurant owners never open this page. It's for the agency running several tenant accounts who wants order counts on a client dashboard without logging into each admin panel, or the POS vendor who'd rather poll /orders every thirty seconds than ask a client's staff to re-key what a Bearer token already sees. The owner and manager roles that gate the admin panel gate this too: build the integration as a manager, and you'll still need the owner to hand you the key, because there's no manager-level path to it.

Frequently Asked Questions

Only the owner. The page lives at Admin → API access, and a manager who opens that URL gets redirected straight back to the dashboard without ever seeing a key. If a manager needs an integration built, the owner has to generate the key and hand it over.

Not in v1. All four endpoints, /me, /menu, /orders, and /reservations, only support GET. Writing a menu item, order, or reservation from outside the admin panel isn't built yet. The API reads your data; it doesn't change it.

You poll. /orders and /reservations accept a since parameter (the newest createdAt you've already seen) and return everything after it, oldest first, up to your limit (25 by default, 100 max). There's no push notification yet. An integration checks on an interval, the same pattern a Zapier Polling Trigger uses.

The old key stops working the moment you do. Regenerating is meant for a key you think leaked, not routine rotation. Update whatever's using the old key first, then regenerate, or that integration goes dark until you fix it.

No. It's included for any tenant on the standard 90 EGP/month (or 1,000 EGP/year) plan. There's no separate API tier or add-on fee. The only limit is 60 requests a minute per key.

Not yet. The REST API is built and stable, and it's shaped for exactly that use (a /me connection test, polling triggers for new orders and reservations), but publishing an actual listing to Zapier's app directory hasn't happened. Today, connecting means calling the endpoints directly or wiring them into a tool like Make or n8n yourself.