HookDeploy has two destination layers:
- Saved destinations (library) — reusable entries at the organization level (
/v1/destinations) - Forward destinations — per-endpoint targets used at forward time (
/v1/endpoints/:id/destinations)
Creating or attaching saved destinations requires an API key whose creator has super_admin or admin role.
Create saved destination
POST /v1/destinations
curl -s -X POST \
"https://api.hookdeploy.dev/v1/destinations" \
-H "Authorization: Bearer hd_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Production Webhook",
"url": "https://myserver.com/webhooks",
"endpoint_id": "550e8400-e29b-41d4-a716-446655440000"
}'
Body fields:
| Field | Required | Description |
|---|---|---|
name | yes | Display name |
url | yes | Target URL (HTTPS for standard destinations) |
endpoint_id | no | If set, also creates a forward destination on that endpoint |
visibility | no | private, org, or restricted |
is_reusable | no | Boolean (defaults to reusable library entry) |
tunnel | no | Optional tunnel object (see below). Requires Team or Enterprise (plan_limit otherwise). |
Tunnel object (Team+ only):
| Field | When |
|---|---|
type | tailscale or cloudflare |
| Tailscale fields | tailscale_client_id, tailscale_client_secret, tailscale_tailnet (optional relay_region) |
| Cloudflare fields | cf_tunnel_url |
Success (201):
{
"data": {
"id": "990e8400-e29b-41d4-a716-446655440004",
"name": "Production Webhook",
"url": "https://myserver.com/webhooks",
"visibility": "private",
"is_reusable": true,
"tunnel_id": null,
"tunnel_status": null,
"created_at": "2026-05-24T12:00:00Z",
"forward_destination_id": "aa0e8400-e29b-41d4-a716-446655440005"
}
}
If endpoint_id is provided and the attach step fails, the saved destination is still created. The response remains HTTP 201 with data plus an attachment_error object (code + message) at the top level — not inside data. Retry attach from the dashboard or a later API call as needed.
List saved destinations
GET /v1/destinations
curl -s "https://api.hookdeploy.dev/v1/destinations?limit=25" \
-H "Authorization: Bearer hd_live_YOUR_KEY"
Query parameters: limit (default 25, max 100), before (cursor).
Response:
{
"data": {
"data": [
{
"id": "990e8400-e29b-41d4-a716-446655440004",
"name": "Production Webhook",
"url": "https://myserver.com/webhooks",
"visibility": "private",
"is_reusable": true,
"tunnel_id": null,
"endpoint_count": 2,
"created_at": "2026-05-24T12:00:00Z"
}
],
"meta": {
"count": 1,
"has_more": false,
"next_cursor": null
}
}
}
Get saved destination
GET /v1/destinations/:id
Includes a nested endpoints array of linked forward destinations.
curl -s "https://api.hookdeploy.dev/v1/destinations/DESTINATION_ID" \
-H "Authorization: Bearer hd_live_YOUR_KEY"
{
"data": {
"id": "990e8400-e29b-41d4-a716-446655440004",
"name": "Production Webhook",
"url": "https://myserver.com/webhooks",
"visibility": "private",
"is_reusable": true,
"tunnel_id": null,
"tunnel_status": null,
"created_at": "2026-05-24T12:00:00Z",
"endpoints": [
{
"endpoint_id": "550e8400-e29b-41d4-a716-446655440000",
"endpoint_name": "Stripe production",
"forward_destination_id": "aa0e8400-e29b-41d4-a716-446655440005"
}
]
}
}
List forward destinations on an endpoint
GET /v1/endpoints/:id/destinations
Returns all forward destinations for an endpoint, ordered by sort_order.
curl -s "https://api.hookdeploy.dev/v1/endpoints/ENDPOINT_ID/destinations" \
-H "Authorization: Bearer hd_live_YOUR_KEY"
Response:
{
"data": {
"data": [
{
"id": "990e8400-e29b-41d4-a716-446655440004",
"name": "Production Server",
"url": "https://myserver.com/webhooks",
"enabled": true,
"tunnel_id": null,
"method_override": null,
"created_at": "2026-05-24T12:00:00Z"
},
{
"id": "aa0e8400-e29b-41d4-a716-446655440005",
"name": "Internal Service",
"url": "10.0.0.5:8080",
"enabled": true,
"tunnel_id": "bb0e8400-e29b-41d4-a716-446655440006",
"method_override": null,
"created_at": "2026-05-24T12:05:00Z"
}
]
}
}
Forward destination fields:
| Field | Description |
|---|---|
id | UUID of the forward destination |
name | Display name |
url | Target URL for standard destinations, or private IP:port for tunnel destinations |
enabled | Whether this destination is active. Disabled destinations are skipped during forwarding. |
tunnel_id | UUID of the associated WireGuard or Tailscale tunnel, or null for standard HTTPS destinations |
method_override | HTTP method to use when forwarding, or null to mirror the original request method |
created_at | ISO 8601 creation timestamp |
Forward destinations are also managed in the dashboard under Endpoints → [endpoint name] → Destinations. Saved destinations live under Destinations.
Error responses
| HTTP | Code | Cause |
|---|---|---|
| 400 | bad_request | Missing name/url, invalid tunnel payload, or other validation errors |
| 401 | unauthorized | Invalid API key |
| 403 | forbidden | API key lacks permission to manage destinations |
| 403 | plan_limit | Tunnel create without Team/Enterprise, or other plan caps |
| 404 | not_found | Destination or endpoint not found |
Next steps
- Requests API — Retrieve captured requests and their forwarding results
- Endpoints API — Manage endpoint URLs
- Incidents — Correlated forward-failure triage