# ApplePass

## Return serial numbers updated since the provided tag for a given device and pass type.

> Called by Apple Wallet to poll for pass updates. Implements the PassKit protocol endpoint for retrieving modified pass serial numbers since a given timestamp.\
> \
> \## Update Tag (Modification Timestamp)\
> The tag parameter represents the last modification timestamp the client knows about:\
> \- When provided: Returns only passes modified after this tag\
> \- When omitted: Returns all registered passes for the device/type combination\
> \- When no updates exist: Returns 204 No Content\
> \
> \## Timestamp Format Evolution\
> \- \*\*Legacy format (before 2024-10-07)\*\*: Seconds since Unix epoch\
> \- \*\*Current format\*\*: Milliseconds since Unix epoch\
> The endpoint automatically detects and handles both formats for backward compatibility.\
> \
> \## Polling Strategy\
> Apple Wallet uses this endpoint for efficient incremental sync of pass updates without downloading entire pass files.

```json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"ApplePass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"paths":{"/api/{tenantId}/passes/apple/{version}/devices/{deviceIdentifier}/registrations/{passTypeIdentifier}":{"get":{"tags":["ApplePass"],"summary":"Return serial numbers updated since the provided tag for a given device and pass type.","description":"Called by Apple Wallet to poll for pass updates. Implements the PassKit protocol endpoint for retrieving modified pass serial numbers since a given timestamp.\n\n## Update Tag (Modification Timestamp)\nThe tag parameter represents the last modification timestamp the client knows about:\n- When provided: Returns only passes modified after this tag\n- When omitted: Returns all registered passes for the device/type combination\n- When no updates exist: Returns 204 No Content\n\n## Timestamp Format Evolution\n- **Legacy format (before 2024-10-07)**: Seconds since Unix epoch\n- **Current format**: Milliseconds since Unix epoch\nThe endpoint automatically detects and handles both formats for backward compatibility.\n\n## Polling Strategy\nApple Wallet uses this endpoint for efficient incremental sync of pass updates without downloading entire pass files.","parameters":[{"name":"deviceIdentifier","in":"path","description":"Device identifier used by Apple for authentication.","required":true,"schema":{"type":"string"}},{"name":"passTypeIdentifier","in":"path","description":"Apple pass type identifier.","required":true,"schema":{"type":"string"}},{"name":"passesUpdatedSince","in":"query","description":"Optional modification tag (timestamp). When omitted, all registrations are returned.","schema":{"type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of updated pass serial numbers"},"204":{"description":"No passes updated since the provided tag"},"401":{"description":"Not authorized","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"500":{"description":"Internal server error while retrieving updated passes"}}}}},"components":{"schemas":{"ProblemDetails":{"type":"object","properties":{"type":{"type":["null","string"]},"title":{"type":["null","string"]},"status":{"type":["null","integer"],"format":"int32"},"detail":{"type":["null","string"]},"instance":{"type":["null","string"]}},"additionalProperties":{}},"HttpValidationProblemDetails":{"type":"object","allOf":[{"$ref":"#/components/schemas/ProblemDetails"}],"properties":{"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"additionalProperties":{}}}}}
```

## Register pass installation on Apple device

> Called by Apple Wallet when a pass is added to a device. Implements the PassKit Web Service device registration endpoint as specified by Apple's PassKit protocol.\
> \
> \## Device Registration Flow\
> When a user adds a pass to their Apple Wallet:\
> 1\. Apple Wallet generates a unique device identifier\
> 2\. The app extracts and sends the push token to this endpoint\
> 3\. The push token enables server-to-device push notifications when pass data changes\
> \
> \## Push Token Management\
> The push token is device and pass-specific. It changes when:\
> \- The device registers the same pass again\
> \- The app reinstalls\
> \- Apple infrastructure updates the token\
> \
> \## Authentication\
> Apple sends an Authorization header with the pass's authentication token as:\
> \`\`\`\
> Authorization: ApplePass \<authentication-token>\
> \`\`\`\
> This token must match the pass's expected authentication value.\
> \
> \## Idempotency\
> Calling this endpoint multiple times with the same device and pass returns 200 OK for existing registrations, updating the push token. First registration returns 201 Created.

````json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"ApplePass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"paths":{"/api/{tenantId}/passes/apple/{version}/devices/{deviceIdentifier}/registrations/{passTypeIdentifier}/{serialNumber}":{"post":{"tags":["ApplePass"],"summary":"Register pass installation on Apple device","description":"Called by Apple Wallet when a pass is added to a device. Implements the PassKit Web Service device registration endpoint as specified by Apple's PassKit protocol.\n\n## Device Registration Flow\nWhen a user adds a pass to their Apple Wallet:\n1. Apple Wallet generates a unique device identifier\n2. The app extracts and sends the push token to this endpoint\n3. The push token enables server-to-device push notifications when pass data changes\n\n## Push Token Management\nThe push token is device and pass-specific. It changes when:\n- The device registers the same pass again\n- The app reinstalls\n- Apple infrastructure updates the token\n\n## Authentication\nApple sends an Authorization header with the pass's authentication token as:\n```\nAuthorization: ApplePass <authentication-token>\n```\nThis token must match the pass's expected authentication value.\n\n## Idempotency\nCalling this endpoint multiple times with the same device and pass returns 200 OK for existing registrations, updating the push token. First registration returns 201 Created.","parameters":[{"name":"deviceIdentifier","in":"path","description":"Unique identifier of the device.","required":true,"schema":{"type":"string"}},{"name":"passTypeIdentifier","in":"path","description":"Apple pass type identifier.","required":true,"schema":{"type":"string"}},{"name":"serialNumber","in":"path","description":"Serial number of the pass.","required":true,"schema":{"type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Body containing `pushToken` to enable push updates.","content":{"application/json":{"schema":{}},"text/json":{"schema":{}},"application/*+json":{"schema":{}}}},"responses":{"200":{"description":"Device already registered or updated"},"201":{"description":"Device newly registered"},"401":{"description":"Authentication token invalid","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"Pass serial number not found","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"500":{"description":"Internal server error while processing device registration"}}}}},"components":{"schemas":{"ProblemDetails":{"type":"object","properties":{"type":{"type":["null","string"]},"title":{"type":["null","string"]},"status":{"type":["null","integer"],"format":"int32"},"detail":{"type":["null","string"]},"instance":{"type":["null","string"]}},"additionalProperties":{}},"HttpValidationProblemDetails":{"type":"object","allOf":[{"$ref":"#/components/schemas/ProblemDetails"}],"properties":{"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"additionalProperties":{}}}}}
````

## Unregister pass removed from Apple device

> Called by Apple Wallet when a pass is removed from a device. Stops push notifications to that device and cleans up device registration.\
> \
> \## Unregistration Scenarios\
> This endpoint is triggered when:\
> \- User manually deletes the pass from Apple Wallet\
> \- Device is factory reset\
> \- App is uninstalled and reinstalled\
> \- Cloud backup/restore occurs\
> \
> \## Device Registration Cleanup\
> \- Removes the device-pass mapping from the registration database\
> \- No further push notifications sent to this device for this pass\
> \- Pass can be re-added and re-registered by the user\
> \- Push token is safely discarded\
> \
> \## Re-registration\
> The same device can re-add the pass later, which creates a new registration via the RegisterDevice endpoint with a fresh push token.\
> \
> \## Authentication\
> Apple sends the same authorization token used during registration for verification.

```json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"ApplePass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"paths":{"/api/{tenantId}/passes/apple/{version}/devices/{deviceIdentifier}/registrations/{passTypeIdentifier}/{serialNumber}":{"delete":{"tags":["ApplePass"],"summary":"Unregister pass removed from Apple device","description":"Called by Apple Wallet when a pass is removed from a device. Stops push notifications to that device and cleans up device registration.\n\n## Unregistration Scenarios\nThis endpoint is triggered when:\n- User manually deletes the pass from Apple Wallet\n- Device is factory reset\n- App is uninstalled and reinstalled\n- Cloud backup/restore occurs\n\n## Device Registration Cleanup\n- Removes the device-pass mapping from the registration database\n- No further push notifications sent to this device for this pass\n- Pass can be re-added and re-registered by the user\n- Push token is safely discarded\n\n## Re-registration\nThe same device can re-add the pass later, which creates a new registration via the RegisterDevice endpoint with a fresh push token.\n\n## Authentication\nApple sends the same authorization token used during registration for verification.","parameters":[{"name":"deviceIdentifier","in":"path","description":"Unique identifier of the device.","required":true,"schema":{"type":"string"}},{"name":"passTypeIdentifier","in":"path","description":"Apple pass type identifier.","required":true,"schema":{"type":"string"}},{"name":"serialNumber","in":"path","description":"Serial number of the pass.","required":true,"schema":{"type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Pass device registration removed"},"401":{"description":"Authentication token invalid","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"Pass not found","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"500":{"description":"Internal server error while removing device registration"}}}}},"components":{"schemas":{"ProblemDetails":{"type":"object","properties":{"type":{"type":["null","string"]},"title":{"type":["null","string"]},"status":{"type":["null","integer"],"format":"int32"},"detail":{"type":["null","string"]},"instance":{"type":["null","string"]}},"additionalProperties":{}},"HttpValidationProblemDetails":{"type":"object","allOf":[{"$ref":"#/components/schemas/ProblemDetails"}],"properties":{"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"additionalProperties":{}}}}}
```

## Log messages sent by Apple PassKit.

> Endpoint to receive and log diagnostic information sent by Apple's PassKit service. Apple Wallet and PassKit framework send error and diagnostic messages to help debug pass delivery, installation, and update issues.\
> \
> \## Diagnostic Information\
> Messages may contain:\
> \- Pass installation failures\
> \- Push notification delivery errors\
> \- Device registration issues\
> \- Signature validation errors\
> \- Update retrieval failures\
> \
> \## Log Format\
> Request body contains a JSON object:\
> \`\`\`json\
> {\
> &#x20; "logs": \[\
> &#x20;   "error message 1",\
> &#x20;   "error message 2"\
> &#x20; ]\
> }\
> \`\`\`\
> \
> \## Server-side Handling\
> Received logs are:\
> \- Stored in application logs with ERROR level\
> \- Associated with the device/pass that sent them\
> \- Useful for debugging why passes fail to update or install\
> \- Used for monitoring pass delivery health\
> \
> \## Use Cases\
> \- Debug pass installation failures\
> \- Monitor PassKit framework issues\
> \- Identify signature validation problems\
> \- Troubleshoot push notification delivery

````json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"ApplePass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"paths":{"/api/{tenantId}/passes/apple/{version}/log":{"post":{"tags":["ApplePass"],"summary":"Log messages sent by Apple PassKit.","description":"Endpoint to receive and log diagnostic information sent by Apple's PassKit service. Apple Wallet and PassKit framework send error and diagnostic messages to help debug pass delivery, installation, and update issues.\n\n## Diagnostic Information\nMessages may contain:\n- Pass installation failures\n- Push notification delivery errors\n- Device registration issues\n- Signature validation errors\n- Update retrieval failures\n\n## Log Format\nRequest body contains a JSON object:\n```json\n{\n  \"logs\": [\n    \"error message 1\",\n    \"error message 2\"\n  ]\n}\n```\n\n## Server-side Handling\nReceived logs are:\n- Stored in application logs with ERROR level\n- Associated with the device/pass that sent them\n- Useful for debugging why passes fail to update or install\n- Used for monitoring pass delivery health\n\n## Use Cases\n- Debug pass installation failures\n- Monitor PassKit framework issues\n- Identify signature validation problems\n- Troubleshoot push notification delivery","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"JSON object containing an array of log messages from Apple PassKit.","content":{"application/json":{"schema":{}},"text/json":{"schema":{}},"application/*+json":{"schema":{}}}},"responses":{"200":{"description":"Logs received and processed"},"500":{"description":"Internal server error while processing logs"}}}}}}
````

## Retrieve the latest version of a pass for Apple Wallet.

> Returns the current pass file in pkpass format. This endpoint supports conditional requests using standard HTTP caching headers to minimize bandwidth usage.\
> \
> \## Conditional Requests (HTTP Caching)\
> The endpoint supports If-Modified-Since header for bandwidth optimization. When the pass has not been modified since the provided timestamp, the server returns 304 Not Modified to avoid transferring the pass file.

```json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"ApplePass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"paths":{"/api/{tenantId}/passes/apple/{version}/passes/{passTypeIdentifier}/{serialNumber}":{"get":{"tags":["ApplePass"],"summary":"Retrieve the latest version of a pass for Apple Wallet.","description":"Returns the current pass file in pkpass format. This endpoint supports conditional requests using standard HTTP caching headers to minimize bandwidth usage.\n\n## Conditional Requests (HTTP Caching)\nThe endpoint supports If-Modified-Since header for bandwidth optimization. When the pass has not been modified since the provided timestamp, the server returns 304 Not Modified to avoid transferring the pass file.","parameters":[{"name":"passTypeIdentifier","in":"path","description":"Apple pass type identifier.","required":true,"schema":{"type":"string"}},{"name":"serialNumber","in":"path","description":"Pass serial number.","required":true,"schema":{"type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Pass file (pkpass) returned","content":{"text/plain":{"schema":{"type":"string","format":"binary"}},"application/json":{"schema":{"type":"string","format":"binary"}},"text/json":{"schema":{"type":"string","format":"binary"}}}},"304":{"description":"Pass unchanged since If-Modified-Since header"},"400":{"description":"Invalid serial number","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"401":{"description":"Not authorized","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"Pass not found","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"500":{"description":"Internal server error while generating pass file"}}}}},"components":{"schemas":{"ProblemDetails":{"type":"object","properties":{"type":{"type":["null","string"]},"title":{"type":["null","string"]},"status":{"type":["null","integer"],"format":"int32"},"detail":{"type":["null","string"]},"instance":{"type":["null","string"]}},"additionalProperties":{}},"HttpValidationProblemDetails":{"type":"object","allOf":[{"$ref":"#/components/schemas/ProblemDetails"}],"properties":{"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}},"additionalProperties":{}}}}}
```
