Skip to main content

Creating Destinations

This guide shows you how to create Destinations in Hooklistener - the endpoints where your webhooks are forwarded. You'll learn how to configure different destination types, add authentication, and test your setup.

What You'll Learn

  • How to create HTTP/HTTPS destinations
  • How to configure Slack, Discord, and Telegram destinations
  • How to add authentication headers and API keys
  • How to test destinations before going live
  • Common configurations for popular services

Prerequisites

  • A Hooklistener account
  • A Source already created
  • Basic understanding of Destinations
  • (Optional) API credentials for your destination service

Creating an HTTP Destination

HTTP destinations are the most flexible - you can send webhooks to any HTTP/HTTPS endpoint.

Via Dashboard

Step 1: Create or Edit a Bridge

  1. Navigate to Bridges
  2. Either:
    • Create a new Bridge, OR
    • Edit an existing Bridge

Step 2: Add Destination

  1. In the Bridge configuration, click "Add Destination"
  2. Select "HTTP/HTTPS" as the destination type

Step 3: Configure Destination

Name:

Production API Endpoint

Use a descriptive name that indicates purpose and environment.

URL:

https://api.example.com/webhooks

The full URL where webhooks should be sent.

Method:

  • POST (most common)
  • PUT
  • PATCH
  • GET (less common for webhooks)

Step 4: Add Headers (Optional but Recommended)

Click "Add Header" to include authentication or custom headers:

Authentication examples:

Bearer Token:

Header: Authorization
Value: Bearer {{API_TOKEN}}

API Key:

Header: X-API-Key
Value: `{{API_KEY}}`

Basic Auth:

Header: Authorization
Value: Basic {{BASE64_CREDENTIALS}}

Custom headers:

Header: Content-Type
Value: application/json

Header: X-Webhook-Source
Value: hooklistener

Header: X-Event-ID
Value: {{EVENT_ID}}

Using Secrets: Reference secrets with {{SECRET_NAME}} syntax for secure credential storage.

Step 5: Configure Retries

Set the maximum number of retry attempts:

  • Critical endpoints: 15 retries (default)
  • Non-critical: 5-10 retries
  • Best effort: 0-3 retries

Step 6: Save

Click "Save Destination" to add it to your Bridge.

Via API

curl -X POST https://api.hooklistener.com/api/v1/bridges \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "My Bridge",
"source": {
"name": "Webhook Source",
"type": "webhook"
},
"destinations": [
{
"name": "Production API",
"type": "http",
"url": "https://api.example.com/webhooks",
"method": "POST",
"headers": {
"Authorization": "Bearer {{API_TOKEN}}",
"Content-Type": "application/json"
},
"max_retries": 15
}
]
}'

Creating a Slack Destination

Send formatted messages directly to Slack channels.

Step 1: Get Slack Webhook URL

  1. Go to api.slack.com/apps
  2. Create a new app or select existing
  3. Navigate to Incoming Webhooks
  4. Click "Add New Webhook to Workspace"
  5. Select the channel
  6. Copy the webhook URL (looks like https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXX)

Step 2: Store in Secrets

  1. Go to Organization SettingsSecrets
  2. Click "Create Secret"
  3. Name: SLACK_WEBHOOK_URL
  4. Value: Paste the webhook URL
  5. Save

Step 3: Create Slack Destination

Via Dashboard:

  1. Add Destination to your Bridge
  2. Select "Slack" type
  3. Name: Slack Alerts Channel
  4. Webhook URL: {{SLACK_WEBHOOK_URL}}
  5. Save

Via API:

curl -X POST https://api.hooklistener.com/api/v1/bridges/{bridge_id}/destinations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Slack Alerts",
"type": "slack",
"webhook_url": "{{SLACK_WEBHOOK_URL}}"
}'

Step 4: Format Messages (Optional)

Use a Transformation to format Slack messages:

addHandler('transform', async (request) => {
return {
...request,
body: {
text: `New webhook received: ${request.body.event_type}`,
blocks: [
{
type: "section",
text: {
type: "mrkdwn",
text: `*Event:* ${request.body.event_type}\n*Time:* ${new Date().toISOString()}`
}
}
]
}
};
});

Creating a Discord Destination

Post messages to Discord channels via webhooks.

Step 1: Get Discord Webhook URL

  1. Open Discord and go to your server
  2. Right-click the channel → Edit Channel
  3. Go to IntegrationsWebhooks
  4. Click "New Webhook"
  5. Customize name and avatar (optional)
  6. Click "Copy Webhook URL"

Step 2: Store in Secrets

  1. Organization SettingsSecretsCreate Secret
  2. Name: DISCORD_WEBHOOK_URL
  3. Value: Paste webhook URL
  4. Save

Step 3: Create Discord Destination

Via Dashboard:

  1. Add Destination
  2. Type: "Discord"
  3. Name: Discord Notifications
  4. Webhook URL: {{DISCORD_WEBHOOK_URL}}
  5. Save

Via API:

curl -X POST https://api.hooklistener.com/api/v1/bridges/{bridge_id}/destinations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Discord Notifications",
"type": "discord",
"webhook_url": "{{DISCORD_WEBHOOK_URL}}"
}'

Creating a Telegram Destination

Send messages to Telegram chats or channels.

Step 1: Create a Telegram Bot

  1. Open Telegram and search for @BotFather
  2. Send /newbot command
  3. Follow prompts to name your bot
  4. Copy the bot token (looks like 123456789:ABCdefGHIjklMNOpqrsTUVwxyz)

Step 2: Get Chat ID

To send messages to a specific chat/channel, you need the chat ID:

For private chat:

  1. Send a message to your bot
  2. Visit: https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates
  3. Find "chat":{"id":123456789} in the response
  4. Copy the chat ID

For channel:

  1. Add your bot to the channel as administrator
  2. Post a message in the channel
  3. Visit: https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates
  4. Find the channel chat ID (usually negative number like -1001234567890)

Step 3: Store Credentials

Create two secrets:

  1. TELEGRAM_BOT_TOKEN = Your bot token
  2. TELEGRAM_CHAT_ID = Your chat/channel ID

Step 4: Create Telegram Destination

Via Dashboard:

  1. Add Destination
  2. Type: "Telegram"
  3. Name: Telegram Admin Alerts
  4. Bot Token: {{TELEGRAM_BOT_TOKEN}}
  5. Chat ID: {{TELEGRAM_CHAT_ID}}
  6. Save

Via API:

curl -X POST https://api.hooklistener.com/api/v1/bridges/{bridge_id}/destinations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Telegram Alerts",
"type": "telegram",
"bot_token": "{{TELEGRAM_BOT_TOKEN}}",
"chat_id": "{{TELEGRAM_CHAT_ID}}"
}'

Common Destination Patterns

Internal API with Authentication

{
"name": "Internal Service",
"type": "http",
"url": "https://internal-api.company.com/webhooks",
"method": "POST",
"headers": {
"Authorization": "Bearer {{INTERNAL_API_TOKEN}}",
"Content-Type": "application/json",
"X-Source": "hooklistener"
},
"max_retries": 15
}

AWS Lambda Function

{
"name": "Lambda Webhook Processor",
"type": "http",
"url": "https://abc123.execute-api.us-east-1.amazonaws.com/prod/webhook",
"method": "POST",
"headers": {
"X-API-Key": "{{AWS_API_KEY}}",
"Content-Type": "application/json"
},
"max_retries": 10
}

Google Cloud Function

{
"name": "GCP Function",
"type": "http",
"url": "https://us-central1-project-id.cloudfunctions.net/webhook-handler",
"method": "POST",
"headers": {
"Content-Type": "application/json"
},
"max_retries": 10
}

Zapier Webhook

{
"name": "Zapier Automation",
"type": "http",
"url": "https://hooks.zapier.com/hooks/catch/123456/abcdef/",
"method": "POST",
"headers": {
"Content-Type": "application/json"
},
"max_retries": 5
}

Make (Integromat) Webhook

{
"name": "Make Scenario",
"type": "http",
"url": "https://hook.us1.make.com/abcdefghijklmnop",
"method": "POST",
"headers": {
"Content-Type": "application/json"
},
"max_retries": 5
}

Testing Your Destination

Test 1: Endpoint Availability

Before adding to Hooklistener, test the endpoint independently:

curl -X POST https://api.example.com/webhooks \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"test": true,
"message": "Test webhook"
}'

Expected: 2xx response indicating endpoint is reachable and accepts webhooks.

Test 2: Hooklistener Delivery

After adding the destination to your Bridge:

  1. Send a test webhook to your Source
  2. Navigate to EventsOutgoing
  3. Find the delivery attempt
  4. Check:
    • Status code (should be 2xx)
    • Response body
    • Latency
    • Any errors

Test 3: Authentication

Verify authentication is working:

With valid credentials:

  • Should receive 200/201/202 response
  • Destination should process webhook

With invalid credentials (test separately):

  • Should receive 401/403 response
  • Update credentials if needed

Test 4: Transformations (if used)

If you added a transformation:

  1. Check transformation logs in the outgoing event
  2. Verify output payload matches expectations
  3. Confirm destination receives transformed data

Test 5: Filters (if used)

If you added filters:

  1. Send webhooks that should match filters
  2. Verify they're delivered
  3. Send webhooks that shouldn't match
  4. Verify they're skipped (not errors)

Troubleshooting

Destination Not Receiving Webhooks

Check Bridge Status:

  • Ensure Bridge is activated
  • Verify Source is receiving webhooks
  • Check if filters are excluding webhooks

Check Destination Configuration:

  • Verify URL is correct
  • Check HTTP method (POST vs PUT)
  • Ensure headers are properly configured

Check Events:

  • Look at outgoing events for error details
  • Check response codes
  • Review error messages

Authentication Failures

401 Unauthorized:

  • Verify API key/token is correct
  • Check token hasn't expired
  • Ensure secret name is correct ({{API_KEY}} not {{API_TOKEN}})
  • Review header format (Bearer, Basic, custom)

403 Forbidden:

  • Check API key permissions/scopes
  • Verify account has necessary access
  • Review IP allowlists if applicable

Timeouts

Connection Timeout:

  • Verify destination endpoint is reachable
  • Check firewall rules
  • Ensure DNS is resolving correctly
  • Test endpoint outside Hooklistener

Response Timeout:

  • Destination taking too long to respond (>30s)
  • Optimize destination endpoint performance
  • Consider async processing on destination side

Rate Limiting

429 Too Many Requests:

  • Destination has rate limits
  • Review webhook volume
  • Implement throttling if needed
  • Contact destination provider for limit increase

Best Practices

Security

  1. Always use HTTPS

    • Never use HTTP for production destinations
    • Verify SSL certificates are valid
    • Monitor certificate expiration
  2. Use secrets for credentials

    • Store all API keys and tokens in Secrets
    • Reference with {{SECRET_NAME}}
    • Never hardcode sensitive data
  3. Minimize exposed data

    • Use transformations to remove sensitive fields
    • Only send necessary data
    • Consider data privacy regulations

Reliability

  1. Configure appropriate retries

    • Critical: 15 retries
    • Important: 10 retries
    • Best-effort: 3-5 retries
  2. Monitor destination health

    • Watch success rates
    • Set up alerts for failures
    • Track circuit breaker status
  3. Design idempotent endpoints

    • Handle duplicate deliveries gracefully
    • Use unique identifiers
    • Implement deduplication on receiver

Performance

  1. Optimize destination response time

    • Return 200 OK quickly
    • Process webhooks asynchronously if needed
    • Keep response under 5 seconds
  2. Monitor latency

    • Track response times
    • Investigate slow destinations
    • Optimize as needed
  3. Handle high volume

    • Ensure destination can handle webhook rate
    • Implement queuing if necessary
    • Scale destination infrastructure

Organization

  1. Use clear names

    • Include purpose: "Payment Notifications"
    • Include environment: "Production API"
    • Make searchable and identifiable
  2. Document destinations

    • Note purpose and owner
    • Link to destination service docs
    • Track configuration changes
  3. Separate environments

    • Different destinations for dev/staging/prod
    • Use different credentials per environment
    • Test in staging first

Advanced Configuration

Multiple Destinations

Send webhooks to multiple endpoints from one Source:

{
"name": "Multi-Destination Bridge",
"source": {...},
"destinations": [
{
"name": "Primary API",
"type": "http",
"url": "https://api.example.com/webhooks"
},
{
"name": "Backup API",
"type": "http",
"url": "https://backup.example.com/webhooks"
},
{
"name": "Slack Notifications",
"type": "slack",
"webhook_url": "{{SLACK_WEBHOOK_URL}}"
}
]
}

Conditional Routing with Filters

Send to different destinations based on webhook content:

{
"destinations": [
{
"name": "High Priority Queue",
"url": "https://api.example.com/high-priority",
"filters": [
{"body.priority": {"$eq": "high"}}
]
},
{
"name": "Normal Queue",
"url": "https://api.example.com/normal"
}
]
}

Transformation per Destination

Apply different transformations to different destinations:

{
"destinations": [
{
"name": "Internal API",
"url": "https://internal.example.com/webhooks",
"transformation_id": "internal-format"
},
{
"name": "Partner API",
"url": "https://partner.example.com/webhooks",
"transformation_id": "partner-format"
}
]
}

Next Steps

Now that you've created destinations, you can:

  1. Build a Complete Bridge connecting Sources to Destinations
  2. Set up Filters for conditional routing
  3. Use Transformations to customize payloads
  4. Monitor Events to track webhook deliveries
  5. Manage Issues when problems occur

Your destinations are ready to receive webhooks! Continue to the Bridge building guide to connect everything together.