Skip to main content
Webhooks allow you to receive real-time notifications when events occur in your application. Set up HTTP endpoints to automatically receive event data as it happens.

Overview

Real-time Notifications

Get instant updates when events occur in your system

Secure Delivery

Webhooks are signed with cryptographic signatures for verification

Reliable Delivery

Automatic retries ensure your webhooks are delivered

Easy Integration

Simple HTTP POST requests to your specified endpoints

Configuration

Setting Up Your Webhook

Assuming you already have an endpoint URL, you can add a webhook integration in the platform.
1

Create Webhook Integration in Platform

In the platform, go to IntegrationsAdd Integration → select Webhook, then supply the webhook details:
  • URL: The endpoint that will receive events
  • Headers: Any custom headers required by your endpoint (e.g., authentication)
  • Body: The JSON payload template your endpoint expects
2

Attach Webhook to Agents

After creating the integration, attach the webhook to individual agents. When those agents run and emit events, your webhook will be invoked with the configured details.
3

Verify Webhook Signature

All webhooks include a cryptographic signature for security verification.

Webhook Payload

Every webhook request contains a standardized payload structure:
{
  "type": "<event_type>",
  "timestamp": "<timestamp>",
  "payload": "<event_payload>"
}

Payload Parameters

type
string
required
The type of event that triggered the webhook. Examples: user.created, payment.completed, order.updated
timestamp
string
required
ISO 8601 timestamp when the event occurredExample: 2024-01-15T10:30:00Z
payload
object
required
The actual event data. Structure varies depending on the event type.

Security & Signature Verification

All webhooks are signed using SHA256 hashing with RSA-PKCS1v15 signing and Base64 encoding for maximum security.

Signature Header

The webhook signature is included in the X-Asteroid-Signature header:
X-Asteroid-Signature: <signature>
Always verify the webhook signature to ensure the request is authentic and hasn’t been tampered with.

Public Key for Verification

Use this Base64-encoded public key to verify webhook signatures:
LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF0SkZ6aXdXUjROUVJzTnpqZw==

JavaScript Implementation

Here’s a complete example of verifying webhook signatures in JavaScript:
const crypto = require('crypto');

// Step 1: Create SHA256 verifier
const verifier = crypto.createVerify('SHA256');

// Step 2: Update verifier with the request body
verifier.update(body);

// Step 3: Convert Base64 public key to buffer
const publicKey = Buffer.from(publicKeyBase64, 'base64');

// Step 4: Verify the signature
const isValid = verifier.verify(publicKey, signature, 'base64');

console.log('Signature valid:', isValid);

Best Practices

Always return appropriate HTTP status codes:
  • 200 - Successfully processed
  • 400 - Bad request/invalid payload
  • 401 - Unauthorized/invalid signature
  • 500 - Server error
Use the timestamp and event data to detect and handle duplicate webhook deliveries.
const processedEvents = new Set();

app.post('/webhook', (req, res) => {
  const eventId = `${req.body.type}-${req.body.timestamp}`;
  
  if (processedEvents.has(eventId)) {
    return res.status(200).json({ message: 'Already processed' });
  }
  
  processedEvents.add(eventId);
  // Process the event...
});
Respond to webhooks within 30 seconds to avoid timeouts and retries.
app.post('/webhook', (req, res) => {
  // Acknowledge receipt immediately
  res.status(200).json({ received: true });
  
  // Process asynchronously
  setImmediate(() => {
    processWebhookEvent(req.body);
  });
});

Testing Your Webhooks

Use webhook.site to test your webhook integration during development. It provides a temporary URL that captures and displays all incoming webhook requests.

Test Payload Example

{
  "type": "user.created",
  "timestamp": "2024-01-15T10:30:00Z",
  "payload": {
    "user_id": "usr_123456789",
    "email": "[email protected]",
    "name": "John Doe",
    "created_at": "2024-01-15T10:30:00Z"
  }
}

Troubleshooting

  • Verify your endpoint URL is accessible from the internet
  • Check that your server is running and responding to POST requests
  • Ensure your firewall allows incoming connections
  • Confirm you’re using the correct public key
  • Verify you’re hashing the raw request body (not parsed JSON)
  • Check that you’re using Base64 decoding for both the key and signature
  • Implement idempotency using event timestamps and IDs
  • Return 200 status code for successfully processed events
  • Avoid returning error codes for already-processed events
I