> 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/filter-and-query-operators.md).

# Opérateurs de filtre et de requête

Filtrez et paginez la liste des Cartes à l’aide de conditions de champ, d’opérateurs de chaîne et d’ensemble, ainsi que de la pagination basée sur l’offset.

## Opérateurs de filtre et de requête

Plusieurs points de terminaison liés aux cartes acceptent un `filtre` tableau qui restreint les résultats par champ de données de carte. Utilisez les filtres avec la pagination pour récupérer exactement l’ensemble de cartes dont vous avez besoin.

Le filtrage est pris en charge sur ces points de terminaison :

* [`GET /api/{tenantId}/passes`](/api-reference/pass-management/pass.md) — lister les cartes
* [`POST /api/{tenantId}/passes/pushUpdate`](/api-reference/pass-management/pass.md) — déclencher une mise à jour push sur un ensemble filtré
* [`POST /api/{tenantId}/passes/export/token`](/api-reference/pass-management/pass.md) — exporter un ensemble filtré

## List passes

> Filters: see Neo.Web.Api.Controllers.FilterModel. Sort: see Neo.Web.Api.Controllers.SortModel; without one the order is unspecified and may change between pages.\
> \`\`\`\
> GET /api/{tenantId}/passes?pageIndex=0\&pageSize=20\&filter\[0].field=passType\&filter\[0].operator=equals\&filter\[0].value=loyalty\&sortBy\[0].field=creationDate\&sortBy\[0].direction=DESC\
> \`\`\`

````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":["tenant.pass:read"]},{"apiKey":[]}],"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":"`id`, `passType`, `themeId`, `creationDate` and `lastUpdateDate` (UTC), `installationStatus` (installed wallets concatenated: `\"\"`, `\"apple\"`, `\"google\"` or `\"applegoogle\"`; test with `contains`), `identifiers.{key}`, or `metadata.{key}` (compared as the type the tenant's metadata configuration gives it)."},"operator":{"description":"Comparison operator. Required.","$ref":"#/components/schemas/FilterModelOperator"},"value":{"type":["null","array"],"items":{"type":"string"},"description":"Values to compare, as repeated `value` query parameters (several only for `in`/`notIn`). Numbers use `.` as decimal separator, booleans are `true`/`false`, dates are ISO 8601 with timezone.\nA value containing `{{`, `{%` or `{#` is first rendered as a Liquid template (`{{ 'now' | date: '%Y-%m-%d' }}`).\n<example>```\nGET /passes?filter[0].field=passType&filter[0].operator=in&filter[0].value=boarding&filter[0].value=loyalty\n```</example>"}},"additionalProperties":false,"description":"One condition on passes. Several conditions must all hold."},"FilterModelOperator":{"enum":["Contains","StartsWith","EndsWith","Equals","IsEmpty","IsNotEmpty","NotEquals","In","NotIn","GreaterThan","LessThan","GreaterThanOrEqual","LessThanOrEqual"],"type":"string","description":"How a pass filter compares the field with its value."},"SortModel":{"type":"object","properties":{"field":{"type":"string","description":"`id`, `passType`, `themeId`, `creationDate`, `lastUpdateDate`, `apple`,\n            `google` (installation data of that wallet), `identifiers.{key}` or `metadata.{key}`; a datetime\n            metadata field sorts chronologically. Any other field is refused with a 400."},"direction":{"description":"`ASC` or `DESC`.","$ref":"#/components/schemas/SortModelDirection"}},"additionalProperties":false,"description":"One sort key for pass queries. Several keys apply in order, the first one being the primary sort."},"SortModelDirection":{"enum":[0,1],"type":"integer","description":"Sort direction for pass list queries, sent as `ASC` or `DESC`.","format":"int32"},"Pass":{"type":"object","properties":{"id":{"type":"string","description":"Id assigned at creation, or set by a `neo.id` identifier."},"secret":{"type":"string","description":"Confidential per-pass secret."},"creationDate":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"When the pass was issued, UTC. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."},"lastUpdateDate":{"oneOf":[{"type":"string","format":"date-time"},{"type":"integer","format":"int64"}],"description":"When the pass content last changed, UTC; equals `creationDate` when it never has. Accepts ISO 8601 date-time string or Unix epoch seconds in request inputs. Responses are serialized as ISO 8601 date-time strings."},"passType":{"type":"string","description":"Pass template the pass renders from."},"identifiers":{"type":"object","additionalProperties":{"type":"string"},"description":"Identifiers of the holder in other systems, keyed by system and field (`shopify.customerId`)."},"metadata":{"type":"object","additionalProperties":{},"description":"Fields computed from the pass by the tenant's metadata configuration, used by filters and sorts. Datetime values are ISO 8601 strings."},"additionalData":{"type":"object","additionalProperties":{},"description":"Free data stored with the pass by its creator and updates."},"providers":{"type":"object","additionalProperties":{},"description":"Wallets the pass is installed on: `apple` (first `installationDate` and `devices`) and `google` (`installationDate`), each present while installed."},"themeId":{"type":["null","string"],"description":"Theme applied to the pass; `null` when none."}},"additionalProperties":false,"description":"A pass as listed by `GET /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":{"get":{"tags":["Pass"],"summary":"List passes","description":"Filters: see Neo.Web.Api.Controllers.FilterModel. Sort: see Neo.Web.Api.Controllers.SortModel; without one the order is unspecified and may change between pages.\n```\nGET /api/{tenantId}/passes?pageIndex=0&pageSize=20&filter[0].field=passType&filter[0].operator=equals&filter[0].value=loyalty&sortBy[0].field=creationDate&sortBy[0].direction=DESC\n```","parameters":[{"name":"pageIndex","in":"query","description":"Zero-based page index. Default 0.","schema":{"maximum":2147483647,"minimum":0,"type":"integer","format":"int32","default":0}},{"name":"pageSize","in":"query","description":"Passes per page. Default 20; 0 returns an empty page with the total still set.","schema":{"maximum":2147483647,"minimum":0,"type":"integer","format":"int32","default":20}},{"name":"filter","in":"query","description":"Query `filter[i].field`, `filter[i].operator`, `filter[i].value`: conditions a pass must all meet.","schema":{"type":"array","items":{"description":"One condition on passes. Several conditions must all hold.","$ref":"#/components/schemas/FilterModel"}}},{"name":"sortBy","in":"query","description":"Query `sortBy[i].field`, `sortBy[i].direction`: sort keys, primary first.","schema":{"type":"array","items":{"description":"One sort key for pass queries. Several keys apply in order, the first one being the primary sort.","$ref":"#/components/schemas/SortModel"}}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The page of passes; the total is in the `x-pagination-total` header.","content":{"text/plain":{"schema":{"type":"array","items":{"description":"A pass as listed by `GET /passes`.","$ref":"#/components/schemas/Pass"}}},"application/json":{"schema":{"type":"array","items":{"description":"A pass as listed by `GET /passes`.","$ref":"#/components/schemas/Pass"}}},"text/json":{"schema":{"type":"array","items":{"description":"A pass as listed by `GET /passes`.","$ref":"#/components/schemas/Pass"}}}}},"400":{"description":"A filter or sort names an unsupported field, a filter has no operator, or paging is negative.","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":"The caller is not authenticated.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"The caller lacks the <c>tenant.pass:read</c> scope, or the endpoint is not enabled for the tenant.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"429":{"description":"Over 1200 requests per minute to this endpoint for the tenant (default limit); retry after <c>Retry-After</c>.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Sent when the limiter knows it.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}}}}}}
````

## Update passes in bulk

> Applies one change to every pass matching the filters (same fields and operators as \`GET /passes\`; no filter selects every pass) and pushes each to its holder's devices. Each pass is queued as its own update, spread by \`options.throughput\`: a 200 means scheduled, not done. Follow progress with \`GET /passes/pushUpdate/status\` under \`options.correlationId\`, stop it with \`POST /passes/pushUpdate/{correlationId}/cancel\`. \`additionalData\` is merged and \`passType\` replaces the template when sent; \`themeId\` omitted keeps each pass's theme, an empty string removes it. Identifiers are not changed.\
> \`\`\`\
> POST /api/{tenantId}/passes/pushUpdate?filter\[0].field=passType\&filter\[0].operator=equals\&filter\[0].value=loyalty\
> { "additionalData": { "offer": "summer2025" }, "options": { "throughput": 12, "correlationId": "campaign-summer-2025" } }\
> \`\`\`

````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":["tenant.pass:pushUpdate"]},{"apiKey":[]}],"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":"`id`, `passType`, `themeId`, `creationDate` and `lastUpdateDate` (UTC), `installationStatus` (installed wallets concatenated: `\"\"`, `\"apple\"`, `\"google\"` or `\"applegoogle\"`; test with `contains`), `identifiers.{key}`, or `metadata.{key}` (compared as the type the tenant's metadata configuration gives it)."},"operator":{"description":"Comparison operator. Required.","$ref":"#/components/schemas/FilterModelOperator"},"value":{"type":["null","array"],"items":{"type":"string"},"description":"Values to compare, as repeated `value` query parameters (several only for `in`/`notIn`). Numbers use `.` as decimal separator, booleans are `true`/`false`, dates are ISO 8601 with timezone.\nA value containing `{{`, `{%` or `{#` is first rendered as a Liquid template (`{{ 'now' | date: '%Y-%m-%d' }}`).\n<example>```\nGET /passes?filter[0].field=passType&filter[0].operator=in&filter[0].value=boarding&filter[0].value=loyalty\n```</example>"}},"additionalProperties":false,"description":"One condition on passes. Several conditions must all hold."},"FilterModelOperator":{"enum":["Contains","StartsWith","EndsWith","Equals","IsEmpty","IsNotEmpty","NotEquals","In","NotIn","GreaterThan","LessThan","GreaterThanOrEqual","LessThanOrEqual"],"type":"string","description":"How a pass filter compares the field with its value."},"MultipleUpdatePassData":{"type":"object","allOf":[{"description":"Changes to apply to an existing pass, with options.","$ref":"#/components/schemas/UpdatePassData_MultipleUpdatePassDataOptions"}],"additionalProperties":false,"description":"Changes applied to every matched pass. Omitted fields are left as they are."},"UpdatePassData_MultipleUpdatePassDataOptions":{"type":"object","properties":{"identifiers":{"type":"object","additionalProperties":{"type":"string"},"description":"Identifiers of the holder in other systems, keyed by system and field (`shopify.customerId`), matched by `findPass`, `id.{key}` lookups and filters. Avoid keys starting with `id.`."},"additionalData":{"type":["null","object"],"additionalProperties":{},"description":"Free data stored with the pass and available to its templates."},"themeId":{"type":["null","string"],"description":"Theme applied to the pass. Omit or `null` to leave it unchanged (none on create); an empty string removes it. An unknown id is refused with a 400."},"passType":{"type":["null","string"],"description":"Pass template to move the pass to. Omitted or blank keeps the current one; an unknown name is refused with a 400."},"updateMetadata":{"type":"boolean","description":"Replaced by `options.updateMetadata`.","default":false,"deprecated":true},"options":{"description":"How the update is applied. Omitted, the defaults of each option apply.","$ref":"#/components/schemas/MultipleUpdatePassDataOptions"}},"additionalProperties":false,"description":"Changes to apply to an existing pass, with options."},"MultipleUpdatePassDataOptions":{"type":"object","allOf":[{"$ref":"#/components/schemas/UpdatePassDataOptions"}],"properties":{"throughput":{"type":"number","description":"Passes updated per second, greater than 0 and at most 1000. Default 12; best effort.","format":"float"}},"additionalProperties":false,"description":"Options for a bulk update."},"UpdatePassDataOptions":{"type":"object","properties":{"updateMetadata":{"type":"boolean","description":"Recomputes the stored pass metadata read by filters and sorts. Slower; unneeded when only displayed content changes. Default `true`, except on a bulk update sent without a body."},"correlationId":{"type":["null","string"],"description":"Groups updates into one operation tracked by `GET /passes/pushUpdate/status` and stopped by `POST /passes/pushUpdate/{correlationId}/cancel`. Random when omitted; a synchronous update then records no progress."}},"additionalProperties":false,"description":"How an update is applied."},"PushUpdateResult":{"type":"object","properties":{"passCount":{"type":"integer","description":"Passes matched by the filters and queued for the update; 0 when none matched.","format":"int32"}},"additionalProperties":false,"description":"What a bulk update scheduled."},"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/pushUpdate":{"post":{"tags":["Pass"],"summary":"Update passes in bulk","description":"Applies one change to every pass matching the filters (same fields and operators as `GET /passes`; no filter selects every pass) and pushes each to its holder's devices. Each pass is queued as its own update, spread by `options.throughput`: a 200 means scheduled, not done. Follow progress with `GET /passes/pushUpdate/status` under `options.correlationId`, stop it with `POST /passes/pushUpdate/{correlationId}/cancel`. `additionalData` is merged and `passType` replaces the template when sent; `themeId` omitted keeps each pass's theme, an empty string removes it. Identifiers are not changed.\n```\nPOST /api/{tenantId}/passes/pushUpdate?filter[0].field=passType&filter[0].operator=equals&filter[0].value=loyalty\n{ \"additionalData\": { \"offer\": \"summer2025\" }, \"options\": { \"throughput\": 12, \"correlationId\": \"campaign-summer-2025\" } }\n```","parameters":[{"name":"filter","in":"query","description":"Query `filter[i].field`, `filter[i].operator`, `filter[i].value`: conditions a pass must all meet.","schema":{"type":"array","items":{"description":"One condition on passes. Several conditions must all hold.","$ref":"#/components/schemas/FilterModel"}}},{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"The change applied to each pass, and options. Omitted, each pass is pushed as it is, without recomputing metadata, at the tenant's default throughput.","content":{"application/json":{"schema":{"description":"Changes applied to every matched pass. Omitted fields are left as they are.","$ref":"#/components/schemas/MultipleUpdatePassData"}},"text/json":{"schema":{"description":"Changes applied to every matched pass. Omitted fields are left as they are.","$ref":"#/components/schemas/MultipleUpdatePassData"}},"application/*+json":{"schema":{"description":"Changes applied to every matched pass. Omitted fields are left as they are.","$ref":"#/components/schemas/MultipleUpdatePassData"}}}},"responses":{"200":{"description":"The passes are scheduled; the body gives how many.","content":{"text/plain":{"schema":{"description":"What a bulk update scheduled.","$ref":"#/components/schemas/PushUpdateResult"}},"application/json":{"schema":{"description":"What a bulk update scheduled.","$ref":"#/components/schemas/PushUpdateResult"}},"text/json":{"schema":{"description":"What a bulk update scheduled.","$ref":"#/components/schemas/PushUpdateResult"}}}},"400":{"description":"`passType` or `themeId` names a template or theme the tenant does not have, a filter names an unsupported field, or a filter has no operator.","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":"The caller is not authenticated.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"The caller lacks the <c>tenant.pass:pushUpdate</c> scope, or the endpoint is not enabled for the tenant.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"429":{"description":"Over 1200 requests per minute to this endpoint for the tenant (default limit); retry after <c>Retry-After</c>.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Sent when the limiter knows it.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}}}}}}
````

## Create a pass export link

> Creates a link downloading the matching passes as an Excel file. Valid for 30 minutes and needs no Authorization header; the filters are checked now and carried by the link.

````json
{"openapi":"3.1.1","info":{"title":"Neostore internal API","version":"v1"},"tags":[{"name":"PassExport"}],"servers":[{"url":"https://app.neostore.cloud","description":"Production Server"},{"url":"https://app-qa.neostore.cloud","description":"Staging Server"}],"security":[{"admin-bearer":["tenant.pass:read"]},{"apiKey":[]}],"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":"`id`, `passType`, `themeId`, `creationDate` and `lastUpdateDate` (UTC), `installationStatus` (installed wallets concatenated: `\"\"`, `\"apple\"`, `\"google\"` or `\"applegoogle\"`; test with `contains`), `identifiers.{key}`, or `metadata.{key}` (compared as the type the tenant's metadata configuration gives it)."},"operator":{"description":"Comparison operator. Required.","$ref":"#/components/schemas/FilterModelOperator"},"value":{"type":["null","array"],"items":{"type":"string"},"description":"Values to compare, as repeated `value` query parameters (several only for `in`/`notIn`). Numbers use `.` as decimal separator, booleans are `true`/`false`, dates are ISO 8601 with timezone.\nA value containing `{{`, `{%` or `{#` is first rendered as a Liquid template (`{{ 'now' | date: '%Y-%m-%d' }}`).\n<example>```\nGET /passes?filter[0].field=passType&filter[0].operator=in&filter[0].value=boarding&filter[0].value=loyalty\n```</example>"}},"additionalProperties":false,"description":"One condition on passes. Several conditions must all hold."},"FilterModelOperator":{"enum":["Contains","StartsWith","EndsWith","Equals","IsEmpty","IsNotEmpty","NotEquals","In","NotIn","GreaterThan","LessThan","GreaterThanOrEqual","LessThanOrEqual"],"type":"string","description":"How a pass filter compares the field with its value."},"ExportTokenResponse":{"type":"object","properties":{"downloadUrl":{"type":"string","description":"Absolute URL of `GET /passes/export/download`, carrying its access token. Valid for 30 minutes; anyone holding it can download the export, so treat it as confidential."}},"additionalProperties":false,"description":"A link that downloads the export without any other credential."},"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/export/token":{"post":{"tags":["PassExport"],"summary":"Create a pass export link","description":"Creates a link downloading the matching passes as an Excel file. Valid for 30 minutes and needs no Authorization header; the filters are checked now and carried by the link.","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"description":"Filters, with the same fields and operators as `GET /passes`. Empty or omitted, every pass is exported.","content":{"application/json":{"schema":{"type":"array","items":{"description":"One condition on passes. Several conditions must all hold.","$ref":"#/components/schemas/FilterModel"}}},"text/json":{"schema":{"type":"array","items":{"description":"One condition on passes. Several conditions must all hold.","$ref":"#/components/schemas/FilterModel"}}},"application/*+json":{"schema":{"type":"array","items":{"description":"One condition on passes. Several conditions must all hold.","$ref":"#/components/schemas/FilterModel"}}}}},"responses":{"200":{"description":"The download link.","content":{"text/plain":{"schema":{"description":"A link that downloads the export without any other credential.","$ref":"#/components/schemas/ExportTokenResponse"}},"application/json":{"schema":{"description":"A link that downloads the export without any other credential.","$ref":"#/components/schemas/ExportTokenResponse"}},"text/json":{"schema":{"description":"A link that downloads the export without any other credential.","$ref":"#/components/schemas/ExportTokenResponse"}}}},"400":{"description":"A filter names an unsupported field or has no operator.","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":"The caller is not authenticated.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"403":{"description":"The caller lacks the <c>tenant.pass:read</c> scope.","content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}},"429":{"description":"Over 1200 requests per minute to this endpoint for the tenant (default limit); retry after <c>Retry-After</c>.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Sent when the limiter knows it.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ProblemDetails"},{"$ref":"#/components/schemas/HttpValidationProblemDetails"}]}}}}}}}}}
````

### Structure de la requête de filtre

Chaque condition de filtre est un `FilterModel` objet avec trois champs :

| Champ       | Type      | Description                                                                        |
| ----------- | --------- | ---------------------------------------------------------------------------------- |
| `champ`     | string    | Le champ de données de carte sur lequel filtrer (p. ex. `passType`, `loyaltyTier`) |
| `opérateur` | string    | L’opérateur de comparaison (voir ci-dessous)                                       |
| `valeur`    | string\[] | Une ou plusieurs valeurs à comparer. Omettez pour `isEmpty` et `isNotEmpty`.       |

Les filtres sont transmis sous forme de paramètres de requête indexés :

```
filter[0].field=passType&filter[0].operator=equals&filter[0].value=boarding
```

Plusieurs conditions sont combinées avec un ET logique :

```
filter[0].field=passType&filter[0].operator=equals&filter[0].value=boarding
&filter[1].field=loyaltyTier&filter[1].operator=isNotEmpty
```

### Opérateurs

#### Opérateurs de chaîne

Ces opérateurs comparent la valeur du champ à une seule chaîne.

| Opérateur    | Comportement                                        |
| ------------ | --------------------------------------------------- |
| `equals`     | Correspondance exacte                               |
| `notEquals`  | Ne correspond pas                                   |
| `contains`   | Le champ contient la valeur en tant que sous-chaîne |
| `startsWith` | Le champ commence par la valeur                     |
| `endsWith`   | Le champ se termine par la valeur                   |

Exemple — cartes dont le niveau de fidélité contient « gold » :

```
filter[0].field=loyaltyTier&filter[0].operator=contains&filter[0].value=gold
```

#### Opérateurs de présence

Ces opérateurs vérifient si un champ a une valeur. Aucun `valeur` paramètre n’est requis.

| Opérateur    | Comportement                    |
| ------------ | ------------------------------- |
| `isEmpty`    | Le champ est absent ou nul      |
| `isNotEmpty` | Le champ a une valeur non nulle |

Exemple — cartes où `externalId` n’est pas défini :

```
filter[0].field=externalId&filter[0].operator=isEmpty
```

#### Opérateurs d’ensemble

Ces opérateurs effectuent une correspondance avec une liste de valeurs. Répétez le `valeur` paramètre pour fournir plusieurs entrées.

| Opérateur | Comportement                                              |
| --------- | --------------------------------------------------------- |
| `in`      | Le champ correspond à n’importe quelle valeur de la liste |
| `notIn`   | Le champ ne correspond à aucune des valeurs de la liste   |

Exemple — cartes de type `boarding` ou `loyalty`:

```
filter[0].field=passType&filter[0].operator=in&filter[0].value=boarding&filter[0].value=loyalty
```

{% hint style="info" %}
`in` et `notIn` sont disponibles uniquement via l’API. Le tableau des cartes du back-office n’expose pas ces opérateurs dans ses contrôles de filtre.
{% endhint %}

### Pagination

Le point de terminaison de liste des cartes utilise une pagination basée sur un décalage.

| Paramètre   | Type   | Par défaut | Description                  |
| ----------- | ------ | ---------- | ---------------------------- |
| `pageIndex` | entier | `0`        | Index de page à base zéro    |
| `pageSize`  | entier | `20`       | Nombre de résultats par page |

La réponse inclut un `x-pagination-total` en-tête contenant le nombre total de cartes correspondantes sur toutes les pages.

Pour récupérer toutes les cartes par lots, incrémentez `pageIndex` jusqu’à ce que le nombre total soit épuisé.

### Combiner les filtres et la pagination

Les paramètres de filtres et de pagination sont des paramètres de requête indépendants et peuvent être combinés librement.


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.thewalletcrew.io/developers-guides/fr/integration-guides/wallet/filter-and-query-operators.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
