API reference

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_path that cannot be resolved lead to a render error in the template (the page responds with 500, admins see details) and to 502 for /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"
}