ConceptsAlerts

Alerts tell you before you ask

Every Swarm machine keeps one feed of what happened: runs that failed, workers waiting on you, refused connections. Ask about it any time, or have it sent to your phone.

Is everything OK?

One question, one answer. Each machine reports one of three states, with the reasons:

ok

Services up, nothing failed today, nothing waiting.

attention

A run failed, a worker waits on you, or spend is near the daily limit.

degraded

Something you turned on (the sandbox, environments or the secret gateway) isn't working. Swarm says which and the command that fixes it.

Say this to your AI

Is everything OK? What did it cost today?

  • swarm_status

One thing needs you: the coder is waiting on which login page to fix. Otherwise ok: 14 runs, 1 failed, $2.18 of your $25 daily limit.

Signals

A signal is one line: a kind, a severity (info, warning or critical), short ids and a summary. Transcripts, commands and secret values never go in, so a signal is safe to send anywhere.

Runs

A job or a scheduled run finished, failed or was stopped.

worker.run.succeededworker.run.failedworker.run.cancelled
Waiting on you

A worker needs an answer, an approval or a plan, then moves on.

agent.blockedagent.unblockedjob.blocked
Keys

Keys made, revoked, or a dead key someone tried to use.

token.mintedtoken.revokedtoken.denied
Sandbox and network

The sandbox state, refused connections, and where secrets went.

sandbox.activesandbox.inactiveegress.refusedsecret.used
Machine

Swarm restarted; your own scripts and monitors can report too.

daemon.startedexternal.*

Sent where you are

  1. Swarm machinesignal feed
  2. Signed POSTonly the kinds you chose
  3. Your receiverchecks the signature
  4. Youphone · Slack · email
Signed with HMAC-SHA256. Nothing is ever received back from the URL.
  • Only what you want: pick kinds (“failed runs and anything waiting on me”) and a minimum severity.
  • Never lost: delivery moves on only when your receiver says OK; failures retry with back-off.
  • Silence means something: an idle machine sends a heartbeat (every 60 seconds by default), so your receiver can tell a quiet machine from a dead one and tell you.
Say this to your AI

Text me on Telegram when a run fails or something is waiting on me.

  • swarm_activity
  • signals.sinks.create

Done. I deployed a small receiver with your bot; it checks every delivery's signature. Test message sent.

Dashboards that only watch

For a status page or a wall screen, your AI makes a monitor key: it can read the machine's status and its signals, nothing else, for up to a year. Across machines, the fleet view gives every machine's status in one call (Many machines).

For developers

Create a sink from the machine's owner, then verify each delivery on your receiver:

create-sink.ts
import { SwarmClient } from '@swarm-agent/sdk';

const swarm = new SwarmClient(); // owner only: run as the user that runs Swarm

const { sink, secret } = await swarm.signals.sinks.create({
  name: 'phone',
  url: process.env.ALERT_RECEIVER_URL,          // your https endpoint
  kinds: ['worker.run.failed', 'agent.blocked'], // prefixes; empty sends all
  minSeverity: 'warning',
  heartbeatSeconds: 60,
});
// Store `secret` on the receiver. It is shown once.
receiver.ts
import { verifySignalDelivery } from '@swarm-agent/sdk';

export async function handle(req: Request) {
  const body = await req.text(); // the raw body, not re-serialized
  const ok = await verifySignalDelivery(
    process.env.SINK_SECRET!,
    req.headers.get('X-Swarm-Timestamp') ?? '',
    body,
    req.headers.get('X-Swarm-Signature') ?? '',
  );
  if (!ok) return new Response('bad signature', { status: 401 });

  const batch = JSON.parse(body);
  for (const s of batch.signals) await sendToPhone(`${s.severity}: ${s.summary}`);
  return new Response('ok'); // a 2xx moves the cursor on
}

More: client.box.summary() for the status, client.signals.list to read the feed with a cursor. Full details: ai/alerts.md.