Server Functions
A Server Function is a reusable Node.js module that runs outside the database. Use them for work that cannot or should not run inside PostgreSQL: calling external HTTP APIs, sending emails, working with AI models, handling files, processing webhooks, or anything that may take seconds or longer. Server Functions have access to the same platform data APIs as Database Workflows - reading and writing records, calling other functions - but they run in a Node.js process and do not hold a database connection for their full duration.
For a full comparison of when to use each, see Database Workflows - choosing between the two.
Server Functions are always written in code - there is no Design mode. The AI/Code tab is the only editor, with an AI assistant as the primary interface and direct code editing available behind the See Code toggle.
The Server Functions screen
Section titled “The Server Functions screen”Navigate to Automation - Server Functions to see all server functions in the current application:
| Column | Description |
|---|---|
| Function Name | Human-readable name |
| Module Name | Which module the function belongs to |
| Created By | The user who created it |
| Modified On | Last modification timestamp |
| Published On | When the function was last published |
| Status | A checkmark (✓) if published and current, or a Publish link if there are unpublished changes |
Use + Add to create a new function, and the row checkboxes plus Delete to remove functions in bulk.
Creating a server function
Section titled “Creating a server function”Clicking + Add opens a panel with:
| Field | Description |
|---|---|
| Function Name | Human-readable name |
| Function ID | Auto-generated from the name |
| Function Module | Which module this function belongs to |
| Description | Optional free text |
Function detail view
Section titled “Function detail view”Click a function to open its detail view. Publish sits at the top left. Top right actions: Run Function, Security Rules, Clone.
Three tabs sit below the header:
- Details - Function Info card (Function Name, Function ID, Module Name)
- AI/Code - the code editor and AI assistant
- Logs - execution log records written by the function itself
Note: unlike Database Workflows, Server Functions do not have a Function Triggers card on their Details tab. Triggers are configured on the Database Workflow side.
AI/Code mode
Section titled “AI/Code mode”The AI/Code tab is the primary way to build and refine a Server Function. It works the same way across both Server Functions and Database Workflows AI/Code mode - the only difference is the code that gets generated: Node.js here, PLV8 there.
AI chat (default view)
Section titled “AI chat (default view)”The tab opens in AI chat view. Describe what you want the function to do, ask the AI to explain existing code, request changes, or ask it to add JSDoc comments to handlers. The AI is already aware of the Node.js module conventions, the api.* platform APIs, and the handler/metadata structure used in Server Functions.
Context: Use the + button (or the paperclip icon) next to the chat input to open the Search context picker. From here you can add entities, views, or other functions as context items. The selected item’s metadata - field definitions, handler signatures, schema - is sent to the AI alongside your message so it can generate code that correctly references your data model. Added context items appear as chips (e.g., “Entities: Person”) with a × to remove, and Clear all removes everything at once.
Applying AI responses: AI suggestions appear as code blocks with Copy and Apply options. Apply pushes the change directly into the code editor. Previous suggestions stay in the chat history and can be re-applied if needed. The AI never automatically modifies the code - Apply is always a deliberate action.
See Code / Use AI toggle
Section titled “See Code / Use AI toggle”Click See Code (top right) to switch from the AI chat to the code editor and read or modify the PLV8 code directly. Click Use AI to return to the chat.
Code structure
Section titled “Code structure”When a new Server Function is created, the editor is pre-populated with a template following the standard Node.js module structure:
METADATA - function identity and declared targets (entities, views, functions)CONSTANTS - reusable business values and configurationPRIVATE_FUNCTIONS - internal helpers not exposed as handlersHANDLERS - public command handlers, returned as the handlers objectThe api object is available automatically and provides all platform operations: reading and writing records (api.get_data, api.save_data, etc.), calling other functions (api.execute_function), and Node.js-only capabilities including api.http.* for HTTP calls, api.ai.* for AI generation and embeddings, api.files.* for file storage, api.secrets.* for secrets management, and api.mail.send for email.
For full API reference and code conventions, see Developer Reference - Node.js Server Functions.
JSDoc and published methods
Section titled “JSDoc and published methods”Adding JSDoc comments to handler functions is how the platform discovers the function’s public interface at publish time. A properly annotated handler:
/** * Write an informational function log row. * @param {Object} input - Payload to attach to the log entry. * @returns {void} */handlers.log_info = input => { api.log_info("Testing handlers", input);};After publishing, the platform extracts the handler name, description, input parameters, and return shape from the JSDoc. This metadata powers the Published methods picker in Run Function, the method selector in workflow Execute Server Function steps, and any tooling that discovers this function’s interface.
The AI can write these JSDoc blocks for you: point it at a handler and ask it to add comments, then Apply the result.
Security Rules
Section titled “Security Rules”Security Rules (top right of the detail view) controls who can execute this function. Each rule overrides the default access behaviour for a specific set of users or roles. The fields and behaviour are identical to Database Workflow security rules - Allow or Forbid per User or Role, with an All Users option.
Running a function
Section titled “Running a function”Run Function (top right of the detail view) opens a panel for testing the function directly from the Designer:
| Field | Description |
|---|---|
| Command | The handler name to invoke - leave empty to call the default run handler |
| Published methods | Opens a picker listing all handlers extracted from JSDoc at last publish, each shown with its name, sync/async indicator, and description. Selecting one fills in the Command field and pre-populates the Input with null values for each discovered parameter, making it easy to fill in test values. |
| Input | A JSON editor for the input payload |
| Result | The response returned by the handler, shown after running |
Click Run to execute. The result appears in the Result section immediately below.
Function logs
Section titled “Function logs”The Logs tab shows records written explicitly by the function using api.log_* calls. These are not automatic execution traces - a log entry only appears if the function code calls api.log_info, api.log_warn, api.log_error, or api.log_debug.
| Column | Description |
|---|---|
| Log ID | Unique identifier for the log entry |
| Log Level | debug, info, warn, or error |
| Message | The message string passed to the log call |
| Data | The structured data object attached to the log entry |
| Created On | Timestamp |
Filter by log level using the Log Levels toggles (Debug, Info, Warn, Error). Use Clear All Logs to wipe the log history, or select rows and use Delete Selected Logs for targeted cleanup.
Where server functions go from here
Section titled “Where server functions go from here”A published Server Function is callable from anywhere in the platform that can invoke a function:
- As an Execute Server Function step inside a Database Workflow - the most common pattern, where a workflow delegates external or long-running work to a Server Function.
- From another Server Function via
api.execute_function- for composing modular logic across functions. - From the UI via Portal Components - as an action a user triggers directly.