Skip to main content
Migrate Already selling? Move your customers to Keylight without re-issuing a single key.
Keylight
Blog
Migration Licensing

How to Import an Existing Customer Base into Keylight

6 min read Nicolas Demanez — Founder

You already have customers. Until recently, bringing them onto Keylight meant emailing us and waiting — there was no self-serve path for a developer who arrived with a list of people who’d already paid. Now there is. You hand Keylight a CSV of your existing customers and every one of them lands as a working license at once. This post walks the whole flow: what the file needs to contain, what happens at each step, when your customers’ existing keys are preserved, and what the Migrated label actually means once they’re in.

If your worry is less “how do I do this” and more “will this break anyone,” read the companion piece first — Migrate License Keys Without Breaking Existing Customers — then come back here for the mechanics.

What you need before you import

The import takes one CSV file with up to five columns. Two are required; the other three are optional and only matter when you have the data to fill them.

  • email (required) — the customer’s email. This is how a license is addressed and how a customer later finds it in the portal.
  • key_type (required) — which of your Keylight key types this license belongs to: your pro-lifetime, pro-annual, whatever you’ve defined. It tells Keylight what entitlements and limits the license carries.
  • license_key (optional) — the exact key string the customer already has. Include it to preserve their key; leave it blank to have Keylight generate one. More on this below.
  • name (optional) — the customer’s name, for your own records and the portal.
  • expires_at (optional) — an expiry date for time-limited licenses, written as a plain ISO date. Leave it blank for keys that don’t expire.

A file looks like this:

email,key_type,license_key,name,expires_at
[email protected],pro-lifetime,KL-9F2A-7C31-DE08,Ada Lovelace,
[email protected],pro-annual,,Grace Hopper,2027-01-15
[email protected],pro-lifetime,,,

Three rows, three shapes. Ada keeps her existing key and never expires. Grace gets a freshly generated annual key that lapses in January 2027. Linus has nothing but an email, so Keylight generates his key and he never expires. All three are valid the instant the import commits.

One file holds up to 5,000 rows. If your base is larger than that, split it into a handful of files and run them in sequence — each import is independent, and duplicates across files are handled for you (see below).

The import flow, step by step

Everything happens in the dashboard, under Licenses → Import.

  1. Upload the CSV. Keylight reads the header row, checks that email and key_type are present, and parses the rows.
  2. Review the preview. Before anything is written, you see exactly what will be created — counts, the key types involved, and any rows that will be skipped. Nothing is committed at this stage. If a column is mislabeled or a key_type doesn’t exist yet, you find out here, not after the fact.
  3. Confirm. When the preview looks right, you commit. Keylight writes the licenses in chunks, so a large file imports steadily rather than as one all-or-nothing transaction.
  4. Read the report. When it finishes, you get a summary of what was created and what was skipped, with reasons.

Two defaults are worth calling out because they’re the ones people assume go the other way:

Duplicates are skipped, not overwritten. If a row matches a license that already exists, Keylight leaves the existing record alone and reports the skip. You can re-run an import — or run overlapping files — without clobbering anything or double-issuing keys. The import is safe to repeat.

Emailing customers is off by default. A plain import is silent: it creates records without sending a single message. That’s almost always what you want when you’re seeding a backlog — you don’t want 4,000 people getting a surprise email the moment you click confirm. When you do want delivery, you turn the option on deliberately. The control is a setting on the import, not a step you can trip over.

Preserve your existing keys, or let Keylight generate them

The license_key column is the hinge of the whole import, so it’s worth being precise about.

Fill it in, and the customer’s existing key is preserved. The string you put in the CSV becomes their Keylight license key, unchanged. This is the difference between a migration your customers barely notice and one that lands a new key in everyone’s inbox. The key they already have — pasted into your app, saved in their password manager, written on a receipt — keeps working, with nothing to re-deliver. Preserving the key is also what makes a silent hand-off possible: your new build can read the key from your old storage and activate it for the customer, so they never see a prompt at all. (The how — and when the customer just enters it once instead — is covered in Migrate License Keys Without Breaking Existing Customers.)

Leave it blank, and Keylight generates a fresh key. That’s the right move when you genuinely don’t have the original strings — for example, if your old system only stored a hash of each key, or you’re coming from a vendor that never exposed the raw key to you. You import by email, Keylight mints a new key per customer, and you deliver it however you like (including by flipping that email option on).

The honest constraint: Keylight can only keep a key it’s handed. If you don’t have the plaintext key string to put in the CSV, there’s nothing to preserve, and a generated key is the outcome. So before you export from your old system, check whether you still have the actual keys — it decides which of these two paths you’re on.

What “Migrated” means on an imported license

Every license that arrives through import is tagged Migrated. It’s easy to read that as a lesser status — a probationary, half-active, “not a real license yet” state. It isn’t.

An imported license is a normal active record. It validates the same way a license you minted by hand does; your app can’t tell the difference, and neither can the customer. Migrated is a provenance flag — it records where the license came from, not what it’s allowed to do. In the dashboard it shows as a neutral gray pill, so you can glance at your list and see your migration backlog at a time, but it places no restriction on the customer and nothing expires it.

It’s also there to set up the next move, if you have one. With your old customers visible inside Keylight, you can attach an upgrade and offer them your new version from the portal — an upgrade swaps the key type in place and keeps the same key string, so a customer’s old key simply becomes the new one. But that’s optional and separate. The import itself doesn’t remint anyone or change a single key out from under them; we deliberately don’t force an auto-remint, because that would push a new key to every customer and contradict the entire point of bringing them in “as they are.”

Where to go next

The import lives behind Licenses → Import in the dashboard, and the full reference — column formats, limits, and edge cases — is in the docs: Bulk import. If you’re weighing import against letting customers claim their own keys, or you’ve got a messy base with missing key strings, the Migration overview lays out every path and the migration hub is the short version.

If you’re not sure which path fits your app, send us your feedback and we’ll help you plan it — we read everything. Keylight starts at $19/month with a free tier, so you can import your base and try it alongside what you run today. Full details on Pricing.

Frequently asked

Do imported customers have to repurchase?+

No. An imported license is a live, active record the moment it lands. If you include the customer's existing key string in the CSV, that exact key keeps working — there is nothing for them to buy again. The first time your Keylight build runs, that key is activated once (your app reads it from your old storage, or the customer enters it once); after that it validates offline like any other license.

What if I don't have the original license-key strings?+

Import by email and leave the license_key column blank. Keylight generates a fresh key for each customer. You only need the original key string when you want to preserve it; otherwise email is enough.

Will importing email all my customers?+

Only if you ask it to. The 'email customer' option is off by default, so a normal import is silent — records are created without sending anything. Turn it on deliberately when you actually want delivery.

Ready to ship?

Create your account and start licensing your apps in under a minute. Free forever tier included.

Start Free