Webhooks

Receive real-time notifications about events in your ARKA AI account.

What are Webhooks?

Webhooks allow you to receive HTTP POST notifications when specific events occur in your ARKA AI account. Instead of polling our API, webhooks push data to your server in real-time.

Common Use Cases

  • Trigger actions when AI tasks complete
  • Monitor token usage in real-time
  • Get notified of integration events
  • Track playbook execution status
  • Receive billing and subscription updates

Setting Up Webhooks

1. Create Webhook Endpoint

First, create an endpoint on your server to receive webhook events:

// Express.js example
app.post('/webhooks/arka-ai', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-arka-signature'];
  const payload = req.body;

  // Verify signature (see security section)
  if (!verifySignature(payload, signature)) {
    return res.status(401).send('Invalid signature');
  }

  const event = JSON.parse(payload);

  // Handle different event types
  switch (event.type) {
    case 'chat.completion.created':
      handleChatCompletion(event.data);
      break;
    case 'usage.threshold.reached':
      handleUsageThreshold(event.data);
      break;
    // ... handle other events
  }

  res.status(200).send('Webhook received');
});

2. Register Webhook in Dashboard

  1. Go to Settings → Webhooks
  2. Click "Add Endpoint"
  3. Enter your webhook URL (must be HTTPS)
  4. Select events to subscribe to
  5. Click "Create Endpoint"
  6. Save the signing secret shown (used for verification)

Event Types

chat.completion.created

Sent when a chat completion is successfully created.

{ "type": "chat.completion.created", "data": { "id": "chatcmpl-abc123", "model": "gpt-4o", "tokens_used": 150, "created_at": "2024-01-15T10:30:00Z" } }

usage.threshold.reached

Sent when you reach a usage threshold (80%, 90%, 100%).

{ "type": "usage.threshold.reached", "data": { "threshold": 80, "tokens_used": 2400000, "tokens_included": 3000000, "period_end": "2024-02-01T00:00:00Z" } }

playbook.execution.completed

Sent when a playbook execution completes (success or failure).

{ "type": "playbook.execution.completed", "data": { "playbook_id": "pb_123abc", "execution_id": "exec_456def", "status": "success", "steps_completed": 5, "total_steps": 5, "completed_at": "2024-01-15T10:35:00Z" } }

integration.connected

Sent when a new integration is successfully connected.

{ "type": "integration.connected", "data": { "integration": "slack", "connected_at": "2024-01-15T10:00:00Z" } }

subscription.updated

Sent when subscription plan changes or renews.

{ "type": "subscription.updated", "data": { "plan": "pro", "status": "active", "period_start": "2024-01-15T00:00:00Z", "period_end": "2024-02-15T00:00:00Z" } }

Webhook Payload Structure

All webhook payloads follow this structure:

{
  "id": "evt_1234567890",
  "type": "event.type.here",
  "created": 1640995200,
  "data": {
    // Event-specific data
  },
  "account_id": "acc_abc123"
}

Security & Verification

Signature Verification

All webhooks include an X-Arka-Signature header containing an HMAC signature. Verify this signature to ensure the webhook is legitimate:

const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// Usage
const signature = req.headers['x-arka-signature'];
const secret = process.env.ARKA_WEBHOOK_SECRET;
const isValid = verifySignature(req.body, signature, secret);

Security Best Practices

  • Always verify signatures - Reject webhooks with invalid signatures
  • Use HTTPS endpoints - Webhooks are only sent to HTTPS URLs
  • Store secrets securely - Use environment variables for webhook secrets
  • Implement idempotency - Handle duplicate webhook deliveries gracefully
  • Validate event types - Only process expected event types

Retry Logic

If your endpoint fails to respond or returns a non-2xx status code:

  • We'll retry up to 3 times with exponential backoff
  • Retry delays: 5 seconds, 25 seconds, 125 seconds
  • After 3 failures, the webhook is marked as failed
  • You can manually retry failed webhooks from the dashboard

💡 Best Practice

Respond with a 2xx status code immediately upon receiving the webhook, then process the event asynchronously. This prevents timeouts and ensures reliable delivery.

Testing Webhooks

Send Test Event

You can send a test event to your webhook endpoint from the dashboard:

  1. Go to Settings → Webhooks
  2. Click on your webhook endpoint
  3. Click "Send Test Event"
  4. Select event type to test
  5. View the request/response in the dashboard

Local Development

Use a tool like ngrok to test webhooks locally:

# Start ngrok tunnel
ngrok http 3000

# Use the HTTPS URL as your webhook endpoint
# e.g., https://abc123.ngrok.io/webhooks/arka-ai

Monitoring Webhooks

Webhook Logs

View webhook delivery history in Settings → Webhooks → Logs:

  • See all webhook attempts (successful and failed)
  • View request/response details
  • Check response times
  • Filter by event type or status
  • Manually retry failed webhooks

Failure Alerts

Enable email alerts for webhook failures:

  1. Go to Settings → Webhooks
  2. Click on your endpoint
  3. Enable "Email on failure"
  4. Receive notifications when webhooks fail

Rate Limits

Webhook deliveries are not rate limited, but your endpoint should:

  • Respond within 10 seconds (timeouts after 10s)
  • Handle at least 100 requests per minute
  • Process events asynchronously to avoid timeouts

Troubleshooting

Webhooks Not Being Received

  • Verify endpoint URL is correct and publicly accessible
  • Ensure endpoint uses HTTPS (not HTTP)
  • Check firewall settings aren't blocking requests
  • Verify endpoint returns 2xx status code
  • Check webhook logs in dashboard for error messages

Signature Verification Failing

  • Use the correct webhook secret (check dashboard)
  • Verify you're using raw request body (not parsed JSON)
  • Ensure using HMAC SHA-256 algorithm
  • Check for timing-safe comparison in verification

Next Steps