Recipes
Copy-paste automation with the HTTP API, from CI pipelines to your SIEM.
All recipes assume:
export THREEAM=https://3am.bank.internal # your console address
export TOKEN=… # the admin token (keep it in your CI's secret store)Pause 3AM during a deployment
Halt before the change, resume after. A halt refuses every action, including fixes that were already approved but not yet run. Diagnosis keeps going.
deploy:
script:
- 'curl -sf -X POST "$THREEAM/v1/halt" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json"
-d "{\"by\": \"ci:$CI_PROJECT_PATH\", \"reason\": \"deploying $CI_COMMIT_SHORT_SHA\"}"'
- ./deploy.sh
after_script:
- 'curl -sf -X POST "$THREEAM/v1/resume" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json"
-d "{\"by\": \"ci:$CI_PROJECT_PATH\"}"'after_script runs even when the deploy fails, so 3AM never stays halted by accident. The halt shows in the console
and the audit log with your reason.
Record changes made outside 3AM
Post deploys and manual fixes to the audit log, so incidents show them in their timeline. This uses the ingest token, not the admin token.
curl -sf -X POST "$THREEAM/v1/events" -H "Authorization: Bearer $INGEST_TOKEN" -H 'Content-Type: application/json' \
-d "{\"type\": \"human.deploy\", \"actor\": \"ci:payments\", \"reason\": \"deployed payments $SHA\",
\"data\": {\"service\": \"payments\", \"version\": \"$SHA\"}}"Export the audit log to your SIEM
Ask for everything after the last event you shipped (after_seq), oldest first, 2000 at a time. Run it on a schedule:
#!/usr/bin/env bash
set -euo pipefail
last=$(cat .last_seq 2>/dev/null || echo 0)
while :; do
page=$(curl -sf -H "Authorization: Bearer $TOKEN" "$THREEAM/v1/ledger?after_seq=$last&order=asc&limit=2000")
[ "$(jq '.events | length' <<<"$page")" -gt 0 ] || break
jq -c '.events[]' <<<"$page" | curl -sf -X POST "$SPLUNK_HEC/services/collector/raw?sourcetype=3am:ledger" \
-H "Authorization: Splunk $HEC_TOKEN" --data-binary @-
last=$(jq '.events[-1].seq' <<<"$page"); echo "$last" > .last_seq
[ "$(jq .more <<<"$page")" = true ] || break
doneBefore handing an export to an auditor, verify the chain on the source:
curl -s -H "Authorization: Bearer $TOKEN" $THREEAM/v1/ledger/verify.
Alert before the licence expires
/v1/status needs no token. With the blackbox exporter's JSON prober, or a small script:
expires=$(curl -sf "$THREEAM/v1/status" | jq -r .licence.expires_at)
days=$(( ( $(date -d "$expires" +%s) - $(date +%s) ) / 86400 ))
[ "$days" -gt 30 ] || echo "3AM licence expires in $days days"List today's incidents and outcomes
curl -sf -H "Authorization: Bearer $TOKEN" "$THREEAM/v1/episodes?limit=200" \
| jq -r '.episodes[] | select(.t_open > (now - 86400 | todate)) | [.t_open, .service, (.alerts|join(",")), .decision, .outcome] | @tsv'2026-10-04T17:54:12Z platform DependencyPortUnreachable abstain escalated
2026-10-04T16:21:03Z core-banking-db MySQLReadOnly act mitigatedPost the daily digest to a channel
text=$(curl -sf -H "Authorization: Bearer $TOKEN" "$THREEAM/v1/digest?days=1" | jq -r .markdown)
jq -n --arg text "$text" '{text: $text}' | curl -sf -X POST "$SLACK_WEBHOOK" -H 'Content-Type: application/json' -d @-Push alerts from a SIEM
curl -s -X POST "$THREEAM/v1/alerts/splunk" -H "Authorization: Bearer $INGEST_TOKEN" \
-H 'Content-Type: application/json' --data @splunk-alert.jsonEvery shape and source name: Alert webhooks.
Make site keys for new sites from a script
curl -s -X POST "$THREEAM/v1/keychain/site-keys" -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"labels":["Frankfurt staging","Singapore DR"],"purpose":"staging","licence":true,"hours":72}' \
| jq -r '.keys[] | "\(.label)\t\(.key)"'Each key is shown once and works once. Deliver it to its site by your secure channel, then on the new host:
./install.sh --keychain-join $HOME_URL --keychain-site-key-file site.key.
Alert when a Keychain member stops syncing
curl -s -H "Authorization: Bearer $TOKEN" "$THREEAM/v1/keychain" \
| jq -r '.members[] | select(.health=="silent" or .health=="gone") | "\(.label) \(.health) \(.quiet_s)s"'Or follow the audit log for keychain.member_silent and keychain.member_gone (syslog forwards security events).
Run a Study every week
curl -s -X POST "$THREEAM/v1/study" -H "Authorization: Bearer $TOKEN" -d '{"minutes":30}' # 409 if one is runningFind incidents with the query language
curl -sG "$THREEAM/v1/episodes" -H "Authorization: Bearer $TOKEN" \
--data-urlencode 'query=service:core-banking result:handed_over opened<7d' --data-urlencode 'limit=50'