# 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.

```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":["null","string"],"description":"Field to filter by (identifiers.*, metadata.*, passType, installationStatus)."},"value":{"type":["null","string"],"description":"Filter value to match."},"operator":{"$ref":"#/components/schemas/FilterModelOperator"}},"additionalProperties":false,"description":"Filter specification for pass queries."},"FilterModelOperator":{"enum":["Contains","StartsWith","EndsWith","Equals","IsEmpty","IsNotEmpty","doesNotEqual"],"type":"string","description":"Filter operators for pass list queries."},"SortModel":{"type":"object","properties":{"field":{"type":["null","string"],"description":"Field to sort by."},"direction":{"$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":["null","string"],"description":"Unique identifier of this pass"},"secret":{"type":["null","string"],"description":"Secret of the Pass"},"creationDate":{"type":"string","description":"Date of pass creation","format":"date-time"},"lastUpdateDate":{"type":"string","description":"Date of last update or pass creation when no update is present","format":"date-time"},"passType":{"type":["null","string"],"description":"Type of pass"},"identifiers":{"type":["null","object"],"additionalProperties":{"type":"string"},"description":"External identifiers"},"metadata":{"type":["null","object"],"additionalProperties":{"type":"null"},"description":"Metadata"},"additionalData":{"type":["null","object"],"additionalProperties":{"type":"null"},"description":"Additional data"},"providers":{"type":["null","object"],"additionalProperties":{},"description":"Installation date per provider"}},"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.","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":{"$ref":"#/components/schemas/FilterModel"}}},{"name":"sortBy","in":"query","description":"Optional sort descriptors. When absent, results are unordered.","schema":{"type":"array","items":{"$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":{"$ref":"#/components/schemas/Pass"}}},"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Pass"}}},"text/json":{"schema":{"type":"array","items":{"$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.

```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":["null","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":["null","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.","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":{"$ref":"#/components/schemas/CreatePassData"}},"text/json":{"schema":{"$ref":"#/components/schemas/CreatePassData"}},"application/*+json":{"schema":{"$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.

```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},"SingleUpdatePassDataOptionsUpdatePassData":{"type":"object","properties":{"identifiers":{"type":["null","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":{"$ref":"#/components/schemas/SingleUpdatePassDataOptions"}},"additionalProperties":false},"SingleUpdatePassDataOptions":{"type":"object","allOf":[{"$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},"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":["null","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.","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":{"$ref":"#/components/schemas/SingleUpdatePassData"}},"text/json":{"schema":{"$ref":"#/components/schemas/SingleUpdatePassData"}},"application/*+json":{"schema":{"$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"}]}}}}}}}}}
```

## GET /api/{tenantId}/passes/{passId}

> Retrieve the specified pass for the specified device.

```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.","parameters":[{"name":"passId","in":"path","description":"Serial number of the pass.","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.

```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},"SingleUpdatePassDataOptionsUpdatePassData":{"type":"object","properties":{"identifiers":{"type":["null","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":{"$ref":"#/components/schemas/SingleUpdatePassDataOptions"}},"additionalProperties":false},"SingleUpdatePassDataOptions":{"type":"object","allOf":[{"$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},"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":["null","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.","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":{"$ref":"#/components/schemas/SingleUpdatePassData"}},"text/json":{"schema":{"$ref":"#/components/schemas/SingleUpdatePassData"}},"application/*+json":{"schema":{"$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"}]}}}}}}}}}
```

## GET /api/{tenantId}/passes/{passId}/connect

> Retrieve a WebSocket URL for pass-level notifications.

```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.","parameters":[{"name":"passId","in":"path","description":"Serial number of the pass.","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":{"$ref":"#/components/schemas/PassConnectResponse"}},"application/json":{"schema":{"$ref":"#/components/schemas/PassConnectResponse"}},"text/json":{"schema":{"$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":["null","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":["null","object"],"additionalProperties":{"type":"array","items":{"type":"string"}}}},"additionalProperties":{}}}}}
```

## GET /api/{tenantId}/passes/{passId}/data

> Retrieve aggregated pass data from all registered data providers.

```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.","parameters":[{"name":"passId","in":"path","description":"Serial number of the pass.","required":true,"schema":{"pattern":"^[\\w-]{5,50}$","type":"string"}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}}}}
```

## GET /api/{tenantId}/passes/{passId}/data/raw

> Retrieve the raw persisted pass document for diagnostics.

```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.","parameters":[{"name":"passId","in":"path","description":"Serial number of the pass.","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":["null","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"}]}}}}}}}}}
```

## GET /api/{tenantId}/passes/{passId}/view

> Redirect to a web page that lets the user view and download the 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"}],"paths":{"/api/{tenantId}/passes/{passId}/view":{"get":{"tags":["Pass"],"summary":"Redirect to a web page that lets the user view and download the pass.","parameters":[{"name":"passId","in":"path","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":["null","object"],"additionalProperties":{"type":"array","items":{"type":"string"}}}},"additionalProperties":{}}}}}
```

## GET /api/{tenantId}/passes/{passIds}

> Retrieve multiple passes for the specified device.

```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.","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"}}}}}}
```

## GET /api/{tenantId}/passes/findPass

> Retrieve a Wallet Crew passId from external identifiers.

```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.","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 using a supplier key or comma-separated pass IDs.

> \*\*Two Modes:\*\*\
> \- \*\*Supplier Mode:\*\* When \`provider\` specified, value passed to registered \`IPassSupplier\` (e.g., order lookup) returns associated pass IDs. Can optionally create missing passes.\
> \- \*\*Direct Mode:\*\* When \`provider\` null, value treated as comma-separated pass IDs.\
> \
> \*\*Preview:\*\* When \`includePreview=true\`, includes title, subtitle, colors, header text, enabled status for UI rendering.\
> \
> \*\*Use Cases:\*\* E-commerce (order → passes); subscriptions (subscription → passes); mobile preview data; loyalty programs (member → passes).

```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/getPasses":{"get":{"tags":["Pass"],"summary":"Retrieve passes using a supplier key or comma-separated pass IDs.","description":"**Two Modes:**\n- **Supplier Mode:** When `provider` specified, value passed to registered `IPassSupplier` (e.g., order lookup) returns associated pass IDs. Can optionally create missing passes.\n- **Direct Mode:** When `provider` null, value treated as comma-separated pass IDs.\n\n**Preview:** When `includePreview=true`, includes title, subtitle, colors, header text, enabled status for UI rendering.\n\n**Use Cases:** E-commerce (order → passes); subscriptions (subscription → passes); mobile preview data; loyalty programs (member → passes).","parameters":[{"name":"value","in":"query","description":"Key supplied to the provider to resolve passIds.","schema":{"type":"string"}},{"name":"provider","in":"query","description":"Provider name registered in DI. If null, value is treated as comma-separated passIds.","schema":{"type":"string"}},{"name":"includePreview","in":"query","description":"When true, include preview details for each pass.","schema":{"type":"boolean","default":false}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Pass identifiers retrieved successfully.","content":{"text/plain":{"schema":{"type":"array","items":{}}},"application/json":{"schema":{"type":"array","items":{}}},"text/json":{"schema":{"type":"array","items":{}}}}}}}}}}
```

## 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":["null","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.

```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":["null","string"],"description":"Field to filter by (identifiers.*, metadata.*, passType, installationStatus)."},"value":{"type":["null","string"],"description":"Filter value to match."},"operator":{"$ref":"#/components/schemas/FilterModelOperator"}},"additionalProperties":false,"description":"Filter specification for pass queries."},"FilterModelOperator":{"enum":["Contains","StartsWith","EndsWith","Equals","IsEmpty","IsNotEmpty","doesNotEqual"],"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":["null","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":{"$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}}},"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.","parameters":[{"name":"filter","in":"query","description":"Optional filters applied to select passes.","schema":{"type":"array","items":{"$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":{"$ref":"#/components/schemas/MultipleUpdatePassData"}},"text/json":{"schema":{"$ref":"#/components/schemas/MultipleUpdatePassData"}},"application/*+json":{"schema":{"$ref":"#/components/schemas/MultipleUpdatePassData"}}}},"responses":{"200":{"description":"Passes scheduled for update; returns the count in the response body.","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/PushUpdateResult"}},"application/json":{"schema":{"$ref":"#/components/schemas/PushUpdateResult"}},"text/json":{"schema":{"$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.

```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.","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.

```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":["null","string"],"description":"Unique operation identifier."},"operationName":{"type":["null","string"],"description":"Operation name/category."},"operationData":{"type":["null","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.","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Statistics retrieved successfully.","content":{"text/plain":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PushUpdateStatistics"}}},"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PushUpdateStatistics"}}},"text/json":{"schema":{"type":"array","items":{"$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":{"$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":{"$ref":"#/components/schemas/PassStatistic"}},"application/json":{"schema":{"$ref":"#/components/schemas/PassStatistic"}},"text/json":{"schema":{"$ref":"#/components/schemas/PassStatistic"}}}}}}}}}
```
