Next Restaurant 6.1.0: move your data in, run payroll, and connect other systems Next Inventory 6.2.0: a REST API and webhooks for your other systems Next DB 6.1: Auto-Updating Tables, Printing, Phone Layout and SEO Next Task 6.0.0: a task manager for Joomla Next Inventory 6.1.1: smoother Check Out, no more list limits, and much faster PHP2Shell: Is Your Joomla Site Safe? What to Do Today Introducing Next Boards: Kanban project and task boards for Joomla Building the Future of Joomla Extensions
NextSoftware

Getting started with the REST API

A public REST surface for what you run alongside Next Restaurant: a kiosk, a booking widget, a mobile app, a delivery or accounting integration, or a sync into another system.

It is off by default. Public endpoints are reachable without an admin session, so they are opt-in rather than opt-out.

What it covers:

Group You can
Catalogue Read locations and each location's live menu
Orders Place orders, read them back, list them for syncing
Reservations Read bookable slots, book a table, change or cancel a booking
Menu & stock 86 an item or change its price at a location, set stock counts, 86 an ingredient
Reporting Read customers, payments, refunds, the sales summary and timesheets

It does not take payment, and it is not a remote-administration interface: settings, staff and the menu structure are managed in the admin.


Two ways in

There are two transports. They take the same keys with the same permissions.

REST (recommended) Query-string (original)
Base /api/index.php/v1/nextrestaurant /index.php?option=com_nextrestaurant&format=json
Style Resource paths and HTTP verbs One path, operation chosen by task=
Covers Everything on this page Locations, menu and placing an order only
Types Real arrays, objects and numbers Some fields are JSON-encoded strings
OpenAPI Fully described Cannot be described — see below
Status Current Supported, frozen

Start with REST. It is the surface the OpenAPI document describes, so you can generate a client, load it into Swagger UI or Postman, and have your tooling validate responses for you.

The query-string lane still works exactly as it always has and is not going away, but it gains no new endpoints. It cannot be expressed in OpenAPI at all: the specification keys every operation on a path plus a method, and two GETs on /index.php are not expressible. That limitation is the reason the REST routes exist.


Enabling it

  1. Go to Apps and turn on the API app.
  2. Go to Configuration → REST API and turn on Enable public API. Press Save.
  3. Under API keys, press New key and create a key for your integration (see below).
  4. Copy the key immediately. It is shown once.

There are two switches and both must be on. The API app under Apps is the master shutoff; Enable public API is the day-to-day one. Turning either off refuses every request, whoever holds a key. See Troubleshooting for what each one does to webhooks.

Each group of endpoints also needs its own app: reservation endpoints need the Reservations app, stock endpoints the Inventory app, and so on. An endpoint whose app is off answers 403 MODULE_DISABLED and names the app.

Before 6.1 this screen was Integrations. The API and webhooks now have a screen each: Configuration → REST API and Configuration → Webhooks. Old bookmarks to Integrations open the REST API screen.


API keys

The Keys tab: each key with its owner, permissions, last use, expiry and switch

Give every integration its own key, with only the permissions it needs. A booking widget needs to read availability and create bookings; it has no business reading payroll. If a key leaks, you revoke that one key and nothing else stops working.

Creating a key. Press New key, give it a name that says which integration uses it (for example "Booking widget"), and tick its permissions in the grid. Each row is one area, with a Read and a Change column:

Area Read Change
Locations & menu menu:read menu:write
Stock levels inventory:read inventory:write
Orders orders:read orders:write
Reservations reservations:read reservations:write
Customers customers:read —
Payments & refunds payments:read —
Sales reports reports:read —
Timesheets staff:read —

The scope names are what the API reports. A request a key lacks the permission for is refused with 403 INSUFFICIENT_SCOPE, and meta.required_scopes names what was missing. A Change permission does not include Read: tick both when an integration needs both.

The key is shown exactly once. Only a SHA-256 hash is stored, so it cannot be recovered. If you lose it, create a new key and revoke the old one. Keys start with nrk_, so a leaked key is easy to recognise in logs and code.

Whose key it is. A key belongs to the person who created it and acts as that Joomla user. It can never do more than that person's Next Restaurant role allows, and this is checked on every request: take a permission away from the person and their keys lose it at once (403 INSUFFICIENT_PERMISSION). The create dialog only offers the permissions your role has. If the person's account is blocked, not yet activated, waiting for a password reset, or deleted, their keys are refused with 403 ACCOUNT_UNUSABLE. Changes a key makes are recorded in the audit log under its owner, marked with the key's name.

Super Users see every key, with an Acts as column naming its owner. Everyone else sees and manages only their own keys.

Expiry. Give a key an Expires date and it works through the end of that day, in the restaurant's time zone; after that it is refused with 401 like an unknown key. Leave it empty for a key that never expires.

Switching a key off. The switch in the Status column stops a key without revoking it: it is refused with 401 until you switch it back on.

Editing. Edit changes a key's name, permissions, expiry and switch. Its token stays the same, so the integration keeps working with its new permissions.

Revoking. Press Revoke on the key's row. Its very next request is refused with 401, and this cannot be undone. A revoked key stays in the list so you can see what existed. The list also shows when each key was last used.

The token from before 6.1. If your site had an API token before updating, it keeps working for exactly what it could do in 6.0 (reading the menu and placing orders), so nothing breaks on update. It does not gain any of the new permissions: to read orders, customers or reports, create a key that holds them. The keys panel says so. Give each integration its own key, then press Revoke on that notice to retire the old token.


Authentication

Every request carries a key:

Authorization: Bearer <your-api-key>

X-Api-Token: <your-api-key> is accepted as an alternative for clients that cannot set an Authorization header.

Writes made with a key are recorded in the audit log as [API: <key name>], so you can tell which integration changed what.


Rate limits

Each key may make 300 reads and 60 changes per minute by default. You can change both on the REST API screen (0 turns a limit off). Every response tells the client where it stands:

RateLimit-Limit: 300
RateLimit-Remaining: 297
RateLimit-Reset: 41

Over the limit, the answer is 429 RATE_LIMITED with a Retry-After header, and nothing ran.

Two more limits protect the site regardless of the key: placing orders is limited to 60 per address per 5 minutes, booking tables to 30 per address per 5 minutes, and an address that sends 20 wrong keys in 5 minutes is refused for 5 minutes, on both lanes, whatever key it sends next. See Worked example & advice.


API health

The Health tab: the setup steps in order, the next one highlighted

With the API switched on, Configuration → REST API → API health checks that clients can actually use it:

Check What it means
Authorization header Whether your web server passes Authorization: Bearer through to Joomla
API key Whether at least one key (or the pre-6.1 token) is active
REST routes Whether the Web Services - Next Restaurant plugin is enabled; without it /api/index.php/v1/nextrestaurant/… answers 404
HTTPS Whether the site is served over HTTPS, so keys aren't sent in clear

The first three stop every client, so they are also raised as a banner across the whole admin, for users who can manage settings, until they are fixed. Re-check runs the header test again immediately; it also re-runs by itself once a day.

When the web server drops the Authorization header

Some servers remove the Authorization header before PHP ever sees it. Every bearer request then fails with 401 Invalid API token, exactly as if the key were wrong. It is a server setting, not something the extension can work around:

Server Drops the header?
nginx + PHP-FPM No
Apache + mod_php No
Apache + PHP-FPM or mod_fcgid (FastCGI) Yes, unless configured

The API health panel shows the fix for your server. On Apache, any one of these works:

  1. Rename htaccess.txt to .htaccess in the site root. Joomla's own file already contains the fix (and you likely want it for SEF URLs anyway).

  2. Or add this line to the virtual host or .htaccess (Apache 2.4.13 or later):

    CGIPassAuth On
  3. Or, on mod_fcgid, add FcgidPassHeader Authorization to the virtual host.

On nginx, if a custom configuration strips it, add to the PHP location block:

fastcgi_param HTTP_AUTHORIZATION $http_authorization;

Until the server is fixed, clients can send the key as X-Api-Token: <your-api-key> instead — custom headers are never stripped.


Next

All Extensions