env. Use one to send form leads to a CRM, call an API with a private key, or check something the browser can’t be trusted with.
Writing a function
A function is aserver_function source file whose name, such as getSlots, starts with a letter and uses letters, numbers, -, and _:
onis the trigger:httporform. Each function has one.envmaps each secret’s name to its value, orundefinedwhen it isn’t set.- Functions run on the WinterTC Minimum Common API (ECMA-429), the web platform Cloudflare Workers, Deno, Bun, and Node share:
fetchto public addresses,Request,Response,Headers,FormData,Blob,File, streams, compression streams,URL,URLPattern, Web Crypto (PBKDF2 runs at most 100,000 iterations and derives at most 512 bits, and generated RSA keys are at most 2,048 bits),TextEncoder,TextDecoder,Intl,AbortController,MessageChannel, timers, andconsole. The Web Platform Tests for these APIs run against the sandbox on every change. - There is no DOM, file system, Node.js built-ins,
WebAssembly, orWebSocket, and the build rejects code that uses an API the sandbox doesn’t provide. - A function can import
@server, shared modules that use neither React nor@website, and pinned npm packages, which load their worker builds. SDKs built onfetchwork, such as OpenAI, Anthropic, Stripe, Resend, Notion, HubSpot, Slack, and SendGrid. Packages that need Node.js networking,WebSocket, orWebAssemblydon’t: usejosefor JWTs, and call the service’s REST API withfetchinstead. Pages can’t import function source. - Return values must be JSON-safe.
The http trigger
Page code imports anhttp function from @server/{name} and calls it. The types come from the handler, and the call never throws for expected failures:
POST /_framework/server/{name} with a JSON body. Draft hosts run the draft’s functions and the live site runs the published ones, with the same secrets. Error codes:
Put expected outcomes, such as “this time slot is taken”, in
data, not in errors. The payload’s type isn’t checked at runtime and anyone can call the function, so validate the payload in the handler, for example with zod’s safeParse. Cactal never retries a call.
The form trigger
Aform function runs in the background after every form submission accepted as not spam, including draft submissions and submissions restored with Not spam. The visitor’s response never waits for it, and the submission is still stored and emailed. Use it, not an http function called from the form’s page, to send submissions to a CRM or another service: an http call skips spam screening. It receives the data the notification email carries:
Limits
Each call gets about 200 ms of CPU (time spent waiting onfetch is free), 10 seconds for http and 30 seconds for form, 64 MB of memory, 50 outgoing requests (4 at a time, each request body and response up to 5 MB), 64 KB of input, and 1 MB of output. Code outside the handler gets 500 ms when the function loads. Free organizations get 1,000,000 http calls a month, with warnings to owners at 80 percent and at the limit; paid plans have no monthly cap. See Plans and limits.
Secrets and redaction
Each secret’s value, plus its base64 (including inside a longer value such as a Basic auth header), base64url, hex, URL-encoded, form-encoded, and JSON-escaped forms, is replaced with[redacted:NAME] in function responses, console output, error messages, and run records. Values under 8 characters are left as written, since hiding them would also hide unrelated text. Outgoing requests are sent exactly as written. Code that deliberately disguises a secret, or sends it to a server it controls, can still leak it, as on any platform with environment variables.
Runs
Every call is recorded for 30 days with its input, output, console output, outgoing requests, and timings.GET /v1/websites/{websiteId}/functions/runslists runs newest first; filter withname.GET /v1/websites/{websiteId}/functions/runs/{runId}returns one run.POST /v1/websites/{websiteId}/functions/{name}/invokeruns anhttpfunction on the draft and returns its result. It makes the function’s real requests.
websiteFunctions.view and websiteFunctions.invoke capabilities (full editors and above).