Routes API

Routes connect sources to destinations.

Endpoints

MethodPathDescription
GET/api/routesList routes
POST/api/routesCreate route
GET/api/routes/{id}Get route
PATCH/api/routes/{id}Update route
DELETE/api/routes/{id}Delete route
GET/api/routes/{id}/circuit-statusGet circuit breaker status
POST/api/routes/{id}/reset-circuitReset circuit breaker
PATCH/api/routes/{id}/circuit-configUpdate circuit breaker config
GET/api/routes/exportExport routes as JSON
POST/api/routes/importImport routes from JSON
POST/api/routes/bulk-pausePause/resume multiple routes
POST/api/routes/bulk-deleteDelete multiple routes

Route Object

{
  "id": "rte_abc123",
  "name": "GitHub to Slack",
  "description": "Forward GitHub events to Slack",
  "sourceId": "src_xyz789",
  "destinationIds": ["dst_slack1", "dst_slack2"],
  "transformId": "tfm_format123",
  "filterId": "flt_pushonly456",
  "priority": 10,
  "filterConditions": null,
  "filterLogic": "AND",
  "failoverDestinationIds": ["dst_backup1"],
  "failoverAfterAttempts": 3,
  "circuitState": "closed",
  "circuitCooldownSeconds": 300,
  "circuitFailureThreshold": 5,
  "circuitProbeSuccessThreshold": 2,
  "notifyOnFailure": true,
  "notifyOnSuccess": false,
  "notifyOnRecovery": true,
  "notifyEmails": "[email protected]",
  "expectedResponse": null,
  "enabled": true,
  "source": {
    "id": "src_xyz789",
    "name": "GitHub"
  },
  "destinations": [
    {"id": "dst_slack1", "name": "Slack #dev"},
    {"id": "dst_slack2", "name": "Slack #alerts"}
  ],
  "transform": {
    "id": "tfm_format123",
    "name": "Slack Formatter"
  },
  "filter": {
    "id": "flt_pushonly456",
    "name": "Push Events Only"
  },
  "eventsRouted": 1523,
  "lastEventAt": "2024-01-15T10:30:00Z",
  "createdAt": "2024-01-01T00:00:00Z",
  "updatedAt": "2024-01-15T10:30:00Z"
}

List Routes

GET /api/routes

Query Parameters

ParameterTypeDescription
pagenumberPage number (default: 1)
pageSizenumberItems per page (default: 20, max: 100)
enabledbooleanFilter by enabled status
sourceIdstringFilter by source
destinationIdstringFilter by destination

Example

curl
curl https://api.hookbase.app/api/routes \
  -H "Authorization: Bearer whr_your_api_key"

Response

{
  "data": [
    {
      "id": "rte_abc123",
      "name": "GitHub to Slack",
      "sourceId": "src_xyz789",
      "destinationIds": ["dst_slack1"],
      "enabled": true,
      "eventsRouted": 1523,
      "source": {"id": "src_xyz789", "name": "GitHub"},
      "destinations": [{"id": "dst_slack1", "name": "Slack #dev"}]
    }
  ],
  "pagination": {
    "total": 5,
    "page": 1,
    "pageSize": 20
  }
}

Create Route

POST /api/routes

Request Body

FieldTypeRequiredDescription
namestringYesDisplay name
sourceIdstringYesSource ID to listen to
destinationIdsstring[]YesArray of destination IDs
descriptionstringNoOptional description
transformIdstringNoTransform to apply
filterIdstringNoFilter to evaluate
prioritynumberNoRoute priority — higher values run first (default: 0)
filterConditionsarrayNoInline filter conditions (alternative to filterId). See Filters
filterLogicstringNoLogic for inline filters: AND or OR (default: AND)
enabledbooleanNoActive status (default: true)

Failover Configuration

FieldTypeDefaultDescription
failoverDestinationIdsstring[][]Backup destination IDs (max 3). See Failover Guide
failoverAfterAttemptsnumber3Switch to failover after this many failed attempts

Circuit Breaker Configuration

FieldTypeDefaultDescription
circuitCooldownSecondsnumber300Seconds to wait in open state before probing
circuitFailureThresholdnumber5Consecutive failures to trip the circuit
circuitProbeSuccessThresholdnumber2Successful probes required to close circuit

See Circuit Breaker Guide for details.

Notification Configuration

FieldTypeDefaultDescription
notifyOnFailurebooleanfalseSend notification when delivery fails
notifyOnSuccessbooleanfalseSend notification when delivery succeeds
notifyOnRecoverybooleanfalseSend notification when route recovers from failure
notifyEmailsstringnullComma-separated email addresses for notifications

Response Validation

FieldTypeDescription
expectedResponseobjectValidate destination response. { "statusCodes": [200, 201], "bodyContains": "ok" }

Example

curl
curl -X POST https://api.hookbase.app/api/routes \
  -H "Authorization: Bearer whr_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "GitHub to Slack",
    "sourceId": "src_xyz789",
    "destinationIds": ["dst_slack1", "dst_slack2"],
    "transformId": "tfm_format123",
    "filterId": "flt_pushonly456"
  }'

Response

{
  "id": "rte_new123",
  "name": "GitHub to Slack",
  "sourceId": "src_xyz789",
  "destinationIds": ["dst_slack1", "dst_slack2"],
  "transformId": "tfm_format123",
  "filterId": "flt_pushonly456",
  "enabled": true,
  "eventsRouted": 0,
  "createdAt": "2024-01-15T10:30:00Z",
  "updatedAt": "2024-01-15T10:30:00Z"
}

Get Route

GET /api/routes/{id}

Example

curl
curl https://api.hookbase.app/api/routes/rte_abc123 \
  -H "Authorization: Bearer whr_your_api_key"

Response

Returns the full route object with expanded source, destinations, transform, and filter.

Update Route

PATCH /api/routes/{id}

Request Body

All fields are optional. Only provided fields are updated.

FieldTypeDescription
namestringDisplay name
destinationIdsstring[]Array of destination IDs
descriptionstringOptional description
transformIdstringTransform ID (null to remove)
filterIdstringFilter ID (null to remove)
enabledbooleanActive status

Warning

The sourceId cannot be changed after creation. Create a new route instead.

Example

curl
curl -X PATCH https://api.hookbase.app/api/routes/rte_abc123 \
  -H "Authorization: Bearer whr_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": false,
    "filterId": null
  }'

Response

Returns the updated route object.

Delete Route

DELETE /api/routes/{id}

Info

Deleting a route does not delete the source, destinations, transform, or filter.

Example

curl
curl -X DELETE https://api.hookbase.app/api/routes/rte_abc123 \
  -H "Authorization: Bearer whr_your_api_key"

Response

204 No Content

Route Statistics

Get statistics for a route:

GET /api/routes/{id}/stats

Query Parameters

ParameterTypeDescription
periodstringTime period: 1h, 24h, 7d, 30d

Response

{
  "eventsRouted": 1523,
  "eventsFiltered": 234,
  "deliveriesSucceeded": 1489,
  "deliveriesFailed": 34,
  "avgLatency": 245,
  "period": "24h"
}

Circuit Breaker Status

Get the current circuit breaker state for a route.

GET /api/routes/{id}/circuit-status

Response

{
  "circuitState": "closed",
  "failureCount": 2,
  "failureThreshold": 5,
  "cooldownSeconds": 300,
  "lastFailureAt": "2024-01-15T10:25:00Z",
  "lastSuccessAt": "2024-01-15T10:30:00Z",
  "openedAt": null,
  "probeSuccessCount": 0,
  "probeSuccessThreshold": 2
}

Circuit States

StateDescription
closedNormal operation — deliveries are flowing
openCircuit tripped — deliveries are paused, failover activated
half_openProbing — sending test deliveries to check recovery

Reset Circuit Breaker

Manually reset the circuit breaker to closed state.

POST /api/routes/{id}/reset-circuit

Example

curl
curl -X POST https://api.hookbase.app/api/routes/rte_abc123/reset-circuit \
  -H "Authorization: Bearer whr_your_api_key"

Response

{
  "message": "Circuit breaker reset to closed",
  "circuitState": "closed"
}

Update Circuit Breaker Config

Update the circuit breaker configuration for a route without modifying other route settings.

PATCH /api/routes/{id}/circuit-config

Request Body

FieldTypeDescription
circuitCooldownSecondsnumberSeconds to wait before probing
circuitFailureThresholdnumberFailures to trip the circuit
circuitProbeSuccessThresholdnumberSuccessful probes to close circuit

Example

curl
curl -X PATCH https://api.hookbase.app/api/routes/rte_abc123/circuit-config \
  -H "Authorization: Bearer whr_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "circuitFailureThreshold": 10,
    "circuitCooldownSeconds": 600
  }'

Response

{
  "circuitCooldownSeconds": 600,
  "circuitFailureThreshold": 10,
  "circuitProbeSuccessThreshold": 2,
  "message": "Circuit breaker configuration updated"
}

Export Routes

Export routes as a portable JSON file. Uses slugs instead of IDs for cross-environment compatibility.

GET /api/routes/export

Query Parameters

ParameterTypeDescription
idsstringComma-separated route IDs to export (optional, exports all if omitted)

Example

curl
# Export all routes
curl https://api.hookbase.app/api/routes/export \
  -H "Authorization: Bearer whr_your_api_key"
 
# Export specific routes
curl "https://api.hookbase.app/api/routes/export?ids=rte_abc,rte_def" \
  -H "Authorization: Bearer whr_your_api_key"

Response

{
  "version": "1.0",
  "exportedAt": "2026-01-30T12:00:00Z",
  "organizationSlug": "acme-corp",
  "routes": [
    {
      "name": "Stripe to Slack",
      "sourceSlug": "stripe-webhooks",
      "destinationSlug": "slack-notifications",
      "filterSlug": "payment-events",
      "transformSlug": null,
      "schemaSlug": null,
      "filterConditions": null,
      "filterLogic": "AND",
      "priority": 10,
      "isActive": true,
      "notifyOnFailure": true,
      "notifyOnSuccess": false,
      "notifyOnRecovery": true,
      "notifyEmails": "[email protected]",
      "failureThreshold": 3,
      "failoverDestinationSlugs": ["backup-webhook"],
      "failoverAfterAttempts": 3,
      "circuitCooldownSeconds": 300,
      "circuitFailureThreshold": 5,
      "circuitProbeSuccessThreshold": 2
    }
  ]
}

Tip

Export files use slugs instead of IDs. This makes them portable between environments. Set up matching source and destination slugs in your target environment before importing.

Import Routes

Import routes from a JSON export file.

POST /api/routes/import

Request Body

FieldTypeRequiredDescription
routesarrayYesArray of route objects from export
conflictStrategystringYesHow to handle name conflicts: skip, rename, or overwrite
validateOnlybooleanNoIf true, validates without creating routes (dry run)

Conflict Strategies

StrategyBehavior
skipKeep existing route, don't import the duplicate
renameImport with suffix: "My Route" becomes "My Route (1)"
overwriteReplace existing route with imported configuration

Example

curl
# Validate import (dry run)
curl -X POST https://api.hookbase.app/api/routes/import \
  -H "Authorization: Bearer whr_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "routes": [...],
    "conflictStrategy": "skip",
    "validateOnly": true
  }'
 
# Import routes
curl -X POST https://api.hookbase.app/api/routes/import \
  -H "Authorization: Bearer whr_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "routes": [...],
    "conflictStrategy": "rename"
  }'

Response

{
  "imported": 3,
  "skipped": 1,
  "overwritten": 0,
  "errors": [],
  "warnings": [
    "Route 'Legacy Webhook' skipped: already exists"
  ],
  "routes": [
    {
      "id": "rte_new123",
      "name": "Stripe to Slack",
      "status": "created"
    },
    {
      "id": "rte_new456",
      "name": "GitHub to Discord",
      "status": "created"
    }
  ]
}

Validation Errors

Before importing, Hookbase validates that all referenced resources exist:

{
  "imported": 0,
  "skipped": 0,
  "errors": [
    "Source 'stripe-webhooks' not found",
    "Destination 'backup-webhook' not found"
  ],
  "warnings": []
}

Warning

All referenced sources, destinations, filters, transforms, and schemas must exist in the target organization before importing.

Bulk Pause Routes

Pause or resume multiple routes at once.

POST /api/routes/bulk-pause

Request Body

FieldTypeRequiredDescription
routeIdsstring[]YesArray of route IDs to update
isActivebooleanYesSet to false to pause, true to resume

Example

curl
# Pause multiple routes
curl -X POST https://api.hookbase.app/api/routes/bulk-pause \
  -H "Authorization: Bearer whr_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "routeIds": ["rte_abc123", "rte_def456", "rte_ghi789"],
    "isActive": false
  }'
 
# Resume multiple routes
curl -X POST https://api.hookbase.app/api/routes/bulk-pause \
  -H "Authorization: Bearer whr_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "routeIds": ["rte_abc123", "rte_def456"],
    "isActive": true
  }'

Response

{
  "updated": 3,
  "routes": [
    { "id": "rte_abc123", "name": "Stripe to Slack", "isActive": false },
    { "id": "rte_def456", "name": "GitHub to Discord", "isActive": false },
    { "id": "rte_ghi789", "name": "Shopify to CRM", "isActive": false }
  ]
}

Bulk Delete Routes

Delete multiple routes at once.

POST /api/routes/bulk-delete

Request Body

FieldTypeRequiredDescription
routeIdsstring[]YesArray of route IDs to delete

Example

curl
curl -X POST https://api.hookbase.app/api/routes/bulk-delete \
  -H "Authorization: Bearer whr_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "routeIds": ["rte_abc123", "rte_def456", "rte_ghi789"]
  }'

Response

{
  "deleted": 3,
  "routes": [
    { "id": "rte_abc123", "name": "Stripe to Slack" },
    { "id": "rte_def456", "name": "GitHub to Discord" },
    { "id": "rte_ghi789", "name": "Shopify to CRM" }
  ]
}

Danger

Bulk delete is irreversible. Consider exporting routes before deleting as a backup.

Error Responses

400 Bad Request

Invalid source or destination:

{
  "error": "Bad Request",
  "message": "Source with ID src_invalid not found",
  "code": "INVALID_SOURCE"
}

404 Not Found

Route not found:

{
  "error": "Not Found",
  "message": "Route with ID rte_xyz not found",
  "code": "RESOURCE_NOT_FOUND"
}

409 Conflict

Duplicate route:

{
  "error": "Conflict",
  "message": "A route with this source and destinations already exists",
  "code": "DUPLICATE_ROUTE"
}