Menuraq Developer API v1
Production API Docs for Menuraq Integrations
Build secure integrations with business-scoped keys, strict scope checks, rate limiting, and traceable request IDs. Use this page as your complete endpoint reference plus in-browser request tester.
Base URL
https://menuraq.comVersion
/api/v1Auth
Bearer or x-api-keyAuthentication
Use API key auth for `/api/v1` endpoints.
Supported headers:
Authorization: Bearer <api_key>
x-api-key: <api_key>Dashboard key-management endpoints (`/api/developer-keys/*`) use signed-in dashboard session tokens.
Quickstart
Fast path to first request.
1. Enable 2FA in Dashboard Settings.
2. Create API key in Dashboard Settings -> Developer API.
3. Grant minimal scopes, then call `/api/v1/business`.
curl -H "Authorization: Bearer $MNRQ_API_KEY" \
"https://menuraq.com/api/v1/business"API Playground
Test endpoints directly from your browser. Your API key is only used in this request and is not persisted.
Scope Model
read:all
Wildcard read access across all read endpoints.
read:business
Business profile and business-level stats.
read:branches
Branch listings and branch metadata.
read:menus
Menus and menu detail payloads.
read:menu-items
Menu item listings.
write:menu-items
Menu item updates (PATCH).
read:analytics
Analytics totals and date windows.
read:promotions
Promotion listings and detail views.
read:templates
Template render access (iframe/html).
API Key Management Endpoints
/api/developer-keysDashboard JWTScope: dashboard-user-sessionList API keys for businesses owned by the signed-in account.
Returns keys with prefix, scopes, expiry, usage timestamps, and creation metadata for your businesses.
Query Params
| Name | Type | Required | Description |
|---|---|---|---|
| businessId | uuid | No | Filter keys by one business. |
Notes
- - Requires signed-in dashboard user session.
- - 2FA must be enabled to access Developer API management UI.
curl -H "Authorization: Bearer $DASHBOARD_JWT" \
"https://menuraq.com/api/developer-keys?businessId=<uuid>"Response Example
{
"ok": true,
"keys": [{
"id": "a4f...",
"name": "Production Mobile",
"key_prefix": "mnrq_live_a1b2c3d4",
"scopes": ["read:business", "read:menus"],
"rate_limit_per_minute": 120
}]
}/api/developer-keysDashboard JWTScope: dashboard-user-sessionCreate a new API key and reveal plaintext once.
Creates a business-scoped key with least-privilege scopes. Plaintext secret is only returned in this response.
Body Params
| Name | Type | Required | Description |
|---|---|---|---|
| businessId | uuid | Yes | Target business ID. |
| name | string | Yes | Readable key name shown in dashboard. |
| scopes | string[] | No | Requested scopes. |
| expiresAt | datetime | No | Exact expiration timestamp. |
| expiresInDays | integer | No | Relative expiration in days. |
| currentPassword | string | No | Password confirmation for password-based accounts. |
Notes
- - A maximum of 3 active API keys is allowed per business.
- - Menuraq enforces secure default rate limiting server-side.
curl -X POST \
-H "Authorization: Bearer $DASHBOARD_JWT" \
-H "Content-Type: application/json" \
-d '{"businessId":"<uuid>","name":"Android app","scopes":["read:business","read:menus"]}' \
"https://menuraq.com/api/developer-keys"Response Example
{
"ok": true,
"key": { "id": "a4f...", "key_prefix": "mnrq_live_a1b2c3d4" },
"apiKey": "mnrq_live_a1b2c3d4_...",
"warning": "Store this API key now. Menuraq will not show it again."
}/api/developer-keys/:id/rotateDashboard JWTScope: dashboard-user-sessionRotate one key and issue a replacement secret.
Invalidates previous key hash and returns a new plaintext key once.
Path Params
| Name | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | API key ID to rotate. |
Body Params
| Name | Type | Required | Description |
|---|---|---|---|
| currentPassword | string | No | Password confirmation for password-based accounts. |
curl -X POST \
-H "Authorization: Bearer $DASHBOARD_JWT" \
-H "Content-Type: application/json" \
-d '{"currentPassword":"<password>"}' \
"https://menuraq.com/api/developer-keys/<id>/rotate"Response Example
{
"ok": true,
"key": { "id": "a4f...", "key_prefix": "mnrq_live_9f8e7d6c" },
"apiKey": "mnrq_live_9f8e7d6c_..."
}/api/developer-keys/:id/secretDashboard JWTScope: dashboard-user-sessionReveal existing secret after password confirmation.
Shows decrypted API key for already-issued keys using secure storage.
Path Params
| Name | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | API key ID to reveal. |
Body Params
| Name | Type | Required | Description |
|---|---|---|---|
| currentPassword | string | Yes | Account password. |
curl -X POST \
-H "Authorization: Bearer $DASHBOARD_JWT" \
-H "Content-Type: application/json" \
-d '{"currentPassword":"<password>"}' \
"https://menuraq.com/api/developer-keys/<id>/secret"Response Example
{
"ok": true,
"key": { "id": "a4f...", "name": "Production Mobile", "key_prefix": "mnrq_live_a1b2c3d4" },
"apiKey": "mnrq_live_a1b2c3d4_..."
}/api/developer-keys/:idDashboard JWTScope: dashboard-user-sessionPermanently delete one API key.
Removes key record and immediately blocks future usage.
Path Params
| Name | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | API key ID to delete. |
curl -X DELETE \
-H "Authorization: Bearer $DASHBOARD_JWT" \
"https://menuraq.com/api/developer-keys/<id>"Response Example
{
"ok": true,
"deleted": true
}/api/developer-keys/:id/usageDashboard JWTScope: dashboard-user-sessionGet usage summary and per-request logs for one key.
Returns aggregate counts and recent request-level logs for observability.
Path Params
| Name | Type | Required | Description |
|---|---|---|---|
| id | uuid | Yes | API key ID. |
Query Params
| Name | Type | Required | Description |
|---|---|---|---|
| date_from | YYYY-MM-DD | No | Window start date. |
| date_to | YYYY-MM-DD | No | Window end date. |
| limit | 1..500 | No | Log row limit. |
curl -H "Authorization: Bearer $DASHBOARD_JWT" \
"https://menuraq.com/api/developer-keys/<id>/usage?limit=100"Response Example
{
"ok": true,
"usage": {
"total_requests": 982,
"window_count": 100,
"summary": { "success_count": 97, "error_count": 3 }
}
}Public Data Endpoints
/api/v1/businessAPI KeyScope: read:businessGet business profile and top-level stats.
Returns business identity data plus aggregate menu/branch/promotion counts.
curl -H "Authorization: Bearer $MNRQ_API_KEY" \
"https://menuraq.com/api/v1/business"Response Example
{
"ok": true,
"request_id": "89ff...",
"data": {
"business": { "id": "b1...", "name": "Blue Olive" },
"stats": { "menus": 4, "branches": 3, "active_promotions": 2 }
}
}/api/v1/branchesAPI KeyScope: read:branchesList branch records for the current business.
Returns branches with status and summary fields.
Query Params
| Name | Type | Required | Description |
|---|---|---|---|
| include_inactive | boolean | No | Include inactive branches in results. |
curl -H "Authorization: Bearer $MNRQ_API_KEY" \
"https://menuraq.com/api/v1/branches?include_inactive=false"Response Example
{
"ok": true,
"data": [
{ "id": "br1...", "name": "Airport", "menu_count": 1 },
{ "id": "br2...", "name": "Downtown", "menu_count": 1 }
]
}/api/v1/analyticsAPI KeyScope: read:analyticsGet aggregate analytics for configured date windows.
Returns totals, per-menu series, and optional daily details.
Query Params
| Name | Type | Required | Description |
|---|---|---|---|
| menu_id | uuid | No | Filter to one menu. |
| date_from | YYYY-MM-DD | No | Window start date. |
| date_to | YYYY-MM-DD | No | Window end date. |
| include_daily | boolean | No | Include day-level rows in output. |
curl -H "Authorization: Bearer $MNRQ_API_KEY" \
"https://menuraq.com/api/v1/analytics?date_from=2026-01-01&date_to=2026-01-31"Response Example
{
"ok": true,
"data": {
"totals": { "views": 3242, "scans": 991, "downloads": 122, "shares": 63 },
"by_menu": [{ "menu_id": "m1...", "views": 3242 }]
}
}/api/v1/promotionsAPI KeyScope: read:promotionsList promotions with activity and menu filters.
Returns promotion rows in business scope, optionally active-only.
Query Params
| Name | Type | Required | Description |
|---|---|---|---|
| menu_id | uuid | No | Filter by menu. |
| active_only | boolean | No | Only active promotions. |
| limit | integer | No | Max rows. |
| offset | integer | No | Pagination offset. |
curl -H "Authorization: Bearer $MNRQ_API_KEY" \
"https://menuraq.com/api/v1/promotions?active_only=true"Response Example
{
"ok": true,
"data": [{ "id": "p1...", "title": "Happy Hour", "is_active": true }]
}/api/v1/promotions/:promotionIdAPI KeyScope: read:promotionsGet one promotion detail in tenant scope.
Returns one promotion object by ID.
Path Params
| Name | Type | Required | Description |
|---|---|---|---|
| promotionId | uuid | Yes | Promotion ID. |
curl -H "Authorization: Bearer $MNRQ_API_KEY" \
"https://menuraq.com/api/v1/promotions/<promotionId>"Response Example
{
"ok": true,
"data": { "id": "p1...", "title": "Happy Hour", "discount_type": "percentage" }
}/api/v1/templates/renderAPI KeyScope: read:templatesGet menu template render as iframe metadata or raw HTML.
Supports menu selector, mode selection, and header visibility control for embeds.
Query Params
| Name | Type | Required | Description |
|---|---|---|---|
| menu_id | uuid | No | Target menu ID (one of menu_id/menu_slug). |
| menu_slug | string | No | Target menu slug (one of menu_id/menu_slug). |
| mode | iframe|html | No | Render output mode. |
| hide_header | boolean | No | When true, public URL adds embed mode and hides the /m page header. |
Notes
- - When mode=iframe, hide_header defaults to true unless explicitly disabled.
curl -H "Authorization: Bearer $MNRQ_API_KEY" \
"https://menuraq.com/api/v1/templates/render?menu_slug=main-menu&mode=iframe&hide_header=true"Response Example
{
"ok": true,
"data": {
"mode": "iframe",
"public_url": "https://menuraq.com/m/main-menu?embed=1",
"presentation": { "hide_header": true },
"embed_code": "<iframe src=\"...\"></iframe>"
}
}HTTP Status Codes
Successful request.
Resource created.
Invalid payload or query parameters.
Missing/invalid credentials or API key.
Insufficient scope or unauthorized access.
Resource not found in tenant scope.
Conflict (for example max keys reached).
Rate limit exceeded.
Internal server error.
Service not configured in environment.
Production checklist
Set `DEVELOPER_API_KEY_PEPPER`, set `DEVELOPER_API_KEY_ENCRYPTION_SECRET`, rotate keys, keep scopes least-privilege, and monitor request logs in Dashboard Settings.