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/",
    "source": null
  },
  "timestamp": "2026-09-12T10:00:00+00:00"
}

referrer is the page the viewer came from, or null when the browser sent none (most email and chat apps). source is the share tag on the link the viewer opened (?ref=linkedin or ?utm_source=linkedin), or null.

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