Audit log streaming

Send your org's audit log (role, channel, member and integration changes) to your own server or SIEM as it happens, signed so the receiver can check each delivery came from Missived.

Before you start

Audit destinations carry audit events (who changed what in the org). For product events such as messages, members joining or meetings, use event subscriptions instead.

The audit log in the app

Org Settings → Audit log lists the org's most recent events, newest first: when, the action (such as channel.deleted), who did it and what it was done to. Filter by an exact action name and press Refresh. Actions taken in your org by a Missived platform admin carry a platform badge.

Add a destination

  1. Open Org Settings → Integrations → Outgoing webhooks → Add outgoing webhook.
  2. Fill in:
Field What it does
Name (optional) A label, such as "Splunk production"
URL Where deliveries are POSTed. https only, public addresses only.
Format OCSF: the Open Cybersecurity Schema Framework (1.8.0) envelope most SIEMs read. Simple JSON: Missived's own flat shape.
Which events A minimum severity: Everything (informational and up), Low and up, Medium and up, High and up, or Critical only
Only these actions (optional) Action names separated by commas; * matches the rest of a name (role.*, channel.deleted). Empty sends every action.
Extra header / Header value (optional) A fixed header for a gateway that wants a token, such as Authorization: Bearer …. Stored encrypted and never shown again.
Also sign with Ed25519 Adds an Ed25519 signature the receiver checks with a public key instead of the shared secret
  1. Add webhook. Copy the signing secret (whsec_…) and, if you chose Ed25519, the public key (whpk_…, not secret). The secret is shown only now.
  2. Choose Send test to send a signed test event. The page shows the request and your receiver's answer.

To change the extra header or the signing type later, add a new destination and delete the old one. The list of action names is at listAuditActions.

What a delivery looks like

Each audit event is one POST:

POST /your/url
content-type: application/json
user-agent: Missived-Webhooks/1.0
webhook-id: 0192a3b4-5c6d-7e8f-9a0b-1c2d3e4f5a6b
webhook-timestamp: 1761480000
webhook-signature: v1,<base64 HMAC-SHA256>

With Simple JSON the body is:

{
  "id": "0192a3b4-5c6d-7e8f-9a0b-1c2d3e4f5a6b",
  "seq": 4182,
  "occurred_at": "2026-10-26T12:00:00.000Z",
  "action": "channel.deleted",
  "outcome": "success",
  "org_id": "…",
  "actor": { "type": "user", "id": "…", "label": "[email protected]", "on_behalf_of": null },
  "target": { "type": "channel", "id": "…", "label": "old-announcements" },
  "metadata": { }
}

With OCSF the body is the OCSF envelope: class_uid, category_uid, activity_id, type_uid, severity_id (1 to 6), time (milliseconds), status / status_id, metadata.version and metadata.product, actor.user (uid, name, type), resource (the target), and unmapped with the Missived action, org_id and the event's metadata. The classes in use are Account Change (3001), Authentication (3002), Entity Management (3004), User Access Management (3005) and API Activity (6003). getAuditSchemas describes the shape.

Verify the signature

Deliveries follow Standard Webhooks, so any Standard Webhooks library verifies them. By hand:

  1. Take webhook-id, webhook-timestamp and the raw body exactly as received, before parsing.
  2. Reject a timestamp more than 5 minutes from now.
  3. Compute HMAC-SHA256 over "{webhook-id}.{webhook-timestamp}.{raw body}", keyed with the base64-decoded part of the secret after whsec_, and base64-encode it.
  4. webhook-signature is a space-separated list. Accept the delivery if any v1, entry matches (compare in constant time).

The same code as for event subscriptions works unchanged.

Ed25519. When it's on, the list also holds a v1a,<base64 signature> entry: an Ed25519 signature over the same "{id}.{timestamp}.{body}" string. The public key is whpk_ followed by a base64 DER (SPKI) key. A receiver that verifies with the public key holds nothing that could forge a delivery.

Extra header. If you set one, it arrives on every delivery as given. It is not a signature; check the signature too.

Rotating the secret

Rotate secret issues a new whsec_ secret (shown once). Until you rotate again, deliveries carry a v1 signature for the new secret and one for the old, so a receiver with either keeps working while you update it.

Retries, pauses and 410

Delivery is at least once.

A paused or switched-off destination says why on the Integrations page. Resume turns it back on and resets the failure count. Pause stops deliveries until you resume.

Delivery log and replay

Each destination shows its health (deliveries and failures in the last 24 hours) and a delivery log with each delivery's status, attempts, your receiver's response code and the start of its answer.

Pull the audit log instead

An Owner or Admin can page through the log with a session or a personal token with the admin:read scope (only an Owner or Admin can give a token that scope):

curl -H "Authorization: Bearer $MISSIVED_TOKEN" \
  "https://api.missived.com/v1/orgs/<orgId>/audit-events?limit=500&since=2026-10-01T00:00:00Z"

See listAuditEvents. App tokens can't read the audit log.

Destinations themselves are managed only from the Integrations page, signed in; API tokens can't manage them yet.

What data moves

Limits

Troubleshooting