Skip to content

Bring your existing customers

Customers who bought before you used Sealcord keep what they paid for: you issue each of them a Sealcord licence for the order they already have, send them the new key, and ship an app version that accepts it. Sealcord cannot read keys made by another system, so their old keys are not imported; each customer gets a new key signed with your product’s key.

  • Your plan. Each licence you issue counts as an active licence from the moment it is issued. Count the customers you will move and check your plan has room, or upgrade first in the Console (plans). A licence that does not fit answers 402 plan_limit_reached and nothing is written.
  • An admin API key with licences:read and licences:write, kept on the machine that runs the move (the key your backend uses).
  • A list of orders from your old system: an order id, the buyer’s email address, the number of seats or machines, and an end date for anything sold for a term.

Run the move as a script that you can stop and start again. For each order:

  1. Store a licence id with the order (a new random UUID), so a second run sends the same id and issues nothing twice.

  2. Send an external reference that names the old order, such as import:order:1234: 1 to 200 printable ASCII characters, never an email or a name. It lets you find the licence by its old order later.

  3. Issue the licence with the customer’s email, the limit they bought, and expires_at for a term that has an end:

    Terminal window
    curl https://api.sealcord.com/v1/admin/licences \
    -H "authorization: Bearer $SEALCORD_TOKEN" \
    -H 'content-type: application/json' \
    -d '{
    "id": "2f9a6c3e-8b14-4d7a-b0e5-3c6d9e1f4a72",
    "product_id": "acme-notes",
    "email": "ada@example.com",
    "limit_kind": "seats",
    "limit_count": 2,
    "external_ref": "import:order:1234"
    }'

    201 Created answers the key. A repeat answers 409 conflict; read the licence by its id to get the key the first run issued, as the order handler does.

  4. Pace the calls. Admin routes allow 300 requests a minute per API key; on 429 rate_limited, wait the seconds in Retry-After-admin and send the same request again.

Skip orders that were refunded or have ended: there is nothing to move. Every licence you issue is in its audit log, so you can see what the move did.

Sealcord does not email keys to your customers: you do, from the address they know you by. Tell them why the key changed, that they paid nothing more, and where to enter it. Keep the email short and put the key on a line of its own, so it is copied whole.

For a while, your app needs to accept the old keys and Sealcord keys:

  1. Ship a version that checks a key the new way first (offline, then activation), and the old way only for keys that do not start with your product’s prefix.
  2. When most customers have the new key, show the others a message that asks them to enter it.
  3. Retire the old check in a later version.

New sales issue Sealcord licences from the start, from your backend or a payment integration.

No. A Sealcord key is signed with your product’s Ed25519 key and carries its own fields, so a key another system made cannot pass Sealcord’s checks. The customer keeps their purchase; only the key changes.

Will the new licences use my customers’ seats?

Section titled “Will the new licences use my customers’ seats?”

Not until their app activates. A licence takes a seat on a machine only when the app calls POST /v1/activations with its key.

What about subscriptions that are still running?

Section titled “What about subscriptions that are still running?”

Issue the licence without an end date, and expire it when the subscription ends, from the backend that hears about the cancellation (on a cancellation). New subscriptions sold through a payment integration are handled for you.