Webhooks
Forward audit events in real-time to your SIEM, log aggregator, or webhook endpoint using CloudEvents v1.0 format.
Webhooks deliver workspace audit events to your external systems via HTTPS. Events are formatted as CloudEvents v1.0, signed with HMAC-SHA256, and delivered in batches with automatic retries.
- 1Navigate to Workspace Settings in the sidebar
- 2Scroll to the Webhooks section
- 3Click Add Destination
- 4Enter your HTTPS webhook URL and an optional description
- 5Add any custom headers your endpoint requires (e.g., API keys, authorization tokens)
- 6Click Create Destination
- 7Copy the HMAC secret — it is shown only once. Store it securely.
- 8Click the Test button to send a test event and verify delivery
You can add multiple destinations per workspace. Each destination can be independently enabled, disabled, tested, or deleted.
Every delivery is a JSON array of CloudEvents v1.0 envelopes:
[
{
"specversion": "1.0",
"id": "aud_abc123",
"source": "https://app.atmos.pro/workspaces/ws_xyz",
"type": "pro.atmos.workspace.created",
"time": "2025-01-15T10:30:00.000Z",
"subject": "ws_target1",
"datacontenttype": "application/json",
"data": {
"actor": { "id": "usr_actor1", "type": "user" },
"action": { "category": "workspace", "action": "created" },
"target": { "type": "workspace", "id": "ws_target1" },
"description": null,
"metadata": {}
}
}
]| Field | Description |
|---|---|
specversion | Always "1.0" |
id | Unique audit log entry ID |
source | Workspace URL that generated the event |
type | Event type in the format pro.atmos.{category}.{action} |
time | ISO 8601 timestamp |
subject | Target resource ID (if applicable) |
datacontenttype | Always "application/json" |
data | Event payload with actor, action, target, description, and metadata |
All event types follow the pattern
pro.atmos.{category}.{action}. See the Audit Log overview for the complete list of categories and actions.Every webhook delivery includes an
X-Webhook-Signature header:X-Webhook-Signature: sha256=5d7861...
The signature is an HMAC-SHA256 hex digest of the raw request body using the destination's secret key. Always verify this signature before processing events.
const crypto = require('crypto');
function verifySignature(body, secret, signatureHeader) {
const expected = 'sha256=' + crypto.createHmac('sha256', secret)
.update(body)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signatureHeader),
Buffer.from(expected)
);
}
// In your webhook handler:
const body = req.body; // raw string, not parsed JSON
const signature = req.headers['x-webhook-signature'];
if (!verifySignature(body, process.env.WEBHOOK_SECRET, signature)) {
return res.status(401).send('Invalid signature');
}import hmac
import hashlib
def verify_signature(body: bytes, secret: str, signature_header: str) -> bool:
expected = 'sha256=' + hmac.new(
secret.encode(), body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature_header, expected)package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
)
func verifySignature(body []byte, secret string, signatureHeader string) bool {
mac := hmac.New(sha256.New, []byte(secret))
mac.Write(body)
expected := "sha256=" + hex.EncodeToString(mac.Sum(nil))
return hmac.Equal([]byte(signatureHeader), []byte(expected))
}- Events are batched — up to 100 events are collected over a 30-second window before delivery
- Failed deliveries are retried up to 5 times with exponential backoff
- After all retries are exhausted, an alert email is sent to notify you of the failure
- Delivery status (success/failure) is visible in the webhook destinations list in workspace settings
- The
X-Webhook-Idheader identifies which destination received the delivery
- 1Create an HTTP Source in your Sumo Logic collector
- 2Copy the HTTP Source URL
- 3Add it as a webhook destination in Atmos Pro
- 4Events arrive as JSON arrays — use the
jsonoperator in Sumo Logic to parse them
- 1Create an HTTP Event Collector (HEC) token in Splunk
- 2Set the webhook URL to
https://your-splunk:8088/services/collector/event - 3Add a custom header:
Authorization: Splunk <your-hec-token> - 4Events will appear in the index associated with your HEC token
- 1Use the Log Intake API endpoint
- 2Set the webhook URL to
https://http-intake.logs.datadoghq.com/api/v2/logs - 3Add a custom header:
DD-API-KEY: <your-api-key> - 4Optionally add
ddsource: atmos-proandddtags: env:productionheaders
Loki expects a specific log format. Use a lightweight proxy such as Vector or Fluent Bit to receive CloudEvents JSON and forward to Loki's push API (
/loki/api/v1/push).Delivery status shows "failed"
- Verify the destination URL is reachable and returns a 2xx status code
- Check that HTTPS is used (HTTP URLs are not allowed)
- Verify any custom headers (e.g., API keys) are correct and not expired
- Check your endpoint's firewall or IP allowlist
Events not appearing in your SIEM
- Confirm the destination is enabled in workspace settings
- Check the audit log viewer to verify events are being recorded
- Send a test event to confirm connectivity
Signature verification fails
- Verify against the raw request body (the exact bytes received), not a re-serialized version
- Use timing-safe comparison (e.g.,
crypto.timingSafeEqualin Node.js) - Ensure you are using the correct secret for the destination