advanced_reports to a product, and every paying customer gets a grant that your application checks through the API or keeps in sync with webhooks. There’s no external platform, OAuth step, or delivery step: the grant itself is the capability.What Gets Delivered
Nothing leaves Dodo Payments. The grant is the deliverable:- On purchase, Dodo Payments creates the grant directly in
Delivered. It never entersPending, needs no customer action, and has no delivery step that can fail. - The grant carries a typed
featurepayload:{ "feature_type": "boolean", "feature_id": "advanced_reports" }. Your application readsfeature_idto decide what to unlock. - Cancellation, refund, or a manual revoke moves the grant to
Revoked, and the flag disappears from the customer’s delivered grants.
feature_id is an identifier you choose, and it isn’t unique across entitlements. Two entitlements can confer the same feature_id, for example a monthly and a yearly Pro plan that both grant advanced_reports.Create a Feature Flag
Open Entitlements
Name the Flag
api_access), and you can edit it. It can’t contain spaces.
Creating a feature flag. The Feature ID is what your application checks; Meta Data attaches limits alongside the flag.
Add Metadata (Optional)
Confirm

The created feature flag. The right pane tracks every customer grant issued from it.
Attach to a Product
Open a product, or create one, and find the Entitlements card. Click + to attach existing entitlements, select your feature flag, and click Done.
Attaching the feature flag to a product. One product can deliver multiple entitlements.

The product now includes the feature flag. Every successful purchase or active subscription grants it.
Required Configuration
Create via API
Attach Limits with Metadata
A boolean flag answers “Does this customer have the feature?”. Metadata answers “With what configuration?”. Entitlement metadata accepts string, integer, number, and boolean values. Every grant takes a frozen snapshot of the entitlement’s metadata when the grant is created. The snapshot is what makes metadata safe to use for plan limits:- Editing the entitlement’s metadata later affects only future grants. Customers keep the limits they purchased under.
- Each grant returns its snapshot in its
metadatafield, so one API call gives you both the flag and its configuration.
advanced_reports flag with { "tier": "pro", "monthly_report_limit": 100 } lets your application unlock the dashboard and enforce the 100-report quota without a second lookup. If you later raise the limit to 250, existing customers stay at 100 until they receive a new grant, for example after a plan change.
Check a Customer’s Features
To build the set of features a customer has, list their delivered feature flag grants. The endpoint returns one row per grant across all entitlements, and you can filter it byintegration_type and status. These examples use the client from Create via API.
feature payload is populated only on feature_flag grants. It’s null for every other integration type. See the List Customer Grants API reference for the full response shape.Lifecycle
Feature flag grants follow the standard grant lifecycle with one simplification: there’s no delivery step, so grants never sit inPending and never move to Failed.
Webhooks
To mirror flags into your own database instead of polling, subscribe to theentitlement_grant.* events:
entitlement_grant.createdarrives alreadyDelivered, with thefeaturepayload. Enable the feature.entitlement_grant.deliveredfires when a previously revoked grant is restored. Enable the feature again.entitlement_grant.revokedmeans access was withdrawn. Disable the feature, and checkrevocation_reasonto choose your messaging.
entitlement_grant.failed, because delivery happens entirely inside Dodo Payments.
Example: Pro Plan Unlocks Advanced Reports
- Create the flag. Set
feature_id: advanced_reportswith metadata{ "tier": "pro", "monthly_report_limit": 100 }. - Attach it to your Pro Plan subscription product.
- A customer subscribes. Dodo Payments creates a
Deliveredgrant and firesentitlement_grant.created. Your webhook handler enablesadvanced_reportsfor the customer with a limit of 100. - Your app gates the feature. On dashboard load, check the cached feature set (or call
listEntitlementGrants) and render the reports tab only whenadvanced_reportsis present. - The customer cancels. Dodo Payments revokes the grant and fires
entitlement_grant.revoked, and your handler disables the feature. If a subscription later recovers through dunning,entitlement_grant.deliveredrestores the feature with no code changes.
Best Practices
- Use stable feature IDs in
snake_case. Your application code checks these strings, so renaming one is a breaking change on both sides. - Use one flag per capability. Prefer
advanced_reportsandapi_accessas two entitlements over a singlepro_bundle, so revocation and plan combinations stay clean. - Drive state from webhooks, and verify with the API. Webhooks keep your database current. The list endpoint is the source of truth for reconciliation jobs and cache misses.
- Treat
Revokedas immediate. A revoked flag means the customer no longer pays for the feature. Gate on the next request, not the next session. - Put limits in metadata, not in code. Changing a quota then requires only an edit to the entitlement. New customers get the new value, and existing grants keep their purchased snapshot.