Guide

Remote triggers

Remote triggers let you dispatch signals and broadcasts from any application to a Station server over HTTP. Your application code calls .trigger() as usual, but execution happens on the Station server instead of locally.


How it works

When you call configure() with a remote endpoint, Station creates an HttpTriggerAdapter internally. Every subsequent .trigger() call sends an HTTP POST to the Station server's v1 API instead of writing to a local adapter.

  1. Client validates input against the signal's Zod schema locally
  2. Client sends POST /api/v1/trigger with the signal name and input
  3. Server authenticates the request via API key, creates a pending run, and returns the run ID
  4. The signal runner on the server picks up the pending run and executes it

1. Set up the Station server

Your Station server needs an adapter for persistence, auth for API key management, and host: "0.0.0.0" to accept remote connections.

// station.config.tsimport { defineConfig } from "station-kit";import { SqliteAdapter } from "station-adapter-sqlite"; export default defineConfig({  port: 4400,  host: "0.0.0.0",  signalsDir: "./signals",  adapter: new SqliteAdapter({ dbPath: "./.station/data/jobs.db" }),  auth: {    username: "admin",    password: "changeme",  },});

Start the server with npx station. The dashboard will be available at http://localhost:4400.


2. Create an API key

API keys authenticate remote trigger requests. Create one from the dashboard Settings page, or via the v1 API:

curl -X POST http://localhost:4400/api/v1/keys \  -H "Authorization: Bearer <session-token>" \  -H "Content-Type: application/json" \  -d '{"name": "my-app", "scopes": ["trigger", "read"]}'

The response includes the full key (prefixed sk_live_). Store it securely — the key is only shown once.

API keys support scoped access: trigger (dispatch jobs), read (view runs and status), cancel (cancel running jobs), and admin (manage keys).


3. Configure the client

In your application, call configure() once at startup. All subsequent .trigger() calls will go to the remote server.

Option A: Explicit configuration

import { configure } from "station-signal"; configure({  endpoint: "https://station.example.com",  apiKey: "sk_live_abc123...",});

Option B: Environment variables

Station auto-detects these environment variables. No code changes needed.

STATION_ENDPOINT=https://station.example.comSTATION_API_KEY=sk_live_abc123...

4. Trigger signals remotely

Once configured, .trigger() works the same as local triggering. The call returns a run ID immediately.

import { sendEmail } from "./signals/send-email.js"; // This sends an HTTP POST to your Station serverconst runId = await sendEmail.trigger({  to: "user@example.com",  subject: "Welcome",  body: "Thanks for signing up.",}); console.log("Dispatched run:", runId);

Broadcasts work the same way:

import { orderPipeline } from "./broadcasts/order-pipeline.js"; const runId = await orderPipeline.trigger({  orderId: "ord_123",  amount: 99.99,});

Deployment

Station includes a deploy command that generates deployment files for your server:

npx station deploy

This writes a Dockerfile and nixpacks.toml to .station/out/. Copy the appropriate file to your project root and deploy to any container platform (Railway, Render, Fly.io, AWS ECS, etc.).


CLI reference

FlagDescription
--port <n>Override server port (default: 4400)
--host <s>Override server host (default: localhost)
--dir <path>Set station directory for generated files (default: .station)
--config <path>Path to config file (default: station.config.ts)
--no-openDon't open browser on start
--no-runnersRead-only mode — don't execute signals or broadcasts