Integrations
Webhooks & Integrations
Azoth emits real-time events to external systems — Slack, PagerDuty, GitHub, and custom HTTP endpoints. All webhooks are HMAC-SHA256 signed.
Webhook events
All events include a common envelope:
{
"event": "budget.alert", // event type (see below)
"timestamp": "2026-05-12T10:00Z",
"workspaceId": "ws_abc123",
"data": { ... } // event-specific payload
}budget.alertA workspace or agent budget has reached its threshold (80%, 100%).budget.exceededHard budget limit hit — further calls will be rejected until reset.loop.detectedA loop pattern was detected and a request terminated.anomaly.spikeUnusual cost spike detected vs rolling 7-day baseline (>3σ).agent.degradedAn agent's error rate crossed the configured threshold.usage.digestDaily digest: top agents, total cost, cache hit rate, anomalies.Signature verification
Every request includes an X-Azoth-Signature header — HMAC-SHA256 of the raw request body, signed with your webhook secret.
import { createHmac, timingSafeEqual } from 'crypto';
function verifyWebhook(rawBody, signature, secret) {
const expected = createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
const sig = Buffer.from(signature.replace('sha256=', ''), 'hex');
const exp = Buffer.from(expected, 'hex');
if (sig.length !== exp.length) return false;
return timingSafeEqual(sig, exp);
}
// In your Next.js route handler:
export async function POST(req) {
const body = await req.text();
const sig = req.headers.get('x-azoth-signature') ?? '';
if (!verifyWebhook(body, sig, process.env.AZOTH_WEBHOOK_SECRET)) {
return Response.json({ error: 'Invalid signature' }, { status: 401 });
}
const event = JSON.parse(body);
// handle event ...
}Slack integration
Setup
- Create a Slack Incoming Webhook at
api.slack.com/apps. - In Azoth: Dashboard → Settings → Notifications → Slack.
- Paste the webhook URL and save. Test with the Send test alert button.
Azoth sends Block Kit messages with severity-coded colors (green = ok, amber = warning, red = critical).
// Example budget.alert Slack message
{
"blocks": [
{ "type": "header", "text": { "type": "plain_text", "text": "⚠️ Budget Alert — support-bot" }},
{ "type": "section", "fields": [
{ "type": "mrkdwn", "text": "*Agent*
support-bot" },
{ "type": "mrkdwn", "text": "*Spent*
$420 / $500" },
{ "type": "mrkdwn", "text": "*Utilization*
84%" },
{ "type": "mrkdwn", "text": "*Period ends*
2026-06-01" }
]}
]
}PagerDuty integration
Setup
- Create an Integration in your PagerDuty service (Events API v2).
- Copy the Integration Key.
- In Azoth: Dashboard → Settings → Notifications → PagerDuty. Paste the key and select which events trigger incidents.
Azoth uses dedup keys based on workspaceId + agentId + eventType to avoid alert storms. Incidents are auto-resolved when the condition clears.
GitHub App integrationDeveloper+
Install the GitHub App
- Go to Dashboard → Settings → Integrations → GitHub App.
- Click Install on GitHub — this redirects to the GitHub App manifest flow.
- Select the repositories to grant access to.
- Back in Azoth, link a repository to a regression test suite.
PR check runs
When a PR is opened or updated, Azoth automatically runs the linked regression suite and posts results as a GitHub Check Run. The check includes a markdown table with pass/fail rates, latency, and cost per test case.
// Check run output example
| Test case | Result | Δ Latency | Δ Cost |
|--------------------|--------|-----------|--------|
| summarize-en | ✓ pass | +12ms | –$0.001|
| extract-entities | ✓ pass | –8ms | –$0.002|
| classify-sentiment | ✗ fail | +240ms | +$0.01 |GitHub Actions workflow
You can also trigger regression runs from your CI pipeline using the Azoth action:
# .github/workflows/azoth.yml
name: Azoth regression
on: [pull_request]
jobs:
regression:
runs-on: ubuntu-latest
steps:
- uses: azoth-os/regression-action@v1
with:
api-key: ${{ secrets.AZOTH_API_KEY }}
suite-id: ${{ vars.AZOTH_SUITE_ID }}
fail-on-regression: trueCustom endpoints
Add any HTTPS endpoint in Dashboard → Settings → Webhooks. Azoth retries failed deliveries 3 times with exponential back-off (1s → 2s → 4s).
// POST to your endpoint
POST https://your-app.com/hooks/azoth
Content-Type: application/json
X-Azoth-Signature: sha256=<hmac>
X-Azoth-Event: budget.alert
X-Azoth-Delivery: evt_abc123
{ "event": "budget.alert", "data": { ... } }