How to send NFC passes from the Command Line
Updated September 15, 2025
TL;DR
Learn how to create, update and manage PassNinja passes using the REST API including authentication request formatting and when to choose REST over SDKs.PassNinja offers official SDKs for multiple programming languages, which simplify authentication, request formatting, and error handling. While SDKs are recommended for most development, there are scenarios where direct HTTP REST API calls are preferable, such as when working in unsupported languages, integrating into shell scripts, or running in CI/CD pipelines. This guide explains the complete lifecycle of a pass using the REST API, from creation and updates to troubleshooting and exploring other commands, and concludes with guidance on choosing between the SDK and REST API.
What are the prerequisites for using the PassNinja REST API
Before you begin, ensure you have a PassNinja account with an API Key and Account ID. You will also need a published pass template, known as the Pass Type Key, available from your dashboard. These credentials are essential for authenticating your requests to the API.
In addition to account credentials, you should have curl installed if you are working on macOS or Linux, or PowerShell if you are on Windows. These tools allow you to send HTTP requests directly from your terminal, which is useful for testing and integrating with scripts.
What are the basics of the PassNinja REST API
All PassNinja REST API requests must use HTTPS to ensure secure communication. Each request requires two authentication headers: X-API-KEY containing your API key and X-ACCOUNT-ID containing your account ID. Without these headers, the API will reject your request.
The API sends and receives data in JSON format and returns standard HTTP status codes to indicate success or failure. Understanding these basics will help you structure your requests correctly and interpret the responses you receive.
How do you create a pass
To create a pass, send a POST request to the /v1/passes endpoint. The request must include authentication headers and a JSON body specifying the pass type and pass fields. Optional fields such as sms and email can be included to automatically send the install link to a recipient.
Example request:
curl -X POST 'https://api.passninja.com/v1/passes' \
-H 'X-API-KEY: YOUR_API_KEY' \
-H 'X-ACCOUNT-ID: YOUR_ACCOUNT_ID' \
-H 'Content-Type: application/json' \
-d '{
"passType": "YOUR_PASS_TYPE_KEY",
"pass": {
"nfc-message": "1234567890",
"strip-image-url": "https://i.imgur.com/7emhMea.png",
"secondary-value-one-text": "0"
},
"sms": "+15551234567",
"email": "user@example.com"
}'Ensure that the passType matches the Pass Type Key from your published template. If you include sms or email, the API will send the installation link automatically.
How do you update a pass
Updating a pass involves sending a PUT request to the /v1/passes/{passType}/{serialNumber} endpoint. You must replace {passType} with your Pass Type Key and {serialNumber} with the serial number returned when the pass was created.
Example request:
curl -X PUT 'https://api.passninja.com/v1/passes/PTK_KEY_HERE/SERIAL_NUMBER_HERE' \
-H 'X-API-KEY: YOUR_API_KEY' \
-H 'X-ACCOUNT-ID: YOUR_ACCOUNT_ID' \
-H 'Content-Type: application/json' \
-d '{
"pass": {
"nfc-message": "1234567890",
"strip-image-url": "https://i.imgur.com/7emhMea.png",
"secondary-value-one-text": "1"
}
}'No sms or email fields are needed when updating a pass, as the update applies directly to the existing pass. If successful, the API returns the same JSON structure as when creating a pass.
What does an example response look like
Both creation and update requests return JSON containing the serial number, pass ID, landing URL, and pass type. The landing URL is the link used to install the pass on a device.
Example response:
{
"serialNumber": "SERIAL_NUMBER_HERE",
"id": "SERIAL_NUMBER_HERE",
"urls": {
"landing": "https://i.installpass.es/p/SERIAL_NUMBER_HERE"
},
"passType": "ptk_xxxxxx"
}Save the serial number for future updates, retrieval, or deletion of the pass. The landing URL can be shared with users to allow them to install the pass.
How do you troubleshoot common issues
If you encounter errors, the API will return a JSON object with an error message and code. For example, missing required fields will produce an error like {"error":"Missing required fields: barcode-message","code":"MI1"}. Ensure all required fields from your template are included.
Other common issues include empty fields, invalid color formats, incorrect authentication headers, mismatched pass types, JSON formatting errors, and forgetting to publish template changes. Always validate your JSON, double-check header values, and confirm that your template is published before making API calls. For a complete list of error codes, refer to the PassNinja API Error Codes documentation.
What other commands are available
Beyond creating and updating passes, the PassNinja REST API supports additional commands. You can use GET to retrieve pass details, DELETE to revoke a pass, FIND to list passes for a template, and DECRYPT to decrypt pass payloads.
curl -X POST 'https://api.passninja.com/v1/passes/PTK_KEY_HERE/decrypt' \
-H 'X-API-KEY: YOUR_API_KEY' \
-H 'X-ACCOUNT-ID: YOUR_ACCOUNT_ID' \
-H 'Content-Type: application/json' \
-d '{
"passType": "YOUR_PASS_TYPE_KEY",
"payload": "55166a9700250a8c51382dd16822b0c763136090b91099c16385f2961b7d9392d31b386cae133dca1b2faf10e93a1f8f26343ef56c4b35d5bf6cb8cd9ff45177e1ea070f0d4fe88887"
)Full details, including request formats, responses and examples for these commands, are available in the PassNinja API Documentation. Exploring these commands can help you build more comprehensive integrations.
How do you decide between using the SDK or the REST API
PassNinja SDKs offer high ease of use by handling authentication, request formatting, and error parsing automatically. They integrate natively with supported programming languages and are quick to set up via package managers. SDKs are best for most application development, especially in supported languages.
The REST API requires manual request construction and error handling but offers maximum flexibility. It is language-agnostic and ideal for quick scripts, unsupported languages, serverless functions, or direct API testing. Choose the SDK for speed and safety in supported environments, and the REST API for flexibility and broader integration scenarios.
Making NFC easy with PassNinja
PassNinja streamlines the creation and distribution of NFC-enabled wallet passes by providing a unified API and management dashboard. This allows developers and businesses to integrate NFC capabilities into their applications without building complex infrastructure from scratch.
By leveraging the REST API, you can dynamically generate passes, update them in real time, and deliver installation links instantly. This flexibility supports a wide range of use cases, from loyalty programs to event ticketing, while maintaining a seamless user experience.
Conclusion
Using the PassNinja REST API directly gives you full control over pass creation, updates, and management. While SDKs simplify the process for supported languages, the REST API is a powerful option for custom integrations and unsupported environments. By following the steps in this guide, you can implement a complete pass lifecycle and decide which integration method best fits your needs.