Praxsuite

Server-Side Logic

Vincent Depassier · August 30, 2026

Most products that let you build a UI leave you stranded the moment you need something to happen on a server. Automations are Praxsuite's answer to that: they are the backend, and there is no server for you to run, scale or patch.

This page is about using them that way — as the trusted half of your system.

Why anything needs a server at all

A browser is a hostile place to keep a secret. Anything your page holds, a visitor holds: keys, tokens, business rules, the lot. And anything your page decides, a visitor can decide differently by editing the request.

So the split is not about convenience, it is about trust:

In the browser

On the server

Displaying data the caller is allowed to see

Holding credentials

Collecting input

Deciding whether something is allowed

Calling your own endpoint

Talking to a paid third-party API

Anything that must happen exactly once

An automation as an HTTP API

The Endpoint trigger turns an automation into an API your app can call. The request comes in, your flow runs, and a Response node defines exactly what goes back — status code, headers, body.

Endpoint trigger ──▶ validate ──▶ do the work ──▶ Response (200, { ok: true })

Three rules the platform enforces, so you find out when you save rather than in production:

  • An endpoint automation must have a Response node.

  • It may have exactly one. Not zero, not two.

  • An automation without an endpoint trigger may not have one at all.

That last rule surprises people. A Response node is meaningless in a scheduled job — there is nobody waiting for an answer — so the validator refuses it rather than letting it sit there doing nothing.

Compare with the Webhook trigger, which answers immediately and runs afterwards. Use webhooks for "another system is telling me something happened". Use endpoints for "my app is asking me a question and needs the answer".

The Script node

When the built-in nodes do not express what you need, the Script node runs your own code — JavaScript or Python — in an isolated sandbox.

Code size

Up to 64 KB

Timeout

1 to 30 seconds; 10 by default

Inputs

Named values you declare, resolved from the flow's context

Outputs

Validated against the output schema you declare

Console

Captured into the run log

It is a genuine escape hatch, not a toy: parse an awkward payload, compute something the formula node cannot express, reshape a response before it goes back to a caller.

Files in and out

A script can declare a blob to load before it runs, arriving either as a base64 string or as an object with the data, content type and filename. And it can return base64 in an output key, which gets uploaded for you and replaced with the stored file's id, URL, filename, content type and size.

Between the two, "read the uploaded CSV, transform it, hand back an XLSX" is a single node.

Three traps that cost an afternoon

Inputs need their braces. An input is a template: {{context.steps.query.rows}}. A bare field name is a literal string, and it will not error — it will just be wrong.

Do not parse what is already parsed. Inputs arrive as real values. Calling JSON.parse on one that is already an object throws, in a way that reads like a platform fault.

Column names lose their spaces. Rows from a Query Rows node reach a script keyed by underscore — Player_Name, not Player Name. Reading the spaced name returns nothing, silently. The gateway does not do this; it only bites inside automations.

Secrets

Credentials belong in the Vault, not in a node's configuration. Read a secret with the Vault node and it becomes available to the nodes downstream; it never appears in the automation's definition, and it is not something a person browsing the flow can read off the screen.

There is a write side too, for rotating a secret from a flow — the honest way to handle a credential that expires on a schedule.

Talking to the outside world

The HTTP Request node calls any internal or external endpoint and captures the response. Combined with the Vault, that is the whole pattern for a third-party integration: read the key, make the call, use the answer — with the key never leaving the server.

Control flow that survives contact with reality

Node

Use it for

If / Else

A decision with a true and a false path

Try / Catch

Work that can fail, with a path for the failure and one that always runs

For Each

Iterating a list from a previous step

For Table

Iterating every row of a table, with filters

Delay

Waiting before continuing

Formula

Arithmetic without dropping into code

Call Automation

Handing work to another flow, fire-and-forget

Try/Catch is the one people reach for too late. An HTTP call to someone else's API will fail eventually — their outage, a timeout, a change they did not announce. Without a catch path, the run stops there and whatever came before is left half-done.

Call Automation is fire-and-forget. It starts the other flow and moves on; it does not wait, and it does not bring back a result. When you need the answer, that is a different design — the work belongs inline, or behind an endpoint you call.

Keeping it fast

Every node costs something, so fewer, larger steps beat many small ones. Two habits pay for themselves:

Filter in the query, not after it. Reading rows and then discarding most of them in a script does the expensive part anyway. Row reads are also capped per call, so a filter is often the difference between correct and quietly truncated.

Do not put a loop where a filter would do. A For Table over everything, with an If inside, is the same work as one filtered query — except it runs a node per row.

Next

  • Trigger nodes — the five ways in

  • Logic nodes — branching, loops, error handling, Response

  • Runs and debugging — reading what actually happened

  • API Gateway — the other half: what clients may do directly