# Pass

## Retrieve passes with optional filtering, sorting, and pagination.

> \*\*Authorization:\*\* Requires \`Pass.Read\` scope.\
> \
> \*\*Filtering:\*\* By identifiers (e.g., \`identifiers.email\`), metadata fields (e.g., \`metadata.loyaltyTier\`), pass type, or installation status (apple, google).\
> \
> \*\*Sorting:\*\* By id, passType, creationDate, lastUpdateDate, apple, google, or any identifier/metadata field.\
> \
> \*\*Pagination:\*\* Zero-based \`pageIndex\` and \`pageSize\`. Total count in \`x-pagination-total\` header.\
> \
> \*\*Use Cases:\*\* Search passes by customer attributes; monitor installation status; filter by loyalty tier or campaign flag.\
> \
> \*\*Example — list loyalty passes, page 0:\*\*\
> \`\`\`\
> GET /api/{tenantId}/passes?pageIndex=0\&pageSize=20\
> &#x20;   \&filter\[0].field=passType\&filter\[0].operator=equals\&filter\[0].value=loyalty\
> &#x20;   \&sortBy\[0].field=creationDate\&sortBy\[0].direction=DESC\
> \`\`\`\
> \*\*Example — passes installed on Apple Wallet:\*\*\
> \`\`\`\
> GET /api/{tenantId}/passes?filter\[0].field=installationStatus\&filter\[0].operator=contains\&filter\[0].value=apple\
> \`\`\`

````json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"Pass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"security":[{"admin-bearer":["ScopedAuthorizeRequirement"]},{"apiKey":["ScopedAuthorizeRequirement"]}],"components":{"securitySchemes":{"admin-bearer":{"type":"oauth2","flows":{"implicit":{"authorizationUrl":"https://auth.neostore.cloud/authorize?audience=https://app.neostore.cloud/api/","scopes":{}}}},"apiKey":{"type":"apiKey","name":"X-API-KEY","in":"header"}},"schemas":{"FilterModel":{"type":"object","properties":{"field":{"type":"string","description":"Field to filter by (identifiers.*, metadata.*, passType, installationStatus)."},"operator":{"description":"Comparison operator to apply.","$ref":"#/components/schemas/FilterModelOperator"},"value":{"type":["null","array"],"items":{"type":"string"},"description":"Filter values. Single-element for most operators; multiple elements for `in` and `notIn`.\nThe query parameter name is `value` (repeated for multiple values).\n<example>\nSingle value (equals, contains, startsWith, …):\n```\nGET /passes?filter[0].field=passType&filter[0].operator=equals&filter[0].value=boarding\n```\nMultiple values (in / notIn):\n```\nGET /passes?filter[0].field=passType&filter[0].operator=in&filter[0].value=boarding&filter[0].value=loyalty\n```\nMultiple filters combined:\n```\nGET /passes?filter[0].field=passType&filter[0].operator=equals&filter[0].value=boarding\n           &filter[1].field=identifiers.customerId&filter[1].operator=startsWith&filter[1].value=CUST-\n```</example>"}},"additionalProperties":false,"description":"Filter specification for pass queries."},"FilterModelOperator":{"enum":["Contains","StartsWith","EndsWith","Equals","IsEmpty","IsNotEmpty","NotEquals","In","NotIn"],"type":"string","description":"Filter operators for pass list queries."},"SortModel":{"type":"object","properties":{"field":{"type":"string","description":"Field to sort by."},"direction":{"description":"Sort direction (ASC or DESC).","$ref":"#/components/schemas/SortModelDirection"}},"additionalProperties":false,"description":"Sort specification for pass queries."},"SortModelDirection":{"enum":[0,1],"type":"integer","description":"Sort direction for pass list queries.","format":"int32"},"Pass":{"type":"object","properties":{"id":{"type":"string","description":"Platform-assigned unique pass identifier. This is a random alphanumeric string generated at creation time and cannot be set by callers (e.g., `xK9mP2nQr7sT`)."},"secret":{"type":"string","description":"Platform-generated opaque token used internally to authenticate pass delivery. Read-only; treat as confidential."},"creationDate":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"Timestamp when the pass was created by the platform. Read-only. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."},"lastUpdateDate":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"Timestamp of the most recent update. Equals `CreationDate` when no update has occurred. Read-only. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."},"passType":{"type":"string","description":"Type of pass, matching a file in the tenant `server/passes/` configuration."},"identifiers":{"type":"object","additionalProperties":{"type":"string"},"description":"External identifiers keyed by system name (e.g., `shopify.customerId`)."},"metadata":{"type":"object","additionalProperties":{"type":"null"},"description":"Computed metadata fields managed by the platform."},"additionalData":{"type":"object","additionalProperties":{"type":"null"},"description":"Arbitrary key/value data persisted with the pass."},"providers":{"type":"object","additionalProperties":{},"description":"Installation details keyed by provider name (e.g., `apple`, `google`). Populated by the platform. Read-only."}},"additionalProperties":false,"description":"Represents a pass returned by the API."}}},"paths":{"/api/{tenantId}/passes":{"get":{"tags":["Pass"],"summary":"Retrieve passes with optional filtering, sorting, and pagination.","description":"**Authorization:** Requires `Pass.Read` scope.\n\n**Filtering:** By identifiers (e.g., `identifiers.email`), metadata fields (e.g., `metadata.loyaltyTier`), pass type, or installation status (apple, google).\n\n**Sorting:** By id, passType, creationDate, lastUpdateDate, apple, google, or any identifier/metadata field.\n\n**Pagination:** Zero-based `pageIndex` and `pageSize`. Total count in `x-pagination-total` header.\n\n**Use Cases:** Search passes by customer attributes; monitor installation status; filter by loyalty tier or campaign flag.\n\n**Example — list loyalty passes, page 0:**\n```\nGET /api/{tenantId}/passes?pageIndex=0&pageSize=20\n    &filter[0].field=passType&filter[0].operator=equals&filter[0].value=loyalty\n    &sortBy[0].field=creationDate&sortBy[0].direction=DESC\n```\n**Example — passes installed on Apple Wallet:**\n```\nGET /api/{tenantId}/passes?filter[0].field=installationStatus&filter[0].operator=contains&filter[0].value=apple\n```","parameters":[{"name":"pageIndex","in":"query","description":"Zero-based page index.","schema":{"type":"integer","format":"int32","default":0}},{"name":"pageSize","in":"query","description":"Number of passes per page.","schema":{"type":"integer","format":"int32","default":20}},{"name":"filter","in":"query","description":"Optional filters applied to identifiers, metadata, pass type, or installation status.","schema":{"type":"array","items":{"description":"Filter specification for pass queries.","$ref":"#/components/schemas/FilterModel"}}},{"name":"sortBy","in":"query","description":"Optional sort descriptors. When absent, results are unordered.","schema":{"type":"array","items":{"description":"Sort specification for pass queries.","$ref":"#/components/schemas/SortModel"}}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Paged list of passes returned successfully.","content":{"text/plain":{"schema":{"type":"array","items":{"description":"Represents a pass returned by the API.","$ref":"#/components/schemas/Pass"}}},"application/json":{"schema":{"type":"array","items":{"description":"Represents a pass returned by the API.","$ref":"#/components/schemas/Pass"}}},"text/json":{"schema":{"type":"array","items":{"description":"Represents a pass returned by the API.","$ref":"#/components/schemas/Pass"}}}}}}}}}}
````

## Create a new pass.

> \*\*Authorization:\*\* Requires \`Pass.Write\` scope OR valid identifier validation (HMAC signature, secret, or allowlisted unsigned).\
> \
> \*\*Security:\*\* Each identifier must validate via: (1) HMAC (key.hmac), (2) registered secret (key.secret), (3) security allowlist, or (4) Pass.Write scope. Omit identifiers if JWT contains customer claims.\
> \
> \*\*Pass Type:\*\* Template to use. Must match file in tenant \`server/passes/\` config.\
> \
> \*\*Use Cases:\*\* API-based pass creation; customer self-service with HMAC; bulk imports.\
> \
> \*\*Example — create with HMAC-signed identifier:\*\*\
> \`\`\`\
> POST /api/{tenantId}/passes?passType=loyalty\
> &#x20;           \
> {\
> &#x20; "identifiers": {\
> &#x20;   "shopify.customerId": "12345",\
> &#x20;   "shopify.customerId.hmac": "{hmac-of-12345}"\
> &#x20; },\
> &#x20; "additionalData": { "loyaltyTier": "silver" }\
> }\
> \`\`\`\
> \*\*Example — create with Pass.Write scope (no HMAC required):\*\*\
> \`\`\`\
> POST /api/{tenantId}/passes?passType=loyalty\
> &#x20;           \
> {\
> &#x20; "identifiers": { "shopify.customerId": "12345" },\
> &#x20; "additionalData": { "loyaltyTier": "silver" }\
> }\
> \`\`\`

````json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"Pass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"security":[{"admin-bearer":["ScopedAuthorizeRequirement"]},{"apiKey":["ScopedAuthorizeRequirement"]}],"components":{"securitySchemes":{"admin-bearer":{"type":"oauth2","flows":{"implicit":{"authorizationUrl":"https://auth.neostore.cloud/authorize?audience=https://app.neostore.cloud/api/","scopes":{}}}},"apiKey":{"type":"apiKey","name":"X-API-KEY","in":"header"}},"schemas":{"CreatePassData":{"type":"object","allOf":[{"$ref":"#/components/schemas/PassData"}],"properties":{"extensions":{"type":["null","object"],"additionalProperties":{"type":"null"},"description":"Extensibility data related to this pass."}},"additionalProperties":false,"description":"Data payload for pass creation operations."},"PassData":{"type":"object","properties":{"identifiers":{"type":"object","additionalProperties":{"type":"string"},"description":"External identifiers of the customer for this pass. Keys must not start with `id.`; common examples are `y2.customerId` or `shopify.customerId`.\nUse an empty value to remove an identifier. Leave the collection empty to keep existing identifiers unchanged."},"additionalData":{"type":["null","object"],"additionalProperties":{"type":"null"},"description":"Arbitrary data to persist with the pass (for example, loyalty tier, store code, or campaign flags)."}},"additionalProperties":false},"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":{}}}},"paths":{"/api/{tenantId}/passes":{"post":{"tags":["Pass"],"summary":"Create a new pass.","description":"**Authorization:** Requires `Pass.Write` scope OR valid identifier validation (HMAC signature, secret, or allowlisted unsigned).\n\n**Security:** Each identifier must validate via: (1) HMAC (key.hmac), (2) registered secret (key.secret), (3) security allowlist, or (4) Pass.Write scope. Omit identifiers if JWT contains customer claims.\n\n**Pass Type:** Template to use. Must match file in tenant `server/passes/` config.\n\n**Use Cases:** API-based pass creation; customer self-service with HMAC; bulk imports.\n\n**Example — create with HMAC-signed identifier:**\n```\nPOST /api/{tenantId}/passes?passType=loyalty\n            \n{\n  \"identifiers\": {\n    \"shopify.customerId\": \"12345\",\n    \"shopify.customerId.hmac\": \"{hmac-of-12345}\"\n  },\n  \"additionalData\": { \"loyaltyTier\": \"silver\" }\n}\n```\n**Example — create with Pass.Write scope (no HMAC required):**\n```\nPOST /api/{tenantId}/passes?passType=loyalty\n            \n{\n  \"identifiers\": { \"shopify.customerId\": \"12345\" },\n  \"additionalData\": { \"loyaltyTier\": \"silver\" }\n}\n```","parameters":[{"name":"passType","in":"query","description":"Type of the pass to create. Must match a file in the tenant `server/passes/` configuration.","schema":{"type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Data related to this pass.","content":{"application/json":{"schema":{"description":"Data payload for pass creation operations.","$ref":"#/components/schemas/CreatePassData"}},"text/json":{"schema":{"description":"Data payload for pass creation operations.","$ref":"#/components/schemas/CreatePassData"}},"application/*+json":{"schema":{"description":"Data payload for pass creation operations.","$ref":"#/components/schemas/CreatePassData"}}}},"responses":{"200":{"description":"Pass created successfully.","content":{"text/plain":{"schema":{"type":"string"}},"application/json":{"schema":{"type":"string"}},"text/json":{"schema":{"type":"string"}}}},"401":{"description":"Identifiers cannot be validated and caller lacks Pass.Write scope.","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"}]}}}}}}}}}
````

## Update a pass and optionally its type.

> \*\*Authorization:\*\* Requires \`Pass.Write\` scope.\
> \
> \*\*Identification:\*\* Use internal \`id\` (e.g., \`id=Ed34kg3oA47\`) or external identifiers with \`id.\` prefix (e.g., \`id.y2.customerId=1233332\`). Multiple identifiers must match exactly one pass.\
> \
> \*\*Data:\*\* Merged with existing data. Empty/null removes fields; omitted fields unchanged.\
> \
> \*\*Metadata:\*\* Set \`options.UpdateMetadata=true\` for recomputation (slower). Set \`options.BypassQueue=true\` for synchronous updates instead of queueing.\
> \
> \*\*Type:\*\* Optionally convert pass to different type.\
> \
> \*\*Use Cases:\*\* Update identifiers/metadata; push notifications; type conversion; bulk updates; urgent changes.\
> \
> \*\*Example — update by platform pass ID:\*\*\
> \`\`\`\
> PATCH /api/{tenantId}/passes?id=xK9mP2nQr7sT\
> &#x20;           \
> {\
> &#x20; "additionalData": { "loyaltyTier": "gold" },\
> &#x20; "options": { "updateMetadata": true }\
> }\
> \`\`\`\
> \*\*Example — update by external identifier:\*\*\
> \`\`\`\
> PATCH /api/{tenantId}/passes?id.shopify.customerId=12345\
> &#x20;           \
> {\
> &#x20; "identifiers": { "email": "<user@example.com>" },\
> &#x20; "additionalData": { "loyaltyTier": "gold" },\
> &#x20; "options": { "updateMetadata": false }\
> }\
> \`\`\`

````json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"Pass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"security":[{"admin-bearer":["ScopedAuthorizeRequirement"]},{"apiKey":["ScopedAuthorizeRequirement"]}],"components":{"securitySchemes":{"admin-bearer":{"type":"oauth2","flows":{"implicit":{"authorizationUrl":"https://auth.neostore.cloud/authorize?audience=https://app.neostore.cloud/api/","scopes":{}}}},"apiKey":{"type":"apiKey","name":"X-API-KEY","in":"header"}},"schemas":{"SingleUpdatePassData":{"type":"object","allOf":[{"$ref":"#/components/schemas/SingleUpdatePassDataOptionsUpdatePassData"}],"properties":{"bypassQueue":{"type":"boolean","description":"Indicates whether the push update should bypass the queue and run immediately. Queuing helps protect the system load and should only be bypassed when required.","default":false,"deprecated":true}},"additionalProperties":false,"description":"Data payload for single pass update operations."},"SingleUpdatePassDataOptionsUpdatePassData":{"type":"object","properties":{"identifiers":{"type":"object","additionalProperties":{"type":"string"},"description":"External identifiers of the customer for this pass. Keys must not start with `id.`; common examples are `y2.customerId` or `shopify.customerId`.\nUse an empty value to remove an identifier. Leave the collection empty to keep existing identifiers unchanged."},"additionalData":{"type":["null","object"],"additionalProperties":{"type":"null"},"description":"Arbitrary data to persist with the pass (for example, loyalty tier, store code, or campaign flags)."},"passType":{"type":["null","string"],"description":"Optional pass type to convert the pass to."},"updateMetadata":{"type":"boolean","description":"Specifies if passes metadata should be updated. Updating metadata is time consuming and could be avoided for notification only push update","default":false,"deprecated":true},"options":{"description":"Options for single pass update operations. Metadata recomputation is enabled by default.\nUse Neo.Web.Api.Controllers.PassController.SingleUpdatePassDataOptions.BypassQueue to apply the update synchronously instead of queueing.","$ref":"#/components/schemas/SingleUpdatePassDataOptions"}},"additionalProperties":false},"SingleUpdatePassDataOptions":{"type":"object","allOf":[{"description":"Options used when updating passes.","$ref":"#/components/schemas/UpdatePassDataOptions"}],"properties":{"bypassQueue":{"type":"boolean","description":"Indicates whether the push update should bypass the queue and run immediately. Queuing helps protect the system load and should only be bypassed when required.","default":false}},"additionalProperties":false,"description":"Options for single pass update operations. Metadata recomputation is enabled by default.\nUse Neo.Web.Api.Controllers.PassController.SingleUpdatePassDataOptions.BypassQueue to apply the update synchronously instead of queueing."},"UpdatePassDataOptions":{"type":"object","properties":{"updateMetadata":{"type":"boolean","description":"When true, recompute and persist pass metadata. Updating metadata is slower and is usually unnecessary for notification-only updates."},"correlationId":{"type":["null","string"],"description":"Groups related updates under the same correlationId. Useful for batch updates (for example nightly jobs) to make retries and logs traceable."}},"additionalProperties":false,"description":"Options used when updating passes."},"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":{}}}},"paths":{"/api/{tenantId}/passes":{"patch":{"tags":["Pass"],"summary":"Update a pass and optionally its type.","description":"**Authorization:** Requires `Pass.Write` scope.\n\n**Identification:** Use internal `id` (e.g., `id=Ed34kg3oA47`) or external identifiers with `id.` prefix (e.g., `id.y2.customerId=1233332`). Multiple identifiers must match exactly one pass.\n\n**Data:** Merged with existing data. Empty/null removes fields; omitted fields unchanged.\n\n**Metadata:** Set `options.UpdateMetadata=true` for recomputation (slower). Set `options.BypassQueue=true` for synchronous updates instead of queueing.\n\n**Type:** Optionally convert pass to different type.\n\n**Use Cases:** Update identifiers/metadata; push notifications; type conversion; bulk updates; urgent changes.\n\n**Example — update by platform pass ID:**\n```\nPATCH /api/{tenantId}/passes?id=xK9mP2nQr7sT\n            \n{\n  \"additionalData\": { \"loyaltyTier\": \"gold\" },\n  \"options\": { \"updateMetadata\": true }\n}\n```\n**Example — update by external identifier:**\n```\nPATCH /api/{tenantId}/passes?id.shopify.customerId=12345\n            \n{\n  \"identifiers\": { \"email\": \"user@example.com\" },\n  \"additionalData\": { \"loyaltyTier\": \"gold\" },\n  \"options\": { \"updateMetadata\": false }\n}\n```","parameters":[{"name":"identifiers","in":"query","description":"identifier of the pass. To update a pass with a Wallet Crew internal id only specify `id` (example : `\"id\": \"Ed34kg3oA47\"`) to update a pass with external identifier prefix the key with `id.` (example : `\"id.y2.customerId\": \"1233332\"`) \n\nWhen multiple external identifiers is submitted all identifiers should be found. \nIf more than one pass is found an exception will be thrown.","schema":{"type":"object","additionalProperties":{"type":"string"}}},{"name":"passType","in":"query","description":"type of the pass to update. type name should be one of the file in the `server/passes/` tenant configuration.","schema":{"type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"data related to this pass. This data will be merge with the existing data.","content":{"application/json":{"schema":{"description":"Data payload for single pass update operations.","$ref":"#/components/schemas/SingleUpdatePassData"}},"text/json":{"schema":{"description":"Data payload for single pass update operations.","$ref":"#/components/schemas/SingleUpdatePassData"}},"application/*+json":{"schema":{"description":"Data payload for single pass update operations.","$ref":"#/components/schemas/SingleUpdatePassData"}}}},"responses":{"200":{"description":"Pass update enqueued or applied successfully."},"404":{"description":"No pass found matching the provided identifiers.","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"}]}}}}}}}}}
````

## Retrieve the specified pass for the specified device.

> Download an Apple Wallet pass:\
> \`\`\`\
> GET /api/{tenantId}/passes/xK9mP2nQr7sT?device=apple\
> \`\`\`\
> Auto-redirect to the appropriate wallet based on user-agent:\
> \`\`\`\
> GET /api/{tenantId}/passes/xK9mP2nQr7sT?device=auto\
> \`\`\`\
> Track the installation source (email campaign, email medium):\
> \`\`\`\
> GET /api/{tenantId}/passes/xK9mP2nQr7sT?device=apple\&neo.src=email-campaign|email\
> \`\`\`

````json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"Pass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"paths":{"/api/{tenantId}/passes/{passId}":{"get":{"tags":["Pass"],"summary":"Retrieve the specified pass for the specified device.","description":"Download an Apple Wallet pass:\n```\nGET /api/{tenantId}/passes/xK9mP2nQr7sT?device=apple\n```\nAuto-redirect to the appropriate wallet based on user-agent:\n```\nGET /api/{tenantId}/passes/xK9mP2nQr7sT?device=auto\n```\nTrack the installation source (email campaign, email medium):\n```\nGET /api/{tenantId}/passes/xK9mP2nQr7sT?device=apple&neo.src=email-campaign|email\n```","parameters":[{"name":"passId","in":"path","description":"Platform-assigned pass identifier (random alphanumeric string, e.g. `xK9mP2nQr7sT`).","required":true,"schema":{"pattern":"^[\\w-]{5,50}$","type":"string"}},{"name":"device","in":"query","description":"Target platform: `apple`, `google`, `preview`, or `auto`.","schema":{"type":"string"}},{"name":"Tags","in":"query","description":"Source tags for categorizing installation source.","schema":{"type":"array","items":{"type":"string"}}},{"name":"Medium","in":"query","description":"Installation medium (e.g., email, sms, app).","schema":{"type":"string"}},{"name":"Origin","in":"query","description":"Installation origin or referrer.","schema":{"type":"string"}},{"name":"UserAgent","in":"query","description":"User agent string from the installation request.","schema":{"type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}}}}
````

## Update a pass using its passId.

> \*\*Authorization:\*\* Requires \`Pass.Write\` scope.\
> \
> \*\*Identification:\*\* Uses the pass's unique \`passId\` directly.\
> \
> \*\*Data:\*\* Merged with existing data. Empty/null removes fields; omitted fields unchanged.\
> \
> \*\*Metadata:\*\* Set \`options.UpdateMetadata=true\` for recomputation (slower). Set \`options.BypassQueue=true\` for synchronous updates instead of queueing.\
> \
> \*\*Type:\*\* Optionally convert pass to different type.\
> \
> \*\*Use Cases:\*\* Update passes by internal ID; push notifications; type conversion; urgent changes.\
> \
> \*\*Example — update metadata and push notification:\*\*\
> \`\`\`\
> PATCH /api/{tenantId}/passes/xK9mP2nQr7sT\
> &#x20;           \
> {\
> &#x20; "additionalData": { "loyaltyTier": "platinum", "points": 5000 },\
> &#x20; "options": { "updateMetadata": true, "bypassQueue": false }\
> }\
> \`\`\`\
> \*\*Example — urgent update, bypass queue:\*\*\
> \`\`\`\
> PATCH /api/{tenantId}/passes/xK9mP2nQr7sT\
> &#x20;           \
> {\
> &#x20; "additionalData": { "boardingStatus": "boarding" },\
> &#x20; "options": { "updateMetadata": true, "bypassQueue": true }\
> }\
> \`\`\`

````json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"Pass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"security":[{"admin-bearer":["ScopedAuthorizeRequirement"]},{"apiKey":["ScopedAuthorizeRequirement"]}],"components":{"securitySchemes":{"admin-bearer":{"type":"oauth2","flows":{"implicit":{"authorizationUrl":"https://auth.neostore.cloud/authorize?audience=https://app.neostore.cloud/api/","scopes":{}}}},"apiKey":{"type":"apiKey","name":"X-API-KEY","in":"header"}},"schemas":{"SingleUpdatePassData":{"type":"object","allOf":[{"$ref":"#/components/schemas/SingleUpdatePassDataOptionsUpdatePassData"}],"properties":{"bypassQueue":{"type":"boolean","description":"Indicates whether the push update should bypass the queue and run immediately. Queuing helps protect the system load and should only be bypassed when required.","default":false,"deprecated":true}},"additionalProperties":false,"description":"Data payload for single pass update operations."},"SingleUpdatePassDataOptionsUpdatePassData":{"type":"object","properties":{"identifiers":{"type":"object","additionalProperties":{"type":"string"},"description":"External identifiers of the customer for this pass. Keys must not start with `id.`; common examples are `y2.customerId` or `shopify.customerId`.\nUse an empty value to remove an identifier. Leave the collection empty to keep existing identifiers unchanged."},"additionalData":{"type":["null","object"],"additionalProperties":{"type":"null"},"description":"Arbitrary data to persist with the pass (for example, loyalty tier, store code, or campaign flags)."},"passType":{"type":["null","string"],"description":"Optional pass type to convert the pass to."},"updateMetadata":{"type":"boolean","description":"Specifies if passes metadata should be updated. Updating metadata is time consuming and could be avoided for notification only push update","default":false,"deprecated":true},"options":{"description":"Options for single pass update operations. Metadata recomputation is enabled by default.\nUse Neo.Web.Api.Controllers.PassController.SingleUpdatePassDataOptions.BypassQueue to apply the update synchronously instead of queueing.","$ref":"#/components/schemas/SingleUpdatePassDataOptions"}},"additionalProperties":false},"SingleUpdatePassDataOptions":{"type":"object","allOf":[{"description":"Options used when updating passes.","$ref":"#/components/schemas/UpdatePassDataOptions"}],"properties":{"bypassQueue":{"type":"boolean","description":"Indicates whether the push update should bypass the queue and run immediately. Queuing helps protect the system load and should only be bypassed when required.","default":false}},"additionalProperties":false,"description":"Options for single pass update operations. Metadata recomputation is enabled by default.\nUse Neo.Web.Api.Controllers.PassController.SingleUpdatePassDataOptions.BypassQueue to apply the update synchronously instead of queueing."},"UpdatePassDataOptions":{"type":"object","properties":{"updateMetadata":{"type":"boolean","description":"When true, recompute and persist pass metadata. Updating metadata is slower and is usually unnecessary for notification-only updates."},"correlationId":{"type":["null","string"],"description":"Groups related updates under the same correlationId. Useful for batch updates (for example nightly jobs) to make retries and logs traceable."}},"additionalProperties":false,"description":"Options used when updating passes."},"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":{}}}},"paths":{"/api/{tenantId}/passes/{passId}":{"patch":{"tags":["Pass"],"summary":"Update a pass using its passId.","description":"**Authorization:** Requires `Pass.Write` scope.\n\n**Identification:** Uses the pass's unique `passId` directly.\n\n**Data:** Merged with existing data. Empty/null removes fields; omitted fields unchanged.\n\n**Metadata:** Set `options.UpdateMetadata=true` for recomputation (slower). Set `options.BypassQueue=true` for synchronous updates instead of queueing.\n\n**Type:** Optionally convert pass to different type.\n\n**Use Cases:** Update passes by internal ID; push notifications; type conversion; urgent changes.\n\n**Example — update metadata and push notification:**\n```\nPATCH /api/{tenantId}/passes/xK9mP2nQr7sT\n            \n{\n  \"additionalData\": { \"loyaltyTier\": \"platinum\", \"points\": 5000 },\n  \"options\": { \"updateMetadata\": true, \"bypassQueue\": false }\n}\n```\n**Example — urgent update, bypass queue:**\n```\nPATCH /api/{tenantId}/passes/xK9mP2nQr7sT\n            \n{\n  \"additionalData\": { \"boardingStatus\": \"boarding\" },\n  \"options\": { \"updateMetadata\": true, \"bypassQueue\": true }\n}\n```","parameters":[{"name":"passId","in":"path","description":"The unique identifier of the pass to update.","required":true,"schema":{"pattern":"^[\\w-]{5,50}$","type":"string"}},{"name":"passType","in":"query","description":"Optional type of the pass to update. Type name should match a file in the `server/passes/` tenant configuration.","schema":{"type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Data payload containing identifiers, additional data, and update options.","content":{"application/json":{"schema":{"description":"Data payload for single pass update operations.","$ref":"#/components/schemas/SingleUpdatePassData"}},"text/json":{"schema":{"description":"Data payload for single pass update operations.","$ref":"#/components/schemas/SingleUpdatePassData"}},"application/*+json":{"schema":{"description":"Data payload for single pass update operations.","$ref":"#/components/schemas/SingleUpdatePassData"}}}},"responses":{"200":{"description":"Pass update queued or completed successfully."},"404":{"description":"Pass with the specified passId 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"}]}}}}}}}}}
````

## Retrieve a WebSocket URL for pass-level notifications.

> \`\`\`\
> GET /api/{tenantId}/passes/xK9mP2nQr7sT/connect\
> &#x20;           \
> \`\`\`

````json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"Pass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"paths":{"/api/{tenantId}/passes/{passId}/connect":{"get":{"tags":["Pass"],"summary":"Retrieve a WebSocket URL for pass-level notifications.","description":"```\nGET /api/{tenantId}/passes/xK9mP2nQr7sT/connect\n            \n```","parameters":[{"name":"passId","in":"path","description":"Platform-assigned pass identifier (random alphanumeric string, e.g. `xK9mP2nQr7sT`).","required":true,"schema":{"pattern":"^[\\w-]{5,50}$","type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"WebSocket URL returned successfully.","content":{"text/plain":{"schema":{"description":"Represents a Web PubSub connection response for a pass.","$ref":"#/components/schemas/PassConnectResponse"}},"application/json":{"schema":{"description":"Represents a Web PubSub connection response for a pass.","$ref":"#/components/schemas/PassConnectResponse"}},"text/json":{"schema":{"description":"Represents a Web PubSub connection response for a pass.","$ref":"#/components/schemas/PassConnectResponse"}}}},"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"}]}}}}}}}},"components":{"schemas":{"PassConnectResponse":{"type":"object","properties":{"url":{"type":"string","description":"WebSocket URL to connect for pass notifications."}},"additionalProperties":false,"description":"Represents a Web PubSub connection response for a pass."},"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":{}}}}}
````

## Retrieve aggregated pass data from all registered data providers.

> \`\`\`\
> GET /api/{tenantId}/passes/xK9mP2nQr7sT/data\
> &#x20;           \
> \`\`\`

````json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"Pass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"paths":{"/api/{tenantId}/passes/{passId}/data":{"get":{"tags":["Pass"],"summary":"Retrieve aggregated pass data from all registered data providers.","description":"```\nGET /api/{tenantId}/passes/xK9mP2nQr7sT/data\n            \n```","parameters":[{"name":"passId","in":"path","description":"Platform-assigned pass identifier (random alphanumeric string, e.g. `xK9mP2nQr7sT`).","required":true,"schema":{"pattern":"^[\\w-]{5,50}$","type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}}}}
````

## Retrieve the raw persisted pass document for diagnostics.

> \`\`\`\
> GET /api/{tenantId}/passes/xK9mP2nQr7sT/data/raw\
> &#x20;           \
> \`\`\`

````json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"Pass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"paths":{"/api/{tenantId}/passes/{passId}/data/raw":{"get":{"tags":["Pass"],"summary":"Retrieve the raw persisted pass document for diagnostics.","description":"```\nGET /api/{tenantId}/passes/xK9mP2nQr7sT/data/raw\n            \n```","parameters":[{"name":"passId","in":"path","description":"Platform-assigned pass identifier (random alphanumeric string, e.g. `xK9mP2nQr7sT`).","required":true,"schema":{"pattern":"^[\\w-]{5,50}$","type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Raw pass document returned."}}}}}}
````

## PUT /api/{tenantId}/passes/{passId}/notification

> Send a notification to the pass identified by its pass identifier

```json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"Pass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"security":[{"admin-bearer":["ScopedAuthorizeRequirement"]},{"apiKey":["ScopedAuthorizeRequirement"]}],"components":{"securitySchemes":{"admin-bearer":{"type":"oauth2","flows":{"implicit":{"authorizationUrl":"https://auth.neostore.cloud/authorize?audience=https://app.neostore.cloud/api/","scopes":{}}}},"apiKey":{"type":"apiKey","name":"X-API-KEY","in":"header"}},"schemas":{"NotifyRequest":{"type":"object","properties":{"content":{"type":["null","string"],"description":"Could be null if LocalizedContent is specified"},"localizedContent":{"type":["null","object"],"additionalProperties":{"type":"string"},"description":"Localized notification content by language code.\nKey: ISO 639-1 code or \"iso2-region\" (e.g., \"en\", \"en-US\").\nValue: The notification content for that language.","propertyNames":{"pattern":"^[a-z]{2}(-[A-Z]{2})?$"}},"options":{"$ref":"#/components/schemas/NotifyRequestOptions"}},"additionalProperties":false},"NotifyRequestOptions":{"type":"object","properties":{"updateData":{"type":"boolean","description":"Indicate if pass data should also be updated when the notification is sent.","default":false},"correlationId":{"maxLength":100,"minLength":10,"type":["null","string"],"description":"Correlation identifier to group and trace related API calls."}},"additionalProperties":false},"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":{}}}},"paths":{"/api/{tenantId}/passes/{passId}/notification":{"put":{"tags":["Pass"],"summary":"Send a notification to the pass identified by its pass identifier","parameters":[{"name":"passId","in":"path","description":"The internal identifier of the pass","required":true,"schema":{"type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"The notification content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotifyRequest"}},"text/json":{"schema":{"$ref":"#/components/schemas/NotifyRequest"}},"application/*+json":{"schema":{"$ref":"#/components/schemas/NotifyRequest"}}}},"responses":{"200":{"description":"OK"},"404":{"description":"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"}]}}}}}}}}}
```

## Redirect to a web page that lets the user view and download the pass.

> \`\`\`\
> GET /api/{tenantId}/passes/xK9mP2nQr7sT/view\
> &#x20;           \
> \`\`\`\
> &#x20;           Additional query parameters are forwarded to the view page.

````json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"Pass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"paths":{"/api/{tenantId}/passes/{passId}/view":{"get":{"tags":["Pass"],"summary":"Redirect to a web page that lets the user view and download the pass.","description":"```\nGET /api/{tenantId}/passes/xK9mP2nQr7sT/view\n            \n```\n            Additional query parameters are forwarded to the view page.","parameters":[{"name":"passId","in":"path","description":"Platform-assigned pass identifier (random alphanumeric string, e.g. `xK9mP2nQr7sT`).","required":true,"schema":{"type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"302":{"description":"Found"},"404":{"description":"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"}]}}}}}}}},"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":{}}}}}
````

## Retrieve multiple passes for the specified device.

> Download a bundle of Apple Wallet passes:\
> \`\`\`\
> GET /api/{tenantId}/passes/xK9mP2nQr7sT,a3Bc4dEf5gHi?device=apple\
> \`\`\`\
> Retrieve JSON for Google Wallet:\
> \`\`\`\
> GET /api/{tenantId}/passes/xK9mP2nQr7sT,a3Bc4dEf5gHi?device=google\
> \`\`\`

````json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"Pass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"paths":{"/api/{tenantId}/passes/{passIds}":{"get":{"tags":["Pass"],"summary":"Retrieve multiple passes for the specified device.","description":"Download a bundle of Apple Wallet passes:\n```\nGET /api/{tenantId}/passes/xK9mP2nQr7sT,a3Bc4dEf5gHi?device=apple\n```\nRetrieve JSON for Google Wallet:\n```\nGET /api/{tenantId}/passes/xK9mP2nQr7sT,a3Bc4dEf5gHi?device=google\n```","parameters":[{"name":"passIds","in":"path","description":"Comma-separated serial numbers of the passes.","required":true,"schema":{"pattern":"^[\\w-]{5,50},([\\w-]{5,50},?)+$","type":"array","items":{"type":"string"},"description":"Collection of pass identifiers with parsing support."}},{"name":"device","in":"query","description":"Target platform: `apple` or `google`.","schema":{"type":"string"}},{"name":"Tags","in":"query","description":"Source tags for categorizing installation source.","schema":{"type":"array","items":{"type":"string"}}},{"name":"Medium","in":"query","description":"Installation medium (e.g., email, sms, app).","schema":{"type":"string"}},{"name":"Origin","in":"query","description":"Installation origin or referrer.","schema":{"type":"string"}},{"name":"UserAgent","in":"query","description":"User agent string from the installation request.","schema":{"type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}}}}
````

## Retrieve a Wallet Crew passId from external identifiers.

> Lookup with HMAC-signed identifier:\
> \`\`\`\
> GET /api/{tenantId}/passes/findPass?shopify.customerId=12345\&shopify.customerId.hmac={hmac}\
> \`\`\`\
> Lookup with Pass.Read scope (no HMAC required):\
> \`\`\`\
> GET /api/{tenantId}/passes/findPass?shopify.customerId=12345\
> \`\`\`

````json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"Pass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"paths":{"/api/{tenantId}/passes/findPass":{"get":{"tags":["Pass"],"summary":"Retrieve a Wallet Crew passId from external identifiers.","description":"Lookup with HMAC-signed identifier:\n```\nGET /api/{tenantId}/passes/findPass?shopify.customerId=12345&shopify.customerId.hmac={hmac}\n```\nLookup with Pass.Read scope (no HMAC required):\n```\nGET /api/{tenantId}/passes/findPass?shopify.customerId=12345\n```","parameters":[{"name":"identifiers","in":"query","description":"- When `{key}` is supplied, either provide `{key}.hmac` signed with a tenant secret, ensure `security.yml` allows unsigned identifiers, or authenticate with a Pass.Read scope (API key or JWT).\n- Authenticated user claims are also considered when present.","schema":{"type":"object","additionalProperties":{"type":"string"}}},{"name":"passType","in":"query","description":"Optional pass type to restrict the search.","schema":{"type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"type":"string"}},"application/json":{"schema":{"type":"string"}},"text/json":{"schema":{"type":"string"}}}},"204":{"description":"No Content"}}}}}}
````

## Retrieve passes by direct pass IDs or via a registered supplier.

> \*\*Two Modes:\*\*\
> \- \*\*Direct Mode:\*\* Pass \`ids=id1,id2\` to look up passes by serial number.\
> \- \*\*Supplier Mode:\*\* Pass \`ids.{provider}={key}\` (e.g. \`ids.shopify=ORDER-12345\`) to resolve pass IDs via a registered Neo.Runtime.Wallet.IPassSupplier. Missing passes are created automatically.\
> &#x20; Optionally sign the lookup with \`ids.{provider}.hmac={hmac}\` or \`ids.{provider}.secret={secret}\`.\
> \
> \*\*Preview:\*\* When \`includePreview=true\`, each item includes title, subtitle, colors, header text, and enabled status.\
> \
> \*\*Use Cases:\*\* E-commerce (order → passes); subscriptions (subscription → passes); mobile preview data; loyalty programs (member → passes).\
> \
> \*\*Example — direct pass IDs lookup:\*\*\
> \`\`\`\
> GET /api/{tenantId}/passes/findPasses?ids=xK9mP2nQr7sT,a3Bc4dEf5gHi\
> \`\`\`\
> \*\*Example — resolve via supplier:\*\*\
> \`\`\`\
> GET /api/{tenantId}/passes/findPasses?ids.shopify=ORDER-12345\&includePreview=true\
> \`\`\`\
> \*\*Example — resolve via supplier with HMAC:\*\*\
> \`\`\`\
> GET /api/{tenantId}/passes/findPasses?ids.shopify=ORDER-12345\&ids.shopify.hmac={hmac}\
> \`\`\`

````json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"Pass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"paths":{"/api/{tenantId}/passes/findPasses":{"get":{"tags":["Pass"],"summary":"Retrieve passes by direct pass IDs or via a registered supplier.","description":"**Two Modes:**\n- **Direct Mode:** Pass `ids=id1,id2` to look up passes by serial number.\n- **Supplier Mode:** Pass `ids.{provider}={key}` (e.g. `ids.shopify=ORDER-12345`) to resolve pass IDs via a registered Neo.Runtime.Wallet.IPassSupplier. Missing passes are created automatically.\n  Optionally sign the lookup with `ids.{provider}.hmac={hmac}` or `ids.{provider}.secret={secret}`.\n\n**Preview:** When `includePreview=true`, each item includes title, subtitle, colors, header text, and enabled status.\n\n**Use Cases:** E-commerce (order → passes); subscriptions (subscription → passes); mobile preview data; loyalty programs (member → passes).\n\n**Example — direct pass IDs lookup:**\n```\nGET /api/{tenantId}/passes/findPasses?ids=xK9mP2nQr7sT,a3Bc4dEf5gHi\n```\n**Example — resolve via supplier:**\n```\nGET /api/{tenantId}/passes/findPasses?ids.shopify=ORDER-12345&includePreview=true\n```\n**Example — resolve via supplier with HMAC:**\n```\nGET /api/{tenantId}/passes/findPasses?ids.shopify=ORDER-12345&ids.shopify.hmac={hmac}\n```","parameters":[{"name":"identifiers","in":"query","description":"Query parameters used to identify passes.\nUse `ids={csv}` for direct lookup, or `ids.{provider}={key}` for supplier-based lookup.","schema":{"type":"object","additionalProperties":{"type":"string"}}},{"name":"includePreview","in":"query","description":"When true, include preview details (title, subtitle, colors, header text, enabled status) for each pass.","schema":{"type":"boolean","default":false}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Pass list retrieved successfully.","content":{"text/plain":{"schema":{"type":"array","items":{}}},"application/json":{"schema":{"type":"array","items":{}}},"text/json":{"schema":{"type":"array","items":{}}}}},"400":{"description":"Bad Request","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"}]}}}}}}}},"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":{}}}}}
````

## PUT /api/{tenantId}/passes/notification

> Send a notification to the corresponding pass

```json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"Pass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"security":[{"admin-bearer":["ScopedAuthorizeRequirement"]},{"apiKey":["ScopedAuthorizeRequirement"]}],"components":{"securitySchemes":{"admin-bearer":{"type":"oauth2","flows":{"implicit":{"authorizationUrl":"https://auth.neostore.cloud/authorize?audience=https://app.neostore.cloud/api/","scopes":{}}}},"apiKey":{"type":"apiKey","name":"X-API-KEY","in":"header"}},"schemas":{"NotifyRequest":{"type":"object","properties":{"content":{"type":["null","string"],"description":"Could be null if LocalizedContent is specified"},"localizedContent":{"type":["null","object"],"additionalProperties":{"type":"string"},"description":"Localized notification content by language code.\nKey: ISO 639-1 code or \"iso2-region\" (e.g., \"en\", \"en-US\").\nValue: The notification content for that language.","propertyNames":{"pattern":"^[a-z]{2}(-[A-Z]{2})?$"}},"options":{"$ref":"#/components/schemas/NotifyRequestOptions"}},"additionalProperties":false},"NotifyRequestOptions":{"type":"object","properties":{"updateData":{"type":"boolean","description":"Indicate if pass data should also be updated when the notification is sent.","default":false},"correlationId":{"maxLength":100,"minLength":10,"type":["null","string"],"description":"Correlation identifier to group and trace related API calls."}},"additionalProperties":false},"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":{}}}},"paths":{"/api/{tenantId}/passes/notification":{"put":{"tags":["Pass"],"summary":"Send a notification to the corresponding pass","parameters":[{"name":"identifiers","in":"query","description":"identifier of the pass. To update a pass with a neostore internal id only specify `id` (example : `\"id\": \"Ed34kg3oA47\"`) to update a pass with external identifier prefix the key with `id.` (example : `\"id.y2.customerId\": \"1233332\"`) \n\nWhen multiple external identifiers is submitted all identifiers should be found. \nIf more than one pass is found an exception will be thrown.","schema":{"type":"object","additionalProperties":{"type":"string"}}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"The notification content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotifyRequest"}},"text/json":{"schema":{"$ref":"#/components/schemas/NotifyRequest"}},"application/*+json":{"schema":{"$ref":"#/components/schemas/NotifyRequest"}}}},"responses":{"200":{"description":"OK"},"404":{"description":"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"}]}}}}}}}}}
```

## Push update for passes matching the filter.

> \*\*Authorization:\*\* Requires \`Pass.Write\` scope.\
> \
> \*\*Filtering:\*\* Same as GetPasses�identifiers, metadata, pass type, installation status.\
> \
> \*\*Async:\*\* Updates are queued. 200 response means scheduled, not complete. Monitor via statistics endpoint.\
> \
> \*\*Data Merge:\*\* Merged into each matching pass. Set \`UpdateMetadata=true\` for recomputation (slower). Adjust \`Throughput\` for concurrency.\
> \
> \*\*Bulk Operations:\*\* Ideal for campaigns, loyalty updates, seasonal offers. Use \`CorrelationId\` for tracking.\
> \
> \*\*Use Cases:\*\* Campaign push; loyalty tier changes; offer refresh; bulk metadata updates.\
> \
> \*\*Example — push a seasonal offer to all loyalty passes:\*\*\
> \`\`\`\
> POST /api/{tenantId}/passes/pushUpdate\
> &#x20;   ?filter\[0].field=passType\&filter\[0].operator=equals\&filter\[0].value=loyalty\
> &#x20;           \
> {\
> &#x20; "additionalData": { "offer": "summer2025", "discount": "20%" },\
> &#x20; "options": {\
> &#x20;   "updateMetadata": true,\
> &#x20;   "throughput": 12,\
> &#x20;   "correlationId": "campaign-summer-2025"\
> &#x20; }\
> }\
> \`\`\`

````json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"Pass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"security":[{"admin-bearer":["ScopedAuthorizeRequirement"]},{"apiKey":["ScopedAuthorizeRequirement"]}],"components":{"securitySchemes":{"admin-bearer":{"type":"oauth2","flows":{"implicit":{"authorizationUrl":"https://auth.neostore.cloud/authorize?audience=https://app.neostore.cloud/api/","scopes":{}}}},"apiKey":{"type":"apiKey","name":"X-API-KEY","in":"header"}},"schemas":{"FilterModel":{"type":"object","properties":{"field":{"type":"string","description":"Field to filter by (identifiers.*, metadata.*, passType, installationStatus)."},"operator":{"description":"Comparison operator to apply.","$ref":"#/components/schemas/FilterModelOperator"},"value":{"type":["null","array"],"items":{"type":"string"},"description":"Filter values. Single-element for most operators; multiple elements for `in` and `notIn`.\nThe query parameter name is `value` (repeated for multiple values).\n<example>\nSingle value (equals, contains, startsWith, …):\n```\nGET /passes?filter[0].field=passType&filter[0].operator=equals&filter[0].value=boarding\n```\nMultiple values (in / notIn):\n```\nGET /passes?filter[0].field=passType&filter[0].operator=in&filter[0].value=boarding&filter[0].value=loyalty\n```\nMultiple filters combined:\n```\nGET /passes?filter[0].field=passType&filter[0].operator=equals&filter[0].value=boarding\n           &filter[1].field=identifiers.customerId&filter[1].operator=startsWith&filter[1].value=CUST-\n```</example>"}},"additionalProperties":false,"description":"Filter specification for pass queries."},"FilterModelOperator":{"enum":["Contains","StartsWith","EndsWith","Equals","IsEmpty","IsNotEmpty","NotEquals","In","NotIn"],"type":"string","description":"Filter operators for pass list queries."},"MultipleUpdatePassData":{"type":"object","allOf":[{"$ref":"#/components/schemas/MultipleUpdatePassDataOptionsUpdatePassData"}],"additionalProperties":false,"description":"Data payload for multi-pass (bulk) update operations."},"MultipleUpdatePassDataOptionsUpdatePassData":{"type":"object","properties":{"identifiers":{"type":"object","additionalProperties":{"type":"string"},"description":"External identifiers of the customer for this pass. Keys must not start with `id.`; common examples are `y2.customerId` or `shopify.customerId`.\nUse an empty value to remove an identifier. Leave the collection empty to keep existing identifiers unchanged."},"additionalData":{"type":["null","object"],"additionalProperties":{"type":"null"},"description":"Arbitrary data to persist with the pass (for example, loyalty tier, store code, or campaign flags)."},"passType":{"type":["null","string"],"description":"Optional pass type to convert the pass to."},"updateMetadata":{"type":"boolean","description":"Specifies if passes metadata should be updated. Updating metadata is time consuming and could be avoided for notification only push update","default":false,"deprecated":true},"options":{"description":"Options for multi-pass (bulk) update operations.","$ref":"#/components/schemas/MultipleUpdatePassDataOptions"}},"additionalProperties":false},"MultipleUpdatePassDataOptions":{"type":"object","allOf":[{"$ref":"#/components/schemas/UpdatePassDataOptions"}],"properties":{"throughput":{"type":"number","description":"Desired throughput (passes per second) when scheduling updates. Default is 12. Throughput is best-effort and can vary. Values below 1 slowly pace updates.","format":"float"}},"additionalProperties":false,"description":"Options for multi-pass (bulk) update operations."},"UpdatePassDataOptions":{"type":"object","properties":{"updateMetadata":{"type":"boolean","description":"When true, recompute and persist pass metadata. Updating metadata is slower and is usually unnecessary for notification-only updates."},"correlationId":{"type":["null","string"],"description":"Groups related updates under the same correlationId. Useful for batch updates (for example nightly jobs) to make retries and logs traceable."}},"additionalProperties":false,"description":"Options used when updating passes."},"PushUpdateResult":{"type":"object","properties":{"passCount":{"type":"integer","description":"Count of passes scheduled for update.","format":"int32"}},"additionalProperties":false,"description":"Result returned after scheduling a bulk push update operation."}}},"paths":{"/api/{tenantId}/passes/pushUpdate":{"post":{"tags":["Pass"],"summary":"Push update for passes matching the filter.","description":"**Authorization:** Requires `Pass.Write` scope.\n\n**Filtering:** Same as GetPasses�identifiers, metadata, pass type, installation status.\n\n**Async:** Updates are queued. 200 response means scheduled, not complete. Monitor via statistics endpoint.\n\n**Data Merge:** Merged into each matching pass. Set `UpdateMetadata=true` for recomputation (slower). Adjust `Throughput` for concurrency.\n\n**Bulk Operations:** Ideal for campaigns, loyalty updates, seasonal offers. Use `CorrelationId` for tracking.\n\n**Use Cases:** Campaign push; loyalty tier changes; offer refresh; bulk metadata updates.\n\n**Example — push a seasonal offer to all loyalty passes:**\n```\nPOST /api/{tenantId}/passes/pushUpdate\n    ?filter[0].field=passType&filter[0].operator=equals&filter[0].value=loyalty\n            \n{\n  \"additionalData\": { \"offer\": \"summer2025\", \"discount\": \"20%\" },\n  \"options\": {\n    \"updateMetadata\": true,\n    \"throughput\": 12,\n    \"correlationId\": \"campaign-summer-2025\"\n  }\n}\n```","parameters":[{"name":"filter","in":"query","description":"Optional filters applied to select passes.","schema":{"type":"array","items":{"description":"Filter specification for pass queries.","$ref":"#/components/schemas/FilterModel"}}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Data to merge into each pass and options controlling metadata refresh and throughput.","content":{"application/json":{"schema":{"description":"Data payload for multi-pass (bulk) update operations.","$ref":"#/components/schemas/MultipleUpdatePassData"}},"text/json":{"schema":{"description":"Data payload for multi-pass (bulk) update operations.","$ref":"#/components/schemas/MultipleUpdatePassData"}},"application/*+json":{"schema":{"description":"Data payload for multi-pass (bulk) update operations.","$ref":"#/components/schemas/MultipleUpdatePassData"}}}},"responses":{"200":{"description":"Passes scheduled for update; returns the count in the response body.","content":{"text/plain":{"schema":{"description":"Result returned after scheduling a bulk push update operation.","$ref":"#/components/schemas/PushUpdateResult"}},"application/json":{"schema":{"description":"Result returned after scheduling a bulk push update operation.","$ref":"#/components/schemas/PushUpdateResult"}},"text/json":{"schema":{"description":"Result returned after scheduling a bulk push update operation.","$ref":"#/components/schemas/PushUpdateResult"}}}}}}}}}
````

## Cancel a running push update operation.

> \*\*Authorization:\*\* Requires \`Pass.Read\` scope.\
> \
> \*\*Cancellation:\*\* Marks operation for cancellation. May take time if updates already dispatched.\
> \
> \*\*Correlation Id:\*\* Use the id from push update schedule or statistics.\
> \
> \*\*Use Cases:\*\* Stop campaign on config error; cancel nightly batch; prevent updates on security issue.\
> \
> \*\*Example:\*\*\
> \`\`\`\
> POST /api/{tenantId}/passes/pushUpdate/campaign-summer-2025/cancel\
> \`\`\`

````json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"Pass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"security":[{"admin-bearer":["ScopedAuthorizeRequirement"]},{"apiKey":["ScopedAuthorizeRequirement"]}],"components":{"securitySchemes":{"admin-bearer":{"type":"oauth2","flows":{"implicit":{"authorizationUrl":"https://auth.neostore.cloud/authorize?audience=https://app.neostore.cloud/api/","scopes":{}}}},"apiKey":{"type":"apiKey","name":"X-API-KEY","in":"header"}}},"paths":{"/api/{tenantId}/passes/pushUpdate/{correlationId}/cancel":{"post":{"tags":["Pass"],"summary":"Cancel a running push update operation.","description":"**Authorization:** Requires `Pass.Read` scope.\n\n**Cancellation:** Marks operation for cancellation. May take time if updates already dispatched.\n\n**Correlation Id:** Use the id from push update schedule or statistics.\n\n**Use Cases:** Stop campaign on config error; cancel nightly batch; prevent updates on security issue.\n\n**Example:**\n```\nPOST /api/{tenantId}/passes/pushUpdate/campaign-summer-2025/cancel\n```","parameters":[{"name":"correlationId","in":"path","description":"CorrelationId used when scheduling the push update.","required":true,"schema":{"type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Cancellation request accepted."}}}}}}
````

## Retrieve execution statistics for recent push update operations.

> \*\*Authorization:\*\* Requires \`Pass.Read\` scope.\
> \
> \*\*Statistics:\*\* Operation id, correlationId, start/last activity, pass count, completed count, error count, Apple/Google deployment counts, cancellation status.\
> \
> \*\*Ordering:\*\* Sorted descending by start date (most recent first).\
> \
> \*\*Use Cases:\*\* Monitor batch progress; track campaign deployment; identify failures; audit history.\
> \
> \*\*Example:\*\*\
> \`\`\`\
> GET /api/{tenantId}/passes/pushUpdate/status\
> \`\`\`

````json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"Pass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"security":[{"admin-bearer":["ScopedAuthorizeRequirement"]},{"apiKey":["ScopedAuthorizeRequirement"]}],"components":{"securitySchemes":{"admin-bearer":{"type":"oauth2","flows":{"implicit":{"authorizationUrl":"https://auth.neostore.cloud/authorize?audience=https://app.neostore.cloud/api/","scopes":{}}}},"apiKey":{"type":"apiKey","name":"X-API-KEY","in":"header"}},"schemas":{"PushUpdateStatistics":{"type":"object","properties":{"id":{"type":"string","description":"Unique operation identifier."},"operationName":{"type":"string","description":"Operation name/category."},"operationData":{"type":"string","description":"Correlation ID for tracking related updates."},"startDate":{"type":"string","description":"Operation start timestamp.","format":"date-time"},"lastActivity":{"type":["null","string"],"description":"Last activity timestamp.","format":"date-time"},"passCount":{"type":"integer","description":"Total passes scheduled for update.","format":"int32"},"completed":{"type":"integer","description":"Number of passes successfully updated.","format":"int32"},"errors":{"type":"integer","description":"Number of passes with update errors.","format":"int32"},"apple":{"type":"integer","description":"Number of Apple Pass updates deployed.","format":"int32"},"google":{"type":"integer","description":"Number of Google Pass updates deployed.","format":"int32"},"isCanceled":{"type":"boolean","description":"Whether the operation was cancelled."}},"additionalProperties":false,"description":"Aggregated status of a push update operation."}}},"paths":{"/api/{tenantId}/passes/pushUpdate/status":{"get":{"tags":["Pass"],"summary":"Retrieve execution statistics for recent push update operations.","description":"**Authorization:** Requires `Pass.Read` scope.\n\n**Statistics:** Operation id, correlationId, start/last activity, pass count, completed count, error count, Apple/Google deployment counts, cancellation status.\n\n**Ordering:** Sorted descending by start date (most recent first).\n\n**Use Cases:** Monitor batch progress; track campaign deployment; identify failures; audit history.\n\n**Example:**\n```\nGET /api/{tenantId}/passes/pushUpdate/status\n```","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Statistics retrieved successfully.","content":{"text/plain":{"schema":{"type":"array","items":{"description":"Aggregated status of a push update operation.","$ref":"#/components/schemas/PushUpdateStatistics"}}},"application/json":{"schema":{"type":"array","items":{"description":"Aggregated status of a push update operation.","$ref":"#/components/schemas/PushUpdateStatistics"}}},"text/json":{"schema":{"type":"array","items":{"description":"Aggregated status of a push update operation.","$ref":"#/components/schemas/PushUpdateStatistics"}}}}}}}}}}
````

## Get pass distribution statistics

> Returns aggregated counts of passes by installation status and platform.\
> \
> \## Authorization\
> Requires \`Pass.Read\` scope.\
> \
> \## Metrics Explained\
> \- \*\*Total\*\*: All passes created (regardless of installation)\
> \- \*\*Active\*\*: Passes currently installed on at least one device\
> \- \*\*Apple\*\*: Passes installed on Apple Wallet\
> \- \*\*Google\*\*: Passes installed on Google Wallet\
> \
> \## Filtering\
> Optional \`passType\` parameter filters statistics to a specific pass type (e.g., "loyalty", "coupon").\
> \
> \## Performance Note\
> This endpoint queries all passes and may be slow for large datasets. For production dashboards, consider using the Insights API with pre-aggregated queries.

```json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"Pass"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"security":[{"admin-bearer":["ScopedAuthorizeRequirement"]},{"apiKey":["ScopedAuthorizeRequirement"]}],"components":{"securitySchemes":{"admin-bearer":{"type":"oauth2","flows":{"implicit":{"authorizationUrl":"https://auth.neostore.cloud/authorize?audience=https://app.neostore.cloud/api/","scopes":{}}}},"apiKey":{"type":"apiKey","name":"X-API-KEY","in":"header"}},"schemas":{"PassStatistic":{"type":"object","properties":{"count":{"description":"Number of active pass","$ref":"#/components/schemas/PassStatisticCount"}},"additionalProperties":false,"description":"Get statistics about pass usage"},"PassStatisticCount":{"type":"object","properties":{"total":{"type":"integer","description":"Total number of passes","format":"int32"},"active":{"type":"integer","description":"Total number of installed pass","format":"int32"},"apple":{"type":"integer","description":"Total number of active pass for apple","format":"int32"},"google":{"type":"integer","description":"Total number of active pass for google","format":"int32"}},"additionalProperties":false,"description":"Get number of active passes per device"}}},"paths":{"/api/{tenantId}/passes/stats":{"get":{"tags":["Pass"],"summary":"Get pass distribution statistics","description":"Returns aggregated counts of passes by installation status and platform.\n\n## Authorization\nRequires `Pass.Read` scope.\n\n## Metrics Explained\n- **Total**: All passes created (regardless of installation)\n- **Active**: Passes currently installed on at least one device\n- **Apple**: Passes installed on Apple Wallet\n- **Google**: Passes installed on Google Wallet\n\n## Filtering\nOptional `passType` parameter filters statistics to a specific pass type (e.g., \"loyalty\", \"coupon\").\n\n## Performance Note\nThis endpoint queries all passes and may be slow for large datasets. For production dashboards, consider using the Insights API with pre-aggregated queries.","parameters":[{"name":"passType","in":"query","description":"Optional pass type filter (must match a tenant pass configuration file).","schema":{"type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"description":"Get statistics about pass usage","$ref":"#/components/schemas/PassStatistic"}},"application/json":{"schema":{"description":"Get statistics about pass usage","$ref":"#/components/schemas/PassStatistic"}},"text/json":{"schema":{"description":"Get statistics about pass usage","$ref":"#/components/schemas/PassStatistic"}}}}}}}}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.thewalletcrew.io/develop/api-reference/pass-management/pass.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
