Admin2 Integration
Endpoints that power Admin2's extensibility and preferences: menubar toolbar items, floating widgets, slide-in context panels, settings-page panels, the registry of plugin-provided custom field components, markdown editor toolbar buttons, and Admin2's user and site preferences and branding. All en...
Endpoints that power Admin2's extensibility and preferences: menubar toolbar items, floating widgets, slide-in context panels, settings-page panels, the registry of plugin-provided custom field components, markdown editor toolbar buttons, and Admin2's user and site preferences and branding.
All endpoints require api.access and are meant to be called by Admin2, not by end-user applications. Writing site preferences and branding also needs a super user. The UI registries are backed by events (onApiMenubarItems, onApiFloatingWidgets, onApiContextPanels, onApiAdminSettingsPanels, onApiMarkdownEditorButtons), which plugins hook to register items. See the Developer Guide for the full integration recipe.
Menubar Items
/menubar/items
{"data": [{"id": "warm-cache", "plugin": "warm-cache", "label": "Warm Cache", "icon": "fa-tachometer", "action": "warm", "confirm": "Warm the cache?"}, {"id": "new-article", "plugin": "my-plugin", "label": "New Article", "icon": "fa-plus", "route": "/pages/new?parent=/blog&template=item"}]}
Response Codes
Execute Menubar Action
/menubar/actions/{plugin}/{action}
Parameters
| Name | Type | Description |
|---|---|---|
| plugin required | string | Owning plugin slug (from the menubar item registration). |
| action required | string | Action key (from the menubar item registration). |
{}
{"data": {"status": "success", "message": "Cache warmed successfully."}}
Response Codes
Floating Widgets
/floating-widgets
{"data": [{"id": "ai-pro-chat", "plugin": "ai-pro", "label": "AI Assistant", "icon": "bot", "priority": 10}, {"id": "users-enhancer", "plugin": "my-plugin", "label": "Users enhancer", "showFab": false, "autoLoad": true, "routes": ["/users"]}]}
Response Codes
Each widget carries an id, plugin, label, icon and optional priority. Widgets are returned in event order; Admin2 sorts them by priority. A widget may declare authorize (a permission string, or an array for an any-of test): widgets the caller fails are left out and authorize is stripped from the response. Two optional flags control loading:
autoLoad— load the widget's script eagerly instead of on first launcher click. Used by field/table enhancers that register behavior without showing a floating action button (usually paired withshowFab: false).routes— a list of admin-internal SPA routes (/users,/pages,/plugin/my-plugin) an autoloading widget applies to. Admin2 loads the script only on an exact route match; omit it to load on every route. The API normalizes each entry to a leading-slash, trailing-slash-free path and drops invalid ones.routesscopes script loading only — it is not a permission boundary;authorizeremains the security check.
See the API Events page for the onApiFloatingWidgets contract and the Developer Guide for the full widget recipe.
Context Panels
/context-panels
{"data": [{"id": "revisions-pro", "plugin": "revisions-pro", "label": "Revision History", "icon": "history", "contexts": ["pages"], "priority": 10, "width": 900, "badgeEndpoint": "/revisions-pro/badge"}]}
Response Codes
Settings Panels
/settings/panels
{"data": [{"id": "login-settings", "plugin": "api", "label": "Login & Security", "description": "Authentication settings", "icon": "fa-shield-alt", "blueprint": "login-settings", "data_endpoint": "/login-settings/data", "save_endpoint": "/login-settings/save", "priority": 0}]}
Response Codes
List Custom Fields
/custom-fields
{"data": {"codeshtheme": {"slug": "codesh", "kind": "plugins"}, "products-status": {"slug": "license-manager", "kind": "plugins"}, "tinymce": {"slug": "mytheme", "kind": "themes"}}}
Response Codes
Editor Toolbar Buttons
/editor/toolbar-buttons
{"data": [{"id": "youtube", "plugin": "youtube", "label": "YouTube Video", "icon": "<svg viewBox=\"0 0 24 24\">...</svg>", "modal": {"component": "youtube-insert", "title": "Insert YouTube Video", "size": "md"}}, {"id": "hr", "plugin": "my-plugin", "label": "Horizontal Rule", "icon": "fa-minus", "insert": {"content": "---", "mode": "insert-at-cursor"}}]}
Response Codes
Get Admin2 Preferences
/admin-next/preferences
{"data": {"branding": {"mode": "default", "text": "Grav", "logoLight": "", "logoDark": "", "logoHeight": 0, "title": "", "subtitle": "", "showPoweredBy": true, "favicon": ""}, "branding_urls": {"light": "", "dark": "", "favicon": ""}, "site": {"colorMode": "", "accentHue": 271, "accentSaturation": 91, "fontFamily": "google-sans", "fontSize": "normal", "editorMode": "normal", "editorKeymap": "default", "editorStickyToolbar": true, "editorFixedHeight": 0, "adminLanguage": "en", "pagesPerPage": 20, "pagesViewMode": "miller", "usersViewMode": "cards", "groupsViewMode": "cards", "pluginsViewMode": "cards", "themesViewMode": "cards", "flexAfterSave": ""}, "site_settings": {"autoSaveEnabled": false, "autoSaveToolbarUndo": true, "autoSaveBatchWindowMs": 0, "collabEnabled": true, "menubarLinks": []}, "media_upload": {"resizeWidth": 0, "resizeHeight": 0, "resizeQuality": 0.8, "minWidth": 0, "minHeight": 0, "maxWidth": 0, "maxHeight": 0}, "user": {"colorMode": "dark"}, "effective": {"colorMode": "dark", "accentHue": 271, "accentSaturation": 91, "fontFamily": "google-sans", "fontSize": "normal", "editorMode": "normal", "editorKeymap": "default", "editorStickyToolbar": true, "editorFixedHeight": 0, "adminLanguage": "en", "pagesPerPage": 20, "pagesViewMode": "miller", "usersViewMode": "cards", "groupsViewMode": "cards", "pluginsViewMode": "cards", "themesViewMode": "cards", "flexAfterSave": "", "autoSaveEnabled": false, "autoSaveToolbarUndo": true, "autoSaveBatchWindowMs": 0, "collabEnabled": true, "menubarLinks": []}, "can_edit_site": true}}
Response Codes
Values that a user can override resolve in this order: built-in defaults, then the site defaults (ui.defaults in user/config/admin-next.yaml), then the user's own overrides (admin_next.preferences in their account file). If the user has never picked an admin language in Admin2, a classic admin language: value on the account is used instead. Site-only settings (ui.settings: auto-save, collaboration and menubar links) are applied last and can't be overridden per user.
Update User Preferences
/admin-next/preferences/user
{"colorMode": "dark", "accentHue": 200, "fontSize": null}
{"data": {"branding": {"mode": "default", "text": "Grav"}, "branding_urls": {"light": "", "dark": "", "favicon": ""}, "site": {"colorMode": "", "accentHue": 271}, "site_settings": {"autoSaveEnabled": false}, "media_upload": {"resizeWidth": 0}, "user": {"colorMode": "dark", "accentHue": 200}, "effective": {"colorMode": "dark", "accentHue": 200, "fontSize": "normal"}, "can_edit_site": false}}
Response Codes
Reset User Preferences
/admin-next/preferences/user
{"data": {"branding": {"mode": "default", "text": "Grav"}, "branding_urls": {"light": "", "dark": "", "favicon": ""}, "site": {"colorMode": "", "accentHue": 271}, "site_settings": {"autoSaveEnabled": false}, "media_upload": {"resizeWidth": 0}, "user": [], "effective": {"colorMode": "", "accentHue": 271}, "can_edit_site": false}}
Response Codes
Update Site Preferences
/admin-next/preferences/site
{"accentHue": 271, "fontFamily": "inter", "colorMode": null, "autoSaveEnabled": true, "menubarLinks": [{"label": "Docs", "url": "https://learn.getgrav.org", "icon": "book", "external": true}]}
{"data": {"branding": {"mode": "default", "text": "Grav"}, "branding_urls": {"light": "", "dark": "", "favicon": ""}, "site": {"colorMode": "", "accentHue": 271, "fontFamily": "inter"}, "site_settings": {"autoSaveEnabled": true, "autoSaveToolbarUndo": true, "autoSaveBatchWindowMs": 0, "collabEnabled": true, "menubarLinks": [{"label": "Docs", "url": "https://learn.getgrav.org", "icon": "book", "external": true}]}, "media_upload": {"resizeWidth": 0}, "user": [], "effective": {"colorMode": "", "accentHue": 271, "fontFamily": "inter", "autoSaveEnabled": true}, "can_edit_site": true}}
Response Codes
Each menubarLinks entry needs a non-empty label and url, and may carry icon and external; entries missing either required field are dropped.
Update Branding
/admin-next/branding
{"mode": "text", "text": "Acme CMS", "title": "Acme Content Admin", "logoHeight": 32, "showPoweredBy": false}
{"data": {"branding": {"mode": "text", "text": "Acme CMS", "logoLight": "", "logoDark": "", "logoHeight": 32, "title": "Acme Content Admin", "subtitle": "", "showPoweredBy": false, "favicon": ""}, "branding_urls": {"light": "", "dark": "", "favicon": ""}, "site": {"colorMode": "", "accentHue": 271}, "site_settings": {"autoSaveEnabled": false}, "media_upload": {"resizeWidth": 0}, "user": [], "effective": {"colorMode": "", "accentHue": 271}, "can_edit_site": true}}
Response Codes
Upload Branding Logo
/admin-next/branding/logo
Parameters
| Name | Type | Description |
|---|---|---|
| variant required | string | Query parameter (or multipart field): `light`, `dark` or `favicon`. The query parameter wins when both are sent. |
| file required | file | The image file (multipart field `file`, or `logo`). |
{"data": {"branding": {"mode": "custom", "text": "Grav", "logoLight": "logo-light-3f9c2a7e5b.svg", "logoDark": "", "logoHeight": 0, "title": "", "subtitle": "", "showPoweredBy": true, "favicon": ""}, "branding_urls": {"light": "/user/media/admin-next/logo-light-3f9c2a7e5b.svg", "dark": "", "favicon": ""}, "site": {"colorMode": "", "accentHue": 271}, "site_settings": {"autoSaveEnabled": false}, "media_upload": {"resizeWidth": 0}, "user": [], "effective": {"colorMode": "", "accentHue": 271}, "can_edit_site": true}}
Response Codes
Delete Branding Logo
/admin-next/branding/logo
Parameters
| Name | Type | Description |
|---|---|---|
| variant required | string | Query parameter: `light`, `dark` or `favicon`. |
{"data": {"branding": {"mode": "default", "text": "Grav", "logoLight": "", "logoDark": "", "logoHeight": 0, "title": "", "subtitle": "", "showPoweredBy": true, "favicon": ""}, "branding_urls": {"light": "", "dark": "", "favicon": ""}, "site": {"colorMode": "", "accentHue": 271}, "site_settings": {"autoSaveEnabled": false}, "media_upload": {"resizeWidth": 0}, "user": [], "effective": {"colorMode": "", "accentHue": 271}, "can_edit_site": true}}