@addpass/api
v0.1.3
Published
TypeScript SDK for the AddPass developer API.
Maintainers
Readme
@addpass/api
TypeScript SDK for the AddPass developer API. It wraps the /generate endpoint with batteries-included validation, normalization, retry helpers, and a fluent builder so you can create Wallet .pkpass files quickly and safely.
Quick links
- Get started at:: https://addpass.io/api
- Support: [email protected]
Installation
npm install @addpass/api
# or: pnpm add @addpass/api
# or: yarn add @addpass/api- Node 18+ is required (native
fetch). - If your runtime lacks
fetch, installnode-fetchand inject it vianew AddPass(..., { fetch }).
Quick start
Node / server runtime
import { AddPass } from '@addpass/api';
const client = new AddPass(process.env.ADDPASS_KEY!, {
retries: 2,
telemetry: { project: 'ticketing-service' },
});
const payload = {
primaryText: 'Summer Gala',
secondaryLabelLeft: 'Date',
secondaryTextLeft: 'Aug 24, 2025',
qrCodeText: 'https://example.com/check-in/ABC123',
};
const buffer = await client.generate(payload, { accept: 'pkpass' });
// → Buffer ready to write to disk or send to the browserStream straight to disk:
await client.generateToFile(payload, { path: 'summer-gala.pkpass' });Preview (dev/QA) returns a short-lived link:
const link = await client.generate(payload, { accept: 'json', delivery: 'link' });
console.log(link.passUrl); // Expires quickly; use for QA onlyBrowser usage
import { AddPassBrowser } from '@addpass/api/browser';
const browserClient = new AddPassBrowser({ endpoint: '/api/passes' });
// Preview a pass link (your endpoint must proxy requests to AddPass)
const link = await browserClient.generate(payload, { accept: 'json' });
// Or trigger a download directly
await browserClient.download(payload, { fileName: 'guest-pass.pkpass' });The browser SDK always posts to your endpoint. That endpoint should authenticate the caller, attach your AddPass API key, and forward the request to AddPass.
Response modes
AddPass supports two delivery styles:
- Stream (default): binary response with
Content-Type: application/vnd.apple.pkpass. - Link (preview): JSON payload
{ message, passId, passUrl, expiresAt }. The link expires quickly and is intended for QA/temporary previews only.
How the SDK selects a mode
accept: 'pkpass' | 'json'→ setsAccepttoapplication/vnd.apple.pkpassorapplication/json.- Optional
delivery: 'stream' | 'link'→ setsX-AddPass-Deliveryto force the mode (the API honors this). - The Node client adds
User-Agent: addpass-node/<version>andContent-Type: application/json. Browsers do not allow custom user-agent strings.
Delivery patterns
Server proxy stream (recommended)
Your server callsAddPass.generateand returns the buffer withContent-Type: application/vnd.apple.pkpass. Keeps passes transient and avoids storage/CORS.Private bucket + short-lived signed URL
Generate the pkpass (stream), store it in a private bucket, mint a V4 signed URL (TTL 60–180s), and return that link. Great for async workflows and email links.One-time token
Return an opaque token; on download, stream the pkpass once and invalidate the token. Zero link sharing after first use.
Pick the pattern that matches your security posture and distribution model. Avoid long-lived public URLs; .pkpass files often contain user-specific data.
Validation & normalization
normalizePayload tidies developer-friendly aliases before validation:
- Color aliases (
colors.background/foreground/label) → hex with a leading#, uppercased. - Aliases like
backfields,qrCode,primaryLabel,secondary[],auxiliary[],locationLat/Longare mapped to canonical fields. qrCodeText→ auto-createdbarcode{ format: 'qr', message, messageEncoding: 'iso-8859-1' }if nobarcodeprovided.expirationDate→date. Empty strings removed. No mutation of original objects.
validatePayload enforces AddPass limits:
primaryTextis required (1–36 chars).- Header/secondary/aux labels and values are length-checked.
- URLs must be http(s); barcodes must use
qr,aztec, orpdf417with messages ≤ 256 chars. - Locations require both
latandlong; back fields capped at 30 entries.
strictMode controls behavior:
'error'(default): throwAddPassValidationErroron issues.'strip': trim/omit overflow values; still enforce required fields.'passthrough': skip validation.
Both Node and browser clients honor constructor-level strictMode. You can also call the helpers directly.
Fluent builder
AddPassBuilder provides a chainable interface:
import { AddPassBuilder } from '@addpass/api';
const builder = new AddPassBuilder()
.primary('VIP Access')
.headerRight({ label: 'Seat', text: 'A12' })
.secondaryLeft({ label: 'Date', text: 'Aug 24, 2025' })
.qr('https://example.com/check-in/SEAT-A12')
.validate('strip');
const payload = builder.payload();
const buffer = await builder.build(client); // delegates to AddPass.generateMethods include: .primary(), .logoText(), .colors({ bg, fg, label }), .headerRight(), .secondaryLeft()/Right(), .auxLeft()/Right(), .thumbnail(), .customLogo(), .qr(), .barcode(), .serial(), .relevantDate(), .legacyDate(), .location(), .backField(), .backFields(), .merge(), .validate(), .payload(), .build().
Timeouts, retries & telemetry
- Default timeout is 30s. Override per call (
{ timeoutMs }) or at the client level. - Retries default to 0. Configure
{ retries, retryOn, backoffMs }as needed (e.g., retry on 429/5xx). - Telemetry (opt-in): adds
X-AddPass-SDK: node-<ver>orweb-<ver>and optionalX-AddPass-Project: <name>for aggregate metrics.
Rate-limit etiquette
The AddPass developer API enforces rolling windows. Avoid large bursts; use backoff on 429 responses (the default retry profile treats 429/5xx as retryable).
Browser notes
- CORS is only required if you
fetch()a signed URL. A plain<a href>to a signed URL does not need CORS. - Downloads rely on the DOM. In non-browser contexts (e.g., React Native), write the
ArrayBuffervia environment-specific APIs.
Examples
- Next.js App Router proxy (server streaming)
- Next.js signed URL pattern (private bucket, short TTL)
- Browser client usage
Find examples and the latest API reference at https://app.addpass.io/api.
License
MIT © AddPass
