Skip to content

Create an action

Write a parameterized SQL action, publish it through validation, manage versions, and set its environments and run permissions.

7 min read

An action is a named operation on your data, usually a SQL statement with parameters. After an action is published, users run it through the generated form on the Run action page, inside a view, from a JS action or on a schedule.

  • Editor and above: create, edit, publish and roll back actions, and set the environments they apply to.
  • Admin and above: set run permissions (the Action permissions card) and delete actions.

The project's action list with each action's kind, read-only or write mode and publish statusThe project's action list with each action's kind, read-only or write mode and publish status

  1. Go to Build > Actions and click New action.

  2. Enter a Name and Slug. The slug is the identifier used to call the action from a view or JS action. It cannot be changed after the action is published.

  3. Set Kind to SQL, then select the Data source (PostgreSQL or MySQL).

  4. Select the Mode:

    • Read-only: runs inside a read-only transaction. Publishing is refused if the SQL contains INSERT, UPDATE or DELETE.
    • Writes data: allowed to write. Users always confirm before running it.

    The mode also cannot be changed after publishing. To change it, create a new action.

  5. Click Create. The detail page opens on the Definition tab.

The Kind field offers SQL and JavaScript (JS actions). SQL actions run on PostgreSQL or MySQL data sources. No action kind runs on an HTTP data source yet; an HTTP data source can currently only store its config and test the connection.

Write the SQL statement in the Definition tab. The editor suggests table and column names from the data source. Write parameters as {{paramName}}:

SELECT id, customer, status, total
FROM orders
WHERE status = {{status}}
ORDER BY id

Declare every {{paramName}} in the Params section:

  1. Click Add a param, or Add N params from the SQL to add every param that the SQL uses but has not declared.
  2. Set the Name to match the text inside {{...}}, the Label shown on the form, the Param type, and select required if needed.
  3. Open Advanced to add a Description (shown under the input on the run form) and a Default value (pre-filled on the run form).

Definition tab of a SQL action: the statement with a param in double curly braces and the Params section belowDefinition tab of a SQL action: the statement with a param in double curly braces and the Params section below

Params are always passed as bound values and are never inserted into the SQL text. An action can have up to 50 params.

TypeInput on the run form
stringText field
number, integerNumber field
booleanSwitch
date, datetimeDate picker; datetime adds a time field
enumDrop-down list

For details, see Parameters.

For an enum param, choose Values from:

  • Fixed list: enter the Enum values, separated by commas. The form previews the options the drop-down will show.
  • Another action: use another action’s result as the list (master data, for example a list of stores). Select Pick a published source action, then choose the Value column and Label column.

Only an enum param with a fixed list can be placed where a column or table name goes, for example to choose the sort column:

SELECT id, customer, total FROM orders ORDER BY {{sort_column}}

The fixed list acts as the allowlist. A list loaded from another action cannot be used in this position. After publishing, the page shows which params are interpolated as identifiers.

A transformer (optional) is a short JavaScript function that reshapes the result before it is displayed: it can rename columns and add links, images or badges. Click Add a transformer:

export default (rows, ctx) => rows.map((r) => ({
ID: linkToView('order-detail', { orderId: r.id }, r.id),
Photo: image(r.photo_url, { width: 40, height: 40 }),
Status: badge(r.status, r.status === 'paid' ? 'success' : 'warning'),
Created: formatDate(r.created_at, 'YYYY-MM-DD'),
}));

Available built-ins: linkToAction, linkToView, linkToURL, image, video, badge, formatDate. The transformer runs in a sandbox: it has no fetch and cannot read anything other than rows and ctx.

  1. Click Save draft to save your edits. Saving a draft runs no checks and does not affect the live version.
  2. Click Publish. The server validates the SQL before allowing it to run. If validation fails, the page shows Publish refused: with each problem and an issue count badge in the page header.
  3. For a write action, or an action enabled in production, the Publish vN? dialog opens. It compares the statement with the live version and lists added, removed and retyped params and the environments the action applies to. Confirm to publish.
  4. Each successful publish creates a new version. The Run action page, views, JS actions, jobs and schedules (including queued jobs) use the new version immediately.
  • The SQL uses a param that is not declared, or a declared param is not used.
  • A param in a column or table name position is not an enum with a fixed list.
  • A Read-only action contains a write statement (INSERT, UPDATE, DELETE).
  • The SQL contains DDL statements such as DROP, ALTER, TRUNCATE, GRANT.
  • The SQL has several statements that are not wrapped in a transaction (PostgreSQL). On MySQL: one statement per action, no transaction control statements, and only allowed statement types (read: SELECT, SHOW, EXPLAIN, DESC; write: INSERT, REPLACE, UPDATE, DELETE, CALL).
  • A built-in value is misspelled, for example {{$user.name}} (only $user.id and $user.email exist).
  • A list source is invalid: the source action does not exist, is not published, or the person publishing cannot run it.

While an unpublished draft exists, the page shows Unpublished draft — the Run action page still runs vN. The Try a run button appears only after the action is published and the user has permission to run it. It opens the Run action page with the form generated from the params. Drafts cannot be run.

  1. Open the Versions (N) tab. Each row is a published version; the live version is marked in use.
  2. Click View code on a version. The Code tab shows that version’s statement and transformer, and the Compare with the live version (vN) tab shows the line-by-line differences.
  3. Click Roll back to this one (or Roll back to vN in the code dialog), then confirm.

Versions tab of an action: the version history and the comparison with the live versionVersions tab of an action: the version history and the comparison with the live version

A rollback only changes which version is in use. It creates no new version and edits no existing version, and you can switch back to the newer version at any time. From the moment you confirm, every run (including queued jobs) uses the selected version.

Actions are shared across the project but run only in the environments that are enabled for them. By default, a new action applies to every environment except production.

  1. Open the Settings & access tab (editors see it as Settings).
  2. In the Applies to environments card, turn each environment on or off. Changes are saved immediately.
  3. Enabling a production environment always requires confirmation: click Enable in production. Turning an environment off requires no confirmation.

The same tab contains the General card: Name, Description (shown to users who run the action), Timeout (seconds) (0.1–300, default 30) and Max rows (1–1,000,000, default 10,000). These changes apply immediately to the live version and do not create a version.

The Action permissions card (visible to admins only) controls who can run the action from the Run action page, in views and through JS actions.

  • Permission mode: open — every member or restricted — only those granted. Changing the mode always requires confirmation.
  • In restricted mode, use Grant run access to to add a member, a group or a JS action, then click Grant. Click Revoke to remove access.
  • A restricted action is hidden from the Run action page for users who have not been granted access. Owners and admins also cannot run it until they are granted access.

Settings & access tab: the Applies to environments card and the Action permissions card with open or restricted modeSettings & access tab: the Applies to environments card and the Action permissions card with open or restricted mode

The Delete action card is at the bottom of the Settings & access tab (Admin role required). When an action is deleted, nobody can run it, its schedules are deleted, unfinished jobs are cancelled and granted permissions are removed. Run history is kept. This operation cannot be undone.

An action cannot be deleted while a JS action calls it, a view (live version) declares it, or another action’s param loads its list from it. The confirmation dialog lists each reference to remove first.