Upload Custom Error Template
Upload a custom HTML page that Ngris will serve in place of the default error page for a given error condition (firewall block, rate limit, bad gateway, etc.). The upload is gated by the custom_error_pages entitlement.
The request is multipart/form-data, not JSON — the HTML is passed as a file part named template. Each upload is auto-validated by an AI content-safety check (XSS, miners, trackers, phishing) before being stored; failing content is rejected with 400.
Request (multipart/form-data)
template file Req
The HTML file to upload. Max size 100 KB.
type string Req
Which error this page replaces. One of:
firewall, rate_limit, bad_gateway, service_unavailable, not_found, request_timeout, internal_error, gateway_timeout.active string
Pass the literal string
"true" to mark the new template active immediately. Any other value (or omission) uploads it as inactive — you can activate later via activate.Response (201 Created)
The newly-created template row (same shape as a list entry, including the rendered content).
Errors
400 Bad Request
File missing, file > 100 KB, unknown
type, or AI safety check found unsafe content. Error body is human-readable (e.g. Security Check Failed: contains tracking pixel).401 Unauthorized
Missing or invalid auth.
403 Forbidden
Caller's plan doesn't include the
custom_error_pages entitlement.503 Service Unavailable
AI validation service is offline. Upload is rejected fail-closed; retry later.
Request
curl -X POST "https://api.ngris.com/v1/templates" \
-H "X-API-KEY: <your_api_key>" \
-F "template=@./403.html;type=text/html" \
-F "type=firewall" \
-F "active=true"
Python
from ngris import Ngris
client = Ngris(api_key="<your_api_key>")
with open("403.html", "rb") as f:
tpl = client.templates.upload(
template=f,
type="firewall",
active=True,
)
print(f"Uploaded #{tpl['id']} ({tpl['type']})")
Response — 201 Created
{
"id": 42,
"user_id": 7,
"type": "firewall",
"content": "<!doctype html><html><body>Blocked.</body></html>",
"is_active": true,
"created_at": "2026-04-29T13:00:00Z",
"updated_at": "2026-04-29T13:00:00Z"
}