API Endpoints¶
Setup¶
Add the URLs to your project's urls.py (see Installation):
path("unveil/", include("wagtail_unveil.urls")),
Then set WAGTAIL_UNVEIL_API_KEY (see Settings Reference).
Authentication¶
The API accepts a Bearer token matching WAGTAIL_UNVEIL_API_KEY:
curl -H "Authorization: Bearer your-secret-key" http://localhost:8000/unveil/api/v1/backend-urls/
| Scenario | Response |
|---|---|
| Valid Bearer token | 200 with data |
| Invalid Bearer token | 403 |
| No key configured | 500 |
Superuser session + DEBUG=True |
200 for URL discovery endpoints; /unveil/api/v1/platform/ still requires Bearer auth |
| Superuser session + built-in production report flow | 200 when WAGTAIL_UNVEIL_ENABLE_PRODUCTION_REPORTS=True |
For normal programmatic or third-party use, authenticate with Authorization: Bearer <key>. The production superuser session path is reserved for the built-in HTML reports and settings page; it is not a general replacement for Bearer-token API access.
Authenticated JSON responses are returned with Cache-Control: private, no-store and vary on Authorization and Cookie.
The platform endpoint also reads WAGTAIL_UNVEIL_PLATFORM_DEPENDENCY_FILE when building dependency inventory data. See Settings Reference.
Backend URLs Endpoint¶
Returns all discovered Wagtail admin URLs.
GET /unveil/api/v1/backend-urls/
Filters (?filter=):
| Value | Returns |
|---|---|
| (omitted) | All backend URLs |
static |
Only URLs without parameters |
parameterized |
Only URLs with parameters |
Examples:
# All backend URLs
curl -H "Authorization: Bearer your-secret-key" http://localhost:8000/unveil/api/v1/backend-urls/
# Static URLs only
curl -H "Authorization: Bearer your-secret-key" "http://localhost:8000/unveil/api/v1/backend-urls/?filter=static"
# Parameterized URLs only
curl -H "Authorization: Bearer your-secret-key" "http://localhost:8000/unveil/api/v1/backend-urls/?filter=parameterized"
Response:
{
"urls": [
{
"route": "admin/",
"name": "wagtailadmin_home",
"namespace": "wagtailadmin",
"has_parameters": false,
"view_name": "wagtail.admin.views.home.HomeView",
"page_type": "",
"is_testable": true,
"skip_reason": "",
"resolved_route": ""
}
],
"count": 190,
"metadata": {
"api_version": "v1",
"api_lifecycle": {
"status": "stable",
"deprecated_on": null,
"sunset_on": null
},
"generated_at": "2026-03-02T12:34:56+00:00",
"applied_filter": null,
"total_count": 190,
"testable_count": 150,
"untestable_count": 40,
"package_version": "0.x.y"
}
}
Item fields:
| Field | Description |
|---|---|
route |
The discovered admin route as registered in Django/Wagtail |
name |
The route name |
namespace |
The Django namespace for the route |
has_parameters |
Whether the discovered route contains path parameters |
view_name |
The dotted Python view path when available |
page_type |
The concrete app_label.ModelName for page-backed admin rows, otherwise an empty string |
is_testable |
Whether the route can be directly tested with a GET request |
skip_reason |
Empty string for testable routes, otherwise the reason the route is not directly testable |
resolved_route |
A concrete resolved admin path when parameter resolution succeeded, otherwise an empty string |
Frontend URLs Endpoint¶
Returns all discovered frontend URLs (Wagtail pages and resolver routes).
GET /unveil/api/v1/frontend-urls/
Filters (?filter=):
| Value | Returns |
|---|---|
| (omitted) | All frontend URLs |
pages |
Only Wagtail page URLs |
resolver |
Only Django resolver URLs |
Page-derived discovery only includes live public Wagtail pages. Live private pages and private-derived example URLs are excluded from the frontend API and report output.
Examples:
# All frontend URLs
curl -H "Authorization: Bearer your-secret-key" http://localhost:8000/unveil/api/v1/frontend-urls/
# Page URLs only
curl -H "Authorization: Bearer your-secret-key" "http://localhost:8000/unveil/api/v1/frontend-urls/?filter=pages"
# Resolver URLs only
curl -H "Authorization: Bearer your-secret-key" "http://localhost:8000/unveil/api/v1/frontend-urls/?filter=resolver"
Response:
{
"urls": [
{
"url": "/contact/",
"source": "page",
"page_type": "forms.FormPage",
"page_title": "Contact",
"name": "",
"resolved_url": "",
"query_params": {},
"is_testable": false,
"skip_reason": "Requires POST submission"
}
],
"count": 42,
"metadata": {
"api_version": "v1",
"api_lifecycle": {
"status": "stable",
"deprecated_on": null,
"sunset_on": null
},
"generated_at": "2026-03-02T12:34:56+00:00",
"applied_filter": "pages",
"total_count": 42,
"testable_count": 31,
"untestable_count": 11,
"package_version": "0.x.y"
}
}
Item fields:
| Field | Description |
|---|---|
url |
The discovered frontend path |
source |
page for Wagtail page-derived URLs or resolver for Django resolver URLs |
page_type |
The app_label.ModelName for page-derived URLs, otherwise an empty string |
page_title |
The Wagtail page title for page-derived URLs, otherwise an empty string |
name |
The Django route name when available, otherwise an empty string |
resolved_url |
A concrete frontend path used for testing when parameter resolution succeeded, otherwise an empty string |
query_params |
An object of representative query parameters used for testing query-driven routes when safe values can be inferred, otherwise an empty object |
is_testable |
Whether the URL can be directly tested with a GET request |
skip_reason |
Empty string for testable URLs, otherwise the reason the URL is not directly testable |
Platform Runtime Endpoint¶
Returns runtime metadata for the current site plus a Python dependency inventory from a configured dependency manifest.
GET /unveil/api/v1/platform/
Configuration:
- Set
WAGTAIL_UNVEIL_PLATFORM_DEPENDENCY_FILEto a supported manifest file such aspyproject.tomlorrequirements.txt - Requirements-style manifests support relative
-r other-file.txtincludes for shared base dependency files - The endpoint still returns
200when dependency metadata is unavailable, and reports the problem inplatform.warnings - Unlike the URL discovery endpoints, this endpoint requires Bearer auth for normal API clients even when
DEBUG=True - The HTML platform report at
/unveil/report/platform/consumes this endpoint internally for superuser debugging, but the browser request authenticates with the signedX-Wagtail-Unveil-Report-Accessheader plus the superuser session, not the Bearer API key
Examples:
curl -H "Authorization: Bearer your-secret-key" http://localhost:8000/unveil/api/v1/platform/
Response:
{
"platform": {
"runtime": {
"python_version": "3.11.11",
"python_implementation": "CPython",
"django_version": "5.2.1",
"wagtail_version": "7.0.2"
},
"python_dependencies": {
"source": {
"path": "pyproject.toml",
"format": "pyproject.toml"
},
"packages": [
{
"name": "Django",
"specifier": ">=5.2",
"installed_version": "5.2.1",
"is_installed": true,
"source_kind": "runtime",
"source_name": null
},
{
"name": "mkdocs-material",
"specifier": ">=9.6",
"installed_version": "",
"is_installed": false,
"source_kind": "group",
"source_name": "docs"
}
]
},
"warnings": []
},
"metadata": {
"api_version": "v1",
"api_lifecycle": {
"status": "stable",
"deprecated_on": null,
"sunset_on": null
},
"generated_at": "2026-04-08T12:34:56+00:00",
"package_version": "0.x.y"
}
}
Platform fields:
| Field | Description |
|---|---|
platform.runtime.python_version |
Python version for the running process |
platform.runtime.python_implementation |
Python implementation such as CPython |
platform.runtime.django_version |
Installed Django version |
platform.runtime.wagtail_version |
Installed Wagtail version |
platform.python_dependencies.source.path |
Basename of the configured manifest file, such as pyproject.toml or base.txt |
platform.python_dependencies.source.format |
Detected manifest type: pyproject.toml, poetry-pyproject, requirements.txt, unknown, or null when no manifest is configured |
platform.python_dependencies.packages |
Sorted list of declared Python dependency entries |
platform.warnings |
Human-readable warnings when dependency metadata is incomplete or unavailable; warnings do not include internal paths or raw exception details |
Dependency item fields:
| Field | Description |
|---|---|
name |
Declared package name |
specifier |
Declared version specifier or source detail |
installed_version |
Installed version from the current Python environment, or an empty string when not installed |
is_installed |
Whether the package is installed in the current environment |
source_kind |
Where the declaration came from: runtime, optional, or group |
source_name |
Extra/group name for optional or grouped dependencies, otherwise null |
Metadata¶
The URL discovery endpoints include a metadata object alongside the top-level urls and count fields:
| Field | Description |
|---|---|
api_version |
Response contract version (v1, v2, ...) |
api_lifecycle |
Lifecycle status (stable or deprecated) with optional deprecated_on / sunset_on dates |
generated_at |
ISO 8601 timestamp for when the response was generated |
applied_filter |
The recognised filter value that was applied, or null |
total_count |
Total URLs in the response after filtering; this matches the top-level count field |
testable_count |
Number of URLs marked testable |
untestable_count |
Number of URLs marked untestable |
package_version |
Installed wagtail-unveil package version (not the API version) |
If a filter query parameter is unrecognised, the response is not filtered and metadata.applied_filter is null.
The platform endpoint also includes metadata, but it omits URL-discovery fields such as applied_filter, total_count, testable_count, and untestable_count.
Deprecation Headers¶
Deprecated API versions return additional response headers:
Deprecation: trueSunset: <RFC 1123 datetime>when a sunset date is configured for that version
API Versioning¶
Versioned endpoints are explicit and can run in parallel (for example v1 and v2). The built-in HTML reports always call the latest stable version.
For the full lifecycle policy, breaking-change criteria, and version bump workflow, see contributing/api-versioning.md.
Related¶
- Configuration — API key and discovery settings
- Features — HTML report counterparts
- API Reference Index — Back to section overview