Webhooks

slim.to can POST to a URL of yours whenever something happens on a link: someone opens it, converts on it, or submits a form on a hosted page. Point a webhook at Slack, Zapier, Make, n8n, or any HTTPS endpoint you run.

Webhooks are a Pro / Team feature. On Free, creating one returns a 403 with "upgrade_required": true.

Set one up

Dashboard: open Dashboard → Integrations, paste the URL, optionally give it a label, and click Add Webhook.

API (session or API key auth):

curl -s -X POST https://slim.to/api/v1/webhooks \
  -H "X-API-Key: $SLIMTO_API_KEY" -H "Content-Type: application/json" \
  -d '{"url": "https://hooks.zapier.com/hooks/catch/…", "label": "Zapier flow"}'

Body fields:

Field
url required Any https:// endpoint. Slack incoming-webhook URLs are auto-detected
label optional A name for the dashboard list
link_id optional Fire only for this link. Omit to fire for every link you own

Events

Every event is a JSON POST with the shape below. There is no signature header today; if you need to verify the sender, use a URL with an unguessable path (as Slack, Zapier and Make already do).

link.opened

Fires once per new viewer session, for both redirect links and hosted files.

{
  "event": "link.opened",
  "link": {
    "id": "52cab9d5-…",
    "slug": "abc123",
    "title": "My doc",
    "short_url": "https://slim.to/abc123"
  },
  "viewer": {
    "country": "US",
    "city": "New York",
    "device": "desktop",
    "browser": "Chrome",
    "os": "macOS",
    "referrer": "https://mail.google.com/"
  },
  "timestamp": "2026-09-12T10:00:00+00:00"
}

conversion

Fires when the viewer page reports a conversion event (a CTA click, a scroll-depth milestone, or a custom conversion). viewer carries the conversion details instead of the device summary:

{
  "event": "conversion",
  "link": { "id": "…", "slug": "abc123", "title": "Pricing", "short_url": "https://slim.to/abc123" },
  "viewer": {
    "type": "cta_click",
    "value": "Book a demo",
    "variant_id": "v2",
    "session_id": "…",
    "country": "US",
    "device": "mobile"
  },
  "timestamp": "…"
}

variant_id is set when the link is running an A/B split test.

form.submitted

Fires when someone submits the form on a hosted page:

{
  "event": "form.submitted",
  "link": { "id": "…", "slug": "abc123", "title": "Waitlist", "short_url": "https://slim.to/abc123" },
  "viewer": {
    "id": "…",
    "email": "ada@example.com",
    "name": "Ada",
    "data": { "email": "ada@example.com", "name": "Ada", "company": "Analytical Engines" },
    "created_at": "…"
  },
  "timestamp": "…"
}

Slack

Paste a Slack Incoming Webhook URL (https://hooks.slack.com/…) and slim.to sends a formatted Block Kit message instead of raw JSON — link title, location, device and browser for opens; name and email for form submissions; type, value and variant for conversions.

Delivery

Manage

Method Path
GET /api/v1/webhooks List yours — {"webhooks": [...]}
POST /api/v1/webhooks Create (body above), returns the webhook
PATCH /api/v1/webhooks/<id> {"is_active": false} to pause, {"label": "…"} to rename
DELETE /api/v1/webhooks/<id> Remove

Each webhook object: id, link_id (null for global), url, label, is_active, created_at.

Other ways to get notified