This is Part 2 of the “Building a Monetized API” series. In Part 1, we set up the Zuplo API gateway for our Vercel-hosted changelog API, imported endpoints, added authentication, and configured rate limiting. In this post, we’re adding the monetization layer on top of that.
23:14Building a Monetized API, Part 2
Watch the video walkthrough of adding meters, plans, Stripe integration, and self-serve subscriptions to the developer portal.
Setting Up Meters and Features
Everything starts in the Zuplo monetization service. Before you create any plans, you need to define what you’re actually charging for. That means setting up meters (the things you count) and features (the things customers get access to).
For our changelog API, we’re metering API requests and gating access to an MCP server (which we’ll add in Part 3).
Create a Meter
Go to Services > Monetization Service in your Zuplo project. Add a blank
meter and call it requests, with an event name of requests. This meter will
count every API request that gets made.
Define Features
Features map to what shows up on your pricing table. Not all features work the same way. Some are metered (counted against a usage limit), some are boolean (on or off), and some are purely for display on the pricing page. We need three:
Requests: linked to the requests meter. This is the usage-based feature
that gets counted against a limit. When a subscriber makes an API call, this
feature’s counter increments.
MCP Server: not linked to any meter. This is a boolean feature: you either have access or you don’t. Plans can grant or deny it.
Monthly Fee: not linked to any meter. This represents the flat subscription cost on paid plans. It shows the price on the pricing table but doesn’t gate anything.
Creating the Plans
With meters and features in place, you can start defining plans. We’re building three: Free, Starter, and Pro.
Free Plan
Add a new plan called free with monthly billing. This is a single-phase plan
that runs indefinitely (or until the subscriber cancels).
Add the requests feature to the phase with a free pricing model. Set the
usage limit to 20. That’s intentionally low for demonstration purposes, but it
shows how hard limits work on free plans. Once a free user hits 20 requests in a
billing period, they’re cut off.
Starter Plan ($29.99/month)
The Starter plan introduces two concepts: a flat monthly fee and graduated overage pricing.
First, add the monthly fee feature as a flat fee of $29.99, paid in advance once per month.
Then add the requests feature using a tiered pricing model with graduated mode. Set up two tiers:
- First 5,000 requests: $0 (included in the monthly fee)
- 5,001 to unlimited: $0.10 per request
Set the usage limit to 5,000 and toggle on soft limit. This is important. A soft limit means that when a subscriber hits 5,000 requests, access doesn’t stop. Instead, every request beyond 5,000 gets billed at $0.10 each. At the end of the billing cycle, Stripe charges the subscriber for $29.99 plus whatever overage they incurred.
Finally, add the MCP server feature with a free pricing model and a
boolean entitlement set to true. Starter subscribers get MCP server access
included in their monthly fee.
Pro Plan ($99.99/month)
The Pro plan follows the exact same setup steps as Starter, just with different values: $99.99/month, 50,000 included requests, and $0.01 per request overage (also with a soft limit). MCP server access is included. There’s nothing new to configure here. If you set up the Starter plan, you already know how to do this one.
Publish and Reorder
Once all three plans are created as drafts, reorder them in the pricing table so they display as Free, Starter, then Pro. Then publish them. These become the live plans available on your developer portal.
If you want to change plans later, you create new drafts and publish them when ready. They’ll replace the existing versions or sit alongside them as additional options.
Monetization Plans and Pricing
Details on phases, free trials, pricing models, and advanced plan configuration.
Connecting Stripe
Before monetization can work end to end, you need a payment provider. Go to the monetization service settings and configure your Stripe integration by pasting in your Stripe secret key. You can find this in the Stripe Dashboard under Developers > API keys.
Use your Stripe test key (sk_test_...) during development. The sandbox
environment lets you simulate the full checkout flow with fake credit card
numbers from the Stripe documentation. Swap to your production key when you go
live.
Stripe Integration
Full setup instructions for connecting Stripe to the Zuplo monetization service.
Adding the Monetization Policy to Endpoints
With plans, meters, and Stripe configured, you still need to tell your endpoints to actually meter requests. This is done with the monetization inbound policy.
The monetization policy does double duty. It handles both API key authentication and request metering in a single policy, so you don’t need a separate API key auth policy anymore. If you had one set up previously (like we did in Part 1 for testing), remove it.
The policy configuration is straightforward. The only thing you need to specify is the meter name and the increment value:
Apply this policy to all your endpoints. In the policy chain, make sure monetization comes first (before rate limiting and any other policies) since it needs to authenticate the API key and meter the request before anything else happens.
Monetization Policy
Full policy reference including metering options, caching, and advanced configuration.
Enabling Monetization on the Developer Portal
The developer portal doesn’t know about monetization by default. You need to add the monetization plugin to your Zudoku configuration.
In your project’s docs folder, open the Zudoku config file and import the
monetization plugin:
Then add it to your plugins array:
Once saved, the developer portal pulls in all the plan data, pricing tables, and subscription management UI from the monetization service automatically.
Developer Portal Setup
Full setup instructions for enabling monetization in the developer portal.
Testing the Full Flow
With everything wired up, the developer portal now shows a pricing table with all three plans. Here’s what the subscriber experience looks like:
Sign up and subscribe. A new user logs in (or signs up) on the developer portal. They see the pricing table and can select a plan. Subscribing to the free plan skips Stripe checkout entirely. Paid plans redirect to a Stripe checkout page.

Get API keys. After subscribing, the user lands on a “My Subscriptions” page with their subscription details, usage analytics, and API keys. Keys are provisioned automatically and can be rolled or deleted from this page.
Make requests. API keys work immediately. The user can test directly from the interactive API reference in the developer portal, where their key is pre-populated in the auth dropdown.
Track usage. Every request increments the meter. The subscription page shows real-time usage against the plan’s limit. On the free plan with a hard limit of 20, the 21st request gets blocked. On paid plans with soft limits, requests beyond the included amount get billed as overage.

Upgrade plans. Subscribers can switch plans from the subscription management page. Upgrading to a paid plan triggers Stripe checkout. Downgrading is available too. Plan changes take effect immediately, and the previous plan shows as expired in the subscription history.
View subscribers. Back in the Zuplo monetization service, the subscribers table shows every customer, their subscription history, and their current plan status.

What we built in Part 2
At this point, the monetization layer is fully wired up:
- Meters tracking every API request
- Three plans (Free, Starter, Pro) with hard and soft limits
- Stripe connected for checkout and billing
- Monetization policy replacing the standalone API key auth
- Developer portal with a self-serve pricing table and subscription management
- End-to-end flow tested: sign up, subscribe, get keys, make requests, track usage
Everything from Part 1 (origin auth, consumer isolation, rate limiting) still works. The monetization policy took over API key authentication, but the custom header policy that sets the gateway secret and consumer ID didn’t need to change at all.
What’s Next
In Part 3, we’ll add an MCP server to the project and write custom code to feature-gate it so that only paid subscribers can access it. After that, we’ll polish up the developer portal to make it look production-ready.
