Webhook Reference

Send alerts to Alerts using a simple HTTP POST request. No SDK required.

Endpoint

POST https://your-domain.com/api/webhook/{token}

Replace {token} with your channel's webhook token. You can find this in the channel settings.

Quick Example

cURL
curl -X POST https://alerts.example.com/api/webhook/abc123def456 \
  -H "Content-Type: application/json" \
  -d '{
    "title": "New user signup",
    "level": "success",
    "emoji": "🎉",
    "message": "[email protected] just created an account"
  }'
JavaScript / TypeScript
const response = await fetch("https://alerts.example.com/api/webhook/abc123def456", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    title: "New user signup",
    level: "success",
    emoji: "🎉",
    message: "[email protected] just created an account",
  }),
});

const data = await response.json();
console.log(data); // { success: true, alertId: "..." }
Python
import requests

response = requests.post(
    "https://alerts.example.com/api/webhook/abc123def456",
    json={
        "title": "New user signup",
        "level": "success",
        "emoji": "🎉",
        "message": "[email protected] just created an account",
    }
)

print(response.json())  # {"success": True, "alertId": "..."}

Request Body

Send a JSON object with the following fields. Only title is required.

FieldTypeRequiredDescription
titlestringRequiredAlert title (1-200 characters)
levelstringOptionalSeverity level: info, success, warning, error. Defaults to info.
emojistringOptionalCustom emoji for the alert (max 10 characters)
messagestringOptionalAlert body text (max 5,000 characters)
fieldsarrayOptionalStructured key-value data (see below)
linkUrlstringOptionalURL for a call-to-action button (max 2,000 characters)
linkTextstringOptionalButton text (max 100 characters, defaults to "View")
sourcestringOptionalSource identifier (e.g., "github-actions", "vercel")
metadataobjectOptionalArbitrary JSON data for debugging or context

Fields Array

The fields array lets you include structured metadata that displays as key-value pairs in the alert.

FieldTypeDescription
labelstringField label (max 100 characters)
valuestringField value (max 1,000 characters)
inlinebooleanIf true, displays in a compact grid layout (default: false)
Fields Example
{
  "title": "Build Failed",
  "level": "error",
  "emoji": "🚨",
  "message": "The production build failed with exit code 1",
  "fields": [
    { "label": "Branch", "value": "main", "inline": true },
    { "label": "Commit", "value": "abc123", "inline": true },
    { "label": "Author", "value": "[email protected]", "inline": true },
    { "label": "Error Output", "value": "npm ERR! Missing required argument #1" }
  ],
  "linkUrl": "https://github.com/org/repo/actions/runs/123",
  "linkText": "View Build",
  "source": "github-actions"
}

Alert Levels

Use the level field to indicate severity. This affects the visual styling and can be used for filtering.

info

General information or neutral updates

success

Successful operations, completions, positive events

warning

Potential issues that need attention

error

Critical errors, failures, immediate action required

Response

Success (201 Created)

json
{
  "success": true,
  "alertId": "clx1234567890abcdef"
}

Error Responses

400Bad Request
json
{
  "error": "Invalid payload",
  "details": [
    {
      "code": "too_small",
      "minimum": 1,
      "type": "string",
      "inclusive": true,
      "exact": false,
      "message": "String must contain at least 1 character(s)",
      "path": ["title"]
    }
  ]
}
404Not Found
json
{
  "error": "Invalid webhook token"
}
500Internal Server Error
json
{
  "error": "Internal server error"
}

Complete Payload Example

Here's an example using all available fields:

json
{
  "title": "Payment Received",
  "level": "success",
  "emoji": "💰",
  "message": "A new payment of $99.00 was processed successfully.",
  "fields": [
    { "label": "Customer", "value": "John Doe", "inline": true },
    { "label": "Email", "value": "[email protected]", "inline": true },
    { "label": "Amount", "value": "$99.00 USD", "inline": true },
    { "label": "Plan", "value": "Pro Monthly" },
    { "label": "Payment Method", "value": "Visa ending in 4242" }
  ],
  "linkUrl": "https://dashboard.stripe.com/payments/pi_123",
  "linkText": "View in Stripe",
  "source": "stripe-webhook",
  "metadata": {
    "payment_intent_id": "pi_123456789",
    "customer_id": "cus_abc123",
    "subscription_id": "sub_xyz789"
  }
}

Common Use Cases

CI/CD Build Notifications

Send alerts when builds succeed or fail in your CI/CD pipeline.

json
{
  "title": "Deployment Complete",
  "level": "success",
  "emoji": "🚀",
  "message": "v2.1.0 deployed to production",
  "fields": [
    { "label": "Environment", "value": "Production", "inline": true },
    { "label": "Duration", "value": "3m 42s", "inline": true }
  ],
  "linkUrl": "https://app.example.com",
  "linkText": "View Site",
  "source": "github-actions"
}

User Signups

Get notified when new users create accounts.

json
{
  "title": "New User Signup",
  "level": "info",
  "emoji": "👋",
  "message": "[email protected] just created an account",
  "fields": [
    { "label": "Source", "value": "Google OAuth", "inline": true },
    { "label": "Plan", "value": "Free Trial", "inline": true }
  ],
  "source": "auth-service"
}

Error Monitoring

Alert your team when critical errors occur.

json
{
  "title": "Unhandled Exception",
  "level": "error",
  "emoji": "🔥",
  "message": "TypeError: Cannot read property 'id' of undefined",
  "fields": [
    { "label": "Service", "value": "api-gateway", "inline": true },
    { "label": "Endpoint", "value": "POST /api/orders", "inline": true },
    { "label": "Stack Trace", "value": "at processOrder (orders.ts:45)\nat handler (route.ts:12)" }
  ],
  "linkUrl": "https://sentry.io/issues/123",
  "linkText": "View in Sentry",
  "source": "error-handler"
}

Payment Events

Track successful payments and failed charges.

json
{
  "title": "Payment Failed",
  "level": "warning",
  "emoji": "⚠️",
  "message": "Subscription renewal payment was declined",
  "fields": [
    { "label": "Customer", "value": "[email protected]", "inline": true },
    { "label": "Amount", "value": "$299.00", "inline": true },
    { "label": "Reason", "value": "Card declined - insufficient funds" }
  ],
  "linkUrl": "https://dashboard.stripe.com/customers/cus_123",
  "linkText": "View Customer",
  "source": "stripe"
}

Integration Tips

Fire and forget

Webhook calls should be fire-and-forget. Don't block your application waiting for the response. Use async/await without awaiting, or send from a background job.

Include context in fields

Use the fields array to include structured data that helps with debugging. This is searchable and displays nicely in the dashboard.

Use source to identify senders

The source field helps you filter alerts by origin. Use consistent identifiers like 'github-actions', 'vercel', 'stripe', or your service names.

Store raw data in metadata

Use the metadata field to store the complete payload from external webhooks. This helps with debugging but won't clutter the alert display.