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.