ZuploZuplo
LoginStart for Free
  • Documentation
  • API Reference
Introduction
Getting Started
    Develop on the web portal
      1 - Setup Your Gateway2 - Rate Limiting3 - API Key Auth4 - Deploy5 - Dynamic Rate LimitingDynamic MCP Server - Quickstart
    Develop locally with the CLI
      1 - Setup Your Gateway2 - Rate Limiting3 - API Key Auth4 - Deploy5 - Dynamic Rate LimitingDynamic MCP Server - Quickstart
Concepts
Development
Policies
Handlers
API Keys
Rate Limiting
MCP Server
MCP Gateway
AI Gateway
Developer Portal
Monetization
    OverviewQuickstart
    Concepts
    Guides
    Reference
      API AccessPlan Examples
    TroubleshootingThird-Party IntegrationsCustom Monetization
GraphQL
Deploying & Source Control
Analytics
Observability
Networking & Infrastructure
Account Management
Programming API
Build with AI
Zuplo CLI
Migration Guides
Platform LimitsSecuritySupportTrust & ComplianceChangelog
powered by Zudoku
Reference

API Access

Buckets

Each Zuplo project includes three isolated buckets that mirror your environment structure:

BucketPurpose
Working CopyYour development sandbox for building and testing
PreviewStaging environments for validating changes before production
ProductionYour live environment serving real customers

Meters, features, plans, and subscriptions are all scoped to a specific bucket. This isolation enables independent development workflows where you can:

  • Experiment freely - Test new pricing models or usage tracking in development without affecting production data
  • Validate changes - Promote your product catalog configuration through preview environments before going live
  • Maintain separation - Keep development test data completely isolated from production customer usage

When you're satisfied with your configuration in one bucket, you can recreate that same configuration in another bucket to promote changes through your deployment pipeline.

Authentication

All Monetization API requests require authentication using a Zuplo API key.

All examples in this documentation assume the following environment variables are set in your terminal:

TerminalCode
# Your Bucket ID (could be working-copy, preview, or production) # (Found in Project Services > Bucket Details — https://portal.zuplo.com/+/account/project/services) export BUCKET_ID=your-bucket-id # Your Zuplo API Key (Found in Account Settings > Zuplo API Keys — # https://portal.zuplo.com/+/account/settings/api-keys) export ZAPI_KEY=zpka_YOUR_API_KEY

Include your API key in the Authorization header:

TerminalCode
curl \ https://dev.zuplo.com/v3/metering/$BUCKET_ID/meters \ --header "Authorization: Bearer $ZAPI_KEY"

Bucket monetization configuration

Each bucket has an optional MonetizationConfiguration that holds bucket-wide behavior — multi-subscription support, plan display order, plan-level overrides, and the default payment grace period. The configuration is read by the runtime and the Developer Portal; it is not stored in OpenMeter.

Read

TerminalCode
curl \ https://dev.zuplo.com/v3/metering/$BUCKET_ID/monetization-configuration \ --header "Authorization: Bearer $ZAPI_KEY"

When no configuration row exists for the bucket, the endpoint returns a default body with multipleSubscriptionsEnabled: false, an empty planOrder, empty planSettings, and maxPaymentOverdueDays: 3.

Upsert

TerminalCode
curl \ https://dev.zuplo.com/v3/metering/$BUCKET_ID/monetization-configuration \ --request PUT \ --header "Authorization: Bearer $ZAPI_KEY" \ --header "Content-Type: application/json" \ --data @- << EOF { "multipleSubscriptionsEnabled": false, "planOrder": ["free", "starter", "pro", "enterprise"], "planSettings": { "pro": { "visiblePhases": ["default"] } }, "maxPaymentOverdueDays": 7 } EOF
FieldTypeDescription
multipleSubscriptionsEnabledbooleanStored on the bucket. Reserved for future multi-subscription rules; today the Developer Portal create-subscription path enforces a single active subscription per customer regardless of this flag.
planOrderstring[]Ordered list of plan keys; drives pricing-page sort and upgrade/downgrade direction during plan changes
planSettingsobjectPer-plan overrides keyed by plan key. The supported sub-key today is visiblePhases — an array of phase keys that should appear on the pricing page
maxPaymentOverdueDaysintegerBucket-default payment grace period. Must be ≥ 0. Defaults to 3 when not set

The request body must include at least one of these fields. All four fields are optional in the request — the upsert preserves any field you don't send.

planOrder is consumed when a customer changes plans through the Developer Portal: a target plan whose index is greater than or equal to the current plan's index is treated as an upgrade (immediate timing); a lower index is treated as a downgrade (next-billing-cycle timing). Plans not listed in planOrder default to upgrade timing.

maxPaymentOverdueDays is the lowest-precedence default for the payment grace period. See Subscription and payment validation for the full precedence chain (customer metadata → plan metadata → bucket configuration → built-in default).

Delete

TerminalCode
curl \ https://dev.zuplo.com/v3/metering/$BUCKET_ID/monetization-configuration \ --request DELETE \ --header "Authorization: Bearer $ZAPI_KEY"

After deletion, GET returns the default body again.

Stripe setup and billing readiness

Most users connect Stripe through the Zuplo Portal. For automated provisioning — CI scripts, infrastructure-as-code, or self-hosted control planes — the same flow is available via these API endpoints.

Install the Stripe app

Connect a Stripe account to a bucket and create the default billing profile in one call:

TerminalCode
curl \ https://dev.zuplo.com/v3/metering/$BUCKET_ID/setup/stripe \ --request POST \ --header "Authorization: Bearer $ZAPI_KEY" \ --header "Content-Type: application/json" \ --data @- << EOF { "apiKey": "rk_test_...", "name": "Stripe Billing Profile", "taxEnabled": false, "taxEnforced": false, "country": "US" } EOF

The endpoint validates the Stripe key prefix against the bucket's environment:

  • Working-copy and preview buckets accept sk_test_* or rk_test_*
  • Production buckets accept sk_live_* or rk_live_*

The response returns the installed appId. The endpoint fails with a 409 Conflict if a Stripe app is already installed for the bucket.

Read the current Stripe setup

TerminalCode
curl \ https://dev.zuplo.com/v3/metering/$BUCKET_ID/setup/stripe \ --header "Authorization: Bearer $ZAPI_KEY"

Returns the connected Stripe app summary and the billing profiles linked to it.

Create an additional billing profile

To attach more billing profiles to the same Stripe app:

TerminalCode
curl \ https://dev.zuplo.com/v3/metering/$BUCKET_ID/setup/stripe/$STRIPE_APP_ID/billing-profile \ --request POST \ --header "Authorization: Bearer $ZAPI_KEY" \ --header "Content-Type: application/json" \ --data @- << EOF { "name": "EU Billing Profile", "taxEnabled": true, "taxEnforced": false, "country": "DE" } EOF

Check billing readiness

A lightweight check for tooling that gates deploys on Stripe being connected:

TerminalCode
curl \ https://dev.zuplo.com/v3/metering/$BUCKET_ID/billing-readiness \ --header "Authorization: Bearer $ZAPI_KEY"

Response:

Code
{ "hasStripeApp": true, "stripeAppId": "app_01H...", "hasDefaultBillingProfile": true, "defaultBillingProfileId": "bp_01H..." }

Use this in setup wizards to gate the UI on whether Stripe is connected.

Update a connected app

Rotate the Stripe key on an existing app, or update its name and metadata:

TerminalCode
curl \ https://dev.zuplo.com/v3/metering/$BUCKET_ID/apps/$APP_ID \ --request PUT \ --header "Authorization: Bearer $ZAPI_KEY" \ --header "Content-Type: application/json" \ --data @- << EOF { "type": "stripe", "name": "Stripe Billing Profile", "secretAPIKey": "rk_test_..." } EOF

The same key-prefix validation applies — a live key is rejected on a non-production bucket and vice versa.

API Reference

For complete API operations, see the API Reference documentation:

  • Meters API
  • Features API
  • Plans API
Edit this page
Last modified on June 11, 2026
Going to ProductionPlan Examples
On this page
  • Buckets
  • Authentication
  • Bucket monetization configuration
    • Read
    • Upsert
    • Delete
  • Stripe setup and billing readiness
    • Install the Stripe app
    • Read the current Stripe setup
    • Create an additional billing profile
    • Check billing readiness
    • Update a connected app
  • API Reference
JSON