Part 4: Dynamic Provisioning
This tutorial will walk you through provisioning plans dynamically in a workflow using JWT tokens.
You'll learn how to evaluate JWT claims at decision time to assign higher-tier plans without requiring manual mapping of payment products in the system. By the end, you'll have a workflow that conditionally provisions a Premium plan whenever a user's token indicates premium access.
Prerequisites
Before you begin, ensure you have the following:
- Every step from Part 3 completed
- Access to a tool to generate JWT tokens (e.g. token.dev or similar)
Important: In a production application, JWT tokens should be securely generated and signed on your backend server. The use of client-side tools is only for demonstration purposes in this tutorial.
Add a Premium Plan
We will first create a new Premium Plan that we will provision dynamically, which includes the "Widget" Feature with the "Enabled" property set to unlimited access.
- Navigate to the Plans page in the MonetizationOS console
- Click "Add Plan"
- Give it a name, e.g. "Premium"
- Click "Create"
You'll notice that we're leaving automatic plan assignments off for this Plan, as we will be assigning it dynamically in a workflow.
Now let's configure the Premium Plan to include the "Widget" Feature, with "Enabled" and "Premium" set to On (true).
- Navigate to the Configure Features tab
- Click "Configure Features"
- Select the "Widget" Feature
- Toggle the "Enabled" property to On (
true) - Toggle the "Premium" property to On (
true) - Click "Update Plan"
Add a JWT Integration
Next, we will add a JWT Integration to our MonetizationOS organization to allow us to use JWT tokens for user identification.
- Navigate to the Integrations page in the MonetizationOS console
- Click "Add an Authentication Method"
- Give it a name, e.g. "Test JWT"
- Copy a Public Key (RS256) from your JWT generation tool (e.g. token.dev) and paste it into the "JWT Public Key" field
- Enter a JWT Claim Key of
email - Click "Save JWT and Continue"
Make a JWT Surface decision
To make a JWT Surface decision update the previous cURL command, replacing userIdentifier with userJwt.
You will need to generate a JWT token for the request. Here is an example token payload you can use in your JWT generation tool:
{
"sub": "1234567890",
"name": "John Doe",
"email": "test@example.com",
"premium": true,
"iat": 1760714314
}Make sure to replace $JWT_TOKEN in the cURL command with your generated JWT token:
curl -X POST https://api.monetizationos.com/api/v1/surface-decisions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"surfaceSlug": "$SURFACE_SLUG",
"identity": {
"userJwt": "$JWT_TOKEN"
}
}'You should receive a response with changes similar to the following:
{
...
"identity": {
"authType": "provided",
"authType": "jwt",
"identifier": "test@example.com",
"isAuthenticated": true,
"jwtClaims": {}
"jwtClaims": {
"sub": "1234567890",
"name": "John Doe",
"email": "test@example.com",
"premium": true,
"iat": 1760714314
}
},
...
}We're now successfully identifying the same user as Part 3 (e.g. "test@example.com") via JWT token.
Add a Dynamic Provisioning workflow
We will now add a Provisioning workflow to dynamically assign the Premium Plan based on the premium claim in a JWT token.
How to add a Dynamic Provisioning Workflow:
- Go to the Plans page in the MonetizationOS console
- Click on the Provisioning Workflows tab
- Click on the "Add Provisioning Workflow" button
- Give it a name, e.g. "Premium Provisioning"
- Click "Create Workflow"
Replace the default code with the following, and click "Update Workflow" to save your changes:
const workflow: ProvisioningWorkflow = async ({ identity }) => {
// Assign premium if provided in JWT claims
return identity.jwtClaims.premium ? ["premium"] : [];
};
export default workflow;Make a JWT Surface decision again
Rerun the JWT Surface decision request again to confirm your provisioning workflow is working as expected.
You should receive a response with changes similar to the following:
{
...
"enabled": {
"counterId": "default:feat_abcd1234.enabled",
"type": "meterable",
"hasAccess": false,
"consumedUnits": 3,
"remainingUnits": 0,
"totalUnits": 3,
"uniqueResources": false,
"resourceIdUsed": false,
"periodStart": "Thu, 01 Jan 1970 00:00:00 GMT",
"hasAccess": true,
"isFallback": false
}
...
"surfaceBehavior": {
"properties": {
"userMessage": "Hello, test+9@example.com",
"isAuthenticated": true,
"widgetAccess": false,
"premiumWidgets": false,
"remainingWidgets": 0,
"widgetAccess": true,
"premiumWidgets": true
}
},
...
}As you can see, your user now has access to the Premium Plan features based on the premium claim in the JWT token.
You have now completed the Hello, World! tutorial. You can now successfully compose a dummy end-to-end flow from anonymous to authenticated to paying user using Surfaces, Features, and Plans.
This is just the start of what you can achieve with MonetizationOS. Explore our Concepts and Admin Guides to learn more about the platform's capabilities and how to implement them in your applications.