Skip to main content
When alerts are triggered or resolved in your AgentMark platform, alert events are sent to your webhook endpoint. This allows you to integrate with monitoring systems, send notifications, and take automated actions.
Alert events are sent only to your production webhook endpoint. They are not handled by the local dev server (agentmark dev).

Event Format

{
  "event": {
    "type": "alert",
    "data": {
      "alert": {
        "id": "string",
        "currentValue": 0,
        "threshold": 0,
        "status": "triggered | resolved",
        "timeWindow": "string",
        "type": "cost | latency | error_rate"
      },
      "message": "string",
      "timestamp": "string"
    }
  }
}

Processing Alert Events

if (event.type === "alert") {
  const alertData = event.data;

  try {
    if (alertData.alert.status === "triggered") {
      await handleTriggeredAlert(alertData);
    } else if (alertData.alert.status === "resolved") {
      await handleResolvedAlert(alertData);
    }

    return NextResponse.json({
      message: "Alert processed",
      alertId: alertData.alert.id,
      status: alertData.alert.status,
    });
  } catch (error) {
    console.error("Alert processing error:", error);
    return NextResponse.json(
      { message: "Error processing alert" },
      { status: 500 }
    );
  }
}

async function handleTriggeredAlert(alertData: any) {
  const { alert, message, timestamp } = alertData;

  switch (alert.type) {
    case "cost":
      console.log(`Cost alert: ${alert.currentValue} exceeded threshold ${alert.threshold}`);
      break;
    case "latency":
      console.log(`Latency alert: ${alert.currentValue}ms exceeded threshold ${alert.threshold}ms`);
      break;
    case "error_rate":
      console.log(`Error rate alert: ${alert.currentValue}% exceeded threshold ${alert.threshold}%`);
      break;
  }
}

async function handleResolvedAlert(alertData: any) {
  const { alert, message, timestamp } = alertData;
  console.log(`Alert ${alert.id} resolved at ${timestamp}`);
}

Alert Types

TypeMonitorsExample Threshold
costAPI usage costsSpending > $50/day
latencyResponse timesP95 latency > 5000ms
error_rateError frequencyError rate > 5%

Integration Examples

Slack Notifications

async function sendSlackNotification(alert: any, message: string) {
  const slackWebhookUrl = process.env.SLACK_WEBHOOK_URL;
  if (!slackWebhookUrl) return;

  await fetch(slackWebhookUrl, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      text: `AgentMark Alert: ${alert.type.toUpperCase()}`,
      blocks: [
        {
          type: "section",
          text: { type: "mrkdwn", text: message },
        },
        {
          type: "section",
          fields: [
            { type: "mrkdwn", text: `*Status:*\n${alert.status}` },
            { type: "mrkdwn", text: `*Current:*\n${alert.currentValue}` },
            { type: "mrkdwn", text: `*Threshold:*\n${alert.threshold}` },
            { type: "mrkdwn", text: `*Window:*\n${alert.timeWindow}` },
          ],
        },
      ],
    }),
  });
}

Email Notifications

async function sendEmailAlert(alert: any, message: string) {
  // Use your preferred email service (Resend, SendGrid, AWS SES, etc.)
  const emailConfig = {
    from: process.env.ALERT_EMAIL_FROM,
    to: process.env.ALERT_EMAIL_TO,
    subject: `AgentMark Alert: ${alert.type} - ${alert.status}`,
    html: `
      <h2>AgentMark Alert</h2>
      <p>${message}</p>
      <table>
        <tr><td><strong>Alert ID:</strong></td><td>${alert.id}</td></tr>
        <tr><td><strong>Type:</strong></td><td>${alert.type}</td></tr>
        <tr><td><strong>Status:</strong></td><td>${alert.status}</td></tr>
        <tr><td><strong>Current Value:</strong></td><td>${alert.currentValue}</td></tr>
        <tr><td><strong>Threshold:</strong></td><td>${alert.threshold}</td></tr>
      </table>
    `,
  };

  // await sendEmail(emailConfig);
}

Best Practices

  1. Respond quickly — return a 200 status promptly, then process the alert asynchronously if needed
  2. Route by type — send cost alerts to finance channels, latency alerts to engineering, etc.
  3. Log everything — store alert events for auditing and trend analysis
  4. Avoid fatigue — use deduplication or cooldown periods for repeated alerts

Have Questions?

We’re here to help! Choose the best way to reach us: