Skip to content

Workflows

A workflow is a short chain of steps that runs in the background. Something starts it, each step hands its result to the next, and the run is kept so you can see what happened.

Workflows come with some plans, and while they are being finished they also go out one site at a time. So the Workflows entry is in the sidebar only for sites whose plan includes them and that we have switched them on for. If yours does not have it, this chapter describes something your site cannot reach yet. Nothing is lost while it is off: a site keeps its workflows and their run history, and they start running again when it is on.

Choose New workflow. The editor takes the whole screen beside the dashboard navigation: the card at the top left holds the workflow’s name and state, and its buttons sit at the top right. It starts on Manual test, so you start its runs yourself. To run it whenever a row is added to a table instead, including one you add on the dashboard, use Change trigger on the trigger node and pick New table record, then choose its table. Name the draft in the card, then open a node to configure it: double-click it, or select it and choose Open from the toolbar above it.

File uploaded is a trigger too. It starts a run for every file put on your site’s Disk, whether you uploaded it there, set it as the favicon or the sharing picture, or your agent added it, and it has nothing to set. The run is handed the file’s name, type, size, dimensions and key, never the picture itself.

Add a step from the + on a connection, the + after the last node, or Add a step at the top right, then search the list and pick one. It lands where you asked and opens its settings when it has any. You can have twenty:

  • Map fields builds the object the next step receives. Its Field mappings JSON object maps each output name to a path or a literal. For example, {"name":{"path":"record.data.name"},"source":{"literal":"Website"}}.
  • Create a record writes that object into a table you choose, so what comes out of your mapping has to match the fields that table asks for.
  • Update record changes one row of a table you choose. Find the row maps table fields to the values that pick the row out, and Change these fields maps the fields to change, both written the way field mappings are. Fields you leave out keep their values. Exactly one row has to match: when several do, the step fails instead of guessing, and When no row matches decides whether a missing row fails the run or finishes it without changes.
  • Run JavaScript runs the Script you write and hands the object it returns to the next step. The script reads input, which is what the step before it handed on, trigger, which is what started the run, and the files on your Disk through disk.list() and disk.get(key). It cannot reach the network or change anything itself, and it is stopped after a second. When it fails, the run says what kind of error it was and on which line.
  • Send a JSON webhook posts it to an HTTPS address. Delivery is at least once, so the receiver should watch the Idempotency-Key header and ignore a repeat. Redirects and private addresses are refused.

Order changes on the canvas. Drop a step onto a connection to insert it there, drag from one node’s output dot to another step’s input to make that step run next, or use Move earlier and Move later in the step’s own menu. Moving a node anywhere else, and panning or zooming, changes the layout only, which is saved with the draft. Delete step takes a step out. Preview field mappings opens a dialog that runs your mapping steps against a sample JSON input and shows what each one makes of it, without saving anything or performing any action.

Tidy up in the bottom-left controls puts every node back in a plain row, beside fit, zoom and 1:1.

Change trigger, on the trigger node’s own toolbar or in its menu, swaps what starts a workflow without rebuilding the rest. Your steps, their settings and the canvas layout all stay where they are.

It clears every setting on the trigger itself, so a table trigger loses the table you picked, and picking it again later does not bring it back. The screen names what it is about to clear and waits for you to confirm. If the new trigger needs a setting the old one did not, the editor shows it as something to fill in and the draft will not save until you do.

Steps you wrote against the old trigger keep running against the new one, so check any mapping that reads from the incoming data.

The editor works on desktop and phone. On a phone the dashboard navigation folds into a bar above the editor. The editor needs JavaScript: if it cannot load, the page says so and asks you to reload, and your saved draft is untouched.

Saving keeps a draft, and a draft never runs. Activate saved draft publishes it, and new runs use it from then on. A run already queued keeps the definition it started with, so activating never changes a run in flight. Pause workflow stops new runs from the trigger, and anything already queued still finishes. Test run still works while a workflow is paused. Resume workflow turns it back on with the version that was live before the pause, and a draft you saved since stays a draft until you activate it. Saving, activating, pausing and resuming each confirm with a notification in the corner of the screen, and you stay where you are. Changes you have not saved yet stay in the editor through activating, pausing and resuming, still unsaved: activating publishes the saved draft, not them.

Test run opens a dialog for a JSON fixture, and Queue test run runs the saved draft on it for real: it writes the records and sends the webhooks your steps ask for, so give it sample data. You land on the run itself, and the test appears in run history like any other run.

If somebody else on your site saved while you were editing, the editor says so and keeps your work: reload to take their version, or override it with your own draft. A draft that was in the editor stays on the page until you leave it, and Restore retained draft puts it back.

Remove asks first, because it deletes the workflow’s run history with it, and runs still waiting in the queue will not start.

Run history in the editor’s card lists the latest runs with when each started, what triggered it, and how it ended, and Runs on the Workflows list shows all of them, a page at a time. Opening one shows the version that ran (a test run says Saved draft), how long it took, the input that started it, and each step with its status, how many attempts it took, its own input and output, and what went wrong if anything did. A failed run offers Retry failed step, which carries on from there.

A run keeps the values it was given as they were sent, including any password, token or key among them, so a step that passes one on gets the real value. It is kept for 30 days, and goes sooner if you delete the row that started it.

A row larger than a run can hold, which takes several long text fields filled to their limit, still shows up in run history: as a failed run that names the row and says it was too large, with nothing to retry.

A workflow can also run when another system posts JSON to an address of the workflow’s own on your site, /-/workflows/<path>, signing every delivery. Use Change trigger and pick Signed webhook, then swap the other steps for a JSON result, because a signed webhook runs JSON results only. Its Result is the JSON object the sender reads back when the run is done. Clear it to hand back what was posted.

Saving gives the workflow its path, made from its name, and a signing secret. The secret opens in a dialog with a Copy button, and that is the only time it’s shown, so put it in the system that sends the webhook before you close it. The Webhook path field in the card holds the path and says the whole address. Change it and save to move the address, which happens straight away. As with any workflow, the path answers only once the saved draft is activated.

Keep the secret private: anybody holding it can post there as though they were the sender. Rotate signing secret makes a new one and shows it the same way. The old one stops working the moment it changes, so rotate when the secret is lost or might have leaked, and give the sender the new one.

Changing a webhook’s trigger keeps its address answering until you activate the new version. After that the path and the secret are gone, and changing back gives it new ones.

A caller posts JSON to the path with three headers:

  • X-Vizitka-Timestamp, the current time in seconds, within five minutes of ours.
  • X-Vizitka-Delivery, a fresh UUID for every delivery. Sending the same one twice, in capitals or lower case, gives back the first run instead of doing the work again, so a caller that retries after a timeout cannot have it done twice.
  • X-Vizitka-Signature, sha256= followed by an HMAC-SHA256 of the method, the path, the timestamp, the delivery UUID and the body, joined with newlines and signed with your signing secret.

Anything unsigned, stale, larger than 64 KB, or not JSON is refused, and a path answers at most 60 requests a minute and 1,000 a day.

A request that passes is accepted straight away, before the work is done, and the answer names the run, its status, and a status_path the caller polls for the result. Polling is signed the same way, with GET as the method and an empty body. A status_path keeps answering after you pause the workflow or change its path, since a run already accepted still finishes.