Build an app
Apps extend a restaurant's account through scoped, revocable OAuth access. Your code runs on your servers; the platform holds the registry, the install ledger, and the billing rails. This guide takes you from zero to an installed, metered app.
1. Register your app
Create an app in the partner dashboard: name, category, the scopes you need, an optional webhook URL, and your billing model. Submitting mints an OAuth client (client id + secret) and puts the app in review. Once an admin approves it, it appears in the App Store and can be installed.
2. Get installed
A restaurant owner installs your app from its App Store detail page, granting the scopes you requested. Installation creates an AppInstallation and (for paid apps) charges the first period through their wallet.
3. Call the API
Exchange an OAuth token for the installing account, then call the REST API with it. Report usage, receive webhooks, or embed a page in their dashboard — covered below.
OAuth & tokens
Apps authenticate with OAuth 2.0 (Laravel Passport). Your client credentials come from the partner dashboard. Use the standard authorization-code flow; the granted token carries the scopes the owner approved at install.
# Exchange an authorization code for an access token
curl -X POST https://www.menubarcode.comoauth/token \
-d grant_type=authorization_code \
-d client_id=YOUR_CLIENT_ID \
-d client_secret=YOUR_CLIENT_SECRET \
-d redirect_uri=YOUR_REDIRECT \
-d code=AUTH_CODE
# Call the API with the returned bearer token
curl https://www.menubarcode.com/api/v1/restaurants \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Accept: application/json"
Tokens are scoped: a call needing orders:read fails unless the owner granted it. Request the minimum set — reviewers check this.
Session tokens
For short-lived, server-to-embed calls, mint a session token from an active installation. Tokens expire after 60 seconds.
GET https://www.menubarcode.comapps/{appId}/session-token
# → { "token": "…", "expires_in": 60 }
Embedded apps
If your app declares an embed_url, the platform hosts it in an iframe inside the owner's dashboard at /apps/{appId}/embed. Pair it with a session token (above) to authenticate the embedded page without a full OAuth round-trip.
Webhooks
Subscribe to events at your app's webhook_url. Deliveries are queued, retried, and signed with the Standard Webhooks scheme using your app's signing secret. Your endpoint must be a public HTTPS URL (no private/loopback/metadata hosts) and return 2xx quickly.
# A delivery your endpoint receives
POST https://your-app.com/webhooks
webhook-id: msg_...
webhook-timestamp: 1710000000
webhook-signature: v1,BASE64_HMAC
Content-Type: application/json
{ "type": "order.paid", "data": { "order_id": 123, ... } }
Verify the signature against your secret before trusting a payload. See the event list.
Usage billing
Usage-billed apps meter consumption by reporting units. Each report is charged to the owner's wallet at your per-unit price. Pass a unique ref to make a report idempotent (a repeat with the same ref is ignored).
curl -X POST https://www.menubarcode.com/api/app/usage \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Accept: application/json" \
-d quantity=1 \
-d ref=unique-key-per-event
| Field | Type | Notes |
|---|---|---|
quantity | number > 0 | required — units consumed |
ref | string ≤ 120 | optional idempotency key |
The endpoint returns 403 if the token doesn't belong to a registered app or the app isn't installed for the account.
How-to guides
Choose a billing type
- Free — no charge on install.
- Recurring — a fixed price charged every billing period (default 30 days) from the owner's wallet.
- Usage-based — a per-unit price billed as you report usage.
Request scopes responsibly
Only request scopes your app uses. Changing scopes on a live listing sends the app back to review. See the scopes reference.
Clean up on uninstall
When an owner uninstalls, the platform revokes the app's tokens and fires an app/uninstalled event. Stop background work and delete stored data for that account when you receive it.
scopes reference
Reflected from the platform's OAuth scope registry.
| Scope | Grants |
|---|---|
menu:read | Read menus, categories and items |
menu:write | Create and update menu items |
orders:read | Read orders and their status |
orders:write | Create and update orders |
analytics:read | Read scan and sales analytics |
restaurant:read | Read restaurant profile and settings |
Webhook events
Events you can subscribe to today:
| Event |
|---|
order.created |
order.status_changed |
order.paid |
refund.completed |
reservation.created |
reservation.cancelled |
customer.created |
shift.opened |
shift.closed |
menu.updated |
entitlement.changed |
subscription.paused |
subscription.resumed |
subscription.renewed |
subscription.expired |
subscription.plan_changed |
subscription.past_due |
subscription.expiring |
subscription.trial_ending |
app.uninstalled |
Listing & review requirements
Before an admin approves your app, it must:
- Request only the scopes it uses, each justified in the description.
- Provide a working webhook endpoint (public HTTPS) if it subscribes to events.
- Declare accurate pricing — the pricing table on your detail page is generated from it.
- Include a clear tagline, description, category, and at least one screenshot.
- Handle uninstall cleanly (revoke access, stop billing, delete account data).
Metadata edits (tagline, description, screenshots, links) go live immediately; price or scope changes re-queue review.
