Incident.io Webhook
Route & Auth
| Property |
Value |
| Method |
POST |
| Path |
/webhooks/incident/lead |
| Auth type |
svix |
| Headers |
webhook-signature, webhook-id, webhook-timestamp |
| Secret |
INCIDENT_WEBHOOK_SECRET |
| Service account |
incidentio-webhook@alan-eu-tools.iam.gserviceaccount.com |
| Response |
204 No Content |
Payload
| Field |
Type |
Description |
event_type |
string |
Event type |
public_incident.incident_updated_v2 |
dict |
Incident details |
incident_status |
string |
Current incident status (triage, live, post-mortem, etc.) |
incident_role_assignments |
list[dict] |
Role assignments with assignee Slack user IDs |
incident_id |
string |
Incident identifier |
Behavior
- Skips incidents in
triage or live status
- For other statuses, finds the "lead" role assignment
- Looks up the Alaner by Slack user ID
- Logs the lead assignment
- Checks if the alaner has the
AlanToolsBackendIamManager role
Integrations
- Incident.io: event source
- Internal DB: alaner lookup by Slack ID
Code reference
apps.eu_tools.webhooks.incident.IncidentLeadBodySchema
Bases: Schema
data
class-attribute
instance-attribute
data = Dict(
data_key="public_incident.incident_updated_v2",
required=True,
)
event_type
class-attribute
instance-attribute
event_type = String(data_key='event_type', required=True)
Bases: MethodView
post
Source code in apps/eu_tools/webhooks/incident.py
| @incidentio_blueprint.arguments(IncidentLeadBodySchema, location="json")
@incidentio_blueprint.response(status_code=204)
def post(self, payload): # type: ignore[no-untyped-def]
if payload["data"].get("incident_status") in ["triage", "live"]:
return
for assignment in payload["data"].get("incident_role_assignments", []):
if assignment["role"]["role_type"] == "lead" and assignment.get("assignee"):
alaner = (
current_session.execute(
select(Alaner).filter(
Alaner.slack_id == assignment["assignee"]["slack_user_id"]
)
)
.scalars()
.unique()
.one_or_none()
)
if alaner and not has_role(alaner, AlanToolsBackendIamManager):
current_logger.info(
f"{alaner.email} is now incident lead for incident id: {payload['data'].get('incident_id')}"
)
|
incidentio_blueprint = CustomBlueprint(
"incident_webhook",
"incident_webhook",
url_prefix="/webhooks/incident",
auth_context_providers=[
WebhookAuthContextProvider(
auth_type=svix,
header_name="webhook-signature",
secret_name_config_key="INCIDENT_WEBHOOK_SECRET",
auth_principal_type=ServiceAccount,
auth_principal_email="incidentio-webhook@alan-eu-tools.iam.gserviceaccount.com",
)
],
)
OpenAPI
Incident.io webhook on ReDoc ⧉