Skip to content
Docs
Integrations Sentry

Sentry

Start AGNT5 workflows automatically from Sentry issues, errors, and comments.

Connect Sentry to AGNT5 and your workflows will start automatically whenever an issue, error, or comment event fires. Every delivery is signature-verified before any workflow runs.


Setup

1. Create the integration in Studio

  1. Go to Settings → Integrations and click Add Integration.
  2. Pick Sentry.
  3. Fill in a name for the integration.
  4. Choose the environment that should receive triggers.
Studio New Sentry Webhook panel showing Name, Environment, Webhook URL, and Signing Secret fields. Studio New Sentry Webhook panel showing Name, Environment, Webhook URL, and Signing Secret fields.
Fill in the name, select the environment, copy the webhook URL, and paste the signing secret from Sentry.

2. Create an integration in Sentry

  1. Go to Settings → Integrations → Custom Integrations and click Create New Integration.

  2. Fill in the required details and paste the webhook URL from AGNT5 Studio.

  3. Under Permissions, configure access for each resource. For example:

    Note:
    Permission Value
    Project Read
    Team Read
    Release No Access
    Distribution No Access
    Issue & Event Read
    Organization Read
    Member Read
    Alerts No Access
  4. Under Webhooks, check the event types you want to trigger workflows. For example:

    Note:

    issue, error, comment, seer, preprod_artifact

  5. Click Save Changes.

  6. Copy the Client Secret and paste it into the Signing secret field in Studio.

[screenshot: Sentry Custom Integrations page with the Create New Integration button and the Client Secret field highlighted]


Events

Each Sentry event has a name in the format sentry.<resource>.<action>. Pass this name to event() in your workflow trigger.

Resource Action Full event name
issue created sentry.issue.created
issue resolved sentry.issue.resolved
issue assigned sentry.issue.assigned
issue ignored sentry.issue.ignored
error created sentry.error.created
comment created sentry.comment.created

Workflow examples

Issue events

Workflows receive the webhook envelope as keyword arguments (**envelope). The body field is the raw verified request body. It may arrive as a JSON string or an already-parsed dict, so parse defensively.

import json
from agnt5 import WorkflowContext, workflow
from agnt5.types import event


def _parse_body(envelope: dict) -> dict:
    body = envelope.get("body", {})
    if isinstance(body, str):
        try:
            body = json.loads(body)
        except json.JSONDecodeError:
            return {}
    return body if isinstance(body, dict) else {}


@workflow(
    name="triage_sentry_issue",
    triggers=[event("sentry.issue.created")],
)
async def triage_sentry_issue(ctx: WorkflowContext, **envelope) -> dict:
    body = _parse_body(envelope)
    issue = body.get("data", {}).get("issue", {})

    ctx.logger.info(
        "Sentry issue.created: %s (level=%s)"
        % (issue.get("title", "unknown"), issue.get("level", "unknown"))
    )

    # add your triage logic here, e.g. open a ticket, page on-call
    return {
        "issue_id": issue.get("id"),
        "title": issue.get("title"),
        "level": issue.get("level"),
        "event_type": envelope.get("event_type"),
    }

Comment events

Comment payloads nest the comment text several levels deep. Extract defensively:

@workflow(
    name="log_sentry_comment",
    triggers=[event("sentry.comment.created")],
)
async def log_sentry_comment(ctx: WorkflowContext, **envelope) -> dict:
    body = _parse_body(envelope)
    data = body.get("data", {})
    comment = data.get("comment") or body.get("comment") or {}
    issue = data.get("issue") or body.get("issue") or {}
    actor = body.get("actor") or {}
    user = comment.get("user") or comment.get("author") or {}

    author = (
        comment.get("author_name")
        or user.get("name")
        or actor.get("name")
        or "unknown"
    )
    text = (
        comment.get("text")
        or comment.get("message")
        or data.get("text")
        or ""
    )

    ctx.logger.info(
        "Sentry comment from %s on %s: %s"
        % (author, issue.get("short_id", "unknown"), text[:200])
    )
    return {"author": author, "issue": issue.get("short_id"), "comment": text}

Viewing triggered runs in Studio

After a Sentry event fires, the run appears in Studio → Runs within seconds. Open the run to see the envelope inputs and workflow output in the trace.

[screenshot: Studio Runs list showing a completed triage_sentry_issue run, with the run detail open showing the sentry.issue.created event_type and the workflow output]


Envelope structure

Every Sentry-triggered run receives this envelope as **envelope:

{
  "_webhook": true,
  "source": "sentry",
  "integration_id": "int_abc123",
  "event_type": "sentry.issue.created",
  "idempotency_key": "req_9f3c…",
  "timestamp": 1733337600,
  "headers": { "sentry-hook-resource": "issue", "request-id": "req_9f3c…" },
  "body": "{\"action\":\"created\",\"data\":{\"issue\":{…}}}"
}

body is the raw signature-verified request body. Parse it with json.loads before use.


Signature verification

  • Every delivery is verified using sentry-hook-signature before any workflow runs.
  • Requests with an invalid or missing signature are rejected with 401.

Delivery semantics

  • Sentry retries failed deliveries automatically.
  • AGNT5 deduplicates using the Request-ID header.
  • A retry replays the original run instead of starting a new one.

© 2026 AGNT5
llms.txt