Back to docs

Webhooks

Set up an endpoint

Create a webhook endpoint in the dashboard or via the API, send a test event, and go live.

Setting up a webhook

Follow these steps to go from zero to a verified, production-ready endpoint.

1. Prepare your receiver URL

Your server needs a public HTTPS URL that accepts POST requests with a JSON body. Callback URLs must use HTTPS.

Your handler should:

  • Read the raw request body as a string or buffer (do not parse JSON before verifying the signature).
  • Read the Styrar-Signature, Styrar-Event-Id, and Styrar-Event-Type headers.
  • Verify the signature (see the Verifying signatures section below).
  • Return 2xx quickly after the event is accepted. Queue heavy work asynchronously.

Example path: https://your-app.com/webhooks/styrar

Styrar cannot deliver to private or loopback addresses such as localhost.

2. Get API access (for programmatic setup)

API keys require a Team or Agency workspace. Create keys under Settings → API keys on an eligible plan.

If you create endpoints via the API instead of the dashboard, you need a Bearer token with:

ScopeAccess
webhooks:readList endpoints, deliveries, and event types
webhooks:writeCreate, update, delete, test, rotate secret, retry deliveries

Create an API key in Settings → API keys with webhooks:read and webhooks:write, or use an OAuth access token from a connected app with the same scopes.

For company workspaces, pass companyId on list and create requests.

3. Create an endpoint in the dashboard

  1. Sign in and open Settings → Webhooks (/settings/webhooks).
  2. Under Endpoints, enter your Endpoint URL (the public HTTPS callback).
  3. Optionally add a Description (for example "Production CRM sync").
  4. Select the Events you want (at least one is required). Common choices:
    • link.clicked for click tracking
    • link.created / link.updated / link.deleted for link lifecycle
    • post.published and campaign.created for funnel events
  5. Click Add endpoint.

After creation, Styrar shows your signing secret (whsec_live_… or whsec_test_…). Copy it immediately and store it in your secrets manager. It is shown only once. If you lose it, use Rotate secret on the endpoint and update your server.

4. Create an endpoint via the API

RequestPOST
Authorization: Bearer sty_live_your_api_key
Content-Type: application/json

{
  "companyId": "cmxyz_company",
  "url": "https://your-app.com/webhooks/styrar",
  "description": "Production CRM sync",
  "eventTypes": [
    "link.clicked",
    "link.created"
  ]
}
Response201 Created
{
  "id": "wh_ep_abc123",
  "url": "https://your-app.com/webhooks/styrar",
  "description": "Production CRM sync",
  "enabled": true,
  "eventTypes": [
    "link.clicked",
    "link.created"
  ],
  "secretPrefix": "whsec_l",
  "companyId": "cmxyz_company",
  "userId": null,
  "disabledAt": null,
  "createdAt": "2026-06-22T12:00:00.000Z",
  "updatedAt": "2026-06-22T12:00:00.000Z",
  "secret": "whsec_live_abc123onlyShownOnce"
}

Store secret immediately. It is not returned on later GET requests. An empty eventTypes array subscribes to all event types; the dashboard requires at least one explicit event.

5. Send a test event

Confirm your server is reachable before relying on live traffic.

Dashboard: On the endpoint row, click Send test. Styrar delivers a webhook.test event. You should see a success toast with the HTTP status code.

API:

RequestPOST
Authorization: Bearer sty_live_your_api_key
Response200 OK
{
  "ok": true,
  "statusCode": 200
}

When the test succeeds, your server should have received a webhook.test event (see Receive an event on your server below).

Check Recent deliveries in the dashboard (or GET /v1/webhooks/deliveries) if the test fails. Common issues:

ProblemWhat to check
Connection refused / timeoutURL is public HTTPS, firewall allows Styrar, tunnel is running
HTTP 4xx/5xx from your appHandler returns 2xx after verify; log raw body and headers
Signature verification failsUse raw body, correct secret, constant-time compare
Endpoint disabledRe-enable in dashboard or fix the issue that caused HTTP 410

6. Verify and process deliveries

On every POST to your URL:

  1. Parse Styrar-Signature into timestamp t and digest v1.
  2. Reject if t is older than your tolerance (5 minutes recommended).
  3. Compute HMAC-SHA256 of "{t}.{raw_body}" with your endpoint secret.
  4. Compare with v1 using a constant-time check.
  5. Parse JSON only after verification succeeds.
  6. Deduplicate on Styrar-Event-Id (at-least-once delivery).

See the Verifying signatures section below for a Node.js example.

7. Go live

  • Keep the endpoint Enabled in the dashboard.
  • Subscribe only to events you need (reduces noise and cost).
  • Monitor Recent deliveries for failures and use Retry when needed.
  • Rotate the secret if it may have leaked (Rotate secret in dashboard or POST …/rotate-secret).

Quick start

  1. Get API access with webhooks:read and webhooks:write scopes (API key or OAuth).
  2. Expose a public HTTPS receiver and create an endpoint in Settings → Webhooks or via POST /v1/webhooks/endpoints.
  3. Copy the signing secret when shown and store it securely.
  4. Send a test event and confirm your server verifies Styrar-Signature and returns 2xx.
  5. Process live events with deduplication on Styrar-Event-Id.

Authentication

Webhook management requires a Bearer token with the scopes listed in step 2 above. API keys with matching scopes work the same way as OAuth access tokens.

Join the beta waitlist

By signing up you agree to receive marketing email. See our Privacy Policy.