REST data sources
REST sources connect external systems (shop, CRM, ERP, headless CMS, your own services …) as a data source. In the template they behave like collections: data("produkte") calls the API, extracts the list and caches the result.
Source object
{
"id": 1,
"slug": "produkte",
"name": "Shop-Produkte",
"method": "GET",
"url": "https://shop.example.com/api/products?category={cat}&limit={limit}",
"headers": { "Authorization": "Bearer {env.SHOP_TOKEN}" },
"body": "",
"list_path": "data.items",
"cache_ttl": 300,
"timeout": 10,
"created_at": 1791191677,
"updated_at": 1791191677
}
| Field | Description |
|---|---|
slug |
Name for data("…"); unique across collections and REST sources |
method |
GET or POST |
url |
Absolute http(s) URL, may contain placeholders |
headers |
Additional request headers (placeholders allowed). Accept: application/json is always set, with a body also Content-Type: application/json |
body |
JSON body for POST (placeholders allowed) |
list_path |
Dot path to the list in the response, e.g. data.items or results.0.entries. Empty = entire response |
cache_ttl |
Cache duration in seconds, 0 = no cache. Default 300 |
timeout |
Timeout in seconds (1–60), default 10 |
Placeholders
| Syntax | Replaced by |
|---|---|
{name} |
Parameter from the template call data("slug", "name", wert) or query parameter for /data/{slug}?name=wert. URL-encoded in the URL, JSON-escaped in the body, unchanged in headers. Missing parameters → empty |
{env.NAME} |
Environment variable NAME of the server process – this keeps secrets out of the database |
Caching
The cache key consists of the method, the fully expanded URL and the body – so different parameters are cached separately. The cache lives in memory and is cleared when a source is changed or deleted, and on restart.
Error behavior
- HTTP status ≥ 400, invalid JSON, a timeout or a
list_paththat cannot be resolved lead to a render error in the template (the page responds with500, admins see details) and to502for/data/{slug}. - Responses over 10 MB are truncated (→ invalid JSON).
| Endpoint | Access | Description |
|---|---|---|
GET /sources |
🔑 | All sources |
GET /sources/{id} |
🔑 | Single source |
POST /sources |
✏️ | Create → 201 |
PUT /sources/{id} |
✏️ | Merge update; clears the cache |
DELETE /sources/{id} |
✏️ | Delete → 204; clears the cache |
POST /sources/test |
✏️ | Test a configuration (see below) |
🔐 Anyone who can create REST sources can make the server fetch arbitrary URLs – including on the internal network. Hand out write tokens sparingly.
POST /sources/test ✏️
Runs a (possibly unsaved) configuration without cache and returns the raw data and the extracted list – ideal for figuring out the list_path.
{
"method": "GET",
"url": "https://shop.example.com/api/products?category={cat}",
"headers": { "Authorization": "Bearer {env.SHOP_TOKEN}" },
"list_path": "data.items",
"params": { "cat": "schuhe" }
}
Response 200 (even if the fetch fails – then with error):
{
"result": {
"status": 200,
"url": "https://shop.example.com/api/products?category=schuhe",
"duration_ms": 84,
"data": [{ "name": "Sneaker", "price": 89.9 }],
"raw": { "data": { "items": [{ "name": "Sneaker", "price": 89.9 }] } },
"cached": false
},
"error": "remote source \"\": path \"data.items\": key \"items\" not found"
}