Telemetry API Documentation
Wallet Telemetry — pass links, event reporting, analytics and webhooks
Overview
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.
/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_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 |
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> }.
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 withfrom/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 |
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-Signature—hex(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
@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
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) |
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 |
401 as "refresh the token and retry once", and back off exponentially on repeated failures.
Testing Your Integration
Using Swagger UI
- Visit the Telemetry API explorer
- Click the Authorize button (🔓 lock icon)
- Tick the scopes you need, enter your client_id and client_secret, and click Authorize
- 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: