Alertmanager API Guide

Version 1.6.8 | Updated: July 24, 2026

Alertmanager API Guide

This document describes how applications can interact with Alertmanager to send alerts, manage silences, and query alert status.

Base URL: http://localhost:9093 (internal) or https://<domain>/alertmanager (via nginx proxy)

Authentication: Basic auth required when accessing via nginx proxy (same credentials as Prometheus).


1. Send Alerts

Endpoint: POST /api/v2/alerts

Content-Type: application/json

Request Format

[
  {
    "labels": {
      "alertname": "HighCpuUsage",
      "severity": "warning",
      "instance": "server-01",
      "service": "api"
    },
    "annotations": {
      "summary": "CPU usage above 80%",
      "description": "Server server-01 CPU at 85% for 5 minutes"
    },
    "startsAt": "2024-01-15T10:00:00Z",
    "endsAt": "2024-01-15T10:30:00Z",
    "generatorURL": "https://monitoring.example.com/graph?query=cpu"
  }
]

Required Fields

Field Type Description

labels.alertname

string

Unique alert identifier

labels.severity

string

critical, warning, or info

Optional Fields

Field Type Description

labels.*

string

Additional labels for routing/grouping

annotations.summary

string

Short description (shown in notifications)

annotations.description

string

Detailed description

startsAt

ISO8601

Alert start time (default: now)

endsAt

ISO8601

Alert end time (for resolved alerts)

generatorURL

string

Link back to source system

Example: Send Alert

curl -X POST http://localhost:9093/api/v2/alerts \
  -H "Content-Type: application/json" \
  -d '[{
    "labels": {
      "alertname": "DatabaseConnectionFailed",
      "severity": "critical",
      "instance": "db-primary",
      "service": "mysql"
    },
    "annotations": {
      "summary": "Cannot connect to MySQL database",
      "description": "Connection refused on db-primary:3306"
    }
  }]'

Response

  • 200 OK — Alert accepted

  • 400 Bad Request — Invalid JSON or missing required fields


2. Get Active Alerts

Endpoint: GET /api/v2/alerts

Query Parameters

Parameter Type Description

active

bool

Show active alerts (default: true)

silenced

bool

Show silenced alerts (default: true)

inhibited

bool

Show inhibited alerts (default: true)

unprocessed

bool

Show unprocessed alerts (default: true)

filter

string

PromQL-style label filter

Example: Get All Active Alerts

curl -s http://localhost:9093/api/v2/alerts | jq

Example: Filter by Severity

curl -s 'http://localhost:9093/api/v2/alerts?filter=severity="critical"' | jq

Example: Filter by Service

curl -s 'http://localhost:9093/api/v2/alerts?filter=service="mysql"' | jq

Response Format

[
  {
    "labels": {
      "alertname": "HighCpuUsage",
      "severity": "warning",
      "instance": "server-01"
    },
    "annotations": {
      "summary": "CPU usage above 80%"
    },
    "startsAt": "2024-01-15T10:00:00.000Z",
    "endsAt": "0001-01-01T00:00:00Z",
    "generatorURL": "",
    "status": {
      "state": "active",
      "silencedBy": [],
      "inhibitedBy": []
    },
    "receivers": ["default"],
    "fingerprint": "abc123def456"
  }
]

3. Resolve Alerts

To resolve an alert, send the same alert with endsAt set to current time or past.

Example: Resolve Alert

curl -X POST http://localhost:9093/api/v2/alerts \
  -H "Content-Type: application/json" \
  -d '[{
    "labels": {
      "alertname": "DatabaseConnectionFailed",
      "severity": "critical",
      "instance": "db-primary",
      "service": "mysql"
    },
    "endsAt": "2024-01-15T10:30:00Z"
  }]'

Note: The labels must exactly match the original alert for it to be resolved.


4. Manage Silences

Silences temporarily suppress notifications for matching alerts.

4.1 Create Silence

Endpoint: POST /api/v2/silences

curl -X POST http://localhost:9093/api/v2/silences \
  -H "Content-Type: application/json" \
  -d '{
    "matchers": [
      {
        "name": "alertname",
        "value": "HighCpuUsage",
        "isRegex": false,
        "isEqual": true
      },
      {
        "name": "instance",
        "value": "server-01",
        "isRegex": false,
        "isEqual": true
      }
    ],
    "startsAt": "2024-01-15T10:00:00Z",
    "endsAt": "2024-01-15T12:00:00Z",
    "createdBy": "admin",
    "comment": "Maintenance window - CPU upgrade"
  }'

Response

{
  "silenceID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

4.2 Get All Silences

Endpoint: GET /api/v2/silences

curl -s http://localhost:9093/api/v2/silences | jq

4.3 Get Silence by ID

Endpoint: GET /api/v2/silence/{silenceID}

curl -s http://localhost:9093/api/v2/silence/a1b2c3d4-e5f6-7890-abcd-ef1234567890 | jq

4.4 Delete (Expire) Silence

Endpoint: DELETE /api/v2/silence/{silenceID}

curl -X DELETE http://localhost:9093/api/v2/silence/a1b2c3d4-e5f6-7890-abcd-ef1234567890

Matcher Options

Field Type Description

name

string

Label name to match

value

string

Value to match (or regex pattern)

isRegex

bool

Treat value as regex

isEqual

bool

true = equals, false = not equals

Example: Silence by Regex

curl -X POST http://localhost:9093/api/v2/silences \
  -H "Content-Type: application/json" \
  -d '{
    "matchers": [
      {
        "name": "instance",
        "value": "server-0[1-3]",
        "isRegex": true,
        "isEqual": true
      }
    ],
    "startsAt": "2024-01-15T10:00:00Z",
    "endsAt": "2024-01-15T14:00:00Z",
    "createdBy": "devops",
    "comment": "Cluster maintenance"
  }'

5. Get Status

5.1 Alertmanager Status

Endpoint: GET /api/v2/status

curl -s http://localhost:9093/api/v2/status | jq

Returns:

  • Cluster status

  • Version info

  • Uptime

  • Configuration (parsed)

5.2 Receivers List

Endpoint: GET /api/v2/receivers

curl -s http://localhost:9093/api/v2/receivers | jq

5.3 Health Check

Endpoint: GET /-/healthy

curl -s http://localhost:9093/-/healthy
# Returns: OK

5.4 Readiness Check

Endpoint: GET /-/ready

curl -s http://localhost:9093/-/ready
# Returns: OK

6. Integration Examples

6.1 Python

import requests
import json
from datetime import datetime, timezone

ALERTMANAGER_URL = "http://localhost:9093"

def send_alert(alertname, severity, instance, summary, description=None, labels=None):
    """Send an alert to Alertmanager."""
    alert = {
        "labels": {
            "alertname": alertname,
            "severity": severity,
            "instance": instance,
            **(labels or {})
        },
        "annotations": {
            "summary": summary
        },
        "startsAt": datetime.now(timezone.utc).isoformat()
    }

    if description:
        alert["annotations"]["description"] = description

    response = requests.post(
        f"{ALERTMANAGER_URL}/api/v2/alerts",
        json=[alert],
        headers={"Content-Type": "application/json"}
    )
    response.raise_for_status()
    return response.status_code == 200

def resolve_alert(alertname, severity, instance, labels=None):
    """Resolve an existing alert."""
    alert = {
        "labels": {
            "alertname": alertname,
            "severity": severity,
            "instance": instance,
            **(labels or {})
        },
        "endsAt": datetime.now(timezone.utc).isoformat()
    }

    response = requests.post(
        f"{ALERTMANAGER_URL}/api/v2/alerts",
        json=[alert],
        headers={"Content-Type": "application/json"}
    )
    response.raise_for_status()
    return response.status_code == 200

def get_active_alerts(severity=None):
    """Get list of active alerts."""
    params = {"active": "true"}
    if severity:
        params["filter"] = f'severity="{severity}"'

    response = requests.get(
        f"{ALERTMANAGER_URL}/api/v2/alerts",
        params=params
    )
    response.raise_for_status()
    return response.json()

def create_silence(alertname, instance, duration_hours, comment, created_by="api"):
    """Create a silence for specific alert."""
    from datetime import timedelta

    now = datetime.now(timezone.utc)
    silence = {
        "matchers": [
            {"name": "alertname", "value": alertname, "isRegex": False, "isEqual": True},
            {"name": "instance", "value": instance, "isRegex": False, "isEqual": True}
        ],
        "startsAt": now.isoformat(),
        "endsAt": (now + timedelta(hours=duration_hours)).isoformat(),
        "createdBy": created_by,
        "comment": comment
    }

    response = requests.post(
        f"{ALERTMANAGER_URL}/api/v2/silences",
        json=silence,
        headers={"Content-Type": "application/json"}
    )
    response.raise_for_status()
    return response.json().get("silenceID")

# Usage examples
if __name__ == "__main__":
    # Send alert
    send_alert(
        alertname="AppError",
        severity="warning",
        instance="api-server-01",
        summary="Application error rate increased",
        description="Error rate above 5% for last 5 minutes",
        labels={"service": "user-api", "environment": "production"}
    )

    # Get critical alerts
    alerts = get_active_alerts(severity="critical")
    print(f"Active critical alerts: {len(alerts)}")

    # Resolve alert
    resolve_alert(
        alertname="AppError",
        severity="warning",
        instance="api-server-01",
        labels={"service": "user-api", "environment": "production"}
    )

    # Create 2-hour silence
    silence_id = create_silence(
        alertname="HighCpuUsage",
        instance="server-01",
        duration_hours=2,
        comment="Planned maintenance"
    )
    print(f"Created silence: {silence_id}")

6.2 Java (Spring Boot)

import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;
import java.time.Instant;
import java.util.*;

public class AlertmanagerClient {

    private final String baseUrl;
    private final RestTemplate restTemplate;

    public AlertmanagerClient(String baseUrl) {
        this.baseUrl = baseUrl;
        this.restTemplate = new RestTemplate();
    }

    public void sendAlert(String alertname, String severity, String instance,
                          String summary, Map<String, String> extraLabels) {

        Map<String, Object> alert = new HashMap<>();

        Map<String, String> labels = new HashMap<>();
        labels.put("alertname", alertname);
        labels.put("severity", severity);
        labels.put("instance", instance);
        if (extraLabels != null) {
            labels.putAll(extraLabels);
        }
        alert.put("labels", labels);

        Map<String, String> annotations = new HashMap<>();
        annotations.put("summary", summary);
        alert.put("annotations", annotations);

        alert.put("startsAt", Instant.now().toString());

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<List<Map<String, Object>>> request =
            new HttpEntity<>(List.of(alert), headers);

        restTemplate.postForEntity(
            baseUrl + "/api/v2/alerts",
            request,
            String.class
        );
    }

    public void resolveAlert(String alertname, String severity, String instance,
                             Map<String, String> extraLabels) {

        Map<String, Object> alert = new HashMap<>();

        Map<String, String> labels = new HashMap<>();
        labels.put("alertname", alertname);
        labels.put("severity", severity);
        labels.put("instance", instance);
        if (extraLabels != null) {
            labels.putAll(extraLabels);
        }
        alert.put("labels", labels);
        alert.put("endsAt", Instant.now().toString());

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<List<Map<String, Object>>> request =
            new HttpEntity<>(List.of(alert), headers);

        restTemplate.postForEntity(
            baseUrl + "/api/v2/alerts",
            request,
            String.class
        );
    }

    public List<Map<String, Object>> getActiveAlerts() {
        ResponseEntity<List> response = restTemplate.getForEntity(
            baseUrl + "/api/v2/alerts?active=true",
            List.class
        );
        return response.getBody();
    }
}

// Usage in Spring Boot service
@Service
public class MonitoringService {

    private final AlertmanagerClient alertmanager;

    public MonitoringService() {
        this.alertmanager = new AlertmanagerClient("http://localhost:9093");
    }

    public void reportDatabaseError(String dbHost, String errorMessage) {
        alertmanager.sendAlert(
            "DatabaseError",
            "critical",
            dbHost,
            errorMessage,
            Map.of("service", "database", "component", "mysql")
        );
    }

    public void clearDatabaseError(String dbHost) {
        alertmanager.resolveAlert(
            "DatabaseError",
            "critical",
            dbHost,
            Map.of("service", "database", "component", "mysql")
        );
    }
}

6.3 Bash Script

#!/bin/bash
# alertmanager-client.sh - Simple Alertmanager CLI

ALERTMANAGER_URL="${ALERTMANAGER_URL:-http://localhost:9093}"

send_alert() {
    local alertname="$1"
    local severity="$2"
    local instance="$3"
    local summary="$4"

    curl -s -X POST "${ALERTMANAGER_URL}/api/v2/alerts" \
        -H "Content-Type: application/json" \
        -d "[{
            \"labels\": {
                \"alertname\": \"${alertname}\",
                \"severity\": \"${severity}\",
                \"instance\": \"${instance}\"
            },
            \"annotations\": {
                \"summary\": \"${summary}\"
            }
        }]"
}

resolve_alert() {
    local alertname="$1"
    local severity="$2"
    local instance="$3"

    curl -s -X POST "${ALERTMANAGER_URL}/api/v2/alerts" \
        -H "Content-Type: application/json" \
        -d "[{
            \"labels\": {
                \"alertname\": \"${alertname}\",
                \"severity\": \"${severity}\",
                \"instance\": \"${instance}\"
            },
            \"endsAt\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"
        }]"
}

list_alerts() {
    curl -s "${ALERTMANAGER_URL}/api/v2/alerts" | jq -r '.[] | "\(.labels.severity)\t\(.labels.alertname)\t\(.labels.instance)"'
}

# Usage
case "$1" in
    send)
        send_alert "$2" "$3" "$4" "$5"
        ;;
    resolve)
        resolve_alert "$2" "$3" "$4"
        ;;
    list)
        list_alerts
        ;;
    *)
        echo "Usage: $0 {send|resolve|list}"
        echo "  send <alertname> <severity> <instance> <summary>"
        echo "  resolve <alertname> <severity> <instance>"
        echo "  list"
        exit 1
        ;;
esac

Common Alert Labels

Use consistent labels across your applications:

Label Values Description

alertname

string

Unique identifier for the alert type

severity

critical, warning, info

Alert priority

instance

hostname/IP

Source of the alert

service

string

Service name (mysql, api, etc.)

environment

production, staging, dev

Environment

team

string

Responsible team

component

string

Specific component


Best Practices

  1. Use consistent labels — Same alert should always have same labels

  2. Always resolve alerts — Send resolution when issue is fixed

  3. Add meaningful annotationssummary and description help operators

  4. Use silences for maintenance — Don’t disable alerting, silence specific alerts

  5. Set appropriate severity — Reserve critical for urgent issues

  6. Include generator URL — Link back to your monitoring/logging system


Error Handling

HTTP Code Meaning Action

200

Success

Alert accepted

400

Bad Request

Check JSON format and required fields

500

Server Error

Check Alertmanager logs

503

Service Unavailable

Alertmanager not ready