Webhooks

Receive real-time HTTP notifications when events occur in your Daily AI Agent OS account.

How Webhooks Work

When an event occurs (like a new signal being generated), Daily AI Agent OS sends an HTTP POST request to your configured endpoint with the event payload. Your server processes the event and returns a 200 response to acknowledge receipt.

Agent runs Signal generated Webhook fired Your server 200 OK

To register a webhook, make a POST request to /v1/webhooks with your endpoint URL and the events you want to subscribe to:

bash
curl -X POST https://api.dailyai.dev/v1/webhooks \
  -H "Authorization: Bearer sk-your-key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/dailyai",
    "events": ["signal.created", "agent.completed"],
    "secret": "whsec_your_secret_key"
  }'

Supported Events

Subscribe to any combination of the following event types:

EventTriggerDescription
signal.createdNew signalFired when an agent generates a new trading or analysis signal
signal.updatedSignal changeFired when a signal's status changes (e.g., confidence updated)
signal.closedSignal closedFired when a signal reaches its take-profit, stop-loss, or expires
agent.startedAgent beginsFired when an agent begins executing a run
agent.completedAgent finishesFired when an agent completes a run successfully
agent.errorAgent errorFired when an agent encounters an error during execution
webhook.testManual testFired when you trigger a test event from the dashboard

Payload Format

All webhook payloads follow a consistent envelope format. The data field contains the event-specific payload.

Common Envelope

json
{
  "id": "evt_abc123def456",
  "type": "signal.created",
  "api_version": "2026-03-01",
  "created_at": "2026-03-25T14:30:00Z",
  "data": { ... }
}

signal.created

json
{
  "id": "evt_sig_001",
  "type": "signal.created",
  "api_version": "2026-03-01",
  "created_at": "2026-03-25T14:30:00Z",
  "data": {
    "signal_id": "sig_abc123",
    "agent_id": "trading",
    "asset": "AAPL",
    "strategy": "momentum",
    "direction": "long",
    "confidence": 0.87,
    "entry_price": 198.45,
    "stop_loss": 195.20,
    "take_profit": 204.10,
    "metadata": {
      "indicators": ["RSI", "MACD", "EMA_20"],
      "reasoning": "Strong momentum with RSI at 65 and MACD crossover"
    }
  }
}

signal.closed

json
{
  "id": "evt_sig_002",
  "type": "signal.closed",
  "api_version": "2026-03-01",
  "created_at": "2026-03-25T18:45:00Z",
  "data": {
    "signal_id": "sig_abc123",
    "asset": "AAPL",
    "close_reason": "take_profit",
    "entry_price": 198.45,
    "exit_price": 204.10,
    "pnl_percent": 2.85,
    "pnl_absolute": 5.65,
    "duration_minutes": 255
  }
}

agent.error

json
{
  "id": "evt_err_001",
  "type": "agent.error",
  "api_version": "2026-03-01",
  "created_at": "2026-03-25T16:00:00Z",
  "data": {
    "agent_id": "trading",
    "run_id": "run_xyz789",
    "error_code": "DATA_UNAVAILABLE",
    "message": "Market data provider returned empty response for AAPL",
    "retryable": true
  }
}

Signature Verification

Every webhook request includes an X-DailyAI-Signature header containing an HMAC-SHA256 signature of the request body. Always verify this signature to ensure the request genuinely came from Daily AI Agent OS.

Security: Never skip signature verification in production. Without it, an attacker could send fake events to your webhook endpoint.

How to Verify

Compute an HMAC-SHA256 hash of the raw request body using your webhook secret, then compare it to the signature in the header.

python
import hmac
import hashlib

def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
    """Verify the webhook signature.

    Args:
        payload: Raw request body bytes
        signature: Value of the X-DailyAI-Signature header
        secret: Your webhook signing secret (whsec_...)

    Returns:
        True if the signature is valid
    """
    expected = hmac.new(
        secret.encode("utf-8"),
        payload,
        hashlib.sha256
    ).hexdigest()

    expected_sig = f"sha256={expected}"
    return hmac.compare_digest(expected_sig, signature)
javascript
const crypto = require('crypto');

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

  const expectedSig = `sha256=${expected}`;
  return crypto.timingSafeEqual(
    Buffer.from(expectedSig),
    Buffer.from(signature)
  );
}

Request Headers

HeaderDescription
X-DailyAI-SignatureHMAC-SHA256 signature: sha256=abc123...
X-DailyAI-EventEvent type (e.g., signal.created)
X-DailyAI-DeliveryUnique delivery ID for deduplication
X-DailyAI-TimestampUnix timestamp of when the event was sent
Content-TypeAlways application/json

Retry Policy

If your endpoint returns a non-2xx response or times out, Daily AI Agent OS will retry the delivery using exponential backoff:

AttemptDelayTotal Elapsed
1st retry30 seconds30 seconds
2nd retry2 minutes2.5 minutes
3rd retry10 minutes12.5 minutes
4th retry30 minutes42.5 minutes
5th retry2 hours~2.7 hours
6th retry (final)8 hours~10.7 hours

After 6 failed attempts, the delivery is marked as failed. You can view failed deliveries and manually retry them from the dashboard under Settings → Webhooks → Deliveries.

Tip: Your endpoint should respond within 10 seconds. Process events asynchronously — acknowledge receipt immediately, then handle the event in a background job.

If your endpoint fails consistently for 72 hours, the webhook will be automatically disabled and you'll receive an email notification.

Testing Webhooks Locally

Use ngrok to expose your local development server to the internet for webhook testing.

Step 1: Start your local server

bash
# Start your webhook receiver (e.g., on port 3000)
node webhook_receiver.js
# or
python webhook_server.py

Step 2: Start ngrok

bash
ngrok http 3000

ngrok will display a public URL like https://abc123.ngrok.io.

Step 3: Register the webhook

bash
curl -X POST https://api.dailyai.dev/v1/webhooks \
  -H "Authorization: Bearer sk-your-key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://abc123.ngrok.io/webhooks/dailyai",
    "events": ["signal.created", "agent.completed"],
    "secret": "whsec_test_secret_123"
  }'

Step 4: Trigger a test event

bash
# Send a test ping from the API
curl -X POST https://api.dailyai.dev/v1/webhooks/whk_your_id/test \
  -H "Authorization: Bearer sk-your-key"

You should see the test event appear in your local server logs and in the ngrok dashboard at http://localhost:4040.

Dashboard testing: You can also trigger test events directly from the Dashboard under Settings → Webhooks → Send Test Event.