Skip to content
Skip to content

API Documentation

Integrate with Passinstance: REST APIs, webhooks, and examples for Apple and Google Wallet passes.

REST APIOpenAPI 3.0JSON ResponsesJWT Authentication

Getting Started

Start building with Passinstance API in minutes. Follow our step-by-step guide to create your first digital pass.

1

Get API Keys

Sign up and generate your API keys from the Passinstance dashboard.

Get Started
2

Create Template

Design your pass template with custom fields, colors, and branding.

POST /templates
3

Generate Passes

Create individual passes from your template with dynamic data.

POST /passes

Quick Start Example

Here's a complete example of creating your first pass in just a few API calls:

Step 1: Create a Template

curl -X POST "https://api.passinstance.com/templates"   -H "Authorization: Bearer your_jwt_token"   -H "Content-Type: application/json"   -d '{ 
    "name": "VIP Event Ticket",
    "description": "Exclusive access ticket template",
    "passType": "eventTicket",
    "organizationName": "Passinstance Events",
    "teamIdentifier": "TEAM123456789",
    "passTypeIdentifier": "pass.com.passinstance.event",
    "backgroundColor": "#1f2937",
    "foregroundColor": "#ffffff",
    "labelColor": "#9ca3af"
  }'

Step 2: Create a Pass

curl -X POST "https://api.passinstance.com/passes"   -H "Authorization: Bearer your_jwt_token"   -H "Content-Type: application/json"   -d '{ 
    "templateId": "tpl_abcdef1234567890",
    "serialNumber": "VIP2024-001",
    "customFields": {
      "customerName": {
        "value": "John Doe",
        "label": "Guest Name"
      },
      "eventDate": {
        "value": "Dec 15, 2024 at 7:00 PM",
        "label": "Event Date"
      },
      "seat": {
        "value": "Section A, Row 5, Seat 12",
        "label": "Seat Assignment"
      }
    },
    "relevantDate": "2024-12-15T19:00:00Z",
    "expirationDate": "2024-12-16T02:00:00Z"
  }'

Step 3: Send Push Notification

curl -X POST "https://api.passinstance.com/passes/pass_1234567890abcdef/push-notifications"   -H "Authorization: Bearer your_jwt_token"   -H "Content-Type: application/json"   -d '{ 
    "message": "Event starting in 30 minutes!"
  }'
Introduction

Authentication

Passinstance API uses JWT (JSON Web Tokens) and API keys for secure authentication

JWT Bearer Token

Include your JWT token in the Authorization header for all authenticated requests:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

🔒 Recommended

JWT tokens provide secure, time-limited access and include user context.

API Key

Use API keys for server-to-server communication:

X-API-Key: pk_live_1234567890abcdef1234567890abcdef

⚠️ Keep Secure

Never expose API keys in client-side code or public repositories.

Common Error Codes

CodeDescriptionSolution
401UnauthorizedCheck your API key or JWT token
403ForbiddenInsufficient permissions for this resource
404Not FoundResource doesn't exist or has been deleted
422Validation ErrorCheck request body format and required fields
429Rate LimitedSlow down requests or upgrade your plan

Code Examples

Ready-to-use code snippets in popular programming languages

JavaScript / Node.js

const axios = require('axios');

// Create a new pass
async function createPass() {
  try {
    const response = await axios.post(
      'https://api.passinstance.com/passes',
      {
        templateId: 'tpl_abcdef1234567890',
        serialNumber: 'EVENT2024-001',
        customFields: {
          customerName: {
            value: 'John Doe',
            label: 'Guest Name'
          }
        }
      },
      {
        headers: {
          'Authorization': 'Bearer your_jwt_token',
          'Content-Type': 'application/json'
        }
      }
    );
    
    console.log('Pass created:', response.data);
    return response.data;
  } catch (error) {
    console.error('Error:', error.response.data);
  }
}

Python

import requests
import json

# Create a new pass
def create_pass():
    url = "https://api.passinstance.com/passes"
    
    headers = {
        "Authorization": "Bearer your_jwt_token",
        "Content-Type": "application/json"
    }
    
    data = {
        "templateId": "tpl_abcdef1234567890",
        "serialNumber": "EVENT2024-001",
        "customFields": {
            "customerName": {
                "value": "John Doe",
                "label": "Guest Name"
            }
        }
    }
    
    try:
        response = requests.post(url, headers=headers, json=data)
        response.raise_for_status()
        
        print("Pass created:", response.json())
        return response.json()
    except requests.exceptions.RequestException as e:
        print("Error:", e)

Ruby

require 'net/http'
require 'uri'
require 'json'

# Create a new pass
def create_pass
  uri = URI('https://api.passinstance.com/passes')
  
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  
  request = Net::HTTP::Post.new(uri)
  request['Authorization'] = 'Bearer your_jwt_token'
  request['Content-Type'] = 'application/json'
  
  request.body = {
    templateId: 'tpl_abcdef1234567890',
    serialNumber: 'EVENT2024-001',
    customFields: {
      customerName: {
        value: 'John Doe',
        label: 'Guest Name'
      }
    }
  }.to_json
  
  begin
    response = http.request(request)
    
    if response.code == '201'
      puts "Pass created: #{JSON.parse(response.body)}"
    else
      puts "Error: #{response.body}"
    end
  rescue => e
    puts "Error: #{e.message}"
  end
end

PHP

<?php
// Create a new pass
function createPass() {
    $url = 'https://api.passinstance.com/passes';
    
    $headers = [
        'Authorization: Bearer your_jwt_token',
        'Content-Type: application/json'
    ];
    
    $data = json_encode([
        'templateId' => 'tpl_abcdef1234567890',
        'serialNumber' => 'EVENT2024-001',
        'customFields' => [
            'customerName' => [
                'value' => 'John Doe',
                'label' => 'Guest Name'
            ]
        ]
    ]);
    
    $curl = curl_init();
    
    curl_setopt_array($curl, [
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $data,
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_SSL_VERIFYPEER => true
    ]);
    
    $response = curl_exec($curl);
    $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    curl_close($curl);
    
    if ($httpCode === 201) {
        echo "Pass created: " . $response;
    } else {
        echo "Error: " . $response;
    }
}
?>

Webhook Integration

Receive real-time notifications when passes are created, updated, or deleted

Setting up Webhooks

Register a webhook URL to receive notifications about pass events:

curl -X POST "https://api.passinstance.com/webhooks"   -H "Authorization: Bearer your_jwt_token"   -H "Content-Type: application/json"   -d '{ 
    "url": "https://your-app.com/webhooks/passinstance",
    "events": [
      "pass.created",
      "pass.updated", 
      "pass.voided",
      "template.created"
    ],
    "secret": "your_webhook_secret_key"
  }'

Webhook Payload Example

Your endpoint will receive HTTP POST requests with this structure:

{ 
  "event": "pass.created",
  "timestamp": "2024-11-20T14:30:00Z",
  "webhookId": "wh_abcdef1234567890",
  "data": {
    "passId": "pass_1234567890abcdef",
    "templateId": "tpl_abcdef1234567890",
    "serialNumber": "EVENT2024-001",
    "organizationName": "Passinstance Events",
    "customFields": {
      "customerName": {
        "value": "John Doe",
        "label": "Guest Name"
      }
    },
    "downloadUrl": "https://api.passinstance.com/passes/pass_1234567890abcdef/download"
  }
}

Webhook Security

Signature Verification

Verify webhook authenticity using the signature header:

const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  
  return signature === `sha256=${expectedSignature}`;
}

Response Requirements

Return HTTP 200 status for successful processing

Respond within 10 seconds to avoid timeouts

Implement idempotency for duplicate events

Use HTTPS endpoints for security

Available Webhook Events

EventDescriptionData Included
pass.createdA new pass has been generatedFull pass object with download URL
pass.updatedPass fields or metadata changedUpdated pass object and changed fields
pass.deletedPass has been permanently removedPass ID and deletion timestamp
pass.voidedPass has been marked as voidedPass ID and void reason
template.createdNew pass template has been createdTemplate object with configuration
template.updatedTemplate design or settings changedUpdated template object

Official SDKs

Get started faster with our official client libraries and SDKs

JS

Node.js SDK

Full-featured SDK with TypeScript support

npm install @passinstance/sdk
PY

Python SDK

Pythonic interface with async support

pip install passinstance
RB

Ruby Gem

Ruby gem with Rails integration

gem install passinstance

SDK Usage Examples

Node.js SDK

const Passinstance = require('@passinstance/sdk');

// Initialize client
const client = new Passinstance({
  apiKey: 'your_api_key_here',
  environment: 'production' // or 'staging'
});

// Create a pass template
const template = await client.templates.create({
  name: 'VIP Event Ticket',
  passType: 'eventTicket',
  organizationName: 'Passinstance Events',
  backgroundColor: '#1f2937',
  foregroundColor: '#ffffff'
});

// Generate a pass from template
const pass = await client.passes.create({
  templateId: template.id,
  serialNumber: 'VIP2024-001',
  customFields: {
    customerName: { value: 'John Doe', label: 'Guest Name' },
    seat: { value: 'A12', label: 'Seat' }
  }
});

// Send push notification
await client.notifications.send(pass.id, {
  message: 'Event starting soon!'
});

console.log('Pass created:', pass.downloadUrl);

Python SDK

import passinstance

# Initialize client
client = passinstance.Client(api_key="your_api_key_here")

# Create a pass template
template = client.templates.create(
    name="VIP Event Ticket",
    pass_type="eventTicket",
    organization_name="Passinstance Events",
    background_color="#1f2937",
    foreground_color="#ffffff"
)

# Generate a pass from template
pass_obj = client.passes.create(
    template_id=template.id,
    serial_number="VIP2024-001",
    custom_fields={
        "customerName": {"value": "John Doe", "label": "Guest Name"},
        "seat": {"value": "A12", "label": "Seat"}
    }
)

# Send push notification
client.notifications.send(
    pass_id=pass_obj.id,
    message="Event starting soon!"
)

print(f"Pass created: {pass_obj.download_url}")

Rate Limits & Best Practices

Guidelines for efficient and reliable API usage

Rate Limits

Starter Plan100 req/min
Professional500 req/min
Enterprise2000 req/min

Rate Limit Headers

X-RateLimit-Limit: 500
X-RateLimit-Remaining: 487
X-RateLimit-Reset: 1640995200

Best Practices

Use Batch Operations

Create multiple passes at once using batch endpoints

Cache Responses

Cache template and pass data to reduce API calls

Handle Errors Gracefully

Implement retry logic with exponential backoff

Use Webhooks

Subscribe to events instead of polling for updates

Validate Locally

Validate data before sending to reduce failed requests

Error Handling Example

async function createPassWithRetry(passData, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await fetch('https://api.passinstance.com/passes', {
        method: 'POST',
        headers: {
          'Authorization': 'Bearer your_jwt_token',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(passData)
      });

      if (response.status === 429) {
        // Rate limited - wait and retry
        const retryAfter = response.headers.get('Retry-After') || 60;
        await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
        continue;
      }

      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(`API Error: ${errorData.message}`);
      }

      return await response.json();
    } catch (error) {
      if (attempt === maxRetries) {
        throw error;
      }
      
      // Exponential backoff
      const delay = Math.pow(2, attempt) * 1000;
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
}

Interactive API Reference

Complete API documentation with live examples and testing capabilities

Loading API reference…

Ready to Start Building?

Get your API keys and start creating mobile wallet passes in minutes. Join thousands of developers building the future of customer engagement.