Skip to content

Webhooks

A webhook is an address on your server that Posty5 calls when something happens. Instead of asking Posty5 for new visits, your system is told within seconds, with a JSON event it can verify.

  1. In the Posty5 dashboard, open Account settings and choose Webhooks.

  2. Add an endpoint, enter its HTTPS address and choose the events it receives.

  3. Choose all your links and QR codes, or only some of them, whether bot visits count, and whether events arrive one by one or in batches.

  4. Save, then copy the signing secret. It is shown this once.

  5. Use Send test to check that your server receives and verifies a webhook.test event.

The address must use HTTPS and be reachable from the internet. Private and local network addresses are refused, and redirects are not followed. You can have up to 10 endpoints.

Event
short_link.visitedSomeone opened one of your short links, including through the QR image of the link.
short_link.visits_milestoneA short link reached one of the visit counts you set (up to 10 values).
qr_code.scannedSomeone scanned one of your dynamic QR codes.
qr_code.scans_milestoneA QR code reached one of the scan counts you set.
webhook.testSent only when you use Send test.

Each event is a JSON POST with an id, a type, the API version, the time it was created and its data, the link or QR code and the visit.

{
"id": "evt_6700f1c2a9e4b51d2c3f0a11",
"type": "short_link.visited",
"apiVersion": "2026-10-01",
"createdAt": "2026-10-04T12:00:00.000Z",
"data": {
"target": {
"type": "shortLink",
"id": "66f0c2a9e4b51d2c3f0a1122",
"code": "aB3xY9",
"url": "https://pst5.com/_aB3xY9",
"name": "Spring sale",
"destinationUrl": "https://shop.example/sale",
"tag": "spring",
"refId": null
},
"visit": {
"at": "2026-10-04T11:59:59.120Z",
"channel": "qr",
"country": "EG",
"deviceType": "mobile",
"os": "Android",
"browser": "Chrome",
"referrerHost": null,
"language": "ar",
"isBot": false,
"outcome": "redirect"
}
}
}

Milestone events carry data.milestone with the metric, the value reached and when, and no visit.

With batched delivery, one POST of type batch carries up to 500 events in data.events.

Events never contain the visitor’s IP address, the full user agent, the full referrer address, a visitor identifier or your account ID. Bot visits are left out unless you include them.

Posty5 signs every delivery with your endpoint’s secret, following the Standard Webhooks specification, in three headers. Reject any request whose signature does not match or whose timestamp is more than 5 minutes old.

  • webhook-id
  • webhook-timestamp
  • webhook-signature

In Node.js, use the @posty5/webhooks package.

import { verifyWebhookSignature } from "@posty5/webhooks";
// rawBody is the request body exactly as received, before JSON parsing.
const event = verifyWebhookSignature({
payload: rawBody,
headers: request.headers,
secret: process.env.POSTY5_WEBHOOK_SECRET,
});

In .NET, use the Posty5.Webhooks package.

using Posty5.Webhooks;
var webhookEvent = WebhookSignature.Verify(rawBody, headers, secret);

In any other language, any Standard Webhooks library verifies Posty5 events with your secret.

  • Answer with any 2xx status within 10 seconds. Anything else counts as a failure.
  • A failed delivery is retried after 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours and 24 hours, then given up.
  • Every retry carries the same webhook-id, so your server can ignore an event it has already handled.
  • An endpoint is turned off after 20 failed deliveries in a row over at least 24 hours, or at once if it answers 410 Gone. You get a notification, and you can turn it back on from the dashboard.
  • The endpoint’s delivery list shows each attempt with its status and your server’s answer, and lets you send a delivery again.

If the secret may have leaked, rotate it from the endpoint’s menu. For 24 hours deliveries carry two signatures, one per secret, so you can update your server without missing events.

The Posty5 Trigger node creates and verifies the endpoint for you. n8n Posty5 Trigger