> 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/fr/integration-guides/getting-started-with-the-api.md).

# Premiers pas avec l’API

## Premiers pas avec l’API

L’API Wallet Crew offre aux développeurs un contrôle programmatique sur les cartes. La création de Carte est prise en charge via le SDK Cinto, les connecteurs et `POST /passes`. Utilisez `POST /passes` pour les flux pilotés par le backend. Voir [Cycle de vie de la Carte → Création d’une carte](/developers-guides/fr/integration-guides/wallet/pass-lifecycle.md).

Chaque point de terminaison de l’API est rattaché à un tenant. Tous les appels incluent un `{tenantId}` segment de chemin et une clé API émise pour ce tenant. Un tenant est un espace de travail isolé sur la plateforme, souvent une marque ou une région. Si le modèle de tenant ne vous est pas familier, commencez par [Concepts clés](/developers-guides/fr/readme/key-concepts.md).

<details>

<summary><strong>Exemples concrets</strong></summary>

* Déclencher un rafraîchissement de carte après la modification d’un solde de fidélité dans un CRM.
* Enregistrer un scan en magasin ou sur site depuis un système de caisse (POS) ou de contrôle d’accès.
* Envoyer une notification push à un détenteur de carte spécifique après un événement opérationnel.

</details>

### Prérequis

Avant d’effectuer un premier appel API, assurez-vous que ces éléments existent déjà :

* Un modèle de carte configuré dans le back-office.
* Au moins une Carte créée via le [documentation du SDK Cinto](https://docs.thewalletcrew.io/guides-enrolment/enrolment/on-your-website#npm-module), un connecteur ou `POST /passes`.
* Une clé API pour le tenant.

### Étape 1 — Obtenir la clé API

Dans le back-office, accédez à **Paramètres → Clés API et secrets → Clés API**.

Créez une nouvelle clé API. La clé est automatiquement rattachée au tenant actuellement sélectionné dans le back-office. Copiez la clé lorsqu’elle est créée. Elle ne sera plus affichée.

{% hint style="warning" %}
Les clés API comportent des permissions. Une clé sans les permissions requises renvoie `401` ou `403`. Utilisez la référence de l’API pour confirmer les exigences spécifiques au point de terminaison. Une page dédiée aux permissions des clés API sera ajoutée séparément.
{% endhint %}

### Étape 2 — Comprendre l’URL de base

Les opérations OpenAPI ci-dessous incluent l’URL de base de production. Remplacez `{tenantId}` par l’identifiant du tenant. Cet identifiant est le slug utilisé dans l’URL du back-office. Par exemple, si l’URL du back-office contient `/tenant/my-brand/`, le `tenantId` est `my-brand`.

{% hint style="info" %}
Chaque point de terminaison de l’API est rattaché à un tenant. Une clé émise pour un tenant ne peut pas accéder aux données d’un autre tenant.
{% endhint %}

### Étape 3 — S’authentifier

Incluez la clé API dans chaque requête à l’aide de l’en-tête `X-API-KEY` .

Si la clé est absente ou invalide, l’API renvoie `401`.

### Étape 4 — Comprendre les identifiants de carte

L’API identifie les cartes via [des identifiants externes](/developers-guides/fr/pass-architecture/structure.md) — des clés qui relient une carte aux systèmes sources tels qu’un ID CRM, un numéro de fidélité ou un ID de billet. La plupart des points de terminaison acceptent un identifiant externe pour cibler la carte correcte.

Certains points de terminaison utilisent également l’identifiant interne `passId`. C’est courant pour les opérations directes comme l’envoi d’une notification à une carte spécifique.

### Premiers appels courants

#### Forcer la mise à jour d’une carte

Une mise à jour forcée est souvent le meilleur premier appel lorsque des cartes existent déjà. Elle valide le rattachement au tenant, l’authentification et l’actualisation du fournisseur sur une carte réelle.

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

Cet appel indique à la plateforme de récupérer à nouveau les données auprès des fournisseurs configurés, de reconstruire la carte et de pousser la version mise à jour vers l’appareil.

#### Enregistrer un scan

Lorsqu’un code-barres de carte est scanné dans un point de vente ou un système de contrôle d’accès, enregistrez l’événement via l’API Scan.

## Record a pass barcode scan event

> Records scan events when pass barcodes/QR codes are scanned. Scans are correlated to passes\
> and generate scan completion events for downstream systems (redemption, attendance tracking, etc.).\
> \
> \## Authorization\
> Requires PassScan.Scan scope

```json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"Scan"}],"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":{"AddScanRequest":{"required":["data","type"],"type":"object","properties":{"data":{"maxLength":2048,"minLength":3,"type":"string","description":"Raw Data of the scan value"},"type":{"description":"Type of data","$ref":"#/components/schemas/TypeEnum"}},"additionalProperties":false},"TypeEnum":{"enum":["manual","text","qrcode","pdf417","aztec","code128","code39","codabar","ean8","ean13","itf14","upca","datamatrix","nfc"],"type":"string"},"AddScanResponse":{"required":["passId"],"type":"object","properties":{"passId":{"type":"string","description":"Identifier of the pass"}},"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}/scans":{"post":{"tags":["Scan"],"summary":"Record a pass barcode scan event","description":"Records scan events when pass barcodes/QR codes are scanned. Scans are correlated to passes\nand generate scan completion events for downstream systems (redemption, attendance tracking, etc.).\n\n## Authorization\nRequires PassScan.Scan scope","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Scan payload containing raw barcode data and format type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddScanRequest"}},"text/json":{"schema":{"$ref":"#/components/schemas/AddScanRequest"}},"application/*+json":{"schema":{"$ref":"#/components/schemas/AddScanRequest"}}}},"responses":{"201":{"description":"Scan successfully recorded; pass identifier returned","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/AddScanResponse"}},"application/json":{"schema":{"$ref":"#/components/schemas/AddScanResponse"}},"text/json":{"schema":{"$ref":"#/components/schemas/AddScanResponse"}}}},"400":{"description":"Invalid scan request (data too short/long, missing type)","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"401":{"description":"Not authorized or invalid credentials","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"404":{"description":"No pass found with matching scan data","content":{"text/plain":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}},"text/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"500":{"description":"Processing error during scan event generation"}}}}}}
```

#### Envoyer une notification push

Utilisez le point de terminaison de notification pour envoyer une notification push à un détenteur de carte spécifique.

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

### Référence de l’API

La référence complète de l’API est disponible sous **Développeurs → Référence de l’API**.

Utilisez-la pour les détails des points de terminaison, les corps des requêtes, les schémas de réponse et les exigences de permission.

[Ouvrir la référence de l’API](https://docs.thewalletcrew.io/api-reference)

### FAQ

<details>

<summary><strong>L’API peut-elle créer une nouvelle carte ?</strong></summary>

Oui. La création de Carte est prise en charge via le SDK Cinto, les connecteurs et `POST /passes`. Utilisez `POST /passes` pour les flux pilotés par le backend. Voir [Cycle de vie de la Carte → Création d’une carte](/developers-guides/fr/integration-guides/wallet/pass-lifecycle.md).

</details>

<details>

<summary><strong>Quel est le meilleur premier appel API ?</strong></summary>

Une mise à jour forcée sur une carte existante est généralement le meilleur premier appel. Elle valide le périmètre du tenant, l’authentification et le chemin de rendu sur une carte réelle.

</details>

<details>

<summary><strong>Les intégrations doivent-elles commencer par <code>passId</code> ou des identifiants externes ?</strong></summary>

La plupart des intégrations commencent par des identifiants externes parce qu’ils existent déjà dans les systèmes sources. Utilisez `passId` lorsqu’une opération directe sur une carte nécessite l’identifiant interne.

</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/fr/integration-guides/getting-started-with-the-api.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.
