Event types
Payload reference for link, campaign, post, and test events.
Call GET /v1/webhooks/event-types for the live catalog in your environment. Subscribe to specific types per endpoint, or pass an empty eventTypes array to receive all events.
webhook.test is only sent when you click Send test; it is not emitted by normal workspace activity.
Event envelope
Every delivery uses the same top-level shape. Event-specific fields live under data.object:
| Field | Type | Description |
|---|---|---|
id | string | Unique event id. Same value as the Styrar-Event-Id header. |
type | string | Event name (for example link.clicked). |
api_version | string | Payload schema version (2026-06-22). |
created_at | string | ISO 8601 timestamp when the event was created. |
workspace.type | string | company or personal. |
workspace.company_id | string | null | Company id when workspace.type is company. |
data.object | object | Event payload (documented per event below). |
Full delivery example (envelope + link.created payload):
{
"id": "evt_outbox_abc123",
"type": "link.created",
"api_version": "2026-06-22",
"created_at": "2026-06-22T12:00:00.000Z",
"workspace": {
"type": "company",
"company_id": "cmxyz_company"
},
"data": {
"object": {
"id": "clink_abc123",
"short_code": "summer",
"title": "Summer sale",
"original_url": "https://example.com/sale",
"is_active": true,
"company_id": "cmxyz_company",
"campaign_id": "ccamp_abc",
"link_group_id": null,
"created_at": "2026-06-22T12:00:00.000Z"
}
}
}
For personal workspaces, workspace.type is personal and workspace.company_id is null. The payload may include company_id: null on link objects.
Event summary
| Event | When it fires | Typical volume |
|---|---|---|
link.created | A short link is created (POST /v1/links, bulk create, or bulk upsert) | Low |
link.updated | A short link is updated (PATCH /v1/links/:id, bulk update, or bulk upsert) | Low |
link.deleted | A short link is soft-deleted (DELETE /v1/links/:id or bulk delete) | Low |
link.clicked | A tracked click is recorded (async, after redirect via click worker) | High |
link.experiment.completed | An A/B link experiment is completed and a winner is selected | Low |
campaign.created | A campaign is created (POST /v1/campaigns) | Low |
post.published | A social post publishes successfully to all platform targets | Low |
webhook.test | You run Send test on an endpoint | On demand |
link.created
Fires when a new short link is saved in your workspace.
Common uses: Sync new links to a CRM, trigger welcome automations, or index links in an external search store.
data.object fields:
| Field | Type | Description |
|---|---|---|
id | string | Link id |
short_code | string | Public short code |
title | string | null | Link title |
original_url | string | null | Destination URL |
is_active | boolean | Whether the link is active |
company_id | string | null | Owning company (company workspace) |
campaign_id | string | null | Linked campaign, if any |
link_group_id | string | null | Folder/group id, if any |
created_at | string | ISO 8601 creation time |
{
"id": "clink_abc123",
"short_code": "summer",
"title": "Summer sale",
"original_url": "https://example.com/sale",
"is_active": true,
"company_id": "cmxyz_company",
"campaign_id": "ccamp_abc",
"link_group_id": null,
"created_at": "2026-06-22T12:00:00.000Z"
}
link.updated
Fires when an existing short link is modified (destination, title, tags, folder, UTM settings, etc.).
Common uses: Keep external systems in sync when a link changes without recreating it.
data.object fields: Same as link.created (see above).
{
"id": "clink_abc123",
"short_code": "summer",
"title": "Summer sale (updated)",
"original_url": "https://example.com/sale-v2",
"is_active": true,
"company_id": "cmxyz_company",
"campaign_id": "ccamp_abc",
"link_group_id": "lgrp_promos",
"created_at": "2026-06-22T12:00:00.000Z"
}
link.deleted
Fires when a short link is soft-deleted (isActive set to false). The link stops resolving publicly but remains in your workspace history.
Common uses: Remove links from external catalogs or pause automations tied to that short code.
data.object fields: Same shape as link.created, with is_active always false.
| Field | Type | Description |
|---|---|---|
id | string | Link id |
short_code | string | Short code at time of deletion |
title | string | null | Link title |
original_url | string | null | Destination URL |
is_active | boolean | false after soft delete |
company_id | string | null | Owning company |
campaign_id | string | null | Linked campaign, if any |
link_group_id | string | null | Folder/group id, if any |
created_at | string | Original creation time |
{
"id": "clink_abc123",
"short_code": "summer",
"title": "Summer sale",
"original_url": "https://example.com/sale",
"is_active": false,
"company_id": "cmxyz_company",
"campaign_id": "ccamp_abc",
"link_group_id": null,
"created_at": "2026-06-22T12:00:00.000Z"
}
link.clicked
Fires after a visitor click is persisted. Delivered asynchronously (not on the redirect path), so expect slight delay under load.
Common uses: Real-time click analytics, geo-based routing in your stack, CRM activity feeds, or warehouse ingestion.
Privacy: Payloads include geo and device dimensions, not raw IP addresses.
data.object fields:
| Field | Type | Description |
|---|---|---|
id | string | Link id |
link_id | string | Same as id |
short_code | string | Short code that was clicked |
title | string | null | Link title |
country | string | null | ISO country code (geo lookup) |
city | string | null | City from geo lookup |
device | string | null | Device class (for example mobile, desktop) |
browser | string | null | Browser name |
os | string | null | Operating system |
platform | string | null | Platform hint from user agent parsing |
referrer | string | null | Referrer URL when available |
routing_rule_id | string | null | Matched geo/device routing rule, if any |
experiment_variant_id | string | null | A/B variant id when click went through an experiment |
clicked_at | string | ISO 8601 click time |
{
"id": "clink_abc123",
"link_id": "clink_abc123",
"short_code": "summer",
"title": "Summer sale",
"country": "NL",
"city": "Amsterdam",
"device": "mobile",
"browser": "Chrome",
"os": "iOS",
"platform": null,
"referrer": "https://instagram.com/",
"routing_rule_id": null,
"experiment_variant_id": null,
"clicked_at": "2026-06-22T12:00:00.000Z"
}
link.experiment.completed
Fires when an A/B test on a short link is marked complete and a winning variant is selected.
Common uses: Log experiment outcomes, update dashboards, or trigger follow-up campaigns based on the winner.
data.object fields:
| Field | Type | Description |
|---|---|---|
id | string | Experiment id |
link_id | string | Parent link id |
short_code | string | null | Parent link short code |
status | string | completed |
assignment_mode | string | null | How traffic was split (for example weighted) |
winning_variant_id | string | null | Id of the winning variant |
ended_at | string | null | ISO 8601 completion time |
variants | array | Per-variant results (see below) |
Each item in variants:
| Field | Type | Description |
|---|---|---|
id | string | Variant id |
label | string | Human-readable label |
weight | number | Traffic weight used in the test |
destination_url | string | URL this variant sent traffic to |
clicks | number | Total clicks recorded for this variant |
{
"id": "lexp_abc123",
"link_id": "clink_abc123",
"short_code": "summer",
"status": "completed",
"assignment_mode": "weighted",
"winning_variant_id": "lvar_b",
"ended_at": "2026-06-22T14:00:00.000Z",
"variants": [
{
"id": "lvar_a",
"label": "Control",
"weight": 50,
"destination_url": "https://example.com/a",
"clicks": 120
},
{
"id": "lvar_b",
"label": "Variant B",
"weight": 50,
"destination_url": "https://example.com/b",
"clicks": 184
}
]
}
campaign.created
Fires when a new campaign is created in your workspace.
Common uses: Provision campaign folders in external tools, start attribution workflows, or notify account managers.
data.object fields:
| Field | Type | Description |
|---|---|---|
id | string | Campaign id |
name | string | Campaign name |
description | string | null | Campaign description |
company_id | string | null | Owning company |
user_id | string | null | Creating user (personal campaigns) |
brand_id | string | null | Brand scope when set |
created_at | string | ISO 8601 creation time |
{
"id": "ccamp_abc123",
"name": "Summer launch",
"description": "Q2 product push",
"company_id": "cmxyz_company",
"user_id": null,
"brand_id": "cbrand_abc",
"created_at": "2026-06-22T12:00:00.000Z"
}
post.published
Fires when a scheduled or immediate post publishes successfully to all configured platform targets.
Common uses: Notify downstream systems that content is live, close the loop on campaign automations, or sync publish state to a data warehouse.
Note: Only emitted when every target succeeds. Partial failures do not emit this event today.
data.object fields:
| Field | Type | Description |
|---|---|---|
id | string | Post id |
post_id | string | Same as id |
status | string | PUBLISHED |
company_id | string | null | Owning company |
user_id | string | null | Owning user (personal workspace) |
brand_id | string | null | Brand scope when set |
campaign_id | string | null | Linked campaign when set |
published_at | string | ISO 8601 publish time |
platform_count | number | Number of platform targets on the post |
{
"id": "cpost_abc123",
"post_id": "cpost_abc123",
"status": "PUBLISHED",
"company_id": "cmxyz_company",
"user_id": null,
"brand_id": "cbrand_abc",
"campaign_id": "ccamp_abc123",
"published_at": "2026-06-22T12:00:00.000Z",
"platform_count": 3
}
webhook.test
Synthetic ping sent only when you click Send test in the dashboard or call POST /v1/webhooks/endpoints/:id/test.
Common uses: Validate your receiver URL, TLS, signature verification, and response handling before going live.
data.object fields:
| Field | Type | Description |
|---|---|---|
endpoint_id | string | Endpoint that received the test |
message | string | Fixed message: Styrar webhook test ping |
{
"endpoint_id": "wh_ep_abc123",
"message": "Styrar webhook test ping"
}