Skip to content

Destinations API

Destinations are endpoints where webhooks get delivered.

Endpoints

MethodPathDescription
GET/api/destinationsList destinations
POST/api/destinationsCreate destination
GET/api/destinations/{id}Get destination
PATCH/api/destinations/{id}Update destination
DELETE/api/destinations/{id}Delete destination
POST/api/destinations/{id}/testSend test webhook
GET/api/destinations/exportExport destinations as JSON
POST/api/destinations/importImport destinations from JSON
DELETE/api/destinations/bulkBulk delete destinations

Destination Object

json
{
  "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

http
GET /api/destinations

Query Parameters

ParameterTypeDescription
pagenumberPage number (default: 1)
pageSizenumberItems per page (default: 20, max: 100)
enabledbooleanFilter by enabled status
searchstringSearch by name or URL

Example

bash
curl https://api.hookbase.app/api/destinations \
  -H "Authorization: Bearer whr_your_api_key"
javascript
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();
python
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

json
{
  "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

http
POST /api/destinations

Request Body

FieldTypeRequiredDescription
namestringYesDisplay name
urlstringYesDelivery URL (HTTPS recommended)
methodstringNoHTTP method: POST, PUT, PATCH (default: POST)
descriptionstringNoOptional description
headersobjectNoCustom headers to include
authTypestringNoAuthentication type (see below)
authConfigobjectNoAuthentication configuration
timeoutMsnumberNoRequest timeout in milliseconds (default: 30000, max: 60000)
rateLimitPerMinutenumberNoMax deliveries per minute (null = unlimited)
retryPolicyobjectNoRetry configuration
enabledbooleanNoActive status (default: true)

Authentication Types

TypeDescriptionAuth Config
noneNo authentication
basicHTTP Basic Auth{ "username": "...", "password": "..." }
bearerBearer token{ "token": "..." }
api_keyAPI key in header{ "headerName": "X-API-Key", "key": "..." }
custom_headerCustom auth header{ "headerName": "...", "headerValue": "..." }

Example — Bearer token auth:

json
{
  "authType": "bearer",
  "authConfig": {
    "token": "sk_live_abc123"
  }
}

Example — API key auth:

json
{
  "authType": "api_key",
  "authConfig": {
    "headerName": "X-API-Key",
    "key": "your-api-key"
  }
}

Retry Policy

FieldTypeDefaultDescription
maxRetriesnumber5Max retry attempts
initialDelaynumber1000First retry delay (ms)
maxDelaynumber60000Max delay between retries (ms)
backoffMultipliernumber2Exponential backoff multiplier

Example

bash
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
    }
  }'
javascript
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();
python
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

json
{
  "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

http
GET /api/destinations/{id}

Example

bash
curl https://api.hookbase.app/api/destinations/dst_xyz789 \
  -H "Authorization: Bearer whr_your_api_key"
javascript
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();
python
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

http
PATCH /api/destinations/{id}

Request Body

All fields are optional. Only provided fields are updated.

FieldTypeDescription
namestringDisplay name
urlstringDelivery URL
descriptionstringOptional description
headersobjectCustom headers (replaces existing)
retryPolicyobjectRetry configuration
enabledbooleanActive status

Example

bash
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
    }
  }'
javascript
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();
python
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

http
DELETE /api/destinations/{id}

WARNING

Deleting a destination removes it from all routes. Deliveries are preserved for history.

Example

bash
curl -X DELETE https://api.hookbase.app/api/destinations/dst_xyz789 \
  -H "Authorization: Bearer whr_your_api_key"
javascript
const response = await fetch('https://api.hookbase.app/api/destinations/dst_xyz789', {
  method: 'DELETE',
  headers: {
    'Authorization': 'Bearer whr_your_api_key',
  },
});
// Returns 204 No Content
python
import requests

response = requests.delete(
    'https://api.hookbase.app/api/destinations/dst_xyz789',
    headers={
        'Authorization': 'Bearer whr_your_api_key',
    },
)
# Returns 204 No Content

Response

204 No Content

Test Destination

Send a test webhook to verify the destination is reachable and configured correctly.

http
POST /api/destinations/{id}/test

Request Body (Optional)

FieldTypeDescription
payloadobjectCustom test payload (default: sample webhook event)

Example

bash
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"
    }
  }'
javascript
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();
python
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

json
{
  "success": true,
  "statusCode": 200,
  "latency": 245,
  "responseBody": "{\"received\": true}",
  "message": "Test webhook delivered successfully"
}

Error Response

json
{
  "success": false,
  "statusCode": 503,
  "latency": 30012,
  "error": "Connection timeout after 30000ms",
  "message": "Test webhook delivery failed"
}

Destination Health

Get health metrics for a destination:

http
GET /api/destinations/{id}/health

Response

json
{
  "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

StatusDescription
healthySuccess rate > 95%
degradedSuccess rate 80-95%
failingSuccess rate < 80%
unknownNo recent deliveries

Export Destinations

Export destinations as a JSON file for backup or migration to another organization.

http
GET /api/destinations/export

Query Parameters

ParameterTypeDescription
idsstringComma-separated destination IDs to export (optional, exports all if not specified)
includeSensitivebooleanInclude auth credentials in export (default: false)

Example

bash
# 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"
javascript
// 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();
python
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

json
{
  "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.

http
POST /api/destinations/import

Request Body

FieldTypeRequiredDescription
destinationsarrayYesArray of destination objects to import
conflictStrategystringYesHow to handle slug conflicts: skip, rename, or overwrite
validateOnlybooleanNoIf true, validates without importing (default: false)

Conflict Strategies

StrategyDescription
skipSkip destinations that already exist (by slug)
renameAuto-rename conflicting destinations (e.g., apiapi-1)
overwriteUpdate existing destinations with imported data

Example

bash
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"
  }'
javascript
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();
python
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:

json
{
  "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

json
{
  "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.

http
DELETE /api/destinations/bulk

Request Body

json
{
  "ids": ["dst_abc123", "dst_def456", "dst_ghi789"]
}

Example

bash
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"]}'
javascript
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();
python
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

json
{
  "success": true,
  "deleted": 2
}

WARNING

Deleting destinations removes them from all routes. Delivery history is preserved.

Error Responses

400 Bad Request

Invalid URL:

json
{
  "error": "Bad Request",
  "message": "Invalid URL format",
  "code": "INVALID_URL"
}

404 Not Found

Destination not found:

json
{
  "error": "Not Found",
  "message": "Destination with ID dst_xyz not found",
  "code": "RESOURCE_NOT_FOUND"
}

Released under the MIT License.