ANALYTICS

Telemetry API Documentation

Wallet Telemetry — pass links, event reporting, analytics and webhooks

Overview

Wallet Telemetry is a reporting layer: generate wallet passes, report events programmatically or receive them via webhooks/polling, and read analytics. The typical shape is generate passes → report/receive events → read analytics.

The API covers two areas:

  • Wallet Passes — resolve or create Add-to-Wallet links, bind recipients to keywords, and push field updates to passes already in customers' wallets (Apple & Google).
  • Telemetry (Add-on) — report events (via REST or the SDK), query the raw wallet event feed and daily analytics rollups, and subscribe HTTPS webhooks to receive events as they happen.
Live: the Telemetry endpoints are generally available under /wallet/telemetry/* and share the Wallet OAuth2 scope (gifting:send). Your merchant is derived from the token. See the interactive explorer for the exact contract.

Base URL

https://ah1ta9hc59.execute-api.ap-southeast-2.amazonaws.com/prod

Authentication & Scopes

The API uses the same OAuth2 Client Credentials flow as the core OAuth2 API — see the OAuth2 Guide for the full token walkthrough. Exchange your client_id and client_secret for a Bearer token, then send it on every request:

Authorization: Bearer YOUR_ACCESS_TOKEN
Merchant scoping is automatic. The gateway authorizer derives your merchant_id from the token server-side — you never supply it in request bodies or query strings for reads.

Scopes

Scope Grants
gifting:send Wallet passes (links, recipients, push, audiences) and telemetry (report events, read analytics/events, manage webhooks). Merchant is derived from your token.

Request the scope when fetching your token:

scope=gifting:send

Endpoints at a Glance

Method Path Purpose Scope
POST /wallet/pass-link Resolve or create an Add-to-Wallet link gifting:send
POST /wallet/pass-recipient Bind a recipient to a keyword gifting:send
POST /wallet/push Push an update to issued passes gifting:send
POST /wallet/telemetry/events Report one or more events gifting:send
GET /wallet/telemetry/events Query the merchant's event feed gifting:send
GET /wallet/telemetry/analytics Daily wallet analytics rollups gifting:send
GET /wallet/telemetry/subscriptions List webhook subscriptions gifting:send
POST /wallet/telemetry/subscriptions Subscribe a webhook gifting:send
DELETE /wallet/telemetry/subscriptions/{webhookId} Remove a webhook subscription gifting:send
Try it live: every endpoint can be exercised from the Telemetry API explorer — click Authorize, tick the scopes you need, and enter your credentials.

Reporting & Querying Events

Reporting an Event

Report events from your own systems with POST /wallet/telemetry/events (scope gifting:send). The event becomes observable in queries and analytics, and is delivered to any matching webhook subscriptions and platform flows. Your merchant is resolved from the token server-side — never supply it yourself.

POST /wallet/telemetry/events
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json

{
  "eventType": "WALLET_APPLE_PASS_ADDED",
  "subject": { "type": "LOYALTY", "id": "acme_9fk2" },
  "metadata": {
    "wallet_provider": "apple",
    "keyword": "acme_9fk2"
  }
}

eventType and a subject { type, id } are required (a top-level giftId is accepted as a shortcut for subject { type: "GIFT", id }). metadata is optional and should stay flat — platform flows filter on those keys. The gateway stamps eventId/eventTs/serviceId and forces references.merchantId to your token's merchant. To report many at once, POST a bare array or { "events": [ … ] } (max 100). A successful call returns 202 { "accepted": <count> }.

Prefer the SDK for reporting — it handles signing, batching, retries and event ids so you don't hand-roll HTTP.

Querying Events

GET /wallet/telemetry/events?from=2026-08-01T00:00:00Z&to=2026-08-11T00:00:00Z&limit=100

Query Parameters

Parameter Type Description
from string Inclusive start of the time window, ISO 8601
to string Inclusive end of the time window, ISO 8601
limit integer Maximum events to return (default 100), newest first

Event Shape

Each event carries a ULID eventId, an eventType (see Event Types), an ISO 8601 eventTs, the emitting serviceId, plus subject, references, event-specific metadata and delivery context objects.

Analytics

  • GET /wallet/telemetry/analytics — daily rollups of wallet activity (event counts, unique subjects, device and UTM-source breakdowns), ready to chart. Filter with from/to.

Telemetry Webhooks

Instead of polling /wallet/telemetry/events, subscribe an HTTPS endpoint and receive events as they happen.

Subscribe

POST /wallet/telemetry/subscriptions
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json

{
  "url": "https://example.com/hooks/wallet-events",
  "eventTypes": ["WALLET_APPLE_PASS_ADDED", "WALLET_GOOGLE_PASS_ADDED"],
  "description": "loyalty pipeline"
}
Field Required Description
url Yes HTTPS endpoint to receive event deliveries
eventTypes No Event types to deliver. Omit or [] = all events
description No A label for your own reference
The response returns a secret — once. The platform generates the signing secret; you don't supply it. Store it from the 201 response — it is never shown again (list responses only include a hasSecret flag). Up to 20 subscriptions per merchant.

Verifying deliveries

Each delivery is a POST to your URL with these headers:

  • X-Telemetry-Signaturehex(HMAC-SHA256(secret, "<X-Telemetry-Timestamp>.<raw body>"))
  • X-Telemetry-Timestamp — unix seconds (also bound into the signature, blocking replay)
  • X-Telemetry-Webhook-Id, X-Telemetry-Event-Id

Recompute the HMAC over <timestamp>.<raw body> and constant-time compare before trusting the payload. Deliveries are at-least-once — deduplicate on X-Telemetry-Event-Id, and respond 2xx quickly (process asynchronously). Failed deliveries retry, then land in a dead-letter queue.

Manage subscriptions with GET /wallet/telemetry/subscriptions (list) and DELETE /wallet/telemetry/subscriptions/{webhookId} (remove).

Telemetry SDK

The @giftdigital/telemetry-partner SDK wraps every endpoint on this page — report events, read analytics and the event feed, and manage webhooks — using your OAuth2 access token. No signing keys, no hand-rolled HTTP.

npm install @giftdigital/telemetry-partner
Which SDK? As an API partner you want @giftdigital/telemetry-partner (OAuth2 token — shown below). The first-party @giftdigital/telemetry-sdk uses an HMAC signing key and is for InTouch's own backend services, not partners. Browser storefront events use a publishable-key pixel. All three report to the same platform — only the credential differs.

Report, read & subscribe — from your backend

import { TelemetryPartner } from "@giftdigital/telemetry-partner";

const telemetry = new TelemetryPartner({
  token: myOAuth2AccessToken,   // string, or () => Promise<string> to auto-refresh
});

// Report an event — merchant is derived from your token
await telemetry.report({
  eventType: "WALLET_APPLE_PASS_ADDED",
  subject: { type: "LOYALTY", id: "acme_9fk2" },
  metadata: { wallet_provider: "apple", keyword: "acme_9fk2" }
});

// Read analytics + the event feed
const { days }   = await telemetry.getAnalytics({ from: "2026-08-01", to: "2026-08-31" });
const { events } = await telemetry.getEvents({ limit: 50 });

// Manage webhooks (hook.secret is returned ONCE — store it)
const hook = await telemetry.createWebhook({
  url: "https://example.com/hooks/wallet-events",
  eventTypes: ["WALLET_APPLE_PASS_ADDED"]
});

Verifying webhook deliveries

import { TelemetryPartner } from "@giftdigital/telemetry-partner";

// pass the RAW request body (not re-serialised)
const ok = TelemetryPartner.verifyWebhookSignature(rawBody, req.headers, secret);
if (!ok) return res.sendStatus(400);
res.sendStatus(200);   // ack fast, process asynchronously
  • Merchant is always derived from your OAuth2 token — you never pass a merchantId.
  • report() accepts one event, an array, or { events: [ … ] } (max 100).
  • Deliveries are at-least-once — deduplicate on the event's eventId.

Versions

The SDK follows semver. Pin a version and upgrade deliberately.

# latest
npm install @giftdigital/telemetry-partner

# a specific version
npm install @giftdigital/telemetry-partner@0.1.0

# check the latest published version
npm view @giftdigital/telemetry-partner version
Always install the latest published version. The SDK is actively maintained; if a field name differs in your installed version, follow that version's own README.

Event Types

The same event-type vocabulary is used everywhere — event reporting, event queries and webhook subscriptions:

Event Type Fires when…
WALLET_LINK_GENERATED An Add-to-Wallet link is created
WALLET_LINK_VIEWED A recipient opens the Add-to-Wallet link
WALLET_PASS_ISSUED A pass is issued
WALLET_PASS_DELIVERED A pass is delivered
WALLET_APPLE_PASS_ADDED A pass is added to Apple Wallet
WALLET_APPLE_PASS_REMOVED A pass is removed from Apple Wallet
WALLET_APPLE_DEVICE_REGISTERED An Apple device registers for pass updates
WALLET_GOOGLE_PASS_ADDED A pass is added to Google Wallet
WALLET_GOOGLE_PASS_REMOVED A pass is removed from Google Wallet
WALLET_APPLE_PUSH_SENT A push update is sent to Apple passes
WALLET_GOOGLE_PUSH_SENT A push update is sent to Google passes
WALLET_PASS_UPDATE_PUSHED A field update is pushed to issued passes
WALLET_SCANNED A pass is scanned at the gate or point of sale
PASS_ACTIVATED A pass is activated — e.g. the customer taps to activate (tap2activate)
What wallets don't expose: neither Apple nor Google reports a pass viewed or in-wallet link-tap signal, so there is no view event — treat adds as the adoption signal.

Code Examples

cURL — Create a Pass Link

curl -X POST 'https://ah1ta9hc59.execute-api.ap-southeast-2.amazonaws.com/prod/wallet/pass-link' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "keyword": "SUMMER24",
    "recipient": "+61400000000",
    "firstname": "Sam",
    "code": "VOUCHER-1234",
    "value": "$25.00"
  }'

cURL — Query Recent Events

curl 'https://ah1ta9hc59.execute-api.ap-southeast-2.amazonaws.com/prod/wallet/telemetry/events?from=2026-08-01T00:00:00Z&limit=50' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN'

Python — Read the Event Feed

import requests

BASE = "https://ah1ta9hc59.execute-api.ap-southeast-2.amazonaws.com/prod"
headers = {"Authorization": "Bearer YOUR_ACCESS_TOKEN"}

params = {"from": "2026-08-01T00:00:00Z", "to": "2026-08-31T00:00:00Z", "limit": 100}
resp = requests.get(f"{BASE}/wallet/telemetry/events", headers=headers, params=params).json()

events = resp.get("events", [])
print(f"Fetched {len(events)} events (newest first)")

Node.js — Push an Update to Issued Passes

const axios = require('axios');

const BASE = 'https://ah1ta9hc59.execute-api.ap-southeast-2.amazonaws.com/prod';

async function pushUpdate(accessToken) {
    const response = await axios.post(`${BASE}/wallet/push`, {
        keyword: 'SUMMER24',
        fields: { value: '$15.00', custom_1: 'Balance updated' }
    }, {
        headers: {
            'Authorization': `Bearer ${accessToken}`,
            'Content-Type': 'application/json'
        }
    });
    console.log('Push result:', response.data);
}

Error Handling

HTTP Status Meaning Solution
401 Missing, invalid or expired token Request a new access token
403 Token lacks the required scope Request a token with the scope from the endpoints table
400 Invalid parameters or body Check required fields and formats (E.164 numbers, ISO 8601 dates)
404 Resource not found Check ids (e.g. webhook {id}) belong to your merchant
Best Practice: treat 401 as "refresh the token and retry once", and back off exponentially on repeated failures.

Testing Your Integration

Using Swagger UI

  1. Visit the Telemetry API explorer
  2. Click the Authorize button (🔓 lock icon)
  3. Tick the scopes you need, enter your client_id and client_secret, and click Authorize
  4. Start with GET /wallet/telemetry/events?limit=1 — a simple read that confirms auth and scoping work

Quick Token Generator

For command-line testing, use our token generator scripts: