Skip to main content

The client

createPult reads PULT_KEY from the environment. You can pass key directly instead, url if you run Pult somewhere other than https://app.pult.sh (PULT_URL works too), and fetch to send Pult’s requests some other way, like through a proxy. The client gives you:
  • pult.send(inbox, item) to send an item. See Sending items.
  • pult.listen() to receive requests over a WebSocket.
  • pult.handler() to receive requests over HTTP instead.
  • pult.log(resource, id, text) to add to a record’s history. See Hooks and history.
  • pult.receive(message) to thread an email reply onto its item. See Email.
  • pult.flag(flag, key) to read a flag. See Flags.
  • pult.deploy() to push your definitions to the environment behind the key.

Keys

Each environment has its own key, created and rotated in the project’s Environments settings. A key looks like pult_<environment>_<secret>; the first part says which environment it belongs to, so one variable is all your app needs. Every request in both directions is signed with the key and carries a timestamp and a one-time nonce. Pult refuses anything unsigned, altered, older than five minutes or seen before, and the SDK does the same for requests from Pult.

WebSocket or webhook

By default your app opens a WebSocket to Pult with pult.listen() and keeps it open. Pult sends action requests, lookups and renders down it, and the SDK answers. This works anywhere a process stays up and needs nothing public. On serverless platforms, switch to webhooks:
Mount the handler on that route and enter your app’s origin for each environment in the project’s Environments settings:
With the nodejs_compat flag on, Workers expose your secrets as process.env and createPult({ project }) finds PULT_KEY by itself. Definition files can import cloudflare:workers, cloudflare:email and cloudflare:sockets at the top. pult build runs outside Workers, so it swaps them for stand-ins while it reads your definitions. A file can still set up a client with env.DB at the top, as long as nothing calls it while the file loads: do the actual work inside your functions. Pass your platform’s context as the second argument so background actions can keep running after the response. On serverless platforms, await every pult.send or hand it to ctx.waitUntil, so the platform doesn’t stop your code before the item is sent. If your app can’t be reached, Pult queues what it needed to deliver and retries with backoff. Actions and replies queued this way show as waiting in the timeline until your app answers.

Environments

Environments are listed in your config from development to production:
The sync environment (the first one unless you say otherwise) follows your code. Whenever your app connects, or sends an item built from definitions Pult hasn’t seen, the SDK deploys your current definitions there. Pult refuses that automatic deploy for every other environment: those change only through pult deploy. The console marks the last environment as production. Data never crosses environments; each one has its own items, history and key.

Deploying definitions

pult deploy builds, shows what changes (including who gains or loses which permission) and pushes the manifest. Removing an inbox from your code archives it: its items stay readable under “Removed from code” in the console. See CLI.