Skip to main content

External Alerts API

External alert sources push alarm state transitions into Lumetry. Source and mapping administration requires CanManageIntegrations.

Create a source

POST /api/external-alert-sources
Authorization: Bearer {user-or-api-token}
Content-Type: application/json
{
"name": "Production Alertmanager",
"providerType": "ALERTMANAGER",
"enabled": true,
"severityMapping": {
"warning": "Warning",
"critical": "Critical"
}
}

providerType is GENERIC, ALERTMANAGER, GRAFANA, or ZABBIX.

The response includes the source, its webhook path, and a source-scoped credential. The credential is shown once:

{
"source": {
"id": 4,
"sourceKey": "source-...",
"name": "Production Alertmanager",
"providerType": "ALERTMANAGER",
"enabled": true
},
"credential": "lmts_...",
"webhookPath": "/v1/alert-sources/source-.../events"
}

Rotate a credential with:

POST /api/external-alert-sources/{id}/credentials/rotate

The old credential stops working immediately.

List sources and ingest health

GET /api/external-alert-sources

Each source includes:

{
"lastReceivedAt": "2026-06-12T08:30:00Z",
"acceptedEventCount": 1842,
"rejectedEventCount": 3,
"lastError": null,
"mappedEventCount": 1790,
"unmappedEventCount": 52,
"mappingCoveragePercent": 97.2
}

Accepted count includes normalized transitions from successful requests, including duplicate deliveries. Rejected count records authenticated webhook requests that could not be parsed, normalized, validated, or persisted. Mapping coverage considers processed events with a mapped or unmapped outcome; in-flight and failed processing jobs are not in the denominator.

Push state transitions

POST /v1/alert-sources/{sourceKey}/events
Authorization: Bearer {source-credential}
Content-Type: application/json

A successful request returns 202 Accepted:

{ "accepted": 2, "duplicate": 0 }

accepted means durably accepted for asynchronous lifecycle processing. duplicate counts provider events Lumetry had already accepted.

Generic canonical payload

{
"definitionKey": "database-unavailable",
"instanceKey": "db-prod-01",
"occurrenceKey": "database-unavailable:db-prod-01:2026-06-11T08:00:00Z",
"eventKey": "provider-event-91823",
"state": "Firing",
"severity": "Critical",
"title": "Production database unavailable",
"description": "Connection checks failed.",
"occurredAt": "2026-06-11T08:00:00Z",
"attributes": {
"host": "db-prod-01"
}
}

The generic endpoint also accepts an array or { "events": [...] }.

For recovery, send the same occurrenceKey with a new eventKey and "state": "Resolved".

Alertmanager

Configure Alertmanager's webhook receiver to post its native payload to the source webhook path. Lumetry uses the alertname label as the definition key, the alert fingerprint as the instance identity, and fingerprint plus startsAt as the occurrence identity.

Grafana Alerting

Configure a Grafana webhook contact point to post its default JSON payload to the source webhook path. Lumetry uses a rule UID label when present. Otherwise, the definition key is derived from the Grafana organization, folder, and alertname. The alert fingerprint is the instance identity, and fingerprint plus startsAt is the occurrence identity.

Zabbix

The Zabbix webhook payload must include triggerid and eventid. For recovery messages, include the original problem event identity as problemEventId or problem_event_id so Lumetry can close the correct occurrence.

Definitions

GET /api/external-alert-definitions?sourceId={sourceId}
POST /api/external-alert-definitions
PUT /api/external-alert-definitions/{id}

Create body:

{
"sourceId": 4,
"externalDefinitionKey": "database-unavailable",
"displayName": "Production database unavailable",
"description": null,
"enabled": true,
"topologyNodeId": 51,
"severityOverride": null,
"metadata": {}
}

topologyNodeId is required. severityOverride may be Warning, Critical, or null to use the source severity mapping.

Unmapped candidates

GET /api/external-alert-candidates?sourceId={sourceId}
POST /api/external-alert-candidates/{id}/register

Register body:

{
"displayName": "Production database unavailable",
"description": null,
"enabled": true,
"topologyNodeId": 51,
"severityOverride": null
}

Registering creates the definition and removes the candidate. If the latest candidate state is firing, it is replayed into the operational alert flow.