Skip to main content

Infrahub supports two different types of webhooks:

  • Standard Webhook sends event information to an external endpoint.
  • Custom Webhook allows the ability to tie events to a transformation to configure the payload being sent to an external endpoint.

Managing webhooks

  1. Login to Infrahub's web interface as an administrator.
  2. Select Integrations -> Webhooks. Webhooks
  3. Click + Add Webhook. Creating an webhook
  4. Fill in the details and click Save. Webhook Detail

Creating a custom webhook with a transform

Custom webhooks allow you to transform event data before sending it to an external endpoint. This is useful when the receiving system expects a specific payload format, such as Slack, Microsoft Teams, GitHub Actions, or other third-party APIs.

For general information about Python transforms, see the Python transform guide. For details about webhook events and payloads, see the webhooks topic.

note

When using a transform with a webhook, the transform receives the webhook event data directly instead of executing its GraphQL query. The query attribute is still required on the transform class but is not used. See GitHub issue #6650 for updates on this requirement.

1. Create the Python transform

Create a Python file with a transform class that processes webhook event data. The transform receives a dictionary containing the event information:

transforms/slack_webhook.py
from typing import Any

from infrahub_sdk.transforms import InfrahubTransform


class SlackWebhookTransform(InfrahubTransform):
query = "placeholder_query" # Required but not used for webhooks
timeout = 10

async def transform(self, data: dict[str, Any]) -> dict[str, Any]:
event_type = data.get("event", "unknown")
node_data = data.get("data", {})
node_kind = node_data.get("kind", "Unknown")
action = node_data.get("action", "unknown")

# Format payload for Slack incoming webhook
return {
"text": f"Infrahub: {node_kind} {action}",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": f"*Event:* `{event_type}`\n*Kind:* {node_kind}\n*Branch:* {data.get('branch') or 'default'}"
}
}
]
}

The data parameter contains:

FieldDescription
dataOriginal event payload (node changes, changelog, etc.)
idUnique event identifier (UUID)
eventEvent type, such as infrahub.node.updated
branchBranch name or None for branch-independent events
account_idUUID of the account that triggered the event
occured_atISO 8601 timestamp of when the event occurred

See the webhooks topic for example event payloads.

2. Create a placeholder GraphQL query

Create a GraphQL query file. This query is required but not executed for webhook transforms:

queries/placeholder.gql
query PlaceholderQuery {
InfrahubStatus {
summary {
active_schema_hash
}
}
}

3. Configure .infrahub.yml

Add the transform and query to your repository configuration:

.infrahub.yml
# yaml-language-server: $schema=https://schema.infrahub.app/python-sdk/repository-config/latest.json
---
python_transforms:
- name: slack_webhook_transform
class_name: SlackWebhookTransform
file_path: "transforms/slack_webhook.py"

queries:
- name: placeholder_query
file_path: "queries/placeholder.gql"

4. Add the repository to Infrahub

Add your repository containing the transform to Infrahub. See the repository guide for instructions.

5. Create the custom webhook

  1. Navigate to Integrations > Webhooks.
  2. Click + Add Webhook.
  3. Select Custom Webhook as the type.
  4. Fill in the webhook details:
    • Name: A descriptive name, such as "Slack Notifications"
    • URL: The destination endpoint
    • Event Type: The event to trigger on, such as infrahub.node.updated
    • Branch Scope: Which branches should trigger this webhook
  5. Select your transformation from the Transformation dropdown.
  6. Click Save.

6. Verify the webhook

  1. Make a change that triggers the configured event. For example, update a node if using infrahub.node.updated.
  2. Check that your external endpoint received the transformed payload.

For troubleshooting, check the Infrahub logs for webhook delivery status and any transform errors.