PO Box 55056 RPO Windermere, Edmonton, AB T6W 5B4, Canada

API Reference

Automate the pass lifecycle three ways: Flow invocable actions (no code), Apex (in-org code), and the REST API (external systems). All three drive the same engine and the same records.

Flow invocable actions

ActionInputsWhat it does
Generate PassrecordId, templateName, sendEmailCreates the pass and writes the signed add-to-wallet URL to the record.
Send MessagepassId | recordId, messagePush notification to one pass; use Bulk Actions for segments.
Switch TemplatepassId, templateNameChanges an installed pass's design in real time.
Expire PasspassId, expiryDateSets or clears expiry; expired passes move to the wallet's expired section.

Apex — upsertPasses and the PassRequest object

The core Apex entry point handles both creation and updates of digital passes:

// Build the request
PassRequest req = new PassRequest();
req.templatePassId     = template.Id;            // Template Pass record
req.passDetails        = new List<String>{ ... }; // ordered per Template Pass Field Content
req.passBarcodes       = new List<String>{ ... }; // ordered per Template Barcode
req.passSendToEmails   = new List<String>{ contact.Email };
req.whatId             = contact.Id;             // merged into the email template
// req.passId          = existingPassId;         // include to UPDATE instead of create

KemicardService.upsertPasses(new List<PassRequest>{ req });
  • Ordering is strict: values in passDetails and passBarcodes must match the Order defined on the Template Pass Field Content and Template Barcode records.
  • Updates: include passId and the server regenerates the pass and pushes the change to the member's wallet via APNs / Google Wallet API.
  • Optional inputs: passLocationDetails (name, latitude, longitude, altitude) and attachmentName.
  • All entry points are bulk-safe and respect the running user's CRUD/FLS.

Prefer clicks over code? The same pipeline is exposed as the Generate Pass invocable action for Flow — see the Flow Integration & Apex Action guide.

REST API

Base URL and bearer-token credentials are issued during onboarding. All endpoints are HTTPS-only.

EndpointMethodPurpose
/v1/passesPOSTIssue a pass for a record + template; returns the signed add-to-wallet URL.
/v1/passes/{id}GETPass status: installed, removed, last updated, last scanned.
/v1/passes/{id}PATCHUpdate fields, switch template, or trigger a push.
/v1/passes/{id}DELETERevoke the pass; the wallet copy is invalidated.
/v1/webhooksPOSTRegister a listener for pass events.

Webhook events

{
  "event": "pass.scanned",
  "passId": "kc_9f27ab",
  "recordId": "003XXXXXXXXXXXX",
  "template": "Gold_Member",
  "timestamp": "2026-07-24T16:02:11Z",
  "meta": { "scanMethod": "qr", "station": "Gate A" }
}

Events: pass.installed, pass.updated, pass.scanned, pass.removed. Deliveries are signed; verify the signature header before trusting payloads.

Error handling

  • 401 Unauthorized — named credential password wrong or user reset; re-enter credentials (see Troubleshooting).
  • 409 Conflict — provisioning mismatch; verify Org ID and licensing.
  • 429 Too Many Requests — back off; coordinate very large batches with support.

Getting API credentials

  1. Request REST access from your account manager — credentials are issued per org (sandbox and production separately).
  2. Store the bearer token in a protected credential store (Named Credential, secrets manager); never hard-code it.
  3. Rotate tokens on your normal secret-rotation cadence; old tokens can be revoked without downtime.

Rate limits & batching

  • Sustained request rates are generous for record-triggered use; for bursts above ~50 requests/second, use Bulk Actions or coordinate a send window with support.
  • Batch endpoints accept arrays of record IDs for issuance — prefer one batched call over hundreds of singles.
  • Webhook deliveries retry with exponential backoff for 24 hours; make your listener idempotent on passId + event + timestamp.

API FAQ

  • Can I call the REST API from Apex? You can, but in-org use is better served by the invocable actions — they respect CRUD/FLS and avoid callout limits.
  • Is there a sandbox base URL? Yes — sandbox credentials point at a staging endpoint so tests never touch production passes.
  • How do I test webhooks locally? Register a tunnel URL (e.g., a request-bin) as your listener in sandbox, inspect payloads, then move the subscription to your production endpoint.