HTTP reference
Admin API
Admin routes live in routes/admin.php. All require auth + verified. Resource actions use permission:{PermissionEnum}; the file manager uses can.manage.files, which maps route name / HTTP method / bulk action to a file permission.
Client
These are same-origin session endpoints for the Inertia SPA (and occasional JSON fetches), not a public API. See Routing overview.
Users
| Method | Path | Route name | Permission |
|---|---|---|---|
GET | /users | users.index | can-show-users |
POST | /users | users.store | can-create-users |
PUT | /users/{user} | users.update | can-edit-users |
DELETE | /users/{user} | users.destroy | can-delete-users |
POST | /users/{user}/restore | users.restore | can-restore-users |
DELETE | /users/{user}/force | users.force-delete | can-force-delete-users |
POST | /users/bulk-actions | users.bulk-actions | Enforced in controller per action (not a single route middleware) |
Controller: App\Http\Controllers\Admin\UserController.
Groups
| Method | Path | Route name | Permission |
|---|---|---|---|
GET | /groups | groups.index | can-show-groups |
POST | /groups | groups.store | can-create-groups |
PUT | /groups/{group} | groups.update | can-edit-groups |
DELETE | /groups/{group} | groups.destroy | can-delete-groups |
POST | /groups/{group}/restore | groups.restore | can-restore-groups |
DELETE | /groups/{group}/force | groups.force-delete | can-force-delete-groups |
POST | /groups/bulk-actions | groups.bulk-actions | Enforced in FormRequest per action (delete / restore / force_delete) |
Controller: UserGroupController. Soft-delete lifecycle matches users (trashed filter on index, restore, force-delete, bulk). Groups inherit role permissions and role-tied collection/file ACL — see Users & groups.
Roles
| Method | Path | Route name | Permission |
|---|---|---|---|
GET | /settings/roles | roles.index | can-show-roles |
GET | /settings/roles/create | roles.create | can-create-roles |
POST | /settings/roles | roles.store | can-create-roles |
GET | /settings/roles/{role}/edit | roles.edit | can-edit-roles |
PUT | /settings/roles/{role} | roles.update | can-edit-roles |
DELETE | /settings/roles/{role} | roles.destroy | can-delete-roles |
POST | /settings/roles/bulk-actions | roles.bulk-actions | Enforced in controller per action |
Controller: RoleController. Create/edit are Inertia form pages; index/store/update/destroy also serve the SPA. Role forms also sync Collection access for the Public CMS API.
API keys
| Method | Path | Route name | Permission |
|---|---|---|---|
GET | /settings/api-keys | api-keys.index | can-show-api-keys |
POST | /settings/api-keys | api-keys.store | can-manage-api-keys |
DELETE | /settings/api-keys/{apiKey} | api-keys.destroy | can-manage-api-keys |
Controller: ApiKeyController. Secrets (ek_…) are shown once after create. Keys authenticate /api/v1 — see Public CMS API.
Permissions (+ sync)
| Method | Path | Route name | Permission |
|---|---|---|---|
GET | /settings/permissions | permissions.index | can-show-permissions |
POST | /settings/permissions | permissions.store | can-create-permissions |
PUT | /settings/permissions/{permission} | permissions.update | can-edit-permissions |
DELETE | /settings/permissions/{permission} | permissions.destroy | can-delete-permissions |
POST | /settings/permissions/sync | permissions.sync | can-edit-permissions |
POST /settings/permissions/sync runs php artisan permissions:sync (optional prune from the request body / controller). Prefer enum-driven sync over ad-hoc DB permission rows — see Effective permissions and Extending Externa.
Activity logs
| Method | Path | Route name | Permission |
|---|---|---|---|
GET | /activity-logs | activity-logs.index | can-show-activity-logs |
Controller: ActivityLogController (Spatie activity log UI).
Jobs monitor
Defined in routes/admin.php under /settings/jobs:
| Method | Path | Route name | Permission |
|---|---|---|---|
GET | /settings/jobs | jobs.index | can-show-jobs |
POST | /settings/jobs/{uuid}/retry | jobs.retry | can-manage-jobs |
DELETE | /settings/jobs/{uuid} | jobs.destroy | can-manage-jobs |
Product notes: Operations — Jobs monitor.
Project settings (related)
Project + branding HTTP live in routes/settings.php (not admin.php) and require can-manage-project-settings:
| Method | Path | Name |
|---|---|---|
GET/PUT | /settings/project | project.edit / project.update |
POST | /settings/project/webhook-test | project.webhook-test |
GET/PUT | /settings/appearance | appearance.edit / appearance.update |
Full guide: Project settings.
Files (can.manage.files)
All routes below sit in:
Route::middleware(['auth', 'verified'])->group(...)
Route::middleware('can.manage.files')->group(...)
Prefix: /files, name prefix: files..
How permissions are chosen
EnsureCanManageFiles resolves a PermissionEnum then checks EffectivePermissionResolver:
| Route name / case | Permission |
|---|---|
files.restore | can-restore-files |
files.force-delete | can-force-delete-files |
files.download, files.download-many, files.zips.download | can-download-files |
files.favorite, files.unfavorite | can-favorite-files |
files.copy | can-copy-files |
files.replace | can-replace-files |
files.tags | can-tag-files |
files.update | can-update-file-metadata |
files.bulk | Depends on JSON action (see below) |
Other GET/HEAD | can-show-files |
Other POST | can-create-files |
Other PUT/PATCH | can-edit-files |
Other DELETE | can-delete-files |
Bulk action → permission:
action | Permission |
|---|---|
restore | can-restore-files |
force_delete | can-force-delete-files |
favorite, unfavorite | can-favorite-files |
tag, untag | can-tag-files |
copy | can-copy-files |
delete | can-delete-files |
move | can-edit-files |
| (default) | can-edit-files |
List, browse, tags
| Method | Path | Route name | Typical permission |
|---|---|---|---|
GET | /files/list | files.list | can-show-files |
GET | /files/tags | files.tags.index | can-show-files |
GET | /files/{folder?} | files.index | can-show-files (folder must be numeric) |
files.index is the Inertia file-manager page. Static /files/* paths are registered before {folder} so names like list are not treated as folder IDs.
Upload and chunked upload
| Method | Path | Route name | Typical permission |
|---|---|---|---|
POST | /files/upload | files.upload | can-create-files |
POST | /files/folders | files.folders.store | can-create-files |
POST | /files/uploads/init | files.uploads.init | can-create-files |
POST | /files/uploads/chunk | files.uploads.chunk | can-create-files |
POST | /files/uploads/complete | files.uploads.complete | can-create-files |
GET | /files/uploads/status | files.uploads.status | can-show-files |
Stale incomplete uploads are cleaned by files:cleanup-uploads (Files configuration).
Bulk, download, zip
| Method | Path | Route name | Permission notes |
|---|---|---|---|
POST | /files/bulk | files.bulk | Per action (table above) |
POST | /files/download | files.download-many | can-download-files |
GET | /files/zips/{jobId} | files.zips.download | can-download-files |
Multi-file/folder zips are prepared asynchronously; expired archives are removed by files:cleanup-zips.
Single-file mutations
| Method | Path | Route name | Permission |
|---|---|---|---|
PATCH | /files/{file} | files.update | can-update-file-metadata |
POST | /files/{file}/replace | files.replace | can-replace-files |
POST | /files/{file}/copy | files.copy | can-copy-files |
POST | /files/{file}/favorite | files.favorite | can-favorite-files |
DELETE | /files/{file}/favorite | files.unfavorite | can-favorite-files |
PUT | /files/{file}/tags | files.tags | can-tag-files |
GET | /files/{file}/download | files.download | can-download-files |
GET | /files/{file}/thumbnail | files.thumbnail | can-show-files |
GET | /files/{file}/where-used | files.where-used | can-show-files |
PATCH | /files/{file}/move | files.move | can-edit-files |
PATCH | /files/{file}/rename | files.rename | can-edit-files |
DELETE | /files/{file} | files.destroy | can-delete-files |
POST | /files/{file}/restore | files.restore | can-restore-files |
DELETE | /files/{file}/force | files.force-delete | can-force-delete-files |
POST | /files/{file}/attach | files.attach | can-create-files (POST default) |
POST | /files/{file}/detach | files.detach | can-create-files (POST default) |
Controller: App\Http\Controllers\Admin\FileController. Storage/threshold config: Files configuration. Tree model: File tree model.