A deal lands in your inbox at a price your pricing page doesn’t have. A design partner wants to try your API for a quarter before committing. Your team is running a closed beta for exactly seven companies.
Your pricing page has three plans. This deal needs a fourth, visible only to the co-founder who signed it. The temptation is to wire something together: Stripe coupons, an off-platform invoice, a hidden plan with an obscure URL. Every one of those paths costs you metering visibility, audit trail, or the ability to scale.
Private plans in Zuplo are built for exactly this shape of problem: a plan that exists, bills, and meters like any other, but is invisible to everyone except the emails you invite.
- Fielding one-off enterprise deals that don't fit your public pricing
- Running a design partner program with bespoke terms per partner
- Gating a closed beta to an invite list of a few specific companies
- Taking board-brokered introductions that arrive with a pre-negotiated price
Three scenarios that break your pricing page
Custom pricing requests arrive in three flavors, all landing at the same engineering problem.
- Enterprise deals. A signed contract at a negotiated rate, usually per-request pricing with a flat commit. Nothing on your public pricing table reflects it.
- Design partners. Early customers at a discount or free for a fixed window. You need them on the same metering infrastructure as paying customers so you get real usage data, but their billing sheet is different.
- Closed beta access. A new API surface you’re not ready to charge for, available only to a handpicked list. Same gateway, same meters, same developer portal, different visibility.
From the engineer’s seat, all three are identical: a plan that exists, bills correctly, and meters usage, but is invisible to everyone except a short list of emails. Teams that get this right have a portfolio of plans behind the scenes and a clean public pricing page. A few are written up in 5 API Monetization Success Stories.
Where the usual workarounds fall apart
These options seem reasonable on the first deal and fall apart by the third.
- Stripe coupons on a public plan. Gets you a discount, not a custom entitlement. Your enterprise customer still sees the public plan’s limits, and you have no clean way to offer a different feature set without cluttering the public tier.
- Off-platform manual invoicing. You skip Stripe and track usage in a spreadsheet. You lose every piece of metering visibility the gateway gives you: no usage dashboards, no overage alerts, no audit trail when the customer disputes a bill.
- Forked public plans. Clone Pro, rename it “Pro Enterprise”, tweak the price. By the fifth deal your pricing table is a mess and your developer portal shows four “Pro” variants to every signed-in user.
Each scales to approximately zero. Zuplo’s answer is the private plan.
Private plans in Zuplo
A private plan lives in your monetization configuration, bills through Stripe, and meters usage through the same gateway pipeline. The one difference: it’s invisible to anyone except users you explicitly invite by email.
You can set these up two ways. In the Zuplo portal UI, which is the fastest path if invites are the whole story and you just want the plan shipped. Or through the monetization API, which is the right choice when you’re building Zuplo more deeply into your own systems (an internal admin tool, CI/CD, infrastructure-as-code). Same primitive, same capability, different surface.
New to Zuplo Monetization?
Private plans sit on top of meters, features, and at least one public plan. If you haven't set those up yet, walk through the monetization quickstart first, then come back here.
In the Zuplo portal
In your Zuplo project, head to Services → Monetization → Pricing and click Add Plan. Fill in the plan name and key, then flip the Private Plan toggle on.

Click Create Draft. From here, configure the plan exactly like you would a public one: pick the pricing (flat fee, usage-based tiers, or a combination), attach the features and entitlements for included units, and wire up the meter that feeds usage into the plan. Then publish.
Once published, the plan lands in the Plans list with a Private badge next to its name and an Invites action next to the status.

Click Invites to add customer emails one at a time. Each invite sends the customer a subscribe URL. Only invited users can use it.
With the monetization API
If you’d rather drive plan creation from code (to template it against signed contract terms, or to sit alongside the rest of your provisioning pipeline), the same flow is three API calls.
Before you start, grab two values from your Zuplo project: the ZUPLO_BUCKET_ID
(your monetization bucket, available in the project’s Monetization settings) and
a ZUPLO_API_KEY (created in project settings, treat it like any other
server-side secret).
1. Create the plan with the private-plan flag. A plan becomes private when
you set "zuplo_private_plan": "true" in its metadata field. Everything else
works identically to a public plan: rate cards, features and entitlements,
prorating, and Stripe Checkout. billingCadence uses ISO 8601 durations, so
P1M means monthly.
Below is a realistic enterprise deal: a $10,000 monthly commit including 1
million requests, with $0.002 per request overage. featureKey values like
monthly_fee and api reference features already defined in your monetization
bucket, so adjust to match your keys.
Save the id from the response. You need it for the next two calls.
2. Publish the draft. Plans are created as drafts. A draft plan can’t be subscribed to, so until you publish it, even an invited user sees nothing on the pricing page.
Once published, a plan can’t be modified. If terms change later, create a new plan, publish it, and invite the customer. In practice the customer schedules cancelation of the old subscription at period end and subscribes to the new one. Gateway traffic doesn’t interrupt; the cutover lands on the billing boundary.
3. Invite the user by email. The user doesn’t need to exist in your Zuplo tenant yet. The invite is by email and activates the first time they sign in with that address.
That’s the whole flow. No quoting system (CPQ) to build, no coupon juggling, no off-platform invoice.
Common mistake:
Creating the invite before publishing the plan. The invite is valid, but the user sees nothing until the plan moves out of draft state. Publish first, invite second.
What each side actually sees
Uninvited users see your Free, Pro, and other published tiers. The Acme Enterprise plan doesn’t appear on the public pricing table, doesn’t surface in the API responses that back it, and isn’t visible to anyone who signs in without a matching invite.
Invited users: when cto@acme.com signs in to the developer portal, the Acme
Enterprise tier appears alongside the public plans. They subscribe through the
same Stripe Checkout flow, get an API key provisioned automatically, and usage
flows through the same meters. If you’ve already built a developer portal for
your public plans, nothing changes to support private ones. The full portal
setup is covered in
Building a Monetized API, Part 4.
Invites are managed through the same metering API, so fixing a typo or revoking access is another API call, not a support ticket.
A single email can be invited to multiple private plans (useful when an enterprise customer also gets beta access). Multiple emails can be invited to one plan, which is how you handle a customer with a team.
Stacking private and public plans
Private plans sit alongside public plans. A customer can hold multiple active subscriptions, and that matters for real enterprise deals.
A common pattern is an enterprise customer on a negotiated base plan (private, fixed commit plus overage) plus an add-on credit pack from your public pricing page (pay-as-you-go top-up). Two subscriptions, two sets of entitlements, one customer.
Each subscription gets its own API key by default, so traffic routes to the right bucket without the customer thinking about it. Usage is tracked independently, and invoices reflect the two separately.
For your side, this is a lever. You don’t need to invent a “private plan with bundled credit pack” frankenstein when a customer upgrades. Sell them the existing public credit pack as a second subscription and keep the private base plan clean. The full subscription state machine is in the subscription lifecycle doc.
Private plans, end to end
The full flow, in order:
- Create the plan with the Private Plan toggle on (portal UI) or
metadata.zuplo_private_plan: "true"(API), with your rate card. - Publish the plan to move it out of draft.
- Add invites for each customer email.
- Confirm that signing in with an invited email shows the private tier.
- Record the plan key and plan ID somewhere retrievable.
Custom enterprise pricing is one of the first places a growing API business starts needing shape it didn’t need on day one. Private plans are the primitive that covers it: same gateway, same meters, same Stripe billing path as your public tiers, with one piece of metadata that controls who sees them. The three scenarios this post opened with (enterprise deals, design partners, closed betas) all collapse to the same recipe above, so the next one, and the one after, don’t need a new system.
Private Plans Reference
Full API reference for creating private plans, managing invites, and subscribing invited users in Zuplo Monetization.
