Troubleshooting the API
What happens when something is switched off or refused, and what to do about it. Every error
response carries a code and a request_id; start from the code.
403 MODULE_DISABLED on every request
The API app is switched off under Apps. It is the master shutoff: every endpoint on both lanes refuses, whatever key is sent. Keys are kept; switch the app back on and they work again.
Webhooks pause, they are not lost. While the API app is off nothing new is queued, and deliveries already waiting are held without using up their retries. They go out when the app is switched back on. See Webhook setup.
A browser's CORS preflight still succeeds while the app is off, so browser code sees the real
403 instead of an opaque network error.
403 MODULE_DISABLED on some endpoints only
The response's meta.module names the app that is off, for example:
{ "errors": [ { "title": "This module is disabled.", "code": "MODULE_DISABLED", "meta": { "module": "reservations" } } ] }
Only that app's endpoints refuse; the rest keep working. Switch the app on under Apps, or stop calling those endpoints. Which app each endpoint needs is in the table on Endpoint details.
An app that is off also produces no new webhook events (nothing in it can happen), and its events disappear from the event picker on the Webhooks screen. Deliveries already queued still go out.
403 API_DISABLED
Enable public API is off on the Configuration → REST API screen. Every endpoint refuses.
Webhooks are not affected by this switch: they follow only the API app on the Apps screen. To stop webhooks, remove the endpoints on the Webhooks screen or switch the API app off.
403 INSUFFICIENT_SCOPE
The key does not have the permission the request needs. meta.required_scopes says which:
{ "errors": [ { "title": "This API key does not have the permission this request needs.", "code": "INSUFFICIENT_SCOPE", "meta": { "required_scopes": ["orders:read"] } } ] }
A key's permissions cannot be edited after it is created. Create a new key with the right permissions, switch the integration to it, and revoke the old one.
403 DEMO_READONLY
The site is in demo mode. Reads work. Writes are refused, except placing an order and booking a table, which stay open because the storefront allows them too. See Demo mode.
403 INSUFFICIENT_PERMISSION
The key holds the permission, but the person it belongs to no longer does: their Next Restaurant
role was changed. A key never does more than its owner's role allows. Give the person the
permission back, or have someone who has it create the key. meta.scopes names what was refused.
403 ACCOUNT_UNUSABLE
The key is right, but the Joomla account it belongs to cannot be used: it is blocked, not yet activated, waiting for a password reset, or deleted. Fix the account under Users, or create a new key under an account that works. This does not count towards the wrong-key lockout.
401 INVALID_TOKEN
The key is missing, mistyped, revoked, switched off or past its expiry date. Check the key list on the REST API screen: the first characters of each key are shown, along with its Expires date and its Status switch.
If every request fails this way even with a key you just created, your web server may be dropping
the Authorization header. The API health panel checks this; see
Getting started.
429 RATE_LIMITED
Read the Retry-After header and wait that many seconds; nothing ran, so the request is safe to
repeat. The cause is one of:
- The key used its budget for the minute (300 reads or 60 changes by default).
RateLimit-Remainingon earlier responses showed it coming. Raise the limits on the REST API screen, or slow down. - 60 orders, or 30 bookings, from the same address in 5 minutes.
- 20 wrong keys from the same address in 5 minutes. The address is then refused for 5 minutes, on both lanes, even with a valid key. This is usually an integration still sending an old or revoked key in a loop: fix the key, then wait.
Plugins switched off
The Health tab of both the REST API and Webhooks screens says when a plugin they need is off: Web Services - NextRestaurant (without it every REST path answers 404) and Task - Next Restaurant Webhooks (without it failed webhooks are never retried). Someone Joomla allows to change plugins gets an Enable it button there, and a Repair button on the API card under Apps. Anyone else is told to ask a Super User. Updates never switch these plugins back on by themselves: switching one off may have been deliberate.
404 on every REST path
The answer comes from Joomla itself (code is the number 404), before Next Restaurant runs. The
Web Services - Next Restaurant plugin is disabled, so the routes do not exist.
The admin shows a banner and the API health panel names the problem, with a link to the plugin. Enable it under System → Plugins. Updates never switch it back on by themselves: if someone disabled it on purpose, that decision stands.
The query-string lane (index.php?option=com_nextrestaurant&format=json&task=publicApi.…) does not
need the plugin and keeps working for locations, the menu and placing orders.
404 NOT_FOUND or UNKNOWN_LOCATION
The id names nothing. UNKNOWN_LOCATION also covers a location that exists but is unpublished:
unpublished locations are invisible to the API.
405 METHOD_NOT_ALLOWED
The path exists but not with that verb, for example DELETE /orders. The Allow header lists the
verbs it does take. There are no DELETE endpoints: cancel a reservation by setting its status.
409 SLOT_UNAVAILABLE when booking
The time is closed, fully booked, too soon (inside the booking lead time) or the party is larger
than the venue seats; the error's title says which. Read
/locations/{id}/availability for that day and book one of the slots it offers.
412 PRECONDITION_FAILED
The record changed since you read it: your If-Match no longer matches its ETag. Read it again,
check the change still makes sense, and retry with the new ETag.
415, 413 or 400 INVALID_JSON on a write
Send the body as JSON with Content-Type: application/json, under 64 KB, as a JSON object (not an
array or a string).
Something else
For a 500, the detail of what failed is in the Joomla log (administrator/logs/), at the time
of the request. When you ask for support, include the request's X-Request-Id.