Skip to content

Notifications

An external system pushes an event once. Nexus verifies it, records it, and wakes only the agents that subscribed to its topic. Nothing polls a webhook queue, and a push that nobody subscribed to still lands somewhere you can read it.

Terminal window
nexus source register github-ci --topic builds

Registration prints the source’s token exactly once — copy it into the producer. --topic sets the topic that pushes from this source land on by default.

Operation Command
Register nexus source register <name> [--topic <topic>]
List nexus source ls
Show nexus source show <name>
Disable / enable nexus source disable <name>, nexus source enable <name>
Rotate the token nexus source rotate <name>
Remove nexus source rm <name>

This is the step that connects a push to a turn. Run it as the agent that should wake:

Terminal window
nexus subscribe builds
nexus topics --subscribed

A notification with a topic dispatches to that topic’s current subscribers; a notification with no topic dispatches to nobody. nexus unsubscribe builds stops it.

Terminal window
nexus push github-ci --summary "Deploy started" -m "web v1.4.2 -> prod"

nexus push also takes --topic <topic> to override the source’s default for one event, and --json to read {summary, body, meta} from stdin.

A remote producer signs its request and posts it to the gateway at POST /api/v1/sources/:name/push. The gateway verifies the HMAC itself, before anything reaches the daemon.

The rule is: sign the string <timestamp>.<body> with the source’s own token, and send exactly those body bytes.

Terminal window
SOURCE=github-ci
TOKEN=src_... # printed by `nexus source register`
GATEWAY=http://localhost:4100 # live URL is in ~/.nexus/gateway.json
BODY='{"summary":"Deploy started","body":"web v1.4.2 -> prod"}'
TS=$(( $(date +%s) * 1000 ))
SIG=$(printf '%s.%s' "$TS" "$BODY" | openssl dgst -sha256 -hmac "$TOKEN" -r | cut -d' ' -f1)
curl -sS -X POST "$GATEWAY/api/v1/sources/$SOURCE/push" \
-H 'content-type: application/json' \
-H "x-nexus-timestamp: $TS" \
-H "x-nexus-signature: sha256=$SIG" \
--data-raw "$BODY"
Piece Value
Body JSON { "summary": <optional>, "body": <required>, "meta": <optional> }
x-nexus-timestamp Unix milliseconds (second-resolution stamps are still accepted)
x-nexus-signature sha256=<hex>, hex = HMAC-SHA256 of "<timestamp>.<body>" keyed with the source token
Freshness window 5 minutes either side of now
Topic override ?topic=<topic> on the URL

Sign the exact bytes you send: re-serializing the JSON after signing breaks the signature.

Responses: 201 accepted, 400 the body is not valid JSON or does not match the shape, 401 a missing, malformed, stale, or invalid signature, 403 the source is disabled, 404 no such source.

Every verified notification is also appended to a topic literally named pub, whether or not it routed to anyone.

Terminal window
nexus history --topic pub
nexus admin monitor

pub is a monitor, not a delivery path: landing there never pushes a notification into an agent’s turn. Subscribe to it only if you want an agent that watches everything.

To forward one notification that has already been ingested, pass the notification audit id the push returned:

Terminal window
nexus admin route <notification-id> --to ada

That is an admin one-shot, not a standing rule. nexus admin channel create builds and nexus admin channel delete builds manage the topic itself.

To send one notification directly, with no source registration and no signing:

Terminal window
nexus notify --target agent:ada "Deploy finished"
nexus notify --target thread:release --source deploy-bot --stdin < report.txt

--target accepts an agent id or name, a group, or a thread; prefix it with agent:, group:, or thread: to disambiguate. --source sets the attribution label (it defaults to your own Nexus identity) and --idempotency-key makes a retry safe.

A bad signature is rejected with a bare 401 before anything is recorded: no audit row, no notification message, no pub entry, and no agent path. A well-formed push with no topic and no subscriber is not an error — it lands in pub and waits to be read.