### Installation Source: https://passmint.com/docs/sdk/node Install the Passmint Node.js SDK via npm. ```APIDOC ## Install ```bash npm install @passmint/node ``` ``` -------------------------------- ### Install the Passmint Node SDK Source: https://passmint.com/docs/quickstart Install the required package using npm to begin using the Passmint SDK in your project. ```bash npm install @passmint/node ``` -------------------------------- ### Install Passmint via npm Source: https://passmint.com/docs/passmint Install the package using the npm CLI. ```bash npm install passmint ``` -------------------------------- ### List templates with GET /v1/templates Source: https://passmint.com/docs/api Returns a list of non-archived templates. The limit parameter controls the number of results returned. ```bash curl "https://api.passmint.com/v1/templates?limit=10" \ -H "Authorization: Bearer pmk_test_xxx" ``` -------------------------------- ### Retrieve a template with GET /v1/templates/:id Source: https://passmint.com/docs/api Returns a single template by ID, including archived templates. ```bash curl https://api.passmint.com/v1/templates/tmpl_xxx \ -H "Authorization: Bearer pmk_test_xxx" ``` -------------------------------- ### GET /v1/webhooks Source: https://passmint.com/docs/webhooks Lists all webhooks registered for the authenticated account. ```APIDOC ## GET /v1/webhooks ### Description Lists all webhooks registered for the authenticated account. ### Method GET ### Endpoint /v1/webhooks ### Response #### Success Response (200) - **webhooks** (array) - List of webhook objects. #### Response Example ``` { "webhooks": [ { "id": "wh_xxx", "url": "https://example.com/webhooks/passmint", "events": ["pass.added_to_wallet"], "description": "Track wallet installs", "enabled": true } ] } ``` ``` -------------------------------- ### Output formats: toUint8Array, toStream, toResponse Source: https://passmint.com/docs/passmint Lists the three output methods available on a signed pass. toResponse() sets Content-Type: application/vnd.apple.pkpass and Content-Disposition: attachment so the pass installs on tap. ```javascript signed.toUint8Array() // Promise signed.toStream() // ReadableStream signed.toResponse(init?) // HTTP Response with content-type set ``` -------------------------------- ### Response Format Examples Source: https://passmint.com/docs/api Single objects include an object field for identification, while list endpoints wrap results in a standard envelope. ```json // Single object { "object": "pass", "id": "pass_xxx", ... } // List { "object": "list", "data": [...], "has_more": false } ``` -------------------------------- ### GET /v1/templates Source: https://passmint.com/docs/api Returns a list of non-archived templates. Supports a limit query parameter. ```APIDOC ## GET /v1/templates ### Description Returns a list of non-archived templates. ### Method GET ### Endpoint /v1/templates ### Parameters #### Query Parameters - **limit** (integer) - Optional - Number of results (default 50, max 100). ### Request Example ``` curl "https://api.passmint.com/v1/templates?limit=10" \ -H "Authorization: Bearer pmk_test_xxx" ``` ### Response #### Success Response (200) - **object** (string) - Always "template". - **id** (string) - Unique identifier (tmpl_xxx). - **name** (string) - Display name. - **type** (string) - One of: event, membership, coupon, loyalty, generic. - **apple_style** (string) - One of: eventTicket, generic, storeCard, coupon, boardingPass. - **design** (object) - Design configuration. - **archived** (boolean) - Whether the template is archived. - **created_at** (string) - ISO 8601 creation timestamp. - **updated_at** (string) - ISO 8601 last update timestamp. #### Response Example (Not provided in source) ``` -------------------------------- ### Passes - Update Source: https://passmint.com/docs/sdk/node Update a pass, pushing live updates to installed passes. ```APIDOC ## Passes - Update ### Description Updates a pass and pushes live updates to installed passes. Requires at least one of `fieldValues` or `metadata`. ### Method `passmint.passes.update` ### Parameters - `passId` (string) - Required - The ID of the pass to update. - `fieldValues` (object) - Optional - Field values to update. - `metadata` (object) - Optional - Metadata to update. - `options.idempotencyKey` (string) - Optional - Custom idempotency key. ### Request Example ```javascript const updated = await passmint.passes.update(pass.id, { fieldValues: { seatNumber: "B7" }, metadata: { upgraded: true }, }) ``` ### Response Returns the updated pass object. ``` -------------------------------- ### GET /v1/templates/:id Source: https://passmint.com/docs/api Returns a single template by ID, including archived templates. ```APIDOC ## GET /v1/templates/:id ### Description Returns a single template by ID, including archived templates. ### Method GET ### Endpoint /v1/templates/:id ### Parameters #### Path Parameters - **id** (string) - Required - The template ID (tmpl_xxx). ### Request Example ``` curl https://api.passmint.com/v1/templates/tmpl_xxx \ -H "Authorization: Bearer pmk_test_xxx" ``` ### Response #### Success Response (200) - **object** (string) - Always "template". - **id** (string) - Unique identifier (tmpl_xxx). - **name** (string) - Display name. - **type** (string) - One of: event, membership, coupon, loyalty, generic. - **apple_style** (string) - One of: eventTicket, generic, storeCard, coupon, boardingPass. - **design** (object) - Design configuration. - **archived** (boolean) - Whether the template is archived. - **created_at** (string) - ISO 8601 creation timestamp. - **updated_at** (string) - ISO 8601 last update timestamp. #### Response Example (Not provided in source) ``` -------------------------------- ### PassEvent object response structure Source: https://passmint.com/docs/api Example JSON response structure for a list of pass events. ```json { "object": "list", "data": [ { "object": "pass_event", "id": "psEvnt_xxx", "pass_id": "pass_xxx", "type": "installed", "metadata": {}, "created_at": "2026-04-16T13:00:00Z" } ], "has_more": false } ``` -------------------------------- ### GET /v1/passes Source: https://passmint.com/docs/api Returns a paginated list of passes, with optional filters by template and holder email. ```APIDOC ## GET /v1/passes ### Description Returns a paginated list of passes. ### Method GET ### Endpoint /v1/passes ### Parameters #### Query Parameters - **template_id** (string) - Optional - Filter by template. - **holder_email** (string) - Optional - Filter by holder email. - **limit** (integer) - Optional - Number of results (default 50, max 100). ### Request Example ``` curl "https://api.passmint.com/v1/passes?template_id=tmpl_xxx&limit=10" \ -H "Authorization: Bearer pmk_test_xxx" ``` ### Response #### Success Response (200) - **object** (string) - Always "list". - **data** (array) - Array of pass objects. - **has_more** (boolean) - Whether there are more results. #### Response Example ``` { "object": "list", "data": [{ "object": "pass", "id": "pass_xxx", ... }], "has_more": false } ``` ``` -------------------------------- ### Webhook payload format Source: https://passmint.com/docs/webhooks Example JSON payload delivered to your webhook endpoint. Contains event metadata and the affected pass object. ```json { "id": "psEvnt_abc123", "type": "pass.added_to_wallet", "created_at": "2026-04-16T12:00:00.000Z", "data": { "pass": { "id": "pass_xxx", "short_id": "abc123", "mode": "live", "holder_email": "alice@example.com", "holder_name": "Alice Johnson", "field_values": { "seatNumber": "A12" }, "voided": false }, "event": { "type": "installed", "metadata": null } } } ``` -------------------------------- ### Initialize SDK Source: https://passmint.com/docs/sdk/node Create a new Passmint client instance with your API key. ```APIDOC ## Initialize ```javascript import { Passmint } from "@passmint/node" const passmint = new Passmint({ apiKey: process.env.PASSMINT_API_KEY!, }) ``` ``` -------------------------------- ### GET /v1/webhooks/:id Source: https://passmint.com/docs/webhooks Retrieves a single webhook by its ID. ```APIDOC ## GET /v1/webhooks/:id ### Description Retrieves a single webhook by its ID. ### Method GET ### Endpoint /v1/webhooks/:id ### Parameters #### Path Parameters - **id** (string) - Required - The webhook ID. ### Response #### Success Response (200) - **id** (string) - Webhook identifier. - **url** (string) - The registered URL. - **events** (array) - Subscribed event types. - **description** (string) - Description of the webhook. - **enabled** (boolean) - Whether the webhook is enabled. #### Response Example ``` { "id": "wh_xxx", "url": "https://example.com/webhooks/passmint", "events": ["pass.added_to_wallet"], "description": "Track wallet installs", "enabled": true } ``` ``` -------------------------------- ### Configuration Options Source: https://passmint.com/docs/sdk/node Constructor options to control SDK behavior: apiKey, baseUrl, timeoutMs, maxRetries. ```APIDOC ## Configuration ```javascript const passmint = new Passmint({ apiKey: process.env.PASSMINT_API_KEY!, baseUrl: "https://api.passmint.com", // default timeoutMs: 30_000, // default maxRetries: 3, // default }) ``` - `apiKey`: required. Your secret API key. - `baseUrl`: override the API host, useful for proxies or self-hosted instances. - `timeoutMs`: per-request timeout in milliseconds. - `maxRetries`: automatic retries on network errors and 5xx responses. You can check the environment at runtime with `passmint.mode`, which returns `"test"` or `"live"` based on the key prefix. ``` -------------------------------- ### Initialize Passmint client Source: https://passmint.com/docs/sdk/node Import and instantiate the Passmint client with your API key from the environment. ```typescript import { Passmint } from "@passmint/node" const passmint = new Passmint({ apiKey: process.env.PASSMINT_API_KEY!, }) ``` -------------------------------- ### Create a webhook with curl Source: https://passmint.com/docs/webhooks Creates a webhook subscription with the Passmint API. Requires a valid API key and a publicly reachable URL. The signing secret is returned only once, so store it immediately. ```bash curl https://api.passmint.com/v1/webhooks \ -H "Authorization: Bearer pmk_test_xxx" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/webhooks/passmint", "events": ["pass.added_to_wallet", "pass.removed"], "description": "Track wallet installs" }' ``` -------------------------------- ### Create a template with POST /v1/templates Source: https://passmint.com/docs/api Creates a new pass template. Supports idempotency via the Idempotency-Key header. ```bash curl https://api.passmint.com/v1/templates \ -H "Authorization: Bearer pmk_test_xxx" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{ "name": "VIP Concert Pass", "type": "event", "apple_style": "eventTicket", "design": { ... } }' ``` ```json { "object": "template", "id": "tmpl_xxx", "name": "VIP Concert Pass", "type": "event", "apple_style": "eventTicket", "design": { ... }, "archived": false, "created_at": "2026-04-16T12:00:00Z", "updated_at": "2026-04-16T12:00:00Z" } ``` -------------------------------- ### Configure Passmint client options Source: https://passmint.com/docs/sdk/node Configure the client with baseUrl, timeoutMs, and maxRetries. baseUrl defaults to https://api.passmint.com, timeoutMs to 30000, and maxRetries to 3. ```typescript const passmint = new Passmint({ apiKey: process.env.PASSMINT_API_KEY!, baseUrl: "https://api.passmint.com", // default timeoutMs: 30_000, // default maxRetries: 3, // default }) ``` -------------------------------- ### Define a pass once and sign for Apple or generate Google save link Source: https://passmint.com/docs/passmint Shows the core workflow: build a Pass with the fluent API, then either sign it with Apple material to produce a pkpass, or generate a Google save link with Google material and allowed origins. ```javascript const pass = Pass.eventTicket({ /* ... */ }).build() const pkpass = await pass.sign(appleMaterial) const saveLink = await pass.toGoogleSaveLink(googleMaterial, { origins: ["example.com"], }) ``` -------------------------------- ### GET /v1/passes/:id/events Source: https://passmint.com/docs/api Lists events for a specific pass. Supports a limit query parameter to control the number of results returned. ```APIDOC ## [GET] /v1/passes/:id/events ### Description List events for a specific pass. ### Method GET ### Endpoint /v1/passes/:id/events ### Parameters #### Path Parameters - **id** (string) - Required - The ID of the pass. #### Query Parameters - **limit** (integer) - Optional - Number of results (default 100, max 200). ### Request Example ``` curl "https://api.passmint.com/v1/passes/pass_xxx/events?limit=20" \ -H "Authorization: Bearer pmk_test_xxx" ``` ### Response #### Success Response (200) - **object** (string) - Always "list". - **data** (array) - Array of pass_event objects. - **has_more** (boolean) - Indicates if there are more results. #### Response Example ``` { "object": "list", "data": [ { "object": "pass_event", "id": "psEvnt_xxx", "pass_id": "pass_xxx", "type": "installed", "metadata": {}, "created_at": "2026-04-16T13:00:00Z" } ], "has_more": false } ``` ``` -------------------------------- ### Issue a pass using the Passmint SDK Source: https://passmint.com/docs/quickstart Initialize the Passmint client with your API key and use the passes.create method to generate a pass URL for a specific template and user. ```typescript import { Passmint } from "@passmint/node" const passmint = new Passmint({ apiKey: process.env.PASSMINT_API_KEY!, }) const pass = await passmint.passes.create({ templateId: "tmpl_xxx", holderEmail: "alice@example.com", holderName: "Alice Johnson", fieldValues: { seatNumber: "A12", section: "Floor", }, }) console.log(pass.url) // → https://passmint.com/p/abc123def456 ``` -------------------------------- ### Templates - Create Source: https://passmint.com/docs/sdk/node Create a new template. ```APIDOC ## Templates - Create ### Description Creates a new template for passes. ### Method `passmint.templates.create` ### Parameters - `name` (string) - Required - Name of the template. - `type` (string) - Required - Type of template: `"event"`, `"membership"`, `"coupon"`, `"loyalty"`, or `"generic"`. - `appleStyle` (string) - Required - Apple Wallet style: `"eventTicket"`, `"generic"`, `"storeCard"`, `"coupon"`, or `"boardingPass"`. - `design` (object) - Required - Design configuration. - `starterTemplateId` (string) - Optional - ID of a starter template. ### Request Example ```javascript const tpl = await passmint.templates.create({ name: "VIP Membership", type: "membership", appleStyle: "storeCard", design: { /* your design config */ }, starterTemplateId: "starter_xxx", // optional }) ``` ### Response Returns the created template object. ``` -------------------------------- ### GET /v1/events Source: https://passmint.com/docs/api Lists recent events across all passes. Supports a limit query parameter to control the number of results returned. ```APIDOC ## [GET] /v1/events ### Description List recent events across all passes. ### Method GET ### Endpoint /v1/events ### Parameters #### Query Parameters - **limit** (integer) - Optional - Number of results (default 100, max 200). ### Request Example ``` curl "https://api.passmint.com/v1/events?limit=50" \ -H "Authorization: Bearer pmk_test_xxx" ``` ### Response #### Success Response (200) - **object** (string) - Always "list". - **data** (array) - Array of pass_event objects. - **has_more** (boolean) - Indicates if there are more results. #### Response Example ``` { "object": "list", "data": [ { "object": "pass_event", "id": "psEvnt_xxx", "pass_id": "pass_xxx", "type": "installed", "metadata": {}, "created_at": "2026-04-16T13:00:00Z" } ], "has_more": false } ``` ``` -------------------------------- ### GET /v1/webhooks/:id/deliveries Source: https://passmint.com/docs/webhooks Inspects recent delivery attempts for a specific webhook, including HTTP status, response body, and timestamps. ```APIDOC ## GET /v1/webhooks/:id/deliveries ### Description Inspects recent delivery attempts for a specific webhook, including HTTP status, response body, and timestamps. ### Method GET ### Endpoint /v1/webhooks/:id/deliveries ### Parameters #### Path Parameters - **id** (string) - Required - The webhook ID. ### Response #### Success Response (200) - **deliveries** (array) - List of delivery records. - **status** (string) - Delivery status: `pending`, `delivered`, `failed`, or `dead`. - **http_status** (integer) - HTTP status code returned by the endpoint. - **response_body** (string) - Response body, truncated to 2,000 characters. - **timestamps** (object) - Timestamps for the delivery attempt. #### Response Example ``` { "deliveries": [ { "status": "delivered", "http_status": 200, "response_body": "OK", "timestamps": { "attempted_at": "2026-04-16T12:00:00.000Z" } } ] } ``` ``` -------------------------------- ### Create an expiring download link Source: https://passmint.com/docs/api Mints a time-limited link to the pass page. The link stops resolving after the specified expiration time. ```bash curl https://api.passmint.com/v1/passes/pass_xxx/download-links \ -H "Authorization: Bearer pmk_test_xxx" \ -H "Content-Type: application/json" \ -d '{ "expires_in": 3600 }' ``` ```json { "object": "pass.download_link", "pass_id": "pass_xxx", "url": "https://passmint.com/p/dl/pdl_mF4jK...", "expires_in": 3600, "expires_at": "2026-04-16T13:00:00Z", "created_at": "2026-04-16T12:00:00Z" } ``` -------------------------------- ### Manage templates with Passmint SDK Source: https://passmint.com/docs/sdk/node Create, retrieve, list, update, and archive templates. The type parameter accepts "event", "membership", "coupon", "loyalty", or "generic". The appleStyle parameter accepts "eventTicket", "generic", "storeCard", "coupon", or "boardingPass". ```typescript // Create a template const tpl = await passmint.templates.create({ name: "VIP Membership", type: "membership", appleStyle: "storeCard", design: { /* your design config */ }, starterTemplateId: "starter_xxx", // optional }) // Retrieve a template const fetched = await passmint.templates.retrieve("tmpl_xxx") // List all templates const templates = await passmint.templates.list() // Update a template const updated = await passmint.templates.update("tmpl_xxx", { name: "Premium Membership", design: { /* updated design */ }, archived: false, }) // Archive a template const result = await passmint.templates.archive("tmpl_xxx") // { id: "tmpl_xxx", deleted: true } ``` -------------------------------- ### PATCH /v1/passes/:id Source: https://passmint.com/docs/api Updates the field values or metadata on a pass. Cannot update voided passes. Live updates are pushed to installed passes automatically. Supports idempotency. ```APIDOC ## PATCH /v1/passes/:id ### Description Update the field values or metadata on a pass. At least one of `field_values` or `metadata` is required. Cannot update voided passes (returns `400`). Live updates are pushed to installed passes automatically. Supports idempotency. ### Method PATCH ### Endpoint /v1/passes/:id ### Parameters #### Path Parameters - **id** (string) - Required - The pass ID. #### Request Body - **field_values** (Record) - Updated field values. - **metadata** (Record) - Updated metadata. ### Request Example ``` curl -X PATCH https://api.passmint.com/v1/passes/pass_xxx \ -H "Authorization: Bearer pmk_test_xxx" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{ "field_values": { "seatNumber": "B7" } }' ``` ### Response #### Success Response (200) - **object** (string) - Always "pass". - **id** (string) - The pass ID. - **short_id** (string) - Short identifier. - **template_id** (string) - The template ID. - **serial_number** (string) - Serial number. - **mode** (string) - Mode (e.g., test). - **holder_email** (string) - Email of the holder. - **holder_name** (string) - Name of the holder. - **field_values** (object) - Field values. - **voided** (boolean) - Whether the pass is voided. - **voided_at** (string or null) - Void timestamp. - **metadata** (object) - Metadata. - **created_via_api** (boolean) - Whether created via API. - **url** (string) - Permanent URL. - **download_url** (string) - Download URL. - **created_at** (string) - Creation timestamp. #### Response Example ``` { "object": "pass", "id": "pass_xxx", "short_id": "abc123", "template_id": "tmpl_xxx", "serial_number": "...", "mode": "test", "holder_email": "alice@example.com", "holder_name": "Alice Johnson", "field_values": { "seatNumber": "A12" }, "voided": false, "voided_at": null, "metadata": { "order_id": "ord_123" }, "created_via_api": true, "url": "https://passmint.com/p/abc123", "download_url": "https://passmint.com/p/abc123/download", "created_at": "2026-04-16T12:00:00Z" } ``` ``` -------------------------------- ### Templates - List Source: https://passmint.com/docs/sdk/node List all templates. ```APIDOC ## Templates - List ### Description Lists all templates. ### Method `passmint.templates.list` ### Request Example ```javascript const templates = await passmint.templates.list() ``` ### Response Returns a list of template objects. ``` -------------------------------- ### Create a webhook Source: https://passmint.com/docs/api Registers a new webhook endpoint. The response contains the secret key, which is only returned once and must be stored securely. ```bash curl https://api.passmint.com/v1/webhooks \ -H "Authorization: Bearer pmk_test_xxx" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/webhooks/passmint", "events": ["pass.issued", "pass.added_to_wallet"], "description": "Production webhook" }' ``` ```json { "object": "webhook", "id": "whk_xxx", "url": "https://example.com/webhooks/passmint", "events": ["pass.issued", "pass.added_to_wallet"], "description": "Production webhook", "enabled": true, "secret": "whsec_xxx", "created_at": "2026-04-16T12:00:00Z" } ``` -------------------------------- ### List webhooks Source: https://passmint.com/docs/api Retrieves all webhooks associated with the account. ```bash curl https://api.passmint.com/v1/webhooks \ -H "Authorization: Bearer pmk_test_xxx" ``` -------------------------------- ### Authentication Source: https://passmint.com/docs/api Pass your API key as a Bearer token in the Authorization header. Test keys use the pmk_test_ prefix and live keys use pmk_live_. The mode is determined by the key prefix. ```APIDOC ## Authentication ### Description Pass your API key as a Bearer token in the Authorization header. Test keys use the pmk_test_ prefix and live keys use pmk_live_. The mode (test or live) is determined by the key prefix. Test keys are available on every plan; live keys require a paid plan. ### Header Authorization: Bearer pmk_test_xxx ### Example Authorization: Bearer pmk_test_xxx ``` -------------------------------- ### Use idempotency keys with Passmint SDK Source: https://passmint.com/docs/sdk/node Pass your own idempotency key to create() and update() for deterministic replay. Keys are scoped per organization, expire after 24 hours, and replayed requests return the original response. ```typescript await passmint.passes.create( { templateId: "tmpl_xxx", holderEmail: "alice@example.com" }, { idempotencyKey: "purchase_42" }, ) await passmint.passes.update( "pass_xxx", { fieldValues: { seatNumber: "C3" } }, { idempotencyKey: "upgrade_42" }, ) ``` -------------------------------- ### Authentication Header Source: https://passmint.com/docs/api Pass your API key as a Bearer token in the Authorization header. Use the pmk_test_ prefix for test keys and pmk_live_ for live keys. ```http Authorization: Bearer pmk_test_xxx ``` -------------------------------- ### Platform-specific escape hatch with applyRaw Source: https://passmint.com/docs/passmint Shows how to pass Apple and Google specific fields not modeled by the unified schema. applyRaw.apple deep-merges into pass.json, applyRaw.google deep-merges into the generated Google object. ```javascript Pass.eventTicket({ // ... applyRaw: { apple: { sharingProhibited: true }, google: { smartTapRedemptionValue: "nfc-payload" }, }, }) ``` -------------------------------- ### POST /v1/templates Source: https://passmint.com/docs/api Creates a new pass template. Supports idempotency. Required fields include name, type, apple_style, and design. ```APIDOC ## POST /v1/templates ### Description Create a new pass template. Supports idempotency. ### Method POST ### Endpoint /v1/templates ### Parameters #### Request Body - **name** (string) - Required - Display name for the template. - **type** (string) - Required - One of: event, membership, coupon, loyalty, generic. - **apple_style** (string) - Required - One of: eventTicket, generic, storeCard, coupon, boardingPass. - **design** (object) - Required - Design configuration for the template. - **require_download_link** (boolean) - Optional - Default false. When true, the permanent pass URLs 404 and passes on this template are only reachable through expiring download links. ### Request Example ``` curl https://api.passmint.com/v1/templates \ -H "Authorization: Bearer pmk_test_xxx" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{ "name": "VIP Concert Pass", "type": "event", "apple_style": "eventTicket", "design": { ... } }' ``` ### Response #### Success Response (200) - **object** (string) - Always "template". - **id** (string) - Unique identifier (tmpl_xxx). - **name** (string) - Display name. - **type** (string) - One of: event, membership, coupon, loyalty, generic. - **apple_style** (string) - One of: eventTicket, generic, storeCard, coupon, boardingPass. - **design** (object) - Design configuration. - **archived** (boolean) - Whether the template is archived. - **created_at** (string) - ISO 8601 creation timestamp. - **updated_at** (string) - ISO 8601 last update timestamp. #### Response Example ``` { "object": "template", "id": "tmpl_xxx", "name": "VIP Concert Pass", "type": "event", "apple_style": "eventTicket", "design": { ... }, "archived": false, "created_at": "2026-04-16T12:00:00Z", "updated_at": "2026-04-16T12:00:00Z" } ``` ``` -------------------------------- ### Verify webhook signature with Node SDK Source: https://passmint.com/docs/webhooks Verifies webhook signatures using the Node SDK's constructEvent method. Requires the PASSMINT_API_KEY and PASSMINT_WEBHOOK_SECRET environment variables. The default tolerance is 5 minutes; older signatures are rejected. ```typescript import { Passmint } from "@passmint/node" const passmint = new Passmint({ apiKey: process.env.PASSMINT_API_KEY!, }) // In your webhook handler const event = passmint.webhooks.constructEvent( rawBody, request.headers["passmint-signature"]!, process.env.PASSMINT_WEBHOOK_SECRET!, ) switch (event.type) { case "pass.added_to_wallet": // Handle install break case "pass.removed": // Handle removal break } ``` -------------------------------- ### Issue a pass Source: https://passmint.com/docs/api Create a new pass from a template. This request supports idempotency via the Idempotency-Key header. ```bash curl https://api.passmint.com/v1/passes \ -H "Authorization: Bearer pmk_test_xxx" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{ "template_id": "tmpl_xxx", "holder_email": "alice@example.com", "holder_name": "Alice Johnson", "field_values": { "seatNumber": "A12" }, "metadata": { "order_id": "ord_123" } }' ``` ```json { "object": "pass", "id": "pass_xxx", "short_id": "abc123", "template_id": "tmpl_xxx", "serial_number": "...", "mode": "test", "holder_email": "alice@example.com", "holder_name": "Alice Johnson", "field_values": { "seatNumber": "A12" }, "voided": false, "voided_at": null, "metadata": { "order_id": "ord_123" }, "created_via_api": true, "url": "https://passmint.com/p/abc123", "download_url": "https://passmint.com/p/abc123/download", "created_at": "2026-04-16T12:00:00Z" } ``` -------------------------------- ### Passes - Create Source: https://passmint.com/docs/sdk/node Create a new pass using a template. ```APIDOC ## Passes - Create ### Description Creates a new pass based on a template. ### Method `passmint.passes.create` ### Parameters - `templateId` (string) - Required - The ID of the template to use. - `holderEmail` (string) - Required - Email of the pass holder. - `fieldValues` (object) - Optional - Field values for the pass. - `options.idempotencyKey` (string) - Optional - Custom idempotency key. ### Request Example ```javascript const pass = await passmint.passes.create({ templateId: "tmpl_xxx", holderEmail: "alice@example.com", fieldValues: { seatNumber: "A12" }, }, { idempotencyKey: "purchase_42" }) ``` ### Response Returns the created pass object. ``` -------------------------------- ### Sign Apple Wallet Passes Source: https://passmint.com/docs/passmint Load signing material from PEM files and create a signed Apple Wallet pass. Keys must be in PKCS#8 PEM format. ```typescript import { Pass, SigningMaterial } from "passmint" const material = await SigningMaterial.fromPem({ signerCertPem: process.env.APPLE_PASS_CERT!, wwdrPem: process.env.APPLE_WWDR_CERT!, privateKeyPkcs8Pem: process.env.APPLE_PASS_KEY!, }) const signed = await Pass.eventTicket({ passTypeIdentifier: "pass.com.example.event", serialNumber: crypto.randomUUID(), teamIdentifier: "ABCD1234EF", organizationName: "Example", description: "Concert ticket", images: { icon: { x2: { bytes: iconPng } } }, barcodes: [{ format: "qr", message: "TICKET-xyz" }], }) .primaryField({ key: "event", label: "Event", value: "Beyoncé Live" }) .secondaryField({ key: "loc", label: "Location", value: "Apple Park" }) .sign(material) ``` -------------------------------- ### Templates - Retrieve Source: https://passmint.com/docs/sdk/node Retrieve a template by ID. ```APIDOC ## Templates - Retrieve ### Description Fetches a single template by its ID. ### Method `passmint.templates.retrieve` ### Parameters - `templateId` (string) - Required - The ID of the template. ### Request Example ```javascript const fetched = await passmint.templates.retrieve("tmpl_xxx") ``` ### Response Returns the template object. ``` -------------------------------- ### Verify webhook signatures with Passmint SDK Source: https://passmint.com/docs/sdk/node Construct a webhook event from the raw body and signature header. The toleranceSeconds parameter defaults to 300 seconds; events with timestamps outside the window are rejected. Throws PassmintError on invalid signature or timestamp. ```typescript const event = passmint.webhooks.constructEvent( rawBody, request.headers["passmint-signature"]!, process.env.PASSMINT_WEBHOOK_SECRET!, 300, // tolerance in seconds (default: 300) ) ``` -------------------------------- ### POST /v1/passes/:id/download-links Source: https://passmint.com/docs/api Mints a time-limited link to the pass page, the expiring alternative to the permanent url on the pass object. The link works like the permanent one until expires_at, after which it stops resolving. ```APIDOC ## POST /v1/passes/:id/download-links ### Description Mints a time-limited link to the pass page, the expiring alternative to the permanent `url` on the pass object. The link works exactly like the permanent one (Apple Wallet download, Google Wallet save, QR handoff) until `expires_at`, after which it stops resolving and the holder is told to request a fresh one. Mint a new link per delivery; links are independent and minting one never invalidates another. Be clear-eyed about what expiry protects. The link itself, in an email, a support thread, a log line, a forwarded message. It does not time-limit the pass. A `.pkpass` downloaded before expiry is a signed file on the holder's device, barcode included, and no link expiry can reach it. To control _redemption_ , use redemption policies and the scanner, not download links. To make expiring links the _only_ way in, disabling the permanent URL entirely, set `require_download_link` on the template. ### Method POST ### Endpoint /v1/passes/:id/download-links ### Parameters #### Path Parameters - **id** (string) - Required - The pass ID. #### Request Body - **expires_in** (integer) - Optional - Lifetime in seconds. Default 3600 (one hour), minimum 60, maximum 604800 (7 days). ### Request Example ``` curl https://api.passmint.com/v1/passes/pass_xxx/download-links \ -H "Authorization: Bearer pmk_test_xxx" \ -H "Content-Type: application/json" \ -d '{ "expires_in": 3600 }' ``` ### Response #### Success Response (200) - **object** (string) - Always "pass.download_link". - **pass_id** (string) - The pass this link resolves to. - **url** (string) - The link to hand to your customer. Contains the one-time-visible token. Passmint stores only a hash, so this is the only place the URL ever appears. - **expires_in** (integer) - Lifetime in seconds, as requested. - **expires_at** (string) - ISO 8601 expiry timestamp. - **created_at** (string) - ISO 8601 creation timestamp. #### Response Example ``` { "object": "pass.download_link", "pass_id": "pass_xxx", "url": "https://passmint.com/p/dl/pdl_mF4jK...", "expires_in": 3600, "expires_at": "2026-04-16T13:00:00Z", "created_at": "2026-04-16T12:00:00Z" } ``` ``` -------------------------------- ### List passes Source: https://passmint.com/docs/api Returns a paginated list of passes, with optional filtering by template or holder email. ```bash curl "https://api.passmint.com/v1/passes?template_id=tmpl_xxx&limit=10" \ -H "Authorization: Bearer pmk_test_xxx" ``` ```json { "object": "list", "data": [{ "object": "pass", "id": "pass_xxx", ... }], "has_more": false } ``` -------------------------------- ### Manage passes with Passmint SDK Source: https://passmint.com/docs/sdk/node Create, retrieve, list, update, void, and fetch events for passes. update() requires at least one of fieldValues or metadata; voided passes cannot be updated. ```typescript // Create a pass const pass = await passmint.passes.create({ templateId: "tmpl_xxx", holderEmail: "alice@example.com", fieldValues: { seatNumber: "A12" }, }, { idempotencyKey: "purchase_42" }) // Retrieve a single pass const fetched = await passmint.passes.retrieve(pass.id) // List passes with optional filters const list = await passmint.passes.list({ limit: 100 }) // Update a pass — pushes live updates to installed passes const updated = await passmint.passes.update(pass.id, { fieldValues: { seatNumber: "B7" }, metadata: { upgraded: true }, }) // Void a pass await passmint.passes.void(pass.id) // Fetch pass events const events = await passmint.passes.events(pass.id) ``` -------------------------------- ### Idempotency Source: https://passmint.com/docs/api Send an Idempotency-Key header on POST and PATCH requests to safely retry without duplicating side effects. Replays within 24 hours return the cached response. Reusing a key with a different request body returns 409. ```APIDOC ## Idempotency ### Description Send an Idempotency-Key header on POST and PATCH requests to safely retry without duplicating side effects. Replays within 24 hours return the cached response. Reusing a key with a different request body returns 409. ### Header Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7 ### Example Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7 ``` -------------------------------- ### Idempotency Source: https://passmint.com/docs/sdk/node Idempotency behavior for create and update methods. ```APIDOC ## Idempotency Both `create()` and `update()` methods auto-generate an idempotency key if you don't provide one. You can pass your own for deterministic replay: ```javascript await passmint.passes.create( { templateId: "tmpl_xxx", holderEmail: "alice@example.com" }, { idempotencyKey: "purchase_42" }, ) await passmint.passes.update( "pass_xxx", { fieldValues: { seatNumber: "C3" } }, { idempotencyKey: "upgrade_42" }, ) ``` - Keys are scoped per organization. - Keys expire after 24 hours. - Replayed requests return the original response without re-executing the operation. ``` -------------------------------- ### Passes - Void Source: https://passmint.com/docs/sdk/node Void a pass. ```APIDOC ## Passes - Void ### Description Voids a pass. Voided passes cannot be updated. ### Method `passmint.passes.void` ### Parameters - `passId` (string) - Required - The ID of the pass to void. ### Request Example ```javascript await passmint.passes.void(pass.id) ``` ### Response No content. ``` -------------------------------- ### Update a webhook Source: https://passmint.com/docs/api Updates properties of an existing webhook, such as the URL, subscribed events, description, or enabled status. ```bash curl -X PATCH https://api.passmint.com/v1/webhooks/whk_xxx \ -H "Authorization: Bearer pmk_test_xxx" \ -H "Content-Type: application/json" \ -d '{ "events": ["*"], "description": "All events" }' ``` -------------------------------- ### Error Handling Source: https://passmint.com/docs/sdk/node Typed errors for branching cleanly. ```APIDOC ## Errors The SDK throws typed errors: - `PassmintError`: base class for all SDK errors. - `PassmintAPIError`: non-2xx response. Includes `status`, `type`, `code`, and `param` properties. - `PassmintAuthError`: thrown on 401/403 responses (bad, expired, or revoked API key). - `PassmintRateLimitError`: includes a `retryAfterSeconds` property with the number of seconds to wait before retrying. ```javascript import { PassmintError, PassmintAPIError, PassmintAuthError, PassmintRateLimitError, } from "@passmint/node" try { await passmint.passes.create({ /* ... */ }) } catch (err) { if (err instanceof PassmintRateLimitError) { console.log(`Retry after ${err.retryAfterSeconds}s`) } else if (err instanceof PassmintAuthError) { console.log("Check your API key") } else if (err instanceof PassmintAPIError) { console.log(err.status, err.code, err.param) } } ``` ```