API Documentation
Integrate with Passinstance: REST APIs, webhooks, and examples for Apple and Google Wallet passes.
Documentation
Start with the API overview and core implementation guidance.
Solutions
See the pass programs and rollout scenarios supported by the platform.
Features
Review the mechanics, updates, and automation options available in Passinstance.
Case Studies
Browse real programs launched with wallet passes across multiple industries.
Resources
Find implementation guides, buyer material, and planning resources.
Contact
Talk to the team if you need help planning an integration or rollout.
Getting Started
Start building with Passinstance API in minutes. Follow our step-by-step guide to create your first digital pass.
Create Template
Design your pass template with custom fields, colors, and branding.
POST /templatesGenerate Passes
Create individual passes from your template with dynamic data.
POST /passesQuick 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!"
}'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
| Code | Description | Solution |
|---|---|---|
| 401 | Unauthorized | Check your API key or JWT token |
| 403 | Forbidden | Insufficient permissions for this resource |
| 404 | Not Found | Resource doesn't exist or has been deleted |
| 422 | Validation Error | Check request body format and required fields |
| 429 | Rate Limited | Slow 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
endPHP
<?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
| Event | Description | Data Included |
|---|---|---|
| pass.created | A new pass has been generated | Full pass object with download URL |
| pass.updated | Pass fields or metadata changed | Updated pass object and changed fields |
| pass.deleted | Pass has been permanently removed | Pass ID and deletion timestamp |
| pass.voided | Pass has been marked as voided | Pass ID and void reason |
| template.created | New pass template has been created | Template object with configuration |
| template.updated | Template design or settings changed | Updated template object |
Official SDKs
Get started faster with our official client libraries and SDKs
Node.js SDK
Full-featured SDK with TypeScript support
npm install @passinstance/sdkPython SDK
Pythonic interface with async support
pip install passinstanceRuby Gem
Ruby gem with Rails integration
gem install passinstanceSDK 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
Rate Limit Headers
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 487
X-RateLimit-Reset: 1640995200Best 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.