Data Functions
Functions come in two kinds. Backend functions run your code in a sandbox — for real logic, secrets, and external APIs. Data functions are declarative: one named data operation (create, read, update…) with a typed parameter schema — no code, no sandbox, entity-call speed. Both live in the same Functions list, both are callable by pages, automations, agents, and other templates.
The best-practice split: the UI only represents data; computation and data access live in the data layer as named functions. Buttons and forms point at a function name — so automations can call the exact same thing headlessly, and the UI can be redesigned without breaking the logic.
Example: a contact form
One data function, two kinds of callers:
// Data function "addContact" (declarative — no code):
{
"operation": "createRow",
"tableName": "Contacts",
"params": [
{ "name": "email", "type": "string" },
{ "name": "message", "type": "string" }
],
"data": {
"email": { "$param": "email" },
"message": { "$param": "message" },
"source": "website"
}
}
// 1) The form's submit button calls it from the page:
await serenities.functions.invoke('addContact', { email, message });
// 2) A CRM automation calls the SAME function headlessly —
// no browser, no AI, same validation, same result.Security model
- 100% server-executed — pages and automations are just callers; a data function can never fail for lack of a browser.
- Callers can only fill declared parameters. Values slot into typed
{"$param": "…"}placeholders — they can never change the table, the operation, or the fixed parts of a filter. Unknown inputs are dropped. - Runs as the member by default (their own row permissions). Elevation to service context is an explicit owner choice per function — use it for things like public contact forms writing to a protected table.
- Execute access rules required, exactly like backend functions — no rules, no execution.
When to use which
| Need | Use |
|---|---|
| Save/read/update rows (forms, lists, toggles) | Data function — fast, auditable at a glance |
| Multi-step logic, calculations, validation chains | Backend function |
| Secrets, env vars, external APIs, email, realtime publish | Backend function |
| Page-private one-off read | Inline entities.* is fine |
A data function can be upgraded to a backend function later without touching any UI — the name is the contract.