> 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/wallet/batch-operations.md).

# Opérations par lot

## Opérations par lot

The Wallet Crew prend en charge deux mécanismes pour mettre à jour des Cartes en masse : l’API de mise à jour push et les imports de fichiers plats SFTP.

#### API de mise à jour push

L’opération ci-dessous déclenche une mise à jour push sur toutes les Cartes qui correspondent à une condition de filtre. C’est le principal mécanisme par lot pour les systèmes connectés à l’API.

Le point de terminaison accepte le même `filtre` tableau que le point de terminaison de liste des Cartes. Voir Filtres et opérateurs de requête pour la référence complète des filtres.

## Push update for passes matching the filter.

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

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

Chaque Carte correspondante est mise en file d’attente pour mise à jour indépendamment. La plateforme résout tous les identifiants de Carte correspondants dans la requête, puis les place en file d’attente comme une seule commande contenant N tâches individuelles par Carte. La `200` réponse signifie que le lot a été accepté et planifié — pas qu’il est terminé.

Il n’existe aucune limite stricte au nombre de Cartes qu’un seul appel peut correspondre. `bypassQueue` n’est pas disponible sur ce point de terminaison.

{% hint style="info" %}
Vous pouvez fournir un `correlationId` dans le corps de la requête. La plateforme l’attache à chaque tâche mise en file d’attente, ce qui vous permet de suivre la progression du traitement via le point de terminaison des statistiques. Il n’existe aucun webhook d’achèvement au niveau du lot.
{% endhint %}

**Échecs partiels**

Chaque Carte est traitée indépendamment. Un échec sur une Carte — par exemple, une erreur de connecteur ou une Carte introuvable — n’affecte pas les autres Cartes du lot. Les Cartes en échec ne sont pas retentées automatiquement, sauf si l’erreur sous-jacente est transitoire.

#### Importations de fichiers plats SFTP

Les imports SFTP vous permettent de mettre à jour des données supplémentaires, des identifiants, des modèles de Carte et des métadonnées sur de nombreuses Cartes en téléversant un fichier CSV. Cette méthode est conçue pour les systèmes hérités qui ne peuvent pas appeler l’API directement.

{% hint style="warning" %}
Les imports SFTP constituent une solution de dernier recours. Utilisez l’API de mise à jour push pour tout système prenant en charge les appels HTTP. SFTP est une fonctionnalité optionnelle — contactez The Wallet Crew pour l’activer sur votre tenant.
{% endhint %}

Chaque ligne du CSV cible une seule Carte. Les Cartes sont mises à jour de manière asynchrone après la détection du fichier sur le serveur SFTP. Comme pour l’API de mise à jour push, les opérations sont par Carte et indépendantes.

Pour le format complet du fichier, la référence des colonnes, les identifiants SFTP et les scripts de mappage personnalisés, voir [Mettre à jour une Carte à l’aide de fichiers plats](https://docs.thewalletcrew.io/configuration/wallet/import-and-export/update-pass-using-flat-files) dans l’espace Configuration.

#### Choisir entre les deux approches

|                         | API de mise à jour push                                         | Fichier plat SFTP                                                                  |
| ----------------------- | --------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| Idéal pour              | Intégrations en temps réel ou planifiées avec accès à l’API     | Systèmes hérités avec exportations de fichiers plats uniquement                    |
| Ciblage                 | Conditions de filtre (n’importe quel champ de données de Carte) | Identifiant par ligne (liste explicite)                                            |
| Données mises à jour    | Déclenche un nouveau chargement du connecteur via push          | Met à jour `additionalData`, `identifiants`, `passType`, `métadonnées` directement |
| Configuration           | Aucune configuration supplémentaire requise                     | Fonctionnalité optionnelle — doit être activée pour chaque tenant                  |
| Suivi de la progression | `correlationId` + point de terminaison des statistiques         | Déclenchement sans suivi                                                           |

#### Suivi de la progression du lot dans la console

La console d’administration fournit une vue en temps réel de toutes les opérations par lot. Ouvrez **Paramètres → Surveillance → mises à jour Wallet**.

La page affiche toutes les opérations de mise à jour push avec les colonnes suivantes :

| Colonne           | Description                                   |
| ----------------- | --------------------------------------------- |
| Début             | Quand le lot a été mis en file d’attente      |
| Dernière activité | Événement de traitement le plus récent        |
| Opération         | Nom interne de l’opération                    |
| Corrélation       | Le `correlationId` fourni dans la requête API |
| Cartes            | Nombre total de Cartes dans le lot            |
| Terminées         | Cartes traitées avec succès                   |
| Erreurs           | Cartes dont le traitement a échoué            |
| Apple             | Livraisons Apple Wallet                       |
| Google            | Livraisons Google Wallet                      |
| Statut            | Statut global du lot, par exemple `Terminées` |

Pour faire correspondre un appel API à une ligne, fournissez un `correlationId` dans l’opération de mise à jour push. La valeur apparaît dans la **Corrélation** colonne, ce qui permet de retrouver facilement le lot parmi les opérations concurrentes.

{% hint style="info" %}
Les opérations en cours peuvent être annulées depuis cette page. Il n’existe aucun webhook d’achèvement au niveau du lot. Utilisez cette vue pour le suivi opérationnel.
{% endhint %}


---

# 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/wallet/batch-operations.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.
