Skip to main content
This guide is for backend developers building a direct integration against the Stell API. Your systems call the API and own the sync between your customer records and Stell. Four flows make up every integration: Add to Wallet, updating passes, in-store usage, and webhooks and go-live. Where this guide says “your CRM”, read it as whatever system of record you run: a CRM, a loyalty engine, or your own platform. Nothing in the API is specific to any of them.
Stell has prebuilt connectors for a growing set of POS and CRM platforms. If yours is one of them, you may not need to write integration code at all. The connector handles the flows in this guide. Contact us to check what’s available for your stack.

Who builds what

The dividing line is simple: you own the calls, Stell owns the wallets.

Stell provides

  • The pass engine: issuance, signing, and distribution for Apple Wallet and Google Wallet
  • Real-time pass updates and push notifications to customer devices
  • Short-lived Add to Wallet links for both platforms
  • Signed webhooks that tell your backend when a pass changes status
  • The merchant portal, for self-service management of your pass templates and change messages

You build

  • A server-side service that calls the Stell API
  • An Add to Wallet touchpoint: a page, app screen, or email
  • An HTTPS webhook endpoint that receives status events
  • The mapping between your customer records and passes, via externalId
  • The business logic: when points change, when tiers change, what messages to send

Before you start

You need three things:
  1. An API key for your backend (Authorization: Bearer sk_prod_…). Create one in the portal. It must stay server-side; see Authentication.
  2. Your programId, the identifier for your pass program, used in every create and lookup call. Find it with List programs or in the portal.
  3. A webhook subscription: your endpoint URL, the event types you want, and a signing secret, created in the portal.

Core concepts

externalId. Your own customer identifier, and the join key across the whole integration. You set it at pass creation, use it for lookups, and get it back in every webhook delivery. No extra mapping table needed. Pass id. Stell’s identifier for a pass, returned when the pass is issued. Store it if convenient. If not, look it up by programId + externalId. Wallet links. Add to Wallet links are short-lived: roughly 15 minutes for the Apple Wallet link, roughly an hour for the Google Wallet save link. Each response carries the exact deadline in expiresAt. Request links at click time, and never cache or store them. Wallet-controlled display. Apple and Google decide the final presentation of passes and notifications, and may coalesce rapid updates. Don’t design flows that rely on one visible notification per update. The in-store payload. What your POS reads from a scan or tap is a choice, not a constant. Set it with the payload field when issuing the pass, or configure it on the pass template with placeholders such as {{externalId}}. Left unset, it falls back to the pass id. See In-store.

Endpoint summary

The complete surface a typical integration touches: Inbound to you: webhook deliveries, signed POSTs to your endpoint when a pass changes status or a transaction is recorded.