Filters API
Filters control which webhook events are forwarded through a route based on conditions applied to the payload.
Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/filters | List filters |
| POST | /api/filters | Create filter |
| GET | /api/filters/{id} | Get filter |
| PATCH | /api/filters/{id} | Update filter |
| DELETE | /api/filters/{id} | Delete filter |
Filter Object
json
{
"id": "flt_abc123",
"name": "Push Events Only",
"description": "Only forward push events from GitHub",
"conditions": [
{
"field": "headers.X-GitHub-Event",
"operator": "equals",
"value": "push"
}
],
"logic": "AND",
"routeCount": 2,
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}Condition Object
| Field | Type | Description |
|---|---|---|
| field | string | JSONPath to the field in payload or headers (e.g., payload.action, headers.X-GitHub-Event) |
| operator | string | Comparison operator (see below) |
| value | string | Value to compare against |
Operators
| Operator | Description | Example |
|---|---|---|
equals | Exact match | "push" |
not_equals | Not equal | "delete" |
contains | String contains | "release" |
not_contains | String does not contain | "test" |
starts_with | String starts with | "refs/heads/" |
ends_with | String ends with | ".json" |
matches | Regex match | "^v\\d+\\.\\d+" |
exists | Field exists (value ignored) | — |
not_exists | Field does not exist (value ignored) | — |
gt | Greater than (numeric) | "100" |
gte | Greater than or equal (numeric) | "100" |
lt | Less than (numeric) | "50" |
lte | Less than or equal (numeric) | "50" |
in | Value in comma-separated list | "push,pull_request,release" |
not_in | Value not in comma-separated list | "bot,automated" |
Logic
| Value | Description |
|---|---|
AND | All conditions must match (default) |
OR | Any condition must match |
List Filters
http
GET /api/filtersQuery Parameters
| Parameter | Type | Description |
|---|---|---|
| page | number | Page number (default: 1) |
| pageSize | number | Items per page (default: 20, max: 100) |
| search | string | Search by name |
Example
bash
curl https://api.hookbase.app/api/filters \
-H "Authorization: Bearer whr_your_api_key"javascript
const response = await fetch('https://api.hookbase.app/api/filters', {
headers: {
'Authorization': 'Bearer whr_your_api_key'
}
});
const data = await response.json();python
import requests
response = requests.get(
'https://api.hookbase.app/api/filters',
headers={'Authorization': 'Bearer whr_your_api_key'}
)
data = response.json()Response
json
{
"data": [
{
"id": "flt_abc123",
"name": "Push Events Only",
"conditions": [
{
"field": "headers.X-GitHub-Event",
"operator": "equals",
"value": "push"
}
],
"logic": "AND",
"routeCount": 2
}
],
"pagination": {
"total": 3,
"page": 1,
"pageSize": 20
}
}Create Filter
http
POST /api/filtersRequest Body
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Display name |
| conditions | array | Yes | Array of condition objects |
| description | string | No | Optional description |
| logic | string | No | AND or OR (default: AND) |
Example
bash
curl -X POST https://api.hookbase.app/api/filters \
-H "Authorization: Bearer whr_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Production Push Events",
"description": "Only forward push events to main branch",
"conditions": [
{
"field": "headers.X-GitHub-Event",
"operator": "equals",
"value": "push"
},
{
"field": "payload.ref",
"operator": "equals",
"value": "refs/heads/main"
}
],
"logic": "AND"
}'javascript
const response = await fetch('https://api.hookbase.app/api/filters', {
method: 'POST',
headers: {
'Authorization': 'Bearer whr_your_api_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Production Push Events',
description: 'Only forward push events to main branch',
conditions: [
{
field: 'headers.X-GitHub-Event',
operator: 'equals',
value: 'push'
},
{
field: 'payload.ref',
operator: 'equals',
value: 'refs/heads/main'
}
],
logic: 'AND'
})
});
const data = await response.json();python
import requests
response = requests.post(
'https://api.hookbase.app/api/filters',
headers={
'Authorization': 'Bearer whr_your_api_key',
'Content-Type': 'application/json'
},
json={
'name': 'Production Push Events',
'description': 'Only forward push events to main branch',
'conditions': [
{
'field': 'headers.X-GitHub-Event',
'operator': 'equals',
'value': 'push'
},
{
'field': 'payload.ref',
'operator': 'equals',
'value': 'refs/heads/main'
}
],
'logic': 'AND'
}
)
data = response.json()Response
json
{
"id": "flt_new123",
"name": "Production Push Events",
"description": "Only forward push events to main branch",
"conditions": [
{
"field": "headers.X-GitHub-Event",
"operator": "equals",
"value": "push"
},
{
"field": "payload.ref",
"operator": "equals",
"value": "refs/heads/main"
}
],
"logic": "AND",
"routeCount": 0,
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}Get Filter
http
GET /api/filters/{id}Example
bash
curl https://api.hookbase.app/api/filters/flt_abc123 \
-H "Authorization: Bearer whr_your_api_key"javascript
const response = await fetch('https://api.hookbase.app/api/filters/flt_abc123', {
headers: {
'Authorization': 'Bearer whr_your_api_key'
}
});
const data = await response.json();python
import requests
response = requests.get(
'https://api.hookbase.app/api/filters/flt_abc123',
headers={'Authorization': 'Bearer whr_your_api_key'}
)
data = response.json()Response
Returns the full filter object.
Update Filter
http
PATCH /api/filters/{id}Request Body
All fields are optional. Only provided fields are updated.
| Field | Type | Description |
|---|---|---|
| name | string | Display name |
| conditions | array | Array of condition objects (replaces existing) |
| description | string | Optional description |
| logic | string | AND or OR |
Example
bash
curl -X PATCH https://api.hookbase.app/api/filters/flt_abc123 \
-H "Authorization: Bearer whr_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"conditions": [
{
"field": "headers.X-GitHub-Event",
"operator": "in",
"value": "push,pull_request,release"
}
]
}'javascript
const response = await fetch('https://api.hookbase.app/api/filters/flt_abc123', {
method: 'PATCH',
headers: {
'Authorization': 'Bearer whr_your_api_key',
'Content-Type': 'application/json'
},
body: JSON.stringify({
conditions: [
{
field: 'headers.X-GitHub-Event',
operator: 'in',
value: 'push,pull_request,release'
}
]
})
});
const data = await response.json();python
import requests
response = requests.patch(
'https://api.hookbase.app/api/filters/flt_abc123',
headers={
'Authorization': 'Bearer whr_your_api_key',
'Content-Type': 'application/json'
},
json={
'conditions': [
{
'field': 'headers.X-GitHub-Event',
'operator': 'in',
'value': 'push,pull_request,release'
}
]
}
)
data = response.json()Response
Returns the updated filter object.
Delete Filter
http
DELETE /api/filters/{id}WARNING
A filter cannot be deleted while it is assigned to active routes. Remove it from all routes first.
Example
bash
curl -X DELETE https://api.hookbase.app/api/filters/flt_abc123 \
-H "Authorization: Bearer whr_your_api_key"javascript
const response = await fetch('https://api.hookbase.app/api/filters/flt_abc123', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer whr_your_api_key'
}
});python
import requests
response = requests.delete(
'https://api.hookbase.app/api/filters/flt_abc123',
headers={'Authorization': 'Bearer whr_your_api_key'}
)Response
204 No ContentInline Filters vs Saved Filters
Routes support two approaches to filtering:
- Saved filters — Create a filter via this API and reference it by
filterIdin the route. Reusable across multiple routes. - Inline filters — Define
filterConditionsandfilterLogicdirectly on the route. Simpler for one-off conditions.
bash
# Using a saved filter
curl -X POST .../routes \
-d '{"name": "My Route", "sourceId": "src_1", "destinationIds": ["dst_1"], "filterId": "flt_abc123"}'
# Using inline conditions
curl -X POST .../routes \
-d '{
"name": "My Route",
"sourceId": "src_1",
"destinationIds": ["dst_1"],
"filterConditions": [
{"field": "headers.X-GitHub-Event", "operator": "equals", "value": "push"}
],
"filterLogic": "AND"
}'Error Responses
400 Bad Request
Invalid condition:
json
{
"error": "Bad Request",
"message": "Invalid operator 'like'. Must be one of: equals, not_equals, contains, ...",
"code": "INVALID_CONDITION"
}409 Conflict
Filter in use:
json
{
"error": "Conflict",
"message": "Filter is assigned to 2 active routes",
"code": "RESOURCE_IN_USE"
}Related
- Filters Guide — Concepts and usage patterns
- Routes API — Assign filters to routes