Partner attribution & postbacks
Know which publisher, affiliate, or agency drove each pass save and each redemption, and tell them in real time with a signed postback.
How it works
- Create a partner in Settings → Partners: a name, a postback URL template, and which events they get. You receive a partner id and a secret once.
- Give the partner a tracking link: any share or enrollment link with
?pid=<partner id>&cid=<their click id>. Your existing UTM parameters keep working alongside. - When a holder saves the pass, the partner id and click id are stamped on that holder's instance, next to first-touch UTM, for the life of the pass.
- On save, and again on every redemption, Pass Studio resolves the template's macros, signs the request, and calls the partner's URL. Retries with backoff for up to two hours.
- Settings shows saves, redemptions, and attributed order revenue per partner over the last 30 days.
Tracking links
https://www.thepassstudio.com/share/SHARE_TOKEN?pid=p_k3f9xq2mza&cid=CLICK_ID
https://www.thepassstudio.com/enroll/SHARE_TOKEN?pid=p_k3f9xq2mza&cid=CLICK_IDpidis the partner id shown in Settings.cidis whatever the partner uses to identify the click;clickidandclick_idare accepted as aliases. Values up to 200 characters, stored verbatim.- Issuing through the API? Send
partnerIdandclickIdin the issue body and the same stamping applies. - Attribution is first-touch: a holder who already has the pass keeps the partner that acquired them.
Postbacks
The postback URL is a template. Every {macro} is replaced and URL-encoded. GET by default; choose POST to receive the same values as a JSON body.
| Macro | Value |
|---|---|
| {clickId} | The click id from the tracking link (cid), verbatim. |
| {partnerId} | The partner id (pid) the link carried, e.g. p_k3f9xq2mza. |
| {event} | save when the pass entered a wallet; redeem when it was redeemed. |
| {passId} | The pass the holder saved. |
| {instanceId} | The holder's instance — stable across save and later redemptions. |
| {orderId} | The order reference on a redemption, when there is one (store orders, API orders). Empty for counter scans. |
| {amount} | Order amount on a redemption when known; empty otherwise. |
| {currency} | ISO currency of amount when known; empty otherwise. |
| {ts} | Unix seconds when the postback was signed. |
| {sig} | HMAC-SHA256 hex of "{partnerId}.{clickId}.{instanceId}.{event}.{ts}" with the partner secret. |
Example
Template: https://track.partner.example/pb?c={clickId}&e={event}&amt={amount}&t={ts}&s={sig}
Sent: GET https://track.partner.example/pb?c=abc123&e=redeem&amt=42.00&t=1789344000&s=9f2c…
Headers: X-PassStudio-Partner: p_k3f9xq2mza
X-PassStudio-Event: redeem
X-PassStudio-Timestamp: 1789344000
X-PassStudio-Signature: sha256=9f2c…Verifying the signature
expected = HMAC_SHA256(secret, partnerId + "." + clickId + "." + instanceId + "." + event + "." + ts)
accept if hex(expected) == sig (and ts is within your tolerance window)- Any 2xx response counts as delivered. Anything else is retried after 1, 5, 30, and 120 minutes, then marked exhausted.
- One postback per partner, instance, and event. A repeat redemption with a distinct order id is a new conversion; a retried webhook for the same one is not.
- Use Send test in Settings to receive a synthetic save postback before any traffic.
Report and data
The partner id and click id appear on every event as acqPartnerId and acqClickId: in the event reference, in Segment as acquisitionPartner and acquisitionClickId, and on the instance returned by the API. A partner who wants to pull their own numbers can be given a read-only key restricted to the passes they promote.
Related
- Organizations, agencies & multi-brand accounts — partners live per workspace, like keys.
- Webhooks — your own endpoints get the same events with holder identity.
- Pass Studio for agencies