API for machine clients
Other systems read and change records through a JSON API under /api/v1/.
The API follows the rules of the user interface: permissions and policies,
tenant isolation, validation with allow lists, UUIDs only, audit. Modules
declare endpoints; authentication, rate limits, logging and the OpenAPI
description come from Anvil.
- Clients are service accounts of one tenant with an explicit list of permissions, not users: they cannot log in to a panel.
- Resource endpoints list, show, create, change and delete the records of a resource, and run its actions.
- Custom endpoints are declared by applications and modules.
| Page | Content |
|---|---|
| Clients and tokens | service accounts, tokens, administration in the panel and on the command line |
| Calling the API | requests, answers and errors, idempotent writes, signed requests |
| Resource endpoints | list, show, create, change, delete, actions and transitions of resources |
| Custom endpoints | endpoints of applications and modules |
| OpenAPI | generated description of the endpoints |
| Logging and limits | audit, access log, security events, what the API does not do |
-
Switch the API on in
app/Config/Anvil.php:public array $apiPanels = ['admin']; // resources with $api in these panelspublic array $apiEndpoints = [\App\Api\ReportApi::class]; // custom endpoint groupsWith one of them set, the route
api/v1/*exists and the resource “API clients” appears next to users and roles (Access::resources()). -
Run the migrations:
php spark migrate --all. -
Exclude the API from the CSRF filter and from session based filters in
app/Config/Filters.php. API requests carry no cookies and no CSRF token; they authenticate with their token.public array $globals = ['before' => ['csrf' => ['except' => ['api/*']],],]; -
Schedule
php spark anvil:api:reviewandphp spark anvil:prunedaily (e.g. with codeigniter4/tasks). -
Operation:
- HTTPS: in production plain HTTP is refused (403). Behind a reverse
proxy, set
Config\App::$proxyIPsso that the client IP and the protocol are taken from the proxy. - Several servers: rate limits and the replay protection of signed
requests use the cache. With more than one server, use a shared cache
(e.g. Redis,
Config\Cache::$handler = 'redis').
- HTTPS: in production plain HTTP is refused (403). Behind a reverse
proxy, set