License keys are the License Key entitlement type. Create a License Key entitlement once with the activation limit, expiry, and activation message you want, then attach it to any product. By default, Dodo Payments generates and emails one key for each unit purchased or each subscription seat.
What Are License Keys?
A license key is a unique token that authorizes access to your product. Use license keys for:- Software licensing: desktop apps, plugins, and CLIs.
- Per-seat controls: limit activations per user or device.
- Digital goods: gate downloads, updates, or premium features.
Create a License Key Entitlement
1
Open Entitlements
Go to Entitlements in the dashboard and click + to create an entitlement.
2
Choose License Key
Select License Keys, enter a Name, and configure how each issued key behaves:
- Fulfillment Mode: Automatic (the default) generates and emails each key. Manual lets you supply each key yourself. See Manual Fulfillment.
- Activations Limit: the maximum number of active activations per key, for example
1for a single user or5for a team license. Select Unlimited for no limit. - License Length: how long a key stays valid after it’s issued, for example 30 days or 1 year, or No expiration. For subscription products, choose No expiration: keys issued for a subscription have no expiry, and their validity follows the subscription status.
- Activation Message: optional customer-facing instructions, up to 2,500 characters, included in the email that delivers the key. For example:
Paste the key in Settings → LicenseorRun: mycli activate <key>.

3
Save the Entitlement
Click Create Entitlement. You can now attach the entitlement to any product.
Attach to Products
Open a product, go to its Entitlements section, and select your License Key entitlement. One product can deliver a license key together with other entitlements on the same purchase, such as Discord access, file downloads, or GitHub repository access.
Selecting the License Key entitlement in the product entitlements panel.
How Keys Are Issued
Key issuance follows the standard grant lifecycle. Each event affects license keys as follows:Quantity Behavior
The number of keys depends on where the grant comes from. Each key gets its own grant.- Subscription products issue one key per seat (
subscriptions.quantity). - One-time products issue one key per unit of the cart line item (
product_cart.quantity). - Manual API grants issue exactly one key.
Fulfillment Mode
Every License Key entitlement has afulfillment_mode that controls who supplies the key:
auto(default, Automatic in the dashboard): Dodo Payments generates and emails the key on payment or subscription. This is the behavior in the table above, and it applies whenfulfillment_modeis omitted.manual(Manual in the dashboard): each unit purchased creates aPendinggrant with no key, and you supply each key value. See Manual Fulfillment.
Manual Fulfillment
With manual fulfillment, you supply each license key instead of Dodo Payments generating it. The purchase creates aPending grant with no key, notifies you with a webhook, and waits for you to submit the key value. Use it when keys come from your own system, a third-party vendor, or a finite pool of pre-printed codes.
For a step-by-step build, from product creation to key delivery, see the Manual License Key Fulfillment Integration Guide.
When to Use It
Automatic fulfillment suits most software licensing. Choose manual fulfillment when Dodo Payments can’t generate the key itself:- Bring your own keys: your application, a desktop product, or your own license server generates the key.
- Third-party vendors: you resell keys that an upstream provider issues, such as a game key, an API credential, or a partner platform license.
- Finite inventory: you hand out codes from a pre-allocated pool and assign them one at a time.
- Human review: you want to check a purchase before you release access.
Enable Manual Fulfillment
To enable manual fulfillment through the API, setfulfillment_mode: "manual" in the License Key entitlement’s integration_config. In the dashboard, set Fulfillment Mode to Manual.
fulfillment_mode is backward compatible. Entitlements created before this setting existed have no fulfillment_mode and behave as auto. Switching to manual affects only grants created after the change. Keys already delivered don’t change.Find Grants Awaiting Fulfillment
When a customer buys a product with a manual-mode entitlement, Dodo Payments creates the grant inPending status with no key and sends an entitlement_grant.created webhook with integration_type: "license_key" and status: "Pending". React to that webhook, or poll the List Customer Grants endpoint with the integration_type and status filters:
Deliver the Key
To deliver a key, send it to the Fulfill License Key Grant endpoint. The grant moves toDelivered, and Dodo Payments emails the key to the customer. It’s the same email the customer receives under automatic fulfillment.
cURL
activations_limit and expires_at are optional. When you omit them, Dodo Payments uses the entitlement’s configuration. Each grant can be fulfilled once: retrying an already-fulfilled grant returns 409 instead of issuing a second key.
You don’t need to email the key yourself. Dodo Payments delivers it when the grant is fulfilled. Importing keys with
POST /license_keys works differently: it does not notify the customer.Activation, Validation, Deactivation
Your software manages a key at runtime through three endpoints. Activation records a device or installation against the key, validation checks that the key is usable, and deactivation frees an activation.Public Endpoints: The activate, deactivate, and validate license endpoints are public and don’t require an API key. Call them directly from desktop software, CLIs, or browser-based clients without exposing your API credentials. The SDK constructors still require a bearer token value, so the SDK examples pass a placeholder.
Activate a License
Activation creates an activation instance for the key and returns it with anlki_ ID. Store that ID, because you need it to deactivate the instance. The request returns 403 if the key isn’t active, 404 if the key doesn’t exist, and 422 if the key has reached its activation limit.
Validate a License
Validation returnsvalid: true when the key’s status is active and the key hasn’t expired. To also check that a specific activation instance still exists, pass its license_key_instance_id.
Deactivate an Activation Instance
Deactivation removes an activation instance and frees one activation on the key. Pass the key and the instance ID that activation returned. The request returns403 if the instance doesn’t belong to the key, and 404 if the key doesn’t exist.
Manage Keys
To see issued keys, open the License Key entitlement under Entitlements. The grants list shows one row per customer key, with the customer, the date accessed, the status, and a Revoke action. To see a key’s expiry, activation count, and activation limit, open it under Sales → License Keys. To list grants programmatically, call List Grants. On each license-key grant, thelicense_key object carries the key, status, expiry, activations used, and activations limit. The object is null on a manual-mode grant that’s still Pending.
Import Existing License Keys via API
To migrate license keys from another system, import them with the Create License Key API. Your customers keep activating, validating, and deactivating the same key strings, so you don’t need to reissue keys. The request requireskey, customer_id, and product_id. Omit activations_limit for unlimited activations, and omit expires_at for a key that never expires. Importing a key string that already exists returns 409.
How Keys Differ by Source
Thesource field records how each license key was created:
Use
source to tell migrated and manually fulfilled keys apart from keys that Dodo Payments generated, for example when you reconcile or audit keys. The field is on license key records, such as the POST /license_keys response. The license_key object on grants from List Grants doesn’t include it. The legacy GET /license_keys endpoint, which returns source and accepts a source filter, is deprecated.
License Keys in Return URL
When a customer buys a product with a License Key entitlement, Dodo Payments appends the generated key to yourreturn_url as the license_key query parameter. Your success page can show the key without an extra API call:
%2C, so read the parameter with a URL parser, which decodes it, before you split it:
subscription_id and the subscription status instead of payment_id:
API Management
Lifecycle Operations (Public Endpoints)
Lifecycle Operations (Public Endpoints)
Activation, deactivation, and validation are public and require no API key.
Activate License
Create an activation instance for a license key.
Deactivate License
Remove an activation instance to free up capacity.
Validate License
Check that a key is active and unexpired before you grant access.
License Key Management
License Key Management
Create, list, retrieve, and update individual license key records. Use these endpoints to import existing keys or read usage details.
Create License Key
Create a license key or import an existing one.
List License Keys
Browse all keys with status and usage details.
Get License Key
Retrieve a specific key and its metadata.
Update License Key
Change the expiry or activation limit, or enable or disable a key.
Entitlement Management
Entitlement Management
Manage the License Key entitlement itself: its activation limit, license length, and activation message.
Create Entitlement
Create a License Key entitlement.
Update Entitlement
Update the entitlement’s configuration.
List Grants
List the keys issued for an entitlement.
Revoke Grant
Revoke a customer’s key manually.
Webhooks
License key delivery and revocation send the fourentitlement_grant.* webhook events. For license-key grants, the payload includes a license_key object with the key, status, expiry, activations used, and activations limit.
The legacy license_key.created event still fires when a license key record is created. See the License Key webhook payload page.
Legacy License Keys
Products created with the older
license_key_enabled flag have been automatically migrated to a License Key entitlement. The migration is transparent: existing customers’ keys keep working, the public /licenses/activate, /licenses/validate, and /licenses/deactivate endpoints keep working, and the /license_keys/* API endpoints read and write the same key store.The standalone Sales → License Keys dashboard section remains available as a flat list of every key issued, for audit and search. To change activation limits, license length, or the activation message, edit the migrated License Key entitlement under Entitlements.Best Practices
- Choose clear activation limits: pick defaults such as 1 for single-user apps or 3–5 for team licenses, and document them for your customers.
- Write precise activation messages: customers copy them from the license key email, so exact paths and commands prevent support tickets.
- Validate keys against the API: for network-connected products, call
/licenses/validateinstead of relying on a locally cached activation. - Use webhooks for revocation: handle
entitlement_grant.revokedto disable in-app features when a customer cancels or receives a refund. - Test subscriptions and one-time purchases: license key behavior differs between the two, for example subscription keys don’t expire, so test both before you go live.