System
Endpoints for system-level operations including information, cache management, environments, logs, backups, translations, and reports.
Endpoints for system-level operations including information, cache management, environments, logs, backups, translations, and reports.
System Info
/system/info
{"data": {"grav_version": "2.1.0", "php_version": "8.3.14", "php_extensions": ["Core", "date", "pcre"], "server_software": "Apache/2.4.58", "environment": "localhost", "plugins": [{"name": "API", "version": "1.0.38", "enabled": true}], "themes": [{"name": "Quark", "version": "2.0.4", "active": true}], "php_config": {"Upload & POST": {"file_uploads": "1", "upload_max_filesize": "64M", "max_file_uploads": "20", "post_max_size": "64M"}}}}
Response Codes
For demo accounts, server_software and the path values in php_config (error log, open_basedir, temp dir, document root, include path, session save path) are replaced with (hidden in demo mode).
Clear Cache
/cache
Parameters
| Name | Type | Description |
|---|---|---|
| scope optional | string | One of `all`, `standard`, `images`, `assets`, `tmp`. Defaults to `standard`. `images`, `assets` and `tmp` clear only that folder. |
{"data": {"scope": "standard", "message": "Cache cleared successfully (scope: standard).", "details": ["Cleared: /var/www/grav/cache/*"]}}
Response Codes
details is the list of per-folder result lines from Grav's cache clear.
Get Translations
/translations/{lang}
Parameters
| Name | Type | Description |
|---|---|---|
| lang required | string | Language code (e.g. `en`, `fr`, `pt-BR`). Short codes are normalized to a full locale (`en` becomes `en-US`, `fr` becomes `fr-FR`); a value that is not a language code falls back to the site's default language. The resolved code is returned in `lang`. |
| prefix optional | string | Only return keys starting with this prefix followed by a dot (case-insensitive), e.g. `PLUGIN_ADMIN`. |
{"data": {"lang": "fr-FR", "dir": "ltr", "count": 1868, "checksum": "5d41402abc4b2a76b9719d911017c592", "strings": {"PLUGIN_ADMIN.SAVE": "Enregistrer"}}}
Response Codes
dir is the text direction (ltr or rtl), and checksum is an MD5 of the returned strings, so a client can cache the map and only refetch it when the checksum changes. Strings contributed only by disabled plugins are left out.
Ping
/ping
{"data": {"pong": true}}
Response Codes
List Environments
/system/environments
{"data": {"detected": "localhost", "environments": [{"name": "", "label": "Default", "exists": true, "hasOverrides": false}, {"name": "staging.example.com", "label": "staging.example.com", "exists": true, "hasOverrides": true}]}}
Response Codes
The first entry is always the base configuration (user/config), with name: "" and label: "Default"; its hasOverrides is always false. Every other entry is an existing user/env/<name>/ folder, and legacy user/<host>/config/ layouts are included too. hasOverrides says whether the environment holds any configuration files.
Get Logs
/system/logs
Parameters
| Name | Type | Description |
|---|---|---|
| file optional | string | Log file to read (default `grav.log`). Must be one of the names listed by `GET /system/logs/files`. |
| page optional | integer | Page number for pagination (default: 1) |
| per_page optional | integer | Number of results per page (default: 20, max: 1000) |
| level optional | string | Filter by log level, case-insensitive (e.g. DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL) |
| search optional | string | Case-insensitive text the message must contain |
{"data": [{"date": "2026-09-21T10:30:00.123456+00:00", "logger": "grav", "level": "WARNING", "message": "Plugin X deprecated method"}], "meta": {"pagination": {"page": 1, "per_page": 20, "total": 150, "total_pages": 8}}, "links": {"self": "/api/v1/system/logs?page=1&per_page=20", "next": "/api/v1/system/logs?page=2&per_page=20", "last": "/api/v1/system/logs?page=8&per_page=20"}}
Response Codes
Reports
/reports
{
"data": [
{
"id": "security-check",
"title": "Grav Security Check",
"provider": "core",
"component": null,
"status": "success",
"message": "Security Scan complete: No issues found.",
"items": []
},
{
"id": "twig-content",
"title": "Twig in Content",
"provider": "core",
"component": null,
"status": "success",
"message": "Twig in Content is disabled. No pages are leaking raw Twig.",
"meta": { "gate": false, "sandbox": true, "editor_enabled": false, "leak_count": 0, "event_count": 0, "global_request_gated": false, "frontmatter_request_gated": false },
"items": []
},
{
"id": "yaml-linter",
"title": "Grav Yaml Linter",
"provider": "core",
"component": null,
"status": "success",
"message": "YAML Linting: No errors found.",
"items": []
},
{
"id": "problems",
"title": "Grav Potential Problems",
"provider": "problems",
"component": "problems-report",
"status": "success",
"message": "No critical problems detected.",
"items": [
{
"id": "PHP Minimum Version",
"level": "critical",
"status": true,
"msg": "Your PHP 8.5.4 is greater than the minimum of 8.3.0 required"
}
]
}
]
}
Response Codes
Report Structure
Each report in the response array contains:
| Field | Type | Description |
|---|---|---|
id |
string | Unique report identifier |
title |
string | Human-readable report title |
provider |
string | Source — core for built-in, or plugin slug |
component |
string|null | Web component ID for custom rendering, or null for default |
status |
string | Overall status: success, warning, or error |
message |
string | Summary message |
meta |
object | Optional report-specific summary values |
items |
array | Report-specific detail items |
Built-in Reports
- Security Check — Scans all pages for potential XSS vulnerabilities. Items contain
routeandfieldfor each issue found. - Twig in Content (
twig-content): Shows whether Twig in page content is switched on and sandboxed, pages whose raw Twig markers render to visitors, and recent tokens the sandbox blocked. Itsmetacarriesgate,sandbox,editor_enabled,leak_count,event_count,global_request_gatedandfrontmatter_request_gated; its items arekind: leakandkind: eventrows. The endpoints under/reports/twig-content/act on this report. - YAML Linter — Checks all YAML files for syntax errors. Items contain
fileanderrorfor each issue found.
Plugin Reports
Plugins add reports by listening for the onApiGenerateReports event. When a report specifies a component, the admin frontend loads the plugin's web component from GET /gpm/plugins/{provider}/report-script/{component}.
See the Plugin API Integration guide for implementation details.
Create Backup
/system/backup
{"data": {"filename": "default_site_backup--20260917120000.zip", "path": "/var/www/grav/backup/default_site_backup--20260917120000.zip", "size": 1048576, "date": "2026-09-17T12:00:00+00:00"}}
Response Codes
List Backups
/system/backups
{"data": {"backups": [{"filename": "default_site_backup--20260917120000.zip", "title": "Default Site Backup", "date": "2026-09-17T12:00:00+00:00", "size": 1048576}], "purge": {"trigger": "space", "max_backups_count": 25, "max_backups_space": 5, "max_backups_time": 365}, "profiles_count": 1}}
Response Codes
date is an ISO 8601 timestamp, the same format Create Backup returns. purge is the site's backups.purge configuration.
Delete Backup
/system/backups/{filename}
Parameters
| Name | Type | Description |
|---|---|---|
| filename required | string | The backup filename (bare basename, e.g. `default_site_backup--20260917120000.zip`). |
Response Codes
Download Backup
/system/backups/{filename}/download
Parameters
| Name | Type | Description |
|---|---|---|
| filename required | string | The backup filename (bare basename ending in `.zip`). |
Response Codes
System Info Report
/systeminfo
{"data": {"php": {"version": "8.3.14", "sapi": "fpm-fcgi", "extensions": ["Core", "date"], "memory_limit": "256M", "max_execution_time": "60", "upload_max_filesize": "64M", "post_max_size": "64M"}, "grav": {"version": "2.1.0", "php_version": "8.3.14"}, "disk": {"free_space": 10737418240, "total_space": 53687091200}, "plugins": {"total": 30, "enabled": 24, "disabled": 6}, "cache": {"enabled": true, "driver": "auto"}}}
Response Codes
disk.free_space and disk.total_space are in bytes, or false when PHP cannot read them.
Create Environment
/system/environments
Parameters
| Name | Type | Description |
|---|---|---|
| name required | string | Environment name, usually a hostname. It must start with a letter or digit and contain only letters, digits, `.`, `_` and `-`. `default` and `base` are reserved. |
{"name": "staging.example.com"}
{"data": {"name": "staging.example.com", "label": "staging.example.com", "exists": true, "hasOverrides": false}}
Response Codes
Delete Environment
/system/environments/{name}
Parameters
| Name | Type | Description |
|---|---|---|
| name required | string | Environment name (path parameter) |
Response Codes
List Log Files
/system/logs/files
{"data": {"files": [{"file": "grav.log", "label": "Grav System Log"}, {"file": "security.log", "label": "Security Log"}, {"file": "email.log", "label": "Email Log"}, {"file": "scheduler.log", "label": "Scheduler Log"}, {"file": "custom-plugin.log", "label": "Custom Plugin Log"}], "default": "grav.log"}}
Response Codes
The four core logs are always listed first, even before they have been written. Any other *.log file in the log:// folder follows, then files plugins add through the onApiLogFiles event. Entries are de-duplicated by file name.
Clear Log
/system/logs
Parameters
| Name | Type | Description |
|---|---|---|
| file optional | string | Log file to clear (default `grav.log`). Can be sent in the JSON body or as a `?file=` query parameter. |
{"file": "grav.log"}
{"data": {"file": "grav.log", "cleared_bytes": 450507, "message": "Log cleared: grav.log"}}
Response Codes
List Admin Languages
/admin/languages
{"data": {"languages": [{"code": "en-US", "name": "English", "native_name": "English", "rtl": false}, {"code": "fr-FR", "name": "French", "native_name": "Français", "rtl": false}]}}
Response Codes
Allow a Blocked Twig Token
/reports/twig-content/allowlist
Parameters
| Name | Type | Description |
|---|---|---|
| rule required | string | The sandbox rule that blocked the token: `tag`, `filter`, `function`, `method` or `property`. |
| token required | string | The tag, filter, function, method or property name to allow. |
| class optional | string | Owning class. Required for `method` and `property`, ignored otherwise. |
{"rule": "filter", "token": "markdown"}
{"data": {"rule": "filter", "key": "allowed_filters", "value": ["markdown"], "resolved": 2}}
Response Codes
key is the security.twig_sandbox key that was written and value its full new value: a list of names for tag, filter and function, or a list of {class, methods} rows for method and property. resolved is the number of recorded block events this removed. The shipped defaults live in code, so the file only holds the site's own additions. Fires onApiConfigUpdated with scope security.
Clear Twig Content Events
/reports/twig-content/events
{"data": {"cleared": true}}
Response Codes
Twig Content Page Status
/reports/twig-content/page
Parameters
| Name | Type | Description |
|---|---|---|
| route required | string | Page route, with leading slash. |
{"data": {"route": "/blog/my-first-post", "gate": false, "sandbox": true, "leak": {"route": "/blog/my-first-post", "requested": true, "gate": false, "reason": "gate_off"}, "events": []}}
Response Codes
gate is security.twig_content.process_enabled and sandbox is security.twig_sandbox.enabled. leak is null when the page has no Twig markers, uses modular or theme Twig, will render its Twig normally, or cannot be found (a missing page is not an error). Its reason is gate_off when the site-wide gate is off, or page_off when the gate is on but the page does not ask for Twig processing. events lists recent blocks for exactly this route, newest first.
Scan Twig Content
/reports/twig-content/scan
{"data": {"tags": {"include": ["/blog/my-first-post"]}, "filters": {"raw": ["/about"]}, "functions": {"source": ["/about", "/contact"]}}}
Response Codes
Each list maps a token to the routes that use it. A list with no findings arrives as an empty array ([]) rather than {}. This is a text scan and an approximation; the block events in the report, recorded at render time, are the reliable signal. The cost grows with the number of pages.
Twig Sandbox Policy
/reports/twig-content/sandbox-policy
{"data": {"enabled": true, "config_access": false, "lists": {"tags": {"defaults": ["if", "for", "set"], "added": [], "denied": [], "effective": ["if", "for", "set"]}, "filters": {"defaults": ["escape", "upper"], "added": ["markdown"], "denied": [], "effective": ["escape", "upper", "markdown"]}, "functions": {"defaults": ["range"], "added": [], "denied": [], "effective": ["range"]}, "methods": {"defaults": {"Grav\\Common\\Page\\Page": ["title", "url"]}, "added": [], "denied": [], "effective": {"Grav\\Common\\Page\\Page": ["title", "url"]}}, "properties": {"defaults": [], "added": [], "denied": [], "effective": []}}, "config_denied_paths": {"defaults": ["plugins", "streams", "security", "backups", "scheduler", "system.cache.redis.password", "system.debugger.token"], "added": [], "effective": ["plugins", "streams", "security", "backups", "scheduler", "system.cache.redis.password", "system.debugger.token"]}}}
Response Codes
The lists in the example are shortened. enabled is security.twig_sandbox.enabled and config_access is security.twig_content.config_access. In methods and properties each entry maps a class to its allowed member names, and an empty map arrives as []. config_denied_paths lists the configuration paths hidden from content Twig. The policy is built from configuration only; additions plugins make through onBuildTwigSandboxPolicy are not included.