> 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/readme.md).

# Developer guide

## Developer guide

This section focuses on API integrations with The Wallet Crew. It covers authentication, the API reference, a first request, and the main paths to follow next.

<a href="https://docs.thewalletcrew.io/api-reference" class="button primary" data-icon="terminal">Open API reference</a> <a href="/spaces/OnaDC4sjKAx53j0QV843/pages/9ffi9GY9n9bSPW9vnNyZ" class="button secondary" data-icon="rocket-launch">Start quickstart</a>

<details>

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

* Create a loyalty pass after signup or checkout.
* Update pass fields after a CRM, ticketing, or POS event.
* Forward wallet lifecycle events to a backend, CRM, or analytics stack.

</details>

### Start here

Most developer projects follow the same path.

{% stepper %}
{% step %}

#### Get credentials

Generate an API key from the admin console in **Settings → Security → API Keys**.

For most first integrations, the API key is sent in the `X-API-KEY` header.
{% endstep %}

{% step %}

#### Open the API reference

Use the API reference to inspect endpoints, request bodies, response schemas, and live examples.

[Open API reference](https://docs.thewalletcrew.io/api-reference)
{% endstep %}

{% step %}

#### Make a first request

Start with an existing pass. This is the fastest way to validate tenant access, authentication, and update behavior without mixing creation logic into the first test.

Continue with [Getting started with the API](/developers-guides/integration-guides/getting-started-with-the-api.md).
{% endstep %}

{% step %}

#### Expand the integration

Once the first management call works, move to creation flows, updates, webhooks, scans, and reporting.
{% endstep %}
{% endstepper %}

### Authentication

The main developer entry point uses an API key. Generate the key from the admin console, then send it in the `X-API-KEY` header.

Some tenant-scoped APIs can use other authentication models or extra scopes. When that happens, the endpoint guide or reference is the source of truth.

{% hint style="info" %}
For a first integration, start with APIs documented around `X-API-KEY`. This is the usual path for pass management, webhooks, scans, and the interactive API reference.
{% endhint %}

### Quickstart

The fastest validation flow is to start with a pass that already exists, trigger a management call, then confirm the result on that pass.

The most common first call is a pass refresh:

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

This validates tenant scope, API key authentication, and the update pipeline on a real pass. Use [Getting started with the API](/developers-guides/integration-guides/getting-started-with-the-api.md) for the end-to-end setup.

If no pass exists yet, start with [Enrolment flows](/developers-guides/integration-guides/wallet/enrolment-flows.md) or [Connector-triggered pass creation](/developers-guides/integration-guides/wallet/connector-triggered-pass-creation.md).

### API reference

Use the API reference when the exact payload shape, response schema, or endpoint behavior matters.

#### Main entry points

* [API reference](https://docs.thewalletcrew.io/api-reference)
* [Webhooks](/developers-guides/integration-guides/webhooks.md)

### Developer guides

These pages cover the main integration patterns.

* [Key concepts](/developers-guides/readme/key-concepts.md) for tenant scope, identifiers, templates, and pass lifecycle basics.
* [Getting started with the API](/developers-guides/integration-guides/getting-started-with-the-api.md) for the first tenant-scoped calls on passes that already exist.
* [Enrolment flows](/developers-guides/integration-guides/wallet/enrolment-flows.md) for pass creation during hosted or custom enrolment journeys.
* [Connector-triggered pass creation](/developers-guides/integration-guides/wallet/connector-triggered-pass-creation.md) for source-driven issuance based on upstream events.
* [Update pass data in templates](/developers-guides/integration-guides/wallet/update-pass-data-in-templates.md) for updating pass data and rendering it in templates.
* [Templating engine](/developers-guides/integration-guides/wallet/liquid-templating.md) for supported DotLiquid syntax, custom filters, and the `minify` tag.
* [Webhooks](/developers-guides/integration-guides/webhooks.md) for real-time event delivery.
* [Scan API](/developers-guides/integration-guides/scan-api.md) for barcode and QR scan ingestion.
* [Insights API](/developers-guides/integration-guides/insights-api.md) for logs, events, and metrics queries.
* [Custom connectors](/developers-guides/integration-guides/custom-connectors.md) for tenant-side integration logic.

### Common next steps

After the first request succeeds, the next step usually depends on the integration goal.

* If passes already exist, start with [Getting started with the API](/developers-guides/integration-guides/getting-started-with-the-api.md).
* If pass issuance starts in a signup, checkout, or hosted form, use [Enrolment flows](/developers-guides/integration-guides/wallet/enrolment-flows.md).
* If pass issuance starts from a source-system event, use [Connector-triggered pass creation](/developers-guides/integration-guides/wallet/connector-triggered-pass-creation.md).
* To keep wallet content fresh, continue with [Update pass data in templates](/developers-guides/integration-guides/wallet/update-pass-data-in-templates.md).
* To notify other systems in real time, use [Webhooks](/developers-guides/integration-guides/webhooks.md).

### FAQ

<details>

<summary><strong>How is authentication retrieved?</strong></summary>

Generate an API key from the admin console, then send it in `X-API-KEY` for the main platform APIs documented in the quickstart flow.

</details>

<details>

<summary><strong>Where is the API reference?</strong></summary>

Use [API reference](https://docs.thewalletcrew.io/api-reference) for the main API entry point.

</details>

<details>

<summary><strong>What is the best first API call?</strong></summary>

A forced update on an existing pass is usually the best first call because it validates tenant access, authentication, and the update path without depending on a creation flow.

</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/readme.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.
