Skip to main content
This guide builds a company event Site, fall-gala, whose page takes RSVPs from signed-in members and whose REST API lets a partner’s server read the guest list. A nightly job removes old RSVPs. Every step uses the Fluid CLI. For the full reference, see Server functions.

Before you start

  • Fluid CLI with its Sites plugin 0.1.349 or later, signed in with fluid login. See Publish a Site.
  • @fluid-app/sites 0.1.71 or later in the Site’s package.json, for fluid.fn.
  • A Site folder, from npm create @fluid-app/fluid-site fall-gala or an existing project. See the Sites quickstart.
  • Sites and the sites gateway turned on for your company. Until then, the routes for API keys, environment variables and logs answer 404. To turn them on, contact support.
1

Add a table for the data

Functions read and write the Site’s own database. Add the table to db/schema.json. See the site database for the format and its rules.
db/schema.json
The rules keep the page from writing the table directly. Functions query as the Site, so the rules don’t apply to them, and the rsvp function below is the only way in.
2

Write the functions

Each file at the top of functions/ is one function, named after the file.
functions/rsvp.ts
functions/guests.ts
functions/nightly-cleanup.ts
Functions run on Cloudflare Workers, not Node.js. Use web APIs such as fetch and crypto.subtle, not node: modules.
3

Declare who may call each one

config/functions.json
signed_in lets only a signed-in visitor call from the Site’s page. key needs one of the Site’s API keys. Giving the scheduled function key access keeps guests from calling it, and its check of ctx.caller.kind keeps a key holder, such as the partner, from running it.
4

Call the function from the page

src/rsvp.ts
Use fluid.fn.fetch, not the page’s own fetch: it sends the visitor’s sign-in with the call.
5

Check and publish

fluid sites lint checks the build output, so build first. It also builds each function and checks config/functions.json without a request. fluid deploy builds the Site, publishes the page, the schema and the functions together, and prints the Site’s address. A new Site is private, so rsvp answers only the people it’s shared with until you share it or make it public. Ask before you make it public. The partner’s key works either way.
6

Store any secrets

If a function calls another service, keep its key as a secret. Functions read it from ctx.secrets, and a change reaches them without a new publish:
7

Add an API key for the partner

With Sites plugin 0.1.360 or later, run fluid sites keys create partner in the Site’s folder: it prints the secret once. With an older plugin, call the API. For a company Site, use a signed-in admin’s token and the site_id in the folder’s .member-site.json:
The answer’s api_key.secret, which starts with fsk_, is shown only this once. For a member’s own Site, call POST /api/member/v2026-10/sites/$SITE_ID/api-keys with the member’s token instead: its answer carries the secret at data.secret. Give it to the partner over a private channel, and never put it in the Site’s code. See Add an API key to a company site.
8

Call the API

The function answers at the Site’s own host, https://<label>.sites.fluid.app. The label is normally the company’s subdomain and the Site’s handle, joined by a hyphen. To be sure, read window.location.origin on the Site’s page.
A key opens the Site’s key and public functions even while the Site is private. Without the key, the call answers 401 fn_key_required.
9

Read the log

Each call is one line with its function, caller, status and time, and the nightly run shows up as a schedule call. What a function prints with console.log isn’t in the log.

Rotate or revoke a key

To rotate, add a new key, move the partner to it, then revoke the old one by its id. List the keys to find the id: each shows its name and first 12 characters, never its secret. A revoked key stops working on the next call.

When something fails

The full list is in What the answers mean.