Getting Started
Use REST against your SnapWallet API host. Server-side integrations should use organization API keys (see below). Use Dashboard → API keys to create keys and choose what each key may access (or leave full access). For every HTTP route and schema, open the tab (loaded from OpenAPI).
1. Configure base URL
# Base URL (no global /api prefix in default Nest bootstrap)
export API=https://your-api-host2. Integration fetch helper (API key)
const API = process.env.SNAPWALLET_API_BASE_URL;
const SNAPWALLET_API_KEY = process.env.SNAPWALLET_API_KEY;
async function api(path, { method = 'GET', body } = {}) {
const headers = {
Accept: 'application/json',
'api-key': SNAPWALLET_API_KEY,
};
if (body) headers['Content-Type'] = 'application/json';
const res = await fetch(`${API}${path}`, { method, headers, body: body ? JSON.stringify(body) : undefined });
if (!res.ok) throw new Error(await res.text());
return res.status === 204 ? null : res.json();
}3. Public pass creation
// Public issuance — POST /v1/snap (no API key; legacy /snap unchanged)
const res = await fetch(`${API}/v1/snap`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
body: JSON.stringify({
fullName: 'Jane Doe',
phoneNumber: '27123456789',
cardNumber: '6006123456789012',
email: 'jane@example.com',
passId: 'PASS_TEMPLATE_UUID',
type: 'apple',
}),
});
if (!res.ok) throw new Error(await res.text());/api prefix unless you add one in bootstrap.http://localhost:4000Authentication and entitlements
Integrations: send your organization API key on every protected request using api-key: <secret> (also accepted: x-api-key). Do not embed keys in browsers or mobile apps.
Console: the dashboard signs in with POST /auth/login and uses Authorization: Bearer <jwt>. JWTs are short-lived sessions, not a substitute for API keys on servers.
What a key may do: in the dashboard you pick capabilities in plain language (gift cards, loyalty, webhooks, and so on). That becomes a small permissions map on the server. Leave full access on unless you intentionally want a narrower integration. The server always intersects what you allow with your subscription package.
// Browser / short-lived human session only — use API keys for servers
async function apiBearer(path, { method = 'GET', token, body } = {}) {
const headers = { Accept: 'application/json', Authorization: `Bearer ${token}` };
if (body) headers['Content-Type'] = 'application/json';
const res = await fetch(`${API}${path}`, { method, headers, body: body ? JSON.stringify(body) : undefined });
if (!res.ok) throw new Error(await res.text());
return res.status === 204 ? null : res.json();
}Keys carry the same authorization surface as scoped features on your account. Store them in a secret manager, rotate on compromise, and never commit them to source control.
HTTP and errors
SnapWallet uses JSON bodies for REST. Send Content-Type: application/json on writes. Errors from Nest HttpException usually include statusCode, message, and error.
Response body
{
"statusCode": 401,
"message": "Incorrect username and password",
"error": "Unauthorized"
}Response body
{
"statusCode": 403,
"message": "Not Authorized. Contact your admin.",
"error": "Forbidden"
}Solutions
Solution mix is driven by your package and key scopes (see feature keys on each card). The published OpenAPI document lists versioned integration routes under /v1 (e.g. GET /v1/pass-template/organization/:id for templates).
Route prefixes: giftcardgiftcard-templategiftcard-transaction
Feature keys: gct (templates), gtx (transactions)
Route prefixes: loyalty-programloyalty-client
Feature keys: lyp (loyalty-client and loyalty-program routes), lyc (customers elsewhere)
Route prefixes: pass-templatemembership-programmembership-enrolment
Feature keys: msp (program) and/or ptm (pass templates)
Route prefixes: eventsevents-customer
Feature keys: evn, eal
Workflow examples
Distribution and enrolment combine templates, programs, and public issuance; see API Reference for all /v1 routes.
List card templates (integration)
GET /v1/pass-template/organization/:id returns id, name, barcodeType (code format), and description per template for enrolment flows.
// Server integration — list org templates (versioned public API)
await api('/v1/pass-template/organization/ORG_UUID');List gift cards (integration)
// Example: list gift cards for an organization (versioned public API)
await api('/v1/giftcard/organization/ORG_UUID');Webhooks
Register outbound webhooks with POST /v1/trigger-events (same payload as the legacy route). Your delivery URL must be HTTPS. Managing triggers requires the etr feature. Configure from Dashboard → Webhooks or the REST routes in API Reference.
Each delivery is a JSON body { event, organizationId, ...payload }. The event string matches the trigger you selected; extra fields depend on that event (for example pass serial numbers on snap captured, or ticket id on event ticket issued). When action is post_webhook, configure an optional signing secret in data to verify x-snapwallet-signature (HMAC-SHA256 of the raw JSON body).
Available trigger events (by solution area)
- Gift cards: gift card issued (
pubsub_public_card_created_event), gift card transaction (pubsub_gift_card_transaction_event) - Loyalty: customer created (
pubsub_customer_created_event), points collected (pubsub_points_collected_event), reward goal reached (pubsub_snap_goal_reached_event), snap captured (pubsub_snap_captured_event) - Membership: enrolment created (
pubsub_membership_enrolment_created_event) - Access (events): event ticket issued (
pubsub_event_ticket_issued_event)
Register with API key
await api('/v1/trigger-events', {
method: 'POST',
body: {
title: 'Notify CRM',
description: 'Forward loyalty snaps',
trigger: 'pubsub_snap_captured_event',
delivery: 'https://example.com/webhooks/snapwallet',
action: 'post_webhook',
organizationId: 'ORG_UUID',
isActive: true,
data: {},
},
});Consumer handler sketch
// Your HTTPS endpoint receives delivery payloads from SnapWallet (shape depends on trigger).
// Verify authenticity using your shared secret or signing scheme once documented for your tenant.
app.post('/webhooks/snapwallet', express.json(), (req, res) => {
console.log('Trigger payload', req.body);
res.status(200).send('OK');
});