# Webhook triggers

URL: https://docs.usestitch.ai/docs/triggers/webhook



Set `provider: webhook`. A webhook still runs against a connected repository.
Inspect its endpoint with `stitch webhooks get <factory-id>`.

## Schema [#schema]

[Webhook trigger JSON Schema](/schema/webhook.json) · [Factory schema](/schema/factory.json)

```yaml
key: external-bug
name: Handle external bug
provider: webhook
harness: coding-agent
sandbox: workspace
agentId: build
initialPrompt: Investigate the incoming bug report.
events: [ticket.created]
payloadFilter:
  priority: [high, urgent]
guards:
  - type: deduplicate
    scope: delivery
enabled: false
```

Send a JSON object with `meta` and `data`. `meta.id` and `meta.event` are required
non-empty strings (at most 128 characters). Reuse the same ID on retries.
`data` must be a JSON object.

```json
{
  "meta": { "id": "ticket-123-created", "event": "ticket.created" },
  "data": { "priority": "high", "title": "Checkout fails" }
}
```

```sh
stitch webhooks send <factory-id> --event ticket.created --idempotency-key ticket-123-created --data-file payload.json
```

For this command, `payload.json` contains only the `data` object; the CLI builds `meta`.
For direct HTTP delivery, send the full envelope to the returned endpoint and keep
its webhook credential private. Key rotation invalidates the old key immediately.

## Filters [#filters]

`events` allows at most 32 names; an empty list accepts any event name.
`payloadFilter` matches `data`, not `meta`. Nested fields are combined with AND.
Each value list is an OR match. Supported operators are `in`, `not_in`, and `exists`.

```yaml
payloadFilter:
  ticket:
    priority:
      in: [high, urgent]
    archived:
      not_in: [true]
    assignee:
      exists: true
```

Lists contain 1–32 scalar values (string, number, boolean, or null).
`exists` checks field presence, including null. `not_in` also passes for missing fields
unless `exists: true` is set. Nested array objects match if any element matches.
Filters are limited to 64 leaf rules and depth 10.
The JSON Schema exposes a payload object; full validation also checks the recursive filter grammar.

## Guards [#guards]

Use `repository` for `max_occurrences`, `cooldown`, and `max_concurrent`.
Use `delivery` for `deduplicate`. Subject, commit, and event scopes are rejected.
Stable `meta.id` plus delivery deduplication prevents repeated admission on retries.
See [guard types and limits](/docs/triggers#guards).
