Checkout, delivery and dispute handling on Stripe Connect Direct charges · seller is merchant of record

License keys

Your buyer gets a key. Your software asks us whether it is good.

The three calls

All three take the same body and return the same shape. They are POST, JSON in and JSON out, and need no authentication — the key is the credential.

/api/licenses/v1/activate Claims a machine. Call it once, when the buyer enters the key.
/api/licenses/v1/validate Checks it still stands. Call it on launch. Never claims a machine.
/api/licenses/v1/deactivate Gives the machine back, so the buyer can move to another.

Request

{
  "key": "H4KM-9QP2-7T1B-XR3D",
  "instanceId": "b8f3…",
  "instanceName": "Nate's MacBook"
}
key
Whatever the buyer pasted. Case and dashes are ignored, so you do not need to clean it up first.
instanceId
Your identifier for this installation. It has to be the same every launch, or each start takes another machine.
instanceName
Optional. Shown to the buyer in the list of their own machines, so make it something they would recognise.

Response

{
  "valid": true,
  "reason": "ok",
  "message": "This key is active on this machine.",
  "productId": "…",
  "productName": "Acme Synth",
  "activationsUsed": 2,
  "activationLimit": 3,
  "expiresAt": null
}

Always HTTP 200 unless the request itself was malformed. A key that is not valid is an answer, not an error — branch on valid, not on the status code. The one status worth handling separately is 429, which means you are calling far more often than any real application needs to.

reason is a stable string, meant for branching:

okGood. Carry on.
not_foundNo such key. Also what a nonsense key returns.
revokedRefunded, disputed, or withdrawn by you.
expiredThe subscription behind it ended.
limit_reachedEvery machine is taken. Tell them to free one.
not_activatedValid key, but not on this machine yet. Call activate.

Two things worth knowing

The machine limit is only as strong as your instance id. We cannot fingerprint a computer from an HTTP request — we count the distinct ids you send us. If you send a fresh random value on every launch, the limit does nothing, and if you send the same constant for every install, one key covers the world. Derive it from something stable about the machine and store it beside your settings.

Decide what happens when we are unreachable. Networks fail and laptops go on planes. Refusing to start because a check timed out punishes the paying customer for our downtime. Cache the last good answer with a timestamp and keep running for a grace period you are comfortable with — a week is common — then ask again.

Versioning

The v1 in the path is a promise. Fields may be added to the response; nothing will be removed or change meaning. If we ever need a shape that breaks that, it becomes v2 and v1 keeps answering — your buyer's copy of version 1.4 will still work long after you have stopped shipping it.