> For the complete documentation index, see [llms.txt](https://docs.thewalletcrew.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.thewalletcrew.io/developers-guides/integration-guides/wallet/pass-lifecycle.md).

# Manage pass lifecycle with the API

## Manage pass lifecycle with the API

The Wallet Crew API manages a pass from creation to wallet removal. It supports pass updates, wallet notifications, and lifecycle events for Apple Wallet and Google Wallet.

Use this guide to choose the right lifecycle action. Use the [API reference](https://docs.thewalletcrew.io/api-reference) for schemas, parameters, and responses.

<details>

<summary><strong>Real-world examples</strong></summary>

* A retailer creates a loyalty pass using a CRM customer identifier.
* An airline updates gate information and sends a wallet refresh.
* An event platform records wallet removal through `Pass:Uninstalled`.

</details>

### Before managing a pass

Passes use identifiers to connect each wallet pass to external records. These identifiers let connectors fetch the latest source data during rendering.

Review [Pass data and sync](/developers-guides/pass-architecture/pass-data-and-sync.md) before designing an integration. Use [Structure](/developers-guides/pass-architecture/structure.md) to choose stable identifier keys.

### Pass state model

The Wallet Crew has no universal pass state field. Pass data defines the state. [Liquid templates](/developers-guides/integration-guides/wallet/liquid-templating.md) map that data to native wallet fields.

Apple Wallet supports these state-related fields:

* `voided` — a boolean that marks the pass invalid in the wallet. Set it to `false` to reverse the change.
* `expirationDate` — an ISO 8601 date that defines when the pass expires.

Google Wallet supports these state-related fields:

* `state` — one of `ACTIVE`, `COMPLETED`, `EXPIRED`, or `INACTIVE`.
* `validTimeInterval` — the time window during which the pass remains valid.

Map the relevant fields in the Apple Wallet and Google Wallet templates. The displayed state changes only after a pass renders again.

{% hint style="info" %}
The Wallet Crew has no soft-delete or archive state. The API does not delete pass records. To deactivate a pass, update the relevant platform state field.
{% endhint %}

### Creating a pass

Create a pass through the operation below. Supply at least one external identifier from the source system.

The Wallet Crew validates identifiers through one of these authorization methods:

* HMAC signature
* Registered secret
* Security allowlist
* `Pass.Write` scope

A pass requires data at creation. The Wallet Crew fetches connector data lazily when the pass first renders. Include data that allows a connector to locate the external record.

## 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"}]}}}}}}}}}
````

{% hint style="info" %}
Pass creation does not fetch connector data immediately. The first installation or render triggers that fetch.
{% endhint %}

### Updating pass data

Use the operation below to update pass data and request a wallet refresh. Submitted fields merge with the existing pass data. Omitted fields remain unchanged. An empty value or `null` removes the submitted field.

## 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"}]}}}}}}}}}
````

#### Push notification behavior

**Backend and device updates**

Pass updates operate at two independent levels:

1. **Backend update** — The Wallet Crew updates the pass record.
2. **Device notification** — The Wallet Crew notifies wallet platforms when active registrations exist.

The backend update completes regardless of installation status. Device delivery depends on whether the pass remains installed.

**Device notification**

After the backend updates, The Wallet Crew attempts to notify Apple Wallet and Google Wallet. The notification depends on active registrations:

* An installed pass can receive an update through its wallet platform.
* An uninstalled pass has no active registrations, so no device notification is sent.
* A later installation receives the latest pass version from The Wallet Crew.

**Queue and deduplication**

The Wallet Crew queues updates by default with `bypassQueue: false`. The queue protects system throughput and deduplicates work. If another update reaches the same pass before the queued task runs, the queue skips the earlier task.

Set `bypassQueue: true` for urgent synchronous updates. Use it for changes such as boarding status updates that must reach the wallet immediately.

**Re-rendering on device**

{% hint style="info" %}
A notification does not update a property directly. When a device receives a notification, its wallet requests the latest pass version. The Wallet Crew fetches fresh connector data before returning that version.
{% endhint %}

{% hint style="info" %}
Backend updates persist. This supports safe updates while a pass is uninstalled.
{% endhint %}

For template mappings and pass fields, see [Update pass data in templates](/developers-guides/integration-guides/wallet/update-pass-data-in-templates.md).

### Sending a standalone notification

Send a text notification without changing pass data with the operation below. The notification appears in the wallet application independently of a data update.

Use `content` for a plain string. Use `localizedContent` for an object keyed by ISO 639 language codes. Use one content format per request.

## 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"}]}}}}}}}}}
```

### Wallet removal

When an end-user removes a pass, the wallet platform notifies The Wallet Crew. Apple sends an HTTP `DELETE` request to the Apple registrations route. Google sends a message with `eventType = "del"`.

The Wallet Crew sends `Pass:Uninstalled` when the last active registration reaches zero. Removing a pass from one of two iPhones does not send the event.

The webhook payload includes:

* `passId`, `passType`, `identifiers`, and `metadata`
* `device` and `deviceIdentifier` — Google sets `deviceIdentifier` to `null`
* `registrationInformation.activeRegistrationCount` and `registrationInformation.totalRegistrationCount`

The Wallet Crew delivers the event through the configured webhook endpoint. The request includes `X-NEOSTORE-EVENTNAME: Pass:Uninstalled`.

{% hint style="info" %}
Removing a pass from a wallet does not delete its The Wallet Crew record. The pass can be installed again later.
{% endhint %}

Configure endpoint delivery and validate signatures in [Webhooks](/developers-guides/integration-guides/webhooks.md).

### FAQ

<details>

<summary><strong>Does updating pass data immediately change an installed pass?</strong></summary>

No. The update creates a new pass version and triggers a wallet refresh. Apple Wallet or Google Wallet then requests that version.

</details>

<details>

<summary><strong>Can a pass be deleted through the API?</strong></summary>

No. The API does not delete pass records. Set the platform-specific state fields to deactivate a pass.

</details>

<details>

<summary><strong>Why was a wallet update not delivered?</strong></summary>

Push delivery requires an active provider registration. Confirm that the pass was installed on the relevant wallet platform.

</details>

<details>

<summary><strong>Can I use failed updates to detect uninstalled passes?</strong></summary>

No. Updates do not fail when a pass is uninstalled. The Wallet Crew processes the backend update successfully. No device push is sent when the pass has no active registrations.

Check installation status with the [pass details endpoint](https://docs.thewalletcrew.io/api-reference). Alternatively, listen for [Pass:Installed and Pass:Uninstalled events](/developers-guides/integration-guides/wallet/pass-lifecycle.md#wallet-removal).

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.thewalletcrew.io/developers-guides/integration-guides/wallet/pass-lifecycle.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
