Hookdeck Outpost is Hookdeck’s managed Outpost service: a control plane and delivery layer for event destinations (webhooks, queues, and more) scoped per tenant—each tenant is one of your platform’s customers.

This quickstart uses the REST API with curl. Topics are assumed to be configured already in the Hookdeck dashboard; use a topic name that exists there when you publish.

Prerequisites

  • A Hookdeck account with an Outpost project
  • An API key (Outpost API key) from your project: Settings → Secrets
  • Topics already configured in the dashboard (for example user.created, order.completed)
  • API base URL: https://api.outpost.hookdeck.com/2025-07-01

Set up credentials

In the Hookdeck Dashboard, open your Outpost project, go to Settings → Secrets, and create or copy an API key. That value is the same Outpost API key you use for the REST API and the SDKs.

Store the API key and base URL in your shell (or in a .env file you source):

export OUTPOST_API_BASE_URL="https://api.outpost.hookdeck.com/2025-07-01"
export OUTPOST_API_KEY="your_api_key"

Use them in the requests below as $OUTPOST_API_BASE_URL and $OUTPOST_API_KEY.

Create a tenant

Each tenant maps to one of your customers. Pick a stable ID from your own system (for example a team or account ID).

TENANT_ID="customer_acme_001"

curl --request PUT "$OUTPOST_API_BASE_URL/tenants/$TENANT_ID" \
  --header "Authorization: Bearer $OUTPOST_API_KEY"

On success, the response status is 200 if this tenant ID already existed, or 201 if Outpost just created it.

Create a webhook destination

Subscribe the tenant to one or more topics you configured in the dashboard. Set config.url to an HTTPS endpoint you control.

If you do not have your own endpoint yet, open Hookdeck Console, create a Source, and paste that Source URL as the webhook URL below (or any HTTPS URL you own). Replace REPLACE_WITH_YOUR_WEBHOOK_URL accordingly.

Replace user.created with a topic that exists in your project if needed.

curl --request POST "$OUTPOST_API_BASE_URL/tenants/$TENANT_ID/destinations" \
  --header "Authorization: Bearer $OUTPOST_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "type": "webhook",
    "topics": ["user.created"],
    "config": {
      "url": "REPLACE_WITH_YOUR_WEBHOOK_URL"
    }
  }'

On success, expect HTTP 2xx (often 201 when this destination is created for the tenant).

To receive every configured topic on this destination, set "topics": ["*"] instead.

Publish a test event

Use the same tenant ID and a topic that matches both your dashboard configuration and the destination’s topics.

curl --request POST "$OUTPOST_API_BASE_URL/publish" \
  --header "Authorization: Bearer $OUTPOST_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "tenant_id": "'"$TENANT_ID"'",
    "topic": "user.created",
    "eligible_for_retry": true,
    "metadata": {
      "source": "quickstart"
    },
    "data": {
      "user_id": "user_123"
    }
  }'

On success, the response status is 202 — the event was accepted for delivery.

HTTP status codes (quick reference)

StepRequestSuccess status
Create tenantPUT …/tenants/{ID}200 or 201
Create destinationPOST …/tenants/{ID}/destinations2xx
PublishPOST …/publish202

Verify delivery

After publish, parse the event id from the 202 response body (for example with jq).

  • In Hookdeck Console, open the Source or connection you used for the webhook URL and confirm the request arrived with the expected payload.
  • In the Hookdeck Dashboard, open your Outpost project and review logs to confirm the event was processed and delivered.

Calling GET …/events with tenant_id (and optional topic) immediately after publish may return an empty list for a short time while Outpost indexes the event. That is normal eventual consistency, not a failed publish — you do not need the events API to finish this walkthrough. If you are building an activity or audit screen in your product, poll with retries instead of a single request; see Publish acceptance vs observability.

Optional: poll the events API

Uses TENANT_ID, OUTPOST_API_BASE_URL, and OUTPOST_API_KEY from the publish section above. Use this when your application must confirm an event appears in the events API (for example while building an activity feed):

EVENT_ID="<event id from publish response>"

for attempt in $(seq 1 8); do
  if curl -s -G "$OUTPOST_API_BASE_URL/events" \
    --data-urlencode "tenant_id=$TENANT_ID" \
    --data-urlencode "topic=user.created" \
    -H "Authorization: Bearer $OUTPOST_API_KEY" \
    | grep -q "$EVENT_ID"; then
    echo "Verified in events list: $EVENT_ID"
    break
  fi
  sleep 1
done

For this quickstart, Console and dashboard logs are sufficient.

Next steps