Skip to content

Filters

Filters control which webhooks get delivered based on payload content.

Overview

Filters evaluate conditions against webhook payloads to determine if they should be delivered. Use filters to:

  • Only process specific event types
  • Filter by payload values
  • Skip test or sandbox events
  • Route based on content

Creating a Filter

Required Fields

FieldDescription
nameHuman-readable name
conditionsArray of condition objects
logicHow to combine conditions: and or or

Condition Structure

Each condition has:

FieldDescription
fieldJSONPath to the field (e.g., action, repository.name)
operatorComparison operator
valueValue to compare against

Operators

OperatorDescriptionExample
equalsExact matchaction equals push
not_equalsNot equalaction not_equals ping
containsString containsmessage contains error
not_containsString doesn't containemail not_contains test
starts_withString starts withref starts_with refs/heads/
ends_withString ends withfilename ends_with .json
matchesRegex matchbranch matches ^feature/.*
greater_thanNumeric greater thanamount greater_than 100
less_thanNumeric less thancount less_than 10
existsField existsmetadata.custom exists
not_existsField doesn't existdeleted_at not_exists

Examples

Only Push Events

json
{
  "name": "Push Events Only",
  "logic": "and",
  "conditions": [
    {
      "field": "action",
      "operator": "equals",
      "value": "push"
    }
  ]
}

Production Only (Skip Test)

json
{
  "name": "Production Only",
  "logic": "and",
  "conditions": [
    {
      "field": "livemode",
      "operator": "equals",
      "value": "true"
    }
  ]
}

High Value Orders

json
{
  "name": "High Value Orders",
  "logic": "and",
  "conditions": [
    {
      "field": "order.total",
      "operator": "greater_than",
      "value": "1000"
    },
    {
      "field": "order.status",
      "operator": "equals",
      "value": "completed"
    }
  ]
}

Multiple Event Types (OR logic)

json
{
  "name": "PR Events",
  "logic": "or",
  "conditions": [
    {
      "field": "action",
      "operator": "equals",
      "value": "opened"
    },
    {
      "field": "action",
      "operator": "equals",
      "value": "closed"
    },
    {
      "field": "action",
      "operator": "equals",
      "value": "merged"
    }
  ]
}

Specific Branch

json
{
  "name": "Main Branch Only",
  "logic": "and",
  "conditions": [
    {
      "field": "ref",
      "operator": "equals",
      "value": "refs/heads/main"
    }
  ]
}

Regex Pattern

json
{
  "name": "Feature Branches",
  "logic": "and",
  "conditions": [
    {
      "field": "ref",
      "operator": "matches",
      "value": "^refs/heads/feature/.*"
    }
  ]
}

Nested Fields

Access nested fields using dot notation:

json
{
  "field": "repository.owner.login",
  "operator": "equals",
  "value": "myorg"
}
json
{
  "field": "pull_request.head.ref",
  "operator": "starts_with",
  "value": "feature/"
}

API Usage

Create Filter

bash
curl -X POST https://api.webhookrelay.com/api/organizations/{orgId}/filters \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Push to Main",
    "logic": "and",
    "conditions": [
      {"field": "action", "operator": "equals", "value": "push"},
      {"field": "ref", "operator": "equals", "value": "refs/heads/main"}
    ]
  }'

List Filters

bash
curl https://api.webhookrelay.com/api/organizations/{orgId}/filters \
  -H "Authorization: Bearer YOUR_TOKEN"

Update Filter

bash
curl -X PATCH https://api.webhookrelay.com/api/organizations/{orgId}/filters/{filterId} \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "conditions": [
      {"field": "action", "operator": "equals", "value": "push"}
    ]
  }'

Delete Filter

bash
curl -X DELETE https://api.webhookrelay.com/api/organizations/{orgId}/filters/{filterId} \
  -H "Authorization: Bearer YOUR_TOKEN"

Using Filters with Routes

Attach a filter to a route:

bash
curl -X PATCH https://api.webhookrelay.com/api/organizations/{orgId}/routes/{routeId} \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "filterId": "flt_abc123"
  }'

Filter Evaluation

When a webhook arrives:

  1. Route is evaluated
  2. If route has a filter:
    • All conditions are evaluated
    • Conditions are combined using the logic (and/or)
    • If result is true: webhook is delivered
    • If result is false: webhook is skipped (not an error)

AND Logic

All conditions must be true:

Condition 1: true  ┐
Condition 2: true  ├─ AND ─▶ true (deliver)
Condition 3: true  ┘

Condition 1: true  ┐
Condition 2: false ├─ AND ─▶ false (skip)
Condition 3: true  ┘

OR Logic

At least one condition must be true:

Condition 1: false ┐
Condition 2: true  ├─ OR ─▶ true (deliver)
Condition 3: false ┘

Condition 1: false ┐
Condition 2: false ├─ OR ─▶ false (skip)
Condition 3: false ┘

Best Practices

  1. Start permissive, then restrict: Begin with broad filters and narrow down

  2. Test with real payloads: Use actual webhook payloads to verify filter behavior

  3. Use descriptive names: Name filters by their purpose (e.g., "Production Push Events")

  4. Combine with transforms: Use filters to route, transforms to reshape

  5. Monitor filtered events: Check Event History for skipped events

Troubleshooting

Events not being delivered

  1. Check if the filter conditions match your payload
  2. Verify field paths are correct (use dot notation for nested fields)
  3. Check operator and value types (strings must be quoted)
  4. Review logic (and vs or)

Unexpected events being delivered

  1. Review filter conditions for typos
  2. Check if the route has no filter attached
  3. Verify the correct route is active

Released under the MIT License.