Custom Scripts & Flows
Two ways to automate work beyond what a form and an approval chain can do on their own.
systemadmin account, which the Persiv team operates. A user with the System Admin role can't open either one. To have something automated, contact the Persiv team. Users can still see a flow's run status on their entries, and approve a flow step that is waiting on them.
Custom Scripts
A Custom Script is a small piece of Python code, stored in the platform and run automatically at a specific point in a smarttable's lifecycle — no separate deployment, no server access needed. Use it when a form field, a formula, or an approval step isn't enough: sending a message to an external system, running a calculation too complex for the Formula Engine, or generating data from another smarttable on the fly.
When a script runs (hook points)
| Hook | Runs |
|---|---|
| Before Save | Just before an entry's data is written — can modify or reject the save |
| After Save | Right after an entry is saved |
| Before Submit | Just before an entry is submitted |
| After Submit | Right after an entry is submitted |
| Before Display | Just before an entry's Display/Print/PDF view is rendered — can inject computed values |
| After Get Entries | Right after the entries table is fetched — can post-process the list |
| Notification Action | When a user takes action (approve/reject) on a notification |
| Scheduled / Cron | On a recurring schedule, independent of any entry being saved — for periodic sync/cleanup jobs |
What a script can do
Scripts run against a controlled API, not raw database access:
- Read/write smarttable data — query and update entries in this or other smarttables
- Send notifications — trigger the same in-app/push notification system described on the Notifications page
- Call external services — make HTTP requests out to another system
systemadmin account can create, edit or run scripts. Every create, edit, run, rollback and delete is recorded in the audit log. Treat script authorship the same as any other trusted-code change — review it before it goes live.
Where to manage scripts
Scripts are written and tested in a dedicated in-app code editor (a full syntax-highlighted Python editor, not a plain textarea). Its toolbar has:
| Button | What it does |
|---|---|
| Save (⌘/Ctrl+S) | Saves the script. If the code changed, you're asked for an optional change note and a new version is recorded. |
| Test Run (⌘/Ctrl+Enter) | Runs the script once with the parameters set under Edit Test Params (a JSON object), and shows the output below the editor |
| Run Now | Runs the script once for real, outside its hook or schedule |
| Version History | Lists every saved version of the code (see below) |
| Execution Logs | Lists the script's recent runs (see below) |
A scheduled script also has two settings that hook scripts don't: Failure emails (addresses emailed when a scheduled run fails) and a timeout. A hook script's failure shows up on the save or submit that triggered it.
Version history and rollback
Each save that changes the code adds a numbered version (v1, v2, …), recording the code, the change note, who saved it and when. Saving without changing the code (for example, only renaming the script) doesn't add a version.
To go back to an earlier version, open Version History and click its rollback button. That version's code becomes the live code, and the rollback is recorded as a new version noted Rollback to vN. Nothing is deleted, so a rollback can itself be undone by rolling back again.
Execution logs
Execution Logs shows the script's 50 most recent runs, newest first. Each run shows:
- Result: success or failed
- Duration in milliseconds
- How it was triggered: hook, schedule, manual (Run Now) or test (Test Run)
- Who triggered it (System when no user started it, such as a scheduled run) and when
- Output, expandable: anything the script printed, any error, and its return value
The scripts dashboard also lists the 10 most recent failed runs across all scripts.
Flows
Flows are a no-code, drag-and-drop way to automate a sequence of steps — build it visually as a flowchart instead of writing code. Use a Flow when you need "when X happens, do Y, then Z" without wanting to write a Custom Script for it.
How a Flow works
- Pick a trigger — what starts the flow. Supported today: a record being created or updated on a chosen smarttable, a manual run, or an API call from another system (see below).
- Add nodes on the visual canvas — each node is one step (e.g. send a notification, update a field, branch on a condition).
- Connect the nodes in the order they should run, including branches for different conditions.
- Publish the flow to make it live. A published flow can be paused and resumed at any time without losing its configuration.
Reviewing runs
Every time a flow runs, it's logged as a Run with a full step-by-step record of what each node did — useful for confirming a flow behaved as expected, or diagnosing why it didn't. Runs that include an approval-style step pause and wait for a person to act, the same way a notification-driven approval does elsewhere in the platform.
Starting a Flow from Another System
A flow whose trigger is set to API call can be started by another system, such as PersivX, with an HTTP request. There's no smarttable involved: the JSON the caller sends becomes the run's data, and the flow's steps refer to its keys (for example {{customer_email}}).
API keys
Calls are authenticated with an API key. Keys are managed in the flow builder: select an API-call trigger and use the API keys (org-wide) box under its Trigger URL.
- Create: enter a name (e.g. PersivX integration) and click +. The full key, starting
pfk_, is shown once. Copy it then: only a hash is stored, so it can't be shown again. - Scope: a key belongs to the organization, not to one flow or one person. It can start any published API-call flow in that organization, and doesn't expire.
- Revoke: click the bin icon next to the key. Any system still using it is refused from the next call. Keys are listed by name and their first few characters only.
Creating and revoking keys is limited to the systemadmin account, and both are recorded in the audit log.
Making the call
The flow's Trigger URL (with a copy button) is shown in the same trigger panel. The calling system sends:
POST <Trigger URL>
Authorization: Bearer pfk_…
Content-Type: application/json
{"customer_email": "a@example.com", "order_no": "SO-1042"}- The body can be a single JSON object (one record), or
{"rows": [ {...}, {...} ]}to run the flow over several records at once. - To make retries safe, send an
Idempotency-Keyheader. A second call with the same key returns the run that was already started instead of starting another. - A successful call returns
201with the queued run. The run then appears under the flow's runs like any other.
| Response | Meaning |
|---|---|
403 | Missing, wrong or revoked key |
404 | No such flow in the key's organization |
400 | The flow isn't published and active, or its trigger isn't set to API call, or the body is malformed |