Destinations API

Destinations are delivery targets for webhooks. Hookbase supports HTTP endpoints and warehouse destinations (S3, R2, GCS, Azure Blob).

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}/testTest destination
GET/api/destinations/exportExport destinations as JSON
POST/api/destinations/importImport destinations from JSON
DELETE/api/destinations/bulkBulk delete destinations

Destination Object

HTTP Destination

{
  "id": "dst_xyz789",
  "name": "Production API",
  "type": "http",
  "url": "https://api.yourapp.com/webhooks",
  "method": "POST",
  "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"
}

Warehouse Destination (S3 example)

{
  "id": "dst_wh_abc123",
  "name": "Analytics Data Lake",
  "type": "s3",
  "url": "",
  "config": {
    "bucket": "my-data-lake",
    "region": "us-east-1",
    "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
    "secretAccessKey": "••••EKEY"
  },
  "fieldMapping": [
    { "source": "$.payload.type", "target": "event_type", "type": "string" },
    { "source": "$.payload.data.amount", "target": "amount", "type": "number" }
  ],
  "enabled": true,
  "createdAt": "2026-02-21T10:30:00Z",
  "updatedAt": "2026-02-21T10:30:00Z"
}

Info

Credential Redaction

Sensitive fields (secretAccessKey, serviceAccountKey, accountKey) are returned as •••• followed by the last 4 characters. Credentials are encrypted at rest using AES-256-GCM.

List Destinations

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

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

Response

{
  "data": [
    {
      "id": "dst_xyz789",
      "name": "Production API",
      "type": "http",
      "url": "https://api.yourapp.com/webhooks",
      "enabled": true,
      "successRate": 98.5,
      "avgLatency": 245,
      "deliveriesCount": 5230
    },
    {
      "id": "dst_wh_abc123",
      "name": "Analytics Data Lake",
      "type": "s3",
      "url": "",
      "config": {
        "bucket": "my-data-lake",
        "region": "us-east-1",
        "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
        "secretAccessKey": "••••EKEY"
      },
      "enabled": true
    }
  ],
  "pagination": {
    "total": 5,
    "page": 1,
    "pageSize": 20
  }
}

Create Destination

POST /api/destinations

Common Fields

FieldTypeRequiredDescription
namestringYesDisplay name
typestringNohttp (default), s3, r2, gcs, or azure_blob
enabledbooleanNoActive status (default: true)

HTTP-Specific Fields

FieldTypeRequiredDescription
urlstringYesDelivery URL (HTTPS recommended)
methodstringNoHTTP method: POST, PUT, PATCH (default: POST)
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

Warehouse-Specific Fields

FieldTypeRequiredDescription
configobjectYesProvider-specific configuration (see below)
fieldMappingarrayNoField mapping rules for structured output

Tip

Plan Requirement

Warehouse destinations (s3, r2, gcs, azure_blob) require a Pro or Business plan.

Authentication Types (HTTP)

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": "..." }

Warehouse Config: S3

{
  "bucket": "my-data-lake",
  "region": "us-east-1",
  "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
  "secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
  "prefix": "webhooks/",
  "fileFormat": "jsonl",
  "partitionBy": "date"
}
FieldTypeRequiredDescription
bucketstringYesS3 bucket name (3-63 chars)
regionstringYesAWS region
accessKeyIdstringYesAWS access key ID
secretAccessKeystringYesAWS secret access key
prefixstringNoPath prefix
fileFormatstringNojsonl (default) or json
partitionBystringNodate (default), hour, or source

Warehouse Config: R2

{
  "bucket": "my-webhook-archive",
  "endpoint": "https://ACCOUNT_ID.r2.cloudflarestorage.com",
  "accessKeyId": "your-r2-access-key-id",
  "secretAccessKey": "your-r2-secret-access-key",
  "prefix": "webhooks/",
  "fileFormat": "jsonl",
  "partitionBy": "date"
}
FieldTypeRequiredDescription
bucketstringYesR2 bucket name (3-63 chars)
endpointstringYesR2 S3-compatible API endpoint (https://{account_id}.r2.cloudflarestorage.com)
accessKeyIdstringYesR2 API token access key ID
secretAccessKeystringYesR2 API token secret access key (encrypted at rest)
prefixstringNoPath prefix
fileFormatstringNojsonl (default) or json
partitionBystringNodate (default), hour, or source

Warehouse Config: GCS

{
  "bucket": "my-gcs-bucket",
  "projectId": "my-gcp-project",
  "serviceAccountKey": "{...}",
  "prefix": "webhooks/",
  "fileFormat": "jsonl",
  "partitionBy": "date"
}
FieldTypeRequiredDescription
bucketstringYesGCS bucket name (3-63 chars)
projectIdstringYesGoogle Cloud project ID
serviceAccountKeystringYesService account key JSON
prefixstringNoPath prefix
fileFormatstringNojsonl (default) or json
partitionBystringNodate (default), hour, or source

Warehouse Config: Azure Blob

{
  "accountName": "myaccount",
  "accountKey": "base64-encoded-key",
  "containerName": "webhook-data",
  "prefix": "webhooks/",
  "fileFormat": "jsonl",
  "partitionBy": "date"
}
FieldTypeRequiredDescription
accountNamestringYesStorage account name (3-24 chars)
accountKeystringYesBase64-encoded account key
containerNamestringYesBlob container name (3-63 chars)
prefixstringNoPath prefix
fileFormatstringNojsonl (default) or json
partitionBystringNodate (default), hour, or source

Field Mapping

FieldTypeRequiredDescription
sourcestringYesJSONPath expression (e.g., $.payload.amount)
targetstringYesOutput column name
typestringYesstring, number, boolean, timestamp, or json
defaultstringNoDefault value if source path is missing

Maximum 50 field mappings per destination.

Example: Create HTTP Destination

curl
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",
    "type": "http",
    "url": "https://api.yourapp.com/webhooks/handler",
    "headers": {
      "Authorization": "Bearer sk_live_xxx"
    },
    "retryPolicy": {
      "maxRetries": 5,
      "initialDelay": 1000,
      "maxDelay": 300000
    }
  }'

Example: Create S3 Warehouse Destination

curl
curl -X POST https://api.hookbase.app/api/destinations \
  -H "Authorization: Bearer whr_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Analytics Data Lake",
    "type": "s3",
    "config": {
      "bucket": "my-data-lake",
      "region": "us-east-1",
      "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
      "secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
      "prefix": "webhooks/stripe/",
      "fileFormat": "jsonl",
      "partitionBy": "date"
    },
    "fieldMapping": [
      { "source": "$.payload.type", "target": "event_type", "type": "string" },
      { "source": "$.payload.data.amount", "target": "amount", "type": "number" },
      { "source": "$.payload.created", "target": "created_at", "type": "timestamp" }
    ]
  }'

Response

{
  "id": "dst_wh_new456",
  "name": "Analytics Data Lake",
  "type": "s3",
  "config": {
    "bucket": "my-data-lake",
    "region": "us-east-1",
    "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
    "secretAccessKey": "••••EKEY"
  },
  "fieldMapping": [
    { "source": "$.payload.type", "target": "event_type", "type": "string" },
    { "source": "$.payload.data.amount", "target": "amount", "type": "number" },
    { "source": "$.payload.created", "target": "created_at", "type": "timestamp" }
  ],
  "enabled": true,
  "createdAt": "2026-02-21T10:30:00Z",
  "updatedAt": "2026-02-21T10:30:00Z"
}

Get Destination

GET /api/destinations/{id}

Example

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

Response

Returns the full destination object. Sensitive credential fields are redacted.

Update Destination

PATCH /api/destinations/{id}

Request Body

All fields are optional. Only provided fields are updated.

FieldTypeDescription
namestringDisplay name
urlstringDelivery URL (HTTP destinations)
headersobjectCustom headers (replaces existing)
retryPolicyobjectRetry configuration
configobjectWarehouse configuration
fieldMappingarrayField mapping rules
enabledbooleanActive status

Info

Updating Credentials

When updating a warehouse destination, redacted credential values (e.g., ••••EKEY) are automatically preserved. Only provide a new value if you are rotating keys.

Example

curl
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
    }
  }'

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
curl -X DELETE https://api.hookbase.app/api/destinations/dst_xyz789 \
  -H "Authorization: Bearer whr_your_api_key"

Response

204 No Content

Test Destination

Send a test webhook (HTTP) or upload a test file (warehouse) to verify the destination is configured correctly.

POST /api/destinations/{id}/test

Request Body (Optional)

FieldTypeDescription
payloadobjectCustom test payload (default: sample webhook event)

Example

curl
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"
    }
  }'

HTTP Destination Response

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

Warehouse Destination Response

{
  "success": true,
  "result": {
    "key": "hookbase/2026-02-21/test-1740150000000.jsonl",
    "size": 142,
    "count": 1
  },
  "message": "Test file uploaded 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}/health

Response

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

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

curl
# 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"

Response

{
  "version": "1.0",
  "exportedAt": "2024-01-15T10:30:00Z",
  "organizationSlug": "myorg",
  "destinations": [
    {
      "name": "Production API",
      "slug": "production-api",
      "type": "http",
      "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/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., api -> api-1)
overwriteUpdate existing destinations with imported data

Example

curl
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",
        "type": "http",
        "url": "https://staging.yourapp.com/webhooks",
        "method": "POST",
        "timeoutMs": 30000,
        "isActive": true
      }
    ],
    "conflictStrategy": "skip"
  }'

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/bulk

Request Body

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

Example

curl
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"]}'

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"
}

Invalid warehouse config:

{
  "error": "Bad Request",
  "message": "Invalid warehouse configuration: bucket must be 3-63 characters"
}

403 Forbidden

Plan restriction:

{
  "error": "Forbidden",
  "message": "Warehouse destinations require Pro or Business plan."
}

404 Not Found

Destination not found:

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