App Functions
Functions are server-side JavaScript that runs inside epilot โ no infrastructure of your own, no exposed endpoints, no credentials in the browser. You write a handler, declare it in your app's manifest, deploy with the CLI, and epilot executes it in a secured sandbox on your behalf.
Functions are the unit for all custom server-side logic in an app. Where they run is decided by their type:
| Type | Triggered by | Typical use |
|---|---|---|
workflow | A CUSTOM_FLOW_ACTION component references it ({ "type": "function", "function_name": "โฆ" }); org admins add that action in the flow builder and it runs with the triggering entity as input | Enrich an entity, call your API through the API Proxy, validate data, reserve something in an external system |
scheduled | A cron schedule, automatically, once per installation | Poll a system that has no webhooks, sync a catalog nightly, refresh cached data |
{
"functions": [
{
"name": "reserve-slot",
"type": "workflow",
"handler": "./functions/reserve-slot/dist/handler.js"
},
{
"name": "sync-open-requests",
"type": "scheduled",
"handler": "./functions/sync-open-requests/dist/handler.js",
"schedule": "rate(30 minutes)"
}
]
}
Functions vs. componentsโ
Components are the surfaces of your app โ journey blocks, custom pages, portal blocks, API proxies. Functions are its behavior. They complement each other:
- A
workflowfunction is wired into the flow builder through aCUSTOM_FLOW_ACTIONcomponent that references it โ the component carries the org-facing name and config UI; the function carries the code. (external_integrationcomponents remain for webhook calls to your servers.) - A
scheduledfunction runs without any user interaction at all. - Functions can call external APIs through your app's API Proxy component, so external credentials stay on the installation and never appear in function code.
Code-first by designโ
There is no code editor in the epilot UI. Functions live in your app repository, are validated at deploy time, versioned with your app, and reviewed when you publish. This is deliberate: scheduled and flow-triggered code must be reproducible per version and per installation โ a UI-edited snippet can be neither.
npx @epilot/cli app add-function reserve-slot --type workflow --label "Reserve slot"
npm run build
npx @epilot/cli app deploy
What installing organizations seeโ
- Workflow functions show up in the flow builder's action picker through their referencing component, under the component's name.
- The installed app's details page shows scheduled functions in a compact summary on the Configuration tab โ label plus a plain-language cadence ("every 30 minutes") โ transparency about what the app runs on the org's behalf in the background. Workflow functions need no extra listing: they appear as their flow-action component cards right above.
- Every run is recorded in the app's Insights, so you (the developer) can monitor failures per version and component.
Continue with Writing functions for the runtime contract.