Webhooks
Admin → Webhooks (/admin/webhooks) subscribes external services to
ARGUS events. Each webhook is an HTTPS endpoint that receives a JSON POST
signed with HMAC-SHA256 whenever one of the subscribed events fires. Think
of it as the raw plumbing underneath Workflows —
lower-level, but simpler to wire into a SIEM, a logging pipeline, or a bespoke
ops console.
Requires admin or superadmin.
The list
Each card shows:
- A status dot (green =
enabled, grey = paused). - The webhook’s name and URL.
- The subscribed event chips.
- A one-line delivery summary —
Last delivery: ...plus{successCount}/{totalDeliveries} successful.
Card actions (icon buttons on the right):
| Icon | Action |
|---|---|
| Pause / Play | Toggle enabled. Paused webhooks keep config but stop dispatching. |
| History | Open the delivery log. |
| Edit | Open the edit form. |
| Delete | Remove the webhook. |
The page header summary reads {webhookCount} configured · {activeCount} active.
Create / edit
New webhook (top-right) opens the edit form. Fields:
- Name — human-readable label, e.g.
Slack Alert Relay. - Endpoint URL —
https://only. Rejected if it returns a redirect. - Signing secret (HMAC-SHA256) — auto-generated on creation; click the eye to reveal and the refresh icon to regenerate. Copy it now — subsequent visits show dots and only the tail of the secret. Regenerating invalidates any previous secret immediately.
- Description — optional notes.
- Event subscriptions — grouped checkbox grid (see below).
- Enabled — pill toggle.
Save writes to /webhooks/{id} at the root of Firestore with an orgId
field. Delivery is handled by the argus-api webhook-dispatcher service —
Firestore rules gate who can write the doc, but the dispatcher is the only
code that reads it.
Event catalog
Exactly the 15 WebhookEventType values, grouped as the UI groups them:
- Flights —
flight.started,flight.completed,flight.failed(RTH, emergency land, safety trigger). - Alerts —
alert.cas(Copilot master-caution),alert.geofence(boundary breach),alert.hms(DJI HMS at WARNING+). - AI / Media —
detection.new(watchlist hit on a live stream),media.captured(photo/video uploaded and cataloged). - Docks —
dock.online(first telemetry),dock.offline(keep-alive expired). - Operations —
operation.created/operation.started(transitioned to active) /operation.completed(closed + report). - Tasks —
task.completed,task.failed.
The webhook also carries a header X-Argus-Event with the event type for
trivial routing.
HMAC signing
Every POST carries the header:
X-Argus-Signature: sha256=<hex>The <hex> is HMAC_SHA256(secret, <raw request body>). Verify it before
trusting the payload. The payload envelope is:
{ "event": "flight.completed", "orgId": "org_abc", "timestamp": 1745500000000, "data": { ... event-specific fields ... }, "idempotencyKey": "flight.completed:flight_xyz:1745500000000"}Use idempotencyKey to de-duplicate — the dispatcher’s retry logic can
re-send the same event (see below).
Retries & backoff
The dispatcher expects a 2xx status code within 10 seconds. Anything else
(timeout, network error, 4xx, 5xx) schedules a retry:
- Attempt 1 — immediate.
- Attempt 2 — +1 minute.
- Attempt 3 — +5 minutes.
After three failures the webhook is auto-disabled (enabled = false)
and an admin.webhook.auto_disabled event is written to the audit log. The
card shows a red pause indicator; you can re-enable it after fixing the
endpoint.
Delivery log
Click the History icon on a webhook card to open Delivery log. Each
row shows:
- HTTP status code (or
ERRfor network errors), colour-coded. - The event type.
- Timestamp.
- Latency in ms.
attempt N/3.- Error message, if any.
Logs are kept for 30 days by default (configurable per plan — Command and Sovereign extend to 365).