{"id":1159,"date":"2026-05-22T17:00:00","date_gmt":"2026-05-22T22:00:00","guid":{"rendered":"https:\/\/tolinku.com\/blog\/?p=1159"},"modified":"2026-03-07T03:34:58","modified_gmt":"2026-03-07T08:34:58","slug":"webhook-payload-formats","status":"publish","type":"post","link":"https:\/\/tolinku.com\/blog\/webhook-payload-formats\/","title":{"rendered":"Webhook Payload Formats: Parsing Deep Link Event Data"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Every webhook integration starts with the same question: what does the payload look like? This reference covers the exact structure of every <a href=\"https:\/\/tolinku.com\/features\/webhooks\">Tolinku webhook<\/a> event, with TypeScript types, field descriptions, and parsing patterns. Bookmark this page. You&#39;ll come back to it every time you add a new event handler.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For setup instructions, see the <a href=\"https:\/\/tolinku.com\/blog\/webhook-setup-guide\/\">webhook setup guide<\/a>. For the full list of events and when they fire, see the <a href=\"https:\/\/tolinku.com\/blog\/webhook-event-types\/\">webhook event types guide<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><img decoding=\"async\" src=\"https:\/\/tolinku.com\/blog\/wp-content\/uploads\/2026\/03\/platform-webhooks.png\" alt=\"Tolinku webhook configuration for event notifications\">\n<em>The webhooks page with create form, webhook list, and delivery log.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Envelope Structure<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Every webhook delivery uses the same envelope format, regardless of event type:<\/p>\n\n\n\n<pre><code class=\"language-json\">{\n  &quot;event&quot;: &quot;link.clicked&quot;,\n  &quot;timestamp&quot;: &quot;2026-05-22T14:30:00.000Z&quot;,\n  &quot;data&quot;: { ... }\n}\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Field<\/th>\n<th>Type<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody><tr>\n<td><code>event<\/code><\/td>\n<td>string<\/td>\n<td>The event type identifier<\/td>\n<\/tr>\n<tr>\n<td><code>timestamp<\/code><\/td>\n<td>string (ISO 8601)<\/td>\n<td>When the event occurred, in UTC<\/td>\n<\/tr>\n<tr>\n<td><code>data<\/code><\/td>\n<td>object<\/td>\n<td>Event-specific payload data<\/td>\n<\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>event<\/code> field is also sent in the <code>X-Webhook-Event<\/code> HTTP header, so you can route events before parsing the body.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">TypeScript Types<\/h3>\n\n\n\n<pre><code class=\"language-typescript\">interface WebhookEnvelope {\n  event: WebhookEventType;\n  timestamp: string; \/\/ ISO 8601\n  data: Record&lt;string, unknown&gt;;\n}\n\ntype WebhookEventType =\n  | &#39;link.clicked&#39;\n  | &#39;deferred_link.claimed&#39;\n  | &#39;install.tracked&#39;\n  | &#39;referral.created&#39;\n  | &#39;referral.completed&#39;\n  | &#39;test&#39;;\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">HTTP Headers<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Every webhook delivery includes these headers:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Header<\/th>\n<th>Example<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody><tr>\n<td><code>Content-Type<\/code><\/td>\n<td><code>application\/json<\/code><\/td>\n<td>Always JSON<\/td>\n<\/tr>\n<tr>\n<td><code>X-Webhook-Signature<\/code><\/td>\n<td><code>a1b2c3d4e5...<\/code><\/td>\n<td>HMAC-SHA256 hex digest of the request body<\/td>\n<\/tr>\n<tr>\n<td><code>X-Webhook-Event<\/code><\/td>\n<td><code>link.clicked<\/code><\/td>\n<td>The event type (matches <code>event<\/code> field in body)<\/td>\n<\/tr>\n<tr>\n<td><code>User-Agent<\/code><\/td>\n<td><code>Tolinku\/1.0<\/code><\/td>\n<td>Identifies the request as from Tolinku<\/td>\n<\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The signature is computed as:<\/p>\n\n\n\n<pre><code class=\"language-typescript\">import crypto from &#39;crypto&#39;;\n\nconst signature = crypto\n  .createHmac(&#39;sha256&#39;, webhookSecret) \/\/ Your whsec_... secret\n  .update(rawRequestBody)              \/\/ The raw bytes, not parsed JSON\n  .digest(&#39;hex&#39;);\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">See the <a href=\"https:\/\/tolinku.com\/blog\/webhook-security-signing\/\">webhook security guide<\/a> for full verification code.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Event: <code>link.clicked<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fires when a user taps or clicks a deep link managed by Tolinku.<\/p>\n\n\n\n<pre><code class=\"language-json\">{\n  &quot;event&quot;: &quot;link.clicked&quot;,\n  &quot;timestamp&quot;: &quot;2026-05-22T14:30:00.000Z&quot;,\n  &quot;data&quot;: {\n    &quot;prefix&quot;: &quot;go&quot;,\n    &quot;token&quot;: &quot;summer-sale&quot;,\n    &quot;hostname&quot;: &quot;links.example.com&quot;,\n    &quot;ip&quot;: &quot;203.0.113.42&quot;,\n    &quot;platform&quot;: &quot;ios&quot;,\n    &quot;device_type&quot;: &quot;mobile&quot;,\n    &quot;campaign&quot;: &quot;instagram-story-may&quot;\n  }\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Field Reference<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Field<\/th>\n<th>Type<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody><tr>\n<td><code>data.prefix<\/code><\/td>\n<td>string<\/td>\n<td>The route prefix (the first path segment of the deep link URL)<\/td>\n<\/tr>\n<tr>\n<td><code>data.token<\/code><\/td>\n<td>string<\/td>\n<td>The route token (the second path segment, identifying the specific link)<\/td>\n<\/tr>\n<tr>\n<td><code>data.hostname<\/code><\/td>\n<td>string<\/td>\n<td>The hostname the link was served from<\/td>\n<\/tr>\n<tr>\n<td><code>data.ip<\/code><\/td>\n<td>string<\/td>\n<td>The IP address of the user who clicked<\/td>\n<\/tr>\n<tr>\n<td><code>data.platform<\/code><\/td>\n<td>string<\/td>\n<td>Detected platform: <code>ios<\/code>, <code>android<\/code>, or <code>web<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>data.device_type<\/code><\/td>\n<td>string<\/td>\n<td>Device classification: <code>mobile<\/code>, <code>tablet<\/code>, or <code>desktop<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>data.campaign<\/code><\/td>\n<td>string or null<\/td>\n<td>Campaign identifier if one was configured on the route<\/td>\n<\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">TypeScript<\/h3>\n\n\n\n<pre><code class=\"language-typescript\">interface LinkClickedData {\n  prefix: string;\n  token: string;\n  hostname: string;\n  ip: string;\n  platform: &#39;ios&#39; | &#39;android&#39; | &#39;web&#39;;\n  device_type: &#39;mobile&#39; | &#39;tablet&#39; | &#39;desktop&#39;;\n  campaign: string | null;\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Notes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>This is the highest-volume event. A popular link can generate thousands of clicks per day.<\/li>\n<li>The <code>campaign<\/code> field is only present if a campaign was set on the route in your Appspace. It will be <code>null<\/code> otherwise.<\/li>\n<li>The <code>prefix<\/code> and <code>token<\/code> together reconstruct the link path: <code>https:\/\/{hostname}\/{prefix}\/{token}<\/code>.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Event: <code>deferred_link.claimed<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fires when a deferred deep link is resolved after app installation. This means a user who clicked a link before having the app installed has now installed and opened the app, and the original click context has been matched to this install.<\/p>\n\n\n\n<pre><code class=\"language-json\">{\n  &quot;event&quot;: &quot;deferred_link.claimed&quot;,\n  &quot;timestamp&quot;: &quot;2026-05-22T14:35:00.000Z&quot;,\n  &quot;data&quot;: {\n    &quot;prefix&quot;: &quot;go&quot;,\n    &quot;token&quot;: &quot;summer-sale&quot;,\n    &quot;platform&quot;: &quot;ios&quot;\n  }\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Field Reference<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Field<\/th>\n<th>Type<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody><tr>\n<td><code>data.prefix<\/code><\/td>\n<td>string<\/td>\n<td>The route prefix from the original click<\/td>\n<\/tr>\n<tr>\n<td><code>data.token<\/code><\/td>\n<td>string<\/td>\n<td>The route token from the original click<\/td>\n<\/tr>\n<tr>\n<td><code>data.platform<\/code><\/td>\n<td>string<\/td>\n<td>The platform the app was installed on<\/td>\n<\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">TypeScript<\/h3>\n\n\n\n<pre><code class=\"language-typescript\">interface DeferredLinkClaimedData {\n  prefix: string;\n  token: string;\n  platform: &#39;ios&#39; | &#39;android&#39;;\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Notes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>This event is the &quot;proof&quot; that a pre-install click resulted in an actual app open.<\/li>\n<li>The data is sparser than <code>link.clicked<\/code> because it represents the resolution, not the original click. Match it to the original click using <code>prefix<\/code> and <code>token<\/code>.<\/li>\n<li>Deferred link resolution uses the attribution matching logic described in the <a href=\"https:\/\/tolinku.com\/docs\/concepts\/deferred-deep-linking\/\">deferred deep linking guide<\/a>.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Event: <code>install.tracked<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fires when an app install is attributed to a deep link.<\/p>\n\n\n\n<pre><code class=\"language-json\">{\n  &quot;event&quot;: &quot;install.tracked&quot;,\n  &quot;timestamp&quot;: &quot;2026-05-22T14:35:01.000Z&quot;,\n  &quot;data&quot;: {\n    &quot;prefix&quot;: &quot;go&quot;,\n    &quot;token&quot;: &quot;summer-sale&quot;,\n    &quot;platform&quot;: &quot;ios&quot;,\n    &quot;campaign&quot;: &quot;instagram-story-may&quot;\n  }\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Field Reference<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Field<\/th>\n<th>Type<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody><tr>\n<td><code>data.prefix<\/code><\/td>\n<td>string<\/td>\n<td>The route prefix that drove the install<\/td>\n<\/tr>\n<tr>\n<td><code>data.token<\/code><\/td>\n<td>string<\/td>\n<td>The route token that drove the install<\/td>\n<\/tr>\n<tr>\n<td><code>data.platform<\/code><\/td>\n<td>string<\/td>\n<td>The platform the app was installed on<\/td>\n<\/tr>\n<tr>\n<td><code>data.campaign<\/code><\/td>\n<td>string or null<\/td>\n<td>Campaign identifier from the original link<\/td>\n<\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">TypeScript<\/h3>\n\n\n\n<pre><code class=\"language-typescript\">interface InstallTrackedData {\n  prefix: string;\n  token: string;\n  platform: &#39;ios&#39; | &#39;android&#39;;\n  campaign: string | null;\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Notes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>This event often fires within seconds of <code>deferred_link.claimed<\/code>, but they are separate events with distinct purposes. <code>deferred_link.claimed<\/code> means the link was resolved; <code>install.tracked<\/code> means the install was attributed.<\/li>\n<li>Use this event for user acquisition metrics: installs per campaign, installs per platform, cost per install (when combined with ad spend data).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Event: <code>referral.created<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fires when a new referral is registered. The referred user clicked a referral link and initiated the signup process.<\/p>\n\n\n\n<pre><code class=\"language-json\">{\n  &quot;event&quot;: &quot;referral.created&quot;,\n  &quot;timestamp&quot;: &quot;2026-05-22T15:00:00.000Z&quot;,\n  &quot;data&quot;: {\n    &quot;referrer_token&quot;: &quot;user-abc123&quot;,\n    &quot;platform&quot;: &quot;android&quot;\n  }\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Field Reference<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Field<\/th>\n<th>Type<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody><tr>\n<td><code>data.referrer_token<\/code><\/td>\n<td>string<\/td>\n<td>The referral token identifying the referrer<\/td>\n<\/tr>\n<tr>\n<td><code>data.platform<\/code><\/td>\n<td>string<\/td>\n<td>The platform the referred user is on<\/td>\n<\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">TypeScript<\/h3>\n\n\n\n<pre><code class=\"language-typescript\">interface ReferralCreatedData {\n  referrer_token: string;\n  platform: &#39;ios&#39; | &#39;android&#39; | &#39;web&#39;;\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Notes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The <code>referrer_token<\/code> maps to the user who created the referral link. Use it to look up the referrer in your database.<\/li>\n<li>This event fires on referral creation, not on completion. The referred user may not yet have finished the required action (e.g., first purchase).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Event: <code>referral.completed<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fires when a referred user completes the target action defined in your referral program.<\/p>\n\n\n\n<pre><code class=\"language-json\">{\n  &quot;event&quot;: &quot;referral.completed&quot;,\n  &quot;timestamp&quot;: &quot;2026-05-22T15:30:00.000Z&quot;,\n  &quot;data&quot;: {\n    &quot;referrer_token&quot;: &quot;user-abc123&quot;,\n    &quot;platform&quot;: &quot;android&quot;\n  }\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Field Reference<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Field<\/th>\n<th>Type<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody><tr>\n<td><code>data.referrer_token<\/code><\/td>\n<td>string<\/td>\n<td>The referral token identifying the referrer<\/td>\n<\/tr>\n<tr>\n<td><code>data.platform<\/code><\/td>\n<td>string<\/td>\n<td>The platform the referred user converted on<\/td>\n<\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">TypeScript<\/h3>\n\n\n\n<pre><code class=\"language-typescript\">interface ReferralCompletedData {\n  referrer_token: string;\n  platform: &#39;ios&#39; | &#39;android&#39; | &#39;web&#39;;\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Notes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>This is the bottom of the referral funnel. It means both parties have done their part: the referrer shared the link, and the referred user completed the target action.<\/li>\n<li>Use this event to trigger reward distribution, update CRM records, or send confirmation emails.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Event: <code>test<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fires when you click the <strong>Test<\/strong> button in the Tolinku dashboard. Used to verify your endpoint is reachable and your signature verification works.<\/p>\n\n\n\n<pre><code class=\"language-json\">{\n  &quot;event&quot;: &quot;test&quot;,\n  &quot;timestamp&quot;: &quot;2026-05-22T10:00:00.000Z&quot;,\n  &quot;data&quot;: {\n    &quot;message&quot;: &quot;This is a test webhook from Tolinku.&quot;,\n    &quot;webhook_id&quot;: &quot;wh_abc123&quot;,\n    &quot;appspace_id&quot;: &quot;as_xyz789&quot;\n  }\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">TypeScript<\/h3>\n\n\n\n<pre><code class=\"language-typescript\">interface TestData {\n  message: string;\n  webhook_id: string;\n  appspace_id: string;\n}\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Parsing Best Practices<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1. Parse After Verifying<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Always verify the <code>X-Webhook-Signature<\/code> against the raw body before parsing JSON. If you parse first, you might compute the signature on a re-serialized string that differs from the original.<\/p>\n\n\n\n<pre><code class=\"language-typescript\">\/\/ Correct: verify raw, then parse\napp.use(&#39;\/webhooks&#39;, express.raw({ type: &#39;application\/json&#39; }));\n\napp.post(&#39;\/webhooks\/tolinku&#39;, (req, res) =&gt; {\n  if (!verifySignature(req.body, req.headers[&#39;x-webhook-signature&#39;])) {\n    return res.status(401).send(&#39;Invalid signature&#39;);\n  }\n  const event = JSON.parse(req.body.toString());\n  \/\/ Process event...\n});\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">2. Handle Unknown Events Gracefully<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">New event types may be added in the future. Don&#39;t crash on unrecognized events:<\/p>\n\n\n\n<pre><code class=\"language-typescript\">function handleEvent(event: WebhookEnvelope) {\n  switch (event.event) {\n    case &#39;link.clicked&#39;:\n      handleClick(event.data as LinkClickedData);\n      break;\n    case &#39;install.tracked&#39;:\n      handleInstall(event.data as InstallTrackedData);\n      break;\n    \/\/ ... other known events\n    default:\n      console.log(`Unknown event type: ${event.event}`);\n      \/\/ Log it but don&#39;t fail\n  }\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">3. Handle Missing Fields<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Not all fields are guaranteed to be present on every event. The <code>campaign<\/code> field, for example, is only populated if a campaign was configured on the route. Always use optional chaining or null checks:<\/p>\n\n\n\n<pre><code class=\"language-typescript\">const campaign = event.data.campaign || &#39;unknown&#39;;\nconst platform = event.data.platform ?? &#39;unknown&#39;;\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">4. Use the Header for Routing<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If you need to route events before parsing the body (e.g., to different queue topics), use the <code>X-Webhook-Event<\/code> header:<\/p>\n\n\n\n<pre><code class=\"language-typescript\">app.post(&#39;\/webhooks\/tolinku&#39;, (req, res) =&gt; {\n  const eventType = req.headers[&#39;x-webhook-event&#39;] as string;\n\n  \/\/ Route to different queues based on event type\n  switch (eventType) {\n    case &#39;link.clicked&#39;:\n      clickQueue.push(req.body);\n      break;\n    case &#39;install.tracked&#39;:\n      installQueue.push(req.body);\n      break;\n    default:\n      defaultQueue.push(req.body);\n  }\n\n  res.status(200).send(&#39;OK&#39;);\n});\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Delivery Characteristics<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Timeout<\/strong>: Tolinku waits 10 seconds for a response. If your endpoint doesn&#39;t respond within 10 seconds, the delivery is marked as failed and retried.<\/li>\n<li><strong>Retries<\/strong>: 3 retries at 1 minute, 5 minutes, and 30 minutes after a failure.<\/li>\n<li><strong>No redirects<\/strong>: Tolinku does not follow HTTP redirects. Your endpoint must respond directly.<\/li>\n<li><strong>HTTPS only<\/strong>: Production webhooks are delivered over HTTPS.<\/li>\n<li><strong>Content-Type<\/strong>: Always <code>application\/json<\/code>.<\/li>\n<li><strong>Method<\/strong>: Always POST.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">For debugging delivery issues, see the <a href=\"https:\/\/tolinku.com\/blog\/webhook-debugging\/\">webhook debugging guide<\/a>. For testing your payload parsing before going to production, see the <a href=\"https:\/\/tolinku.com\/blog\/webhook-testing-tools\/\">webhook testing tools guide<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Understand and parse Tolinku webhook payloads. Detailed field reference for all five event types with TypeScript types and parsing examples.<\/p>\n","protected":false},"author":2,"featured_media":1158,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"rank_math_title":"Webhook Payload Formats: Parsing Deep Link Event Data","rank_math_description":"Understand and parse Tolinku webhook payloads. Detailed field reference for all five event types with TypeScript types and parsing examples.","rank_math_focus_keyword":"webhook payload format","rank_math_canonical_url":"","rank_math_facebook_title":"","rank_math_facebook_description":"","rank_math_facebook_image":"https:\/\/tolinku.com\/blog\/wp-content\/uploads\/2026\/03\/og-webhook-payload-formats.png","rank_math_facebook_image_id":"","rank_math_twitter_title":"","rank_math_twitter_description":"","rank_math_twitter_image":"https:\/\/tolinku.com\/blog\/wp-content\/uploads\/2026\/03\/og-webhook-payload-formats.png","footnotes":""},"categories":[15],"tags":[62,20,75,264,291,290,61],"class_list":["post-1159","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-engineering","tag-api","tag-deep-linking","tag-developer-tools","tag-engineering","tag-json","tag-typescript","tag-webhooks"],"_links":{"self":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1159","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/comments?post=1159"}],"version-history":[{"count":2,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1159\/revisions"}],"predecessor-version":[{"id":2262,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1159\/revisions\/2262"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/media\/1158"}],"wp:attachment":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/media?parent=1159"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/categories?post=1159"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/tags?post=1159"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}