> 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/connectors/custom-connector/custom-connector-scripting-reference/bulk-pass-update-row-transformation.md).

# Bulk pass update row transformation

Customize throughput and row parsing for bulk "update passes" imports, using \`runtime.import.updatePasses.rowTransformer\`.

These two optional hooks customize the bulk "update passes" import pipeline (CSV files dropped for import, including through SFTP). They exist for files whose columns do not follow the [documented column reference](/configure/advanced-configuration/wallet/import-and-export/update-pass-using-flat-files.md), typically an export from a CRM or POS that cannot be changed. Each hook can be implemented independently, and neither needs additional configuration beyond registering the endpoint in a script.

```js
/**
 * @param {string} fileName - Name of the file being imported.
 * @returns {number|null} A throughput override for this file, or null to use the default.
 */
function getThroughput(fileName) {
  return fileName.startsWith("priority-") ? 20 : null;
}

/**
 * @typedef {Object} UpdatePassInformation
 * @property {Record<string, string>} Identifiers
 * @property {string} [PassType]
 * @property {string} [ThemeId]
 * @property {string} [BenefitTemplateId]
 * @property {Record<string, string|null>} [AdditionalData]
 * @property {boolean} UpdateMetadata
 * @property {Record<string, string|null>} [NewIdentifiers]
 * @property {string} [Notification]
 * @property {Record<string, string>} [NotificationLocalizations]
 */

/**
 * @param {Record<string, string>} row - The current CSV row, as column name → value.
 * @returns {UpdatePassInformation|null} The transformed row, or null to apply the default column parsing.
 */
function transform(row) {
  return null; // fall back to the default parsing for every row
}

export default function (context) {
  context.register('runtime.import.updatePasses.rowTransformer', {
    GetThroughput: getThroughput,
    Transform: transform
  });
}
```

`GetThroughput` is called once per file, before rows are read. `Transform` is called once per row. Either function can be omitted from the registered object — an omitted or `null`-returning function falls back to the platform's default behavior for that row or file.

## Throughput

The throughput is the number of pass updates delivered per second. It applies to the whole file: updates are spread at that pace from the first row to the last, however many rows the file has. Returning `null` keeps the default pace.

## Fields of UpdatePassInformation

Every field left out or `null` leaves the corresponding part of the pass unchanged.

| Field                       | Meaning                                                                                                                                                              |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Identifiers`               | The passes to update. An `id` key selects one pass by its pass identifier; otherwise `id.<name>` keys select every pass carrying all the given external identifiers. |
| `PassType`                  | The pass template to switch to.                                                                                                                                      |
| `ThemeId`                   | The theme to apply. An empty string `""` removes the current theme.                                                                                                  |
| `BenefitTemplateId`         | A benefit template, granted to each pass before the pass is updated.                                                                                                 |
| `AdditionalData`            | Keys to merge into the pass's additional data. A `null` value removes the key.                                                                                       |
| `UpdateMetadata`            | `true` recomputes the pass metadata with the update. Slower.                                                                                                         |
| `NewIdentifiers`            | External identifiers to set, keyed by identifier name (an `id.` prefix is accepted and ignored). Every value is required.                                            |
| `Notification`              | The default notification text, for devices whose language has no entry in `NotificationLocalizations`.                                                               |
| `NotificationLocalizations` | Notification text per language code, for example `{ "fr": "Bonjour !" }`. When this and `Notification` are both empty, no notification is sent.                      |

{% hint style="info" %}
In a CSV column, a single dash `-` removes the theme. A script returns an empty string `""` instead: the dash is a convention of the CSV columns only, so a script that returns `"-"` names a theme called `-`, and the row is refused if no such theme exists.
{% endhint %}

## Validation and errors

The object returned by `Transform` goes through the same checks as a row read from the documented columns. A row whose `PassType`, `ThemeId` or `BenefitTemplateId` does not exist on the tenant, or whose `NewIdentifiers` has an empty value, is refused: nothing is changed for it, the other rows carry on, and the import log counts it under its reason.

An error thrown by `Transform` is different. It means the script cannot handle the file, so the import stops at that row and the import log shows **Import failed**. Rows queued before it are still applied. To leave a row out without stopping the file, return it with an empty `Identifiers`: it targets no pass and counts as **No match**.

When a script maps the rows, the import log does not list ignored columns: which columns the script reads is up to the script.


---

# 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/connectors/custom-connector/custom-connector-scripting-reference/bulk-pass-update-row-transformation.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.
