Destinations API
Destinations are endpoints where webhooks get delivered.
Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/destinations | List destinations |
| POST | /api/destinations | Create destination |
| GET | /api/destinations/{id} | Get destination |
| PATCH | /api/destinations/{id} | Update destination |
| DELETE | /api/destinations/{id} | Delete destination |
| POST | /api/destinations/{id}/test | Send test webhook |
| GET | /api/destinations/export | Export destinations as JSON |
| POST | /api/destinations/import | Import destinations from JSON |
| DELETE | /api/destinations/bulk | Bulk delete destinations |
Destination Object
{
"id": "dst_xyz789",
"name": "Production API",
"url": "https://api.yourapp.com/webhooks",
"method": "POST",
"description": "Main webhook handler",
"headers": {
"X-Custom-Header": "value"
},
"authType": "bearer",
"authConfig": {
"token": "sk_live_xxx"
},
"timeoutMs": 30000,
"rateLimitPerMinute": 500,
"retryPolicy": {
"maxRetries": 5,
"initialDelay": 1000,
"maxDelay": 60000,
"backoffMultiplier": 2
},
"enabled": true,
"successRate": 98.5,
"avgLatency": 245,
"deliveriesCount": 5230,
"lastDeliveryAt": "2024-01-15T10:30:00Z",
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}List Destinations
GET /api/destinationsQuery Parameters
| Parameter | Type | Description |
|---|---|---|
| page | number | Page number (default: 1) |
| pageSize | number | Items per page (default: 20, max: 100) |
| enabled | boolean | Filter by enabled status |
| search | string | Search by name or URL |
Example
curl https://api.hookbase.app/api/destinations \
-H "Authorization: Bearer whr_your_api_key"const response = await fetch('https://api.hookbase.app/api/destinations', {
method: 'GET',
headers: {
'Authorization': 'Bearer whr_your_api_key',
},
});
const { data, pagination } = await response.json();import requests
response = requests.get(
'https://api.hookbase.app/api/destinations',
headers={
'Authorization': 'Bearer whr_your_api_key',
},
)
result = response.json()
data = result['data']Response
{
"data": [
{
"id": "dst_xyz789",
"name": "Production API",
"url": "https://api.yourapp.com/webhooks",
"enabled": true,
"successRate": 98.5,
"avgLatency": 245,
"deliveriesCount": 5230
}
],
"pagination": {
"total": 3,
"page": 1,
"pageSize": 20
}
}Create Destination
POST /api/destinationsRequest Body
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Display name |
| url | string | Yes | Delivery URL (HTTPS recommended) |
| method | string | No | HTTP method: POST, PUT, PATCH (default: POST) |
| description | string | No | Optional description |
| headers | object | No | Custom headers to include |
| authType | string | No | Authentication type (see below) |
| authConfig | object | No | Authentication configuration |
| timeoutMs | number | No | Request timeout in milliseconds (default: 30000, max: 60000) |
| rateLimitPerMinute | number | No | Max deliveries per minute (null = unlimited) |
| retryPolicy | object | No | Retry configuration |
| enabled | boolean | No | Active status (default: true) |
Authentication Types
| Type | Description | Auth Config |
|---|---|---|
none | No authentication | — |
basic | HTTP Basic Auth | { "username": "...", "password": "..." } |
bearer | Bearer token | { "token": "..." } |
api_key | API key in header | { "headerName": "X-API-Key", "key": "..." } |
custom_header | Custom auth header | { "headerName": "...", "headerValue": "..." } |
Example — Bearer token auth:
{
"authType": "bearer",
"authConfig": {
"token": "sk_live_abc123"
}
}Example — API key auth:
{
"authType": "api_key",
"authConfig": {
"headerName": "X-API-Key",
"key": "your-api-key"
}
}Retry Policy
| Field | Type | Default | Description |
|---|---|---|---|
| maxRetries | number | 5 | Max retry attempts |
| initialDelay | number | 1000 | First retry delay (ms) |
| maxDelay | number | 60000 | Max delay between retries (ms) |
| backoffMultiplier | number | 2 | Exponential backoff multiplier |
Example
curl -X POST https://api.hookbase.app/api/destinations \
-H "Authorization: Bearer whr_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Production API",
"url": "https://api.yourapp.com/webhooks/handler",
"headers": {
"Authorization": "Bearer sk_live_xxx",
"X-Source": "webhookrelay"
},
"retryPolicy": {
"maxRetries": 5,
"initialDelay": 1000,
"maxDelay": 300000
}
}'const response = await fetch('https://api.hookbase.app/api/destinations', {
method: 'POST',
headers: {
'Authorization': 'Bearer whr_your_api_key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Production API',
url: 'https://api.yourapp.com/webhooks/handler',
headers: {
'Authorization': 'Bearer sk_live_xxx',
'X-Source': 'webhookrelay'
},
retryPolicy: {
maxRetries: 5,
initialDelay: 1000,
maxDelay: 300000
}
}),
});
const data = await response.json();import requests
response = requests.post(
'https://api.hookbase.app/api/destinations',
headers={
'Authorization': 'Bearer whr_your_api_key',
'Content-Type': 'application/json',
},
json={
'name': 'Production API',
'url': 'https://api.yourapp.com/webhooks/handler',
'headers': {
'Authorization': 'Bearer sk_live_xxx',
'X-Source': 'webhookrelay'
},
'retryPolicy': {
'maxRetries': 5,
'initialDelay': 1000,
'maxDelay': 300000
}
},
)
data = response.json()Response
{
"id": "dst_new123",
"name": "Production API",
"url": "https://api.yourapp.com/webhooks/handler",
"headers": {
"Authorization": "Bearer sk_live_xxx",
"X-Source": "webhookrelay"
},
"retryPolicy": {
"maxRetries": 5,
"initialDelay": 1000,
"maxDelay": 300000,
"backoffMultiplier": 2
},
"enabled": true,
"successRate": null,
"avgLatency": null,
"deliveriesCount": 0,
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}Get Destination
GET /api/destinations/{id}Example
curl https://api.hookbase.app/api/destinations/dst_xyz789 \
-H "Authorization: Bearer whr_your_api_key"const response = await fetch('https://api.hookbase.app/api/destinations/dst_xyz789', {
method: 'GET',
headers: {
'Authorization': 'Bearer whr_your_api_key',
},
});
const data = await response.json();import requests
response = requests.get(
'https://api.hookbase.app/api/destinations/dst_xyz789',
headers={
'Authorization': 'Bearer whr_your_api_key',
},
)
data = response.json()Response
Returns the full destination object.
Update Destination
PATCH /api/destinations/{id}Request Body
All fields are optional. Only provided fields are updated.
| Field | Type | Description |
|---|---|---|
| name | string | Display name |
| url | string | Delivery URL |
| description | string | Optional description |
| headers | object | Custom headers (replaces existing) |
| retryPolicy | object | Retry configuration |
| enabled | boolean | Active status |
Example
curl -X PATCH https://api.hookbase.app/api/destinations/dst_xyz789 \
-H "Authorization: Bearer whr_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://api.yourapp.com/webhooks/v2/handler",
"retryPolicy": {
"maxRetries": 10
}
}'const response = await fetch('https://api.hookbase.app/api/destinations/dst_xyz789', {
method: 'PATCH',
headers: {
'Authorization': 'Bearer whr_your_api_key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
url: 'https://api.yourapp.com/webhooks/v2/handler',
retryPolicy: {
maxRetries: 10
}
}),
});
const data = await response.json();import requests
response = requests.patch(
'https://api.hookbase.app/api/destinations/dst_xyz789',
headers={
'Authorization': 'Bearer whr_your_api_key',
'Content-Type': 'application/json',
},
json={
'url': 'https://api.yourapp.com/webhooks/v2/handler',
'retryPolicy': {
'maxRetries': 10
}
},
)
data = response.json()Response
Returns the updated destination object.
Delete Destination
DELETE /api/destinations/{id}WARNING
Deleting a destination removes it from all routes. Deliveries are preserved for history.
Example
curl -X DELETE https://api.hookbase.app/api/destinations/dst_xyz789 \
-H "Authorization: Bearer whr_your_api_key"const response = await fetch('https://api.hookbase.app/api/destinations/dst_xyz789', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer whr_your_api_key',
},
});
// Returns 204 No Contentimport requests
response = requests.delete(
'https://api.hookbase.app/api/destinations/dst_xyz789',
headers={
'Authorization': 'Bearer whr_your_api_key',
},
)
# Returns 204 No ContentResponse
204 No ContentTest Destination
Send a test webhook to verify the destination is reachable and configured correctly.
POST /api/destinations/{id}/testRequest Body (Optional)
| Field | Type | Description |
|---|---|---|
| payload | object | Custom test payload (default: sample webhook event) |
Example
curl -X POST https://api.hookbase.app/api/destinations/dst_xyz789/test \
-H "Authorization: Bearer whr_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"payload": {
"event": "test",
"timestamp": "2024-01-15T10:30:00Z"
}
}'const response = await fetch('https://api.hookbase.app/api/destinations/dst_xyz789/test', {
method: 'POST',
headers: {
'Authorization': 'Bearer whr_your_api_key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
payload: {
event: 'test',
timestamp: '2024-01-15T10:30:00Z'
}
}),
});
const data = await response.json();import requests
response = requests.post(
'https://api.hookbase.app/api/destinations/dst_xyz789/test',
headers={
'Authorization': 'Bearer whr_your_api_key',
'Content-Type': 'application/json',
},
json={
'payload': {
'event': 'test',
'timestamp': '2024-01-15T10:30:00Z'
}
},
)
data = response.json()Response
{
"success": true,
"statusCode": 200,
"latency": 245,
"responseBody": "{\"received\": true}",
"message": "Test webhook delivered successfully"
}Error Response
{
"success": false,
"statusCode": 503,
"latency": 30012,
"error": "Connection timeout after 30000ms",
"message": "Test webhook delivery failed"
}Destination Health
Get health metrics for a destination:
GET /api/destinations/{id}/healthResponse
{
"successRate": 98.5,
"avgLatency": 245,
"p50Latency": 180,
"p95Latency": 450,
"p99Latency": 890,
"totalDeliveries": 5230,
"successfulDeliveries": 5152,
"failedDeliveries": 78,
"lastDeliveryAt": "2024-01-15T10:30:00Z",
"lastSuccessAt": "2024-01-15T10:30:00Z",
"lastFailureAt": "2024-01-15T09:15:00Z",
"status": "healthy"
}Status Values
| Status | Description |
|---|---|
healthy | Success rate > 95% |
degraded | Success rate 80-95% |
failing | Success rate < 80% |
unknown | No recent deliveries |
Export Destinations
Export destinations as a JSON file for backup or migration to another organization.
GET /api/destinations/exportQuery Parameters
| Parameter | Type | Description |
|---|---|---|
| ids | string | Comma-separated destination IDs to export (optional, exports all if not specified) |
| includeSensitive | boolean | Include auth credentials in export (default: false) |
Example
# Export all destinations (auth credentials redacted)
curl https://api.hookbase.app/api/destinations/export \
-H "Authorization: Bearer whr_your_api_key"
# Export specific destinations with credentials
curl "https://api.hookbase.app/api/destinations/export?ids=dst_1,dst_2&includeSensitive=true" \
-H "Authorization: Bearer whr_your_api_key"// Export all destinations (auth credentials redacted)
const response1 = await fetch('https://api.hookbase.app/api/destinations/export', {
method: 'GET',
headers: {
'Authorization': 'Bearer whr_your_api_key',
},
});
const data1 = await response1.json();
// Export specific destinations with credentials
const response2 = await fetch('https://api.hookbase.app/api/destinations/export?ids=dst_1,dst_2&includeSensitive=true', {
method: 'GET',
headers: {
'Authorization': 'Bearer whr_your_api_key',
},
});
const data2 = await response2.json();import requests
# Export all destinations (auth credentials redacted)
response1 = requests.get(
'https://api.hookbase.app/api/destinations/export',
headers={
'Authorization': 'Bearer whr_your_api_key',
},
)
data1 = response1.json()
# Export specific destinations with credentials
response2 = requests.get(
'https://api.hookbase.app/api/destinations/export',
params={
'ids': 'dst_1,dst_2',
'includeSensitive': 'true'
},
headers={
'Authorization': 'Bearer whr_your_api_key',
},
)
data2 = response2.json()Response
{
"version": "1.0",
"exportedAt": "2024-01-15T10:30:00Z",
"organizationSlug": "myorg",
"destinations": [
{
"name": "Production API",
"slug": "production-api",
"url": "https://api.yourapp.com/webhooks",
"method": "POST",
"headers": {
"X-Custom-Header": "value"
},
"authType": "bearer",
"authConfig": "***REDACTED***",
"timeoutMs": 30000,
"rateLimitPerMinute": null,
"isActive": true
}
]
}TIP
When includeSensitive is false (default), authentication credentials are replaced with ***REDACTED***. You'll need to reconfigure auth settings after importing.
Import Destinations
Import destinations from a JSON export file.
POST /api/destinations/importRequest Body
| Field | Type | Required | Description |
|---|---|---|---|
| destinations | array | Yes | Array of destination objects to import |
| conflictStrategy | string | Yes | How to handle slug conflicts: skip, rename, or overwrite |
| validateOnly | boolean | No | If true, validates without importing (default: false) |
Conflict Strategies
| Strategy | Description |
|---|---|
skip | Skip destinations that already exist (by slug) |
rename | Auto-rename conflicting destinations (e.g., api → api-1) |
overwrite | Update existing destinations with imported data |
Example
curl -X POST https://api.hookbase.app/api/destinations/import \
-H "Authorization: Bearer whr_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"destinations": [
{
"name": "Staging API",
"slug": "staging-api",
"url": "https://staging.yourapp.com/webhooks",
"method": "POST",
"timeoutMs": 30000,
"isActive": true
}
],
"conflictStrategy": "skip"
}'const response = await fetch('https://api.hookbase.app/api/destinations/import', {
method: 'POST',
headers: {
'Authorization': 'Bearer whr_your_api_key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
destinations: [
{
name: 'Staging API',
slug: 'staging-api',
url: 'https://staging.yourapp.com/webhooks',
method: 'POST',
timeoutMs: 30000,
isActive: true
}
],
conflictStrategy: 'skip'
}),
});
const data = await response.json();import requests
response = requests.post(
'https://api.hookbase.app/api/destinations/import',
headers={
'Authorization': 'Bearer whr_your_api_key',
'Content-Type': 'application/json',
},
json={
'destinations': [
{
'name': 'Staging API',
'slug': 'staging-api',
'url': 'https://staging.yourapp.com/webhooks',
'method': 'POST',
'timeoutMs': 30000,
'isActive': True
}
],
'conflictStrategy': 'skip'
},
)
data = response.json()Validation Response
When validateOnly: true:
{
"valid": true,
"validationResults": [
{
"index": 0,
"name": "Staging API",
"slug": "staging-api",
"status": "valid",
"errors": [],
"warnings": []
}
],
"summary": {
"total": 1,
"toCreate": 1,
"toOverwrite": 0,
"toSkip": 0,
"errors": 0
}
}Import Response
{
"success": true,
"summary": {
"imported": 3,
"skipped": 1,
"overwritten": 0,
"failed": 0
},
"details": {
"imported": ["Staging API", "Development API", "QA Endpoint"],
"skipped": ["Production API"],
"overwritten": [],
"failed": []
}
}Bulk Delete Destinations
Delete multiple destinations in a single request.
DELETE /api/destinations/bulkRequest Body
{
"ids": ["dst_abc123", "dst_def456", "dst_ghi789"]
}Example
curl -X DELETE https://api.hookbase.app/api/destinations/bulk \
-H "Authorization: Bearer whr_your_api_key" \
-H "Content-Type: application/json" \
-d '{"ids": ["dst_abc123", "dst_def456"]}'const response = await fetch('https://api.hookbase.app/api/destinations/bulk', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer whr_your_api_key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
ids: ['dst_abc123', 'dst_def456']
}),
});
const data = await response.json();import requests
response = requests.delete(
'https://api.hookbase.app/api/destinations/bulk',
headers={
'Authorization': 'Bearer whr_your_api_key',
'Content-Type': 'application/json',
},
json={
'ids': ['dst_abc123', 'dst_def456']
},
)
data = response.json()Response
{
"success": true,
"deleted": 2
}WARNING
Deleting destinations removes them from all routes. Delivery history is preserved.
Error Responses
400 Bad Request
Invalid URL:
{
"error": "Bad Request",
"message": "Invalid URL format",
"code": "INVALID_URL"
}404 Not Found
Destination not found:
{
"error": "Not Found",
"message": "Destination with ID dst_xyz not found",
"code": "RESOURCE_NOT_FOUND"
}