Templates API
The v2.12.8 template routes use /api/v1 and require the admin role. They expose stored catalog records, including custom and Coming Soon entries. A returned record is not a guarantee that it can be deployed on the current host.
List Templates
GET /api/v1/templates
| Parameter | Meaning |
|---|---|
category | Optional catalog category filter |
search | Optional search text |
limit | Default 50; values outside 1–100 fall back to 50 |
offset | Default 0; negative values become 0 |
curl 'https://panel.example.com/api/v1/templates?category=ai&limit=50&offset=0' \
-H "Authorization: Bearer ${PANEL_API_KEY}"
The response contains data and pagination: {total, limit, offset}. Pagination counts catalog records matching the filter, not deployable cards. The handler does not implement featured or sort query parameters.
Get Template Detail
GET /api/v1/templates/{id}
Use the UUID id from the list. name is the slug (for example uptime-kuma), while displayName is the label. The route does not resolve a slug to a UUID.
Both list and detail return id, name, displayName, description, category, icon, tags, isCurated, isCustom, trending, comingSoon, gpuRequired, spec, createdBy, createdAt, and updatedAt. Optional links include website, github, and documentation. spec contains the Compose or Git definition, minResources, securityProfile, and variables.
Variable Schema
Read spec.variables, rather than a top-level variables field:
| Field | Meaning |
|---|---|
name | Substitution key |
displayName | Form label |
type | string, integer, boolean, password, or select |
default | String default |
required | Whether a value is required |
description | Help text |
options | For selects, objects with value and label |
locked, hidden | Optional form behavior flags |
content, mount | Optional file-variable fields |
Deployment accepts a string-to-string map, including values for integer and boolean variables. Follow the selected template's actual schema and validation errors; do not assume arbitrary min/max/pattern objects are part of this API.
Get Template Logo
The record's icon field carries the icon. There is no dedicated unauthenticated /templates/{id}/logo handler in this interface.
Deploy from Template
POST /api/v1/templates/{id}/deploy
Pick a deployable record, copy its UUID into the URL, and supply the variables it requires. The UUID below is illustrative; replace it with one from your panel.
curl -X POST https://panel.example.com/api/v1/templates/10000000-0000-4000-8000-000000000001/deploy \
-H "Authorization: Bearer ${PANEL_API_KEY}" \
-H 'Content-Type: application/json' \
-d '{"name":"my-monitor","variables":{"SERVICE_NAME":"my-monitor"}}'
The body supports name, description, variables, optional customerId, resourceLimits, securityMode, and aiSource. Customer assignment is optional for an admin deployment; use an actual customer UUID when assigning one.
Successful deployment queues work and returns 202 Accepted:
{
"serviceId": "20000000-0000-4000-8000-000000000002",
"deploymentId": "30000000-0000-4000-8000-000000000003",
"status": "pending"
}
Git-backed templates additionally return deployType: "git". Compose-backed results can include generatedSecrets; treat that response as sensitive and do not record it in logs, screenshots, or support messages. Poll service/deployment status to confirm completion.
Variable Validation
Invalid requests commonly return 400 with a validation_failed domain error. An unresolved-variable failure instead returns string error: "unresolved_variables", a message, and unresolvedVariables. Correct the payload using the selected record; there is no universal 422 field-error map.
Template Categories
Read categories from catalog records and use the category list filter. There is no separate category-count endpoint in this handler. See the template overview for the distinction between source manifests, browser cards, deployable entries, and Coming Soon entries.