# Migrate existing customers

> Bring the customers you already have onto Toolaby, from Stripe or from a file.

Whatever you sold with before, Toolaby needs one fact per person: an email address and what they hold. A tool's **Import** page takes that from two sources: the Stripe account under **Configure → Payments**, and a file. Nothing is charged and nothing is emailed by an import; a person appears under Customers and the extension unlocks for them at its next check. Subscriptions on another Stripe account are moved, with their cards, from the same page: see [Move subscriptions from another Stripe account](https://toolaby.app/docs/move-subscriptions.md).

## Before you begin

* The tool registered, with its plans under Pricing. Imported licences and subscriptions are recorded against a plan.
* For a Stripe import: sales made on the Stripe account under **Configure → Payments**, the one Toolaby made for the workspace. Subscriptions on another Stripe account are moved: see [Move subscriptions from another Stripe account](https://toolaby.app/docs/move-subscriptions.md). One-time sales there come in from a file.

## From Stripe

For sales made outside Toolaby's checkout on the workspace's Stripe account, the one under **Configure → Payments**: one-time payments through payment links or Checkout, and subscriptions. A one-time payment made without Checkout, such as an invoice, comes in [from a file](#from-a-file). Toolaby makes that account when you connect Stripe, and **Connect** does not attach an account you already have. So sales on a Stripe account you used before Toolaby are not read here: move its subscriptions with [Move subscriptions from another Stripe account](https://toolaby.app/docs/move-subscriptions.md), and import its one-time sales [from a file](#from-a-file).

On the Hobby plan a sale made after the tool joined Toolaby, the day it was created, is refused: it was made outside Toolaby, without its fee. On Pro it is imported as a pass. See [Plans](https://toolaby.app/docs/plans.md).

1. On the tool's **Import** page, select **Read the account**. Toolaby reads every paid one-time Checkout Session, and every subscription that is active, trialing or past due, that is not its own. A sale refunded in full or disputed before the import is left out. Nothing is written by reading.
2. The sales appear grouped by what was sold: product, amount, interval. For each group, choose the plan it becomes, or leave it on **Skip**.
3. Select **Import** on a group.

What is written:

| Sale               | Becomes                                                                           | And                                                                                                                       |
| ------------------ | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| A one-time payment | A lifetime licence for the buyer's email, on the plan chosen, dated from the sale | Carries the Stripe payment id, so a refund or dispute made in Stripe after the import reaches the licence                 |
| A subscription     | The subscription on the buyer's account, on the plan chosen                       | Tagged on Stripe as Toolaby's, so every later event about it — a renewal, a cancellation, a plan switch — reaches Toolaby |

A licence attaches to an account when the person signs in with that address; until then it is the address's, as a purchase made signed out is. A subscription needs an account, which the import creates. A sale with no email cannot be imported and is listed as such.

Reading the account again, or importing a group twice, changes nothing: each sale is recorded once. Each sale written is one of the workspace's 20,000 additions a day ([Limits](https://toolaby.app/docs/limits.md)); one already imported counts nothing.

## From a file

For everything else: sales on another Stripe account or another platform, a spreadsheet, a beta list. One CSV, one row per person:

```csv
email,kind,plan,key,since,until,note
maya@example.com,licence,default,OLD-1234-5678,2025-11-03,,from the old store
beta@example.com,grant,,,2026-01-10,2026-12-31,beta tester
```

| Column  |                      |                                                                                                                                                                    |
| ------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `email` | required             | The person's address.                                                                                                                                              |
| `kind`  | `licence` or `grant` | Default `licence`. A grant is access without a purchase, with or without an end.                                                                                   |
| `plan`  | a one-time plan's id | Licences only. Empty: the tool's `default` plan, even if it is a subscription. Name a one-time plan to be sure.                                                    |
| `key`   |                      | A key the person already has. Kept, so they can still claim by it on their account page. Empty: a new key is recorded and never sent; the person signs in instead. |
| `since` | `2026-03-14`         | When they bought, or when access began.                                                                                                                            |
| `until` | `2026-03-14`         | Grants only. Empty: until revoked. A date already past is refused: the grant would hold nothing.                                                                   |
| `note`  |                      | Shown on the customer's page.                                                                                                                                      |

Choose the file; Toolaby reads it and shows how many rows are ready and which have a problem, by line. Select **Import**. A row already imported is skipped, so a file can be sent again after fixing a line.

Every row is a pass: on the Hobby plan, rows beyond 100 live passes are left out with the reason. See [Plans](https://toolaby.app/docs/plans.md).

A file holds at most 10,000 rows, saved as CSV (UTF-8); a file with NUL characters, as a UTF-16 file has, is refused. Each row written is one of the workspace's 20,000 additions a day, shared with grants and customers added from the dashboard, the API and the command line. A row already imported counts nothing. Rows past the day's additions are left out with the reason: send the file again the next day. See [Limits](https://toolaby.app/docs/limits.md).

Subscriptions cannot be imported from a file: a file holds no card. Subscriptions on another Stripe account are moved with their cards: see [Move subscriptions from another Stripe account](https://toolaby.app/docs/move-subscriptions.md).

## Cases

| You have                                                    | Do                                                                                                                                                                                                                                                                                                                                             |
| ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Payment links or Checkout on the workspace's Stripe account | From Stripe, one-time payments → a lifetime plan.                                                                                                                                                                                                                                                                                              |
| Subscriptions on the workspace's Stripe account             | From Stripe, subscriptions → a subscription plan. Billing continues on Stripe as before.                                                                                                                                                                                                                                                       |
| One-time sales on another Stripe account                    | From a file: export the payments from that account as a CSV, one row per buyer's address. Rename the address column to `email`; other columns are ignored. Leave out failed and refunded payments.                                                                                                                                             |
| Licence keys from another platform                          | From a file, with the `key` column. Buyers keep their keys; they can also sign in.                                                                                                                                                                                                                                                             |
| A list of buyers with no keys                               | From a file, without `key`. Buyers sign in with their address.                                                                                                                                                                                                                                                                                 |
| Subscriptions on another Stripe account                     | Move them, with their cards: Stripe copies the customers, Toolaby makes each subscription again on your account. See [Move subscriptions from another Stripe account](https://toolaby.app/docs/move-subscriptions.md).                                                                                                                                               |
| Subscriptions on another platform                           | Two ways. Import them as grants with `until` set to each period's end, and email buyers to subscribe on your checkout page before then. Or keep billing there and manage access from its webhooks with the [API](https://toolaby.app/docs/reference/api.md): a grant when a subscription starts, revoked when it ends. Grants are passes: 100 live at once on Hobby. |
| Free users you want to keep free                            | Set **Pricing → Access** to *Everything free*, with **Require an account** on if you want them signed in; nothing to import. To keep only the existing ones free once you charge, import them as grants.                                                                                                                                       |
| Buyers you know only by name                                | Nothing to import: Toolaby identifies a buyer by email.                                                                                                                                                                                                                                                                                        |
| An extension on ExtensionPay                                | `wire --from-extensionpay` switches its code and copies its plans; its subscriptions move from your Stripe account, and its one-time buyers come in from a file. See [Move from ExtensionPay](https://toolaby.app/docs/extensionpay.md).                                                                                                                             |

## After importing

* Imported people are under Customers, with the note and date you gave.
* The extension unlocks for a person once they sign in with the imported address, or at once on a device that already holds an imported key.
* Refunds, cancellations and plan switches for Stripe-imported sales reach Toolaby through Stripe's webhooks as for any other sale.
