zuplo 6.69.9 → 6.69.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/ai-gateway/apps.mdx +5 -5
- package/docs/ai-gateway/custom-providers.mdx +6 -5
- package/docs/ai-gateway/getting-started.mdx +2 -1
- package/docs/ai-gateway/guardrails.mdx +2 -2
- package/docs/ai-gateway/managing-apps.mdx +10 -8
- package/docs/ai-gateway/managing-providers.mdx +9 -7
- package/docs/ai-gateway/managing-teams.mdx +4 -4
- package/docs/ai-gateway/usage-limits.mdx +8 -5
- package/docs/articles/accounts/audit-logs.mdx +3 -5
- package/docs/articles/accounts/billing.mdx +9 -5
- package/docs/articles/accounts/default-api-key.mdx +4 -5
- package/docs/articles/accounts/delete-account.mdx +11 -11
- package/docs/articles/accounts/enterprise-sso.mdx +5 -3
- package/docs/articles/accounts/managing-account-members.mdx +3 -3
- package/docs/articles/accounts/zuplo-api-keys.mdx +8 -6
- package/docs/articles/api-key-administration.mdx +8 -5
- package/docs/articles/api-key-end-users.mdx +4 -3
- package/docs/articles/api-key-self-serve-integration.mdx +8 -4
- package/docs/articles/branch-based-deployments.mdx +7 -4
- package/docs/articles/custom-ci-cd-azure.mdx +3 -2
- package/docs/articles/custom-ci-cd-bitbucket.mdx +3 -2
- package/docs/articles/custom-ci-cd-circleci.mdx +4 -2
- package/docs/articles/custom-ci-cd-github.mdx +5 -3
- package/docs/articles/custom-ci-cd-gitlab.mdx +3 -2
- package/docs/articles/custom-ci-cd.mdx +6 -8
- package/docs/articles/custom-domains.mdx +8 -6
- package/docs/articles/environments.mdx +5 -2
- package/docs/articles/mcp-quickstart.mdx +2 -2
- package/docs/articles/migrate-from-kong.md +2 -2
- package/docs/articles/monetization/api-access.mdx +3 -2
- package/docs/articles/monetization/billing-models.md +137 -31
- package/docs/articles/monetization/developer-portal.md +7 -3
- package/docs/articles/monetization/features.mdx +0 -28
- package/docs/articles/monetization/meters.mdx +14 -7
- package/docs/articles/monetization/plans.mdx +1 -3
- package/docs/articles/monetization/pricing-models.mdx +21 -7
- package/docs/articles/monetization/private-plans.md +0 -1
- package/docs/articles/monetization/quickstart.md +4 -2
- package/docs/articles/monetization/rate-cards.mdx +40 -7
- package/docs/articles/monetization/stripe-integration.md +16 -12
- package/docs/articles/monetization/subscription-lifecycle.md +4 -4
- package/docs/articles/monorepo-deployment.mdx +2 -3
- package/docs/articles/source-control-setup-github.mdx +6 -4
- package/docs/articles/step-1-setup-basic-gateway.mdx +3 -3
- package/docs/articles/step-3-add-api-key-auth-local.mdx +4 -3
- package/docs/articles/step-3-add-api-key-auth.mdx +3 -2
- package/docs/articles/step-4-deploying-to-the-edge.mdx +6 -4
- package/docs/articles/testing.mdx +4 -3
- package/docs/articles/troubleshooting.md +7 -4
- package/docs/cli/authentication.mdx +4 -2
- package/docs/cli/bucket-list.mdx +71 -0
- package/docs/cli/deploy.mdx +2 -1
- package/docs/cli/deploy.partial.mdx +2 -1
- package/docs/cli/logout.mdx +25 -0
- package/docs/concepts/api-keys.md +9 -8
- package/docs/concepts/authentication.mdx +3 -2
- package/docs/concepts/source-control-and-deployment.mdx +3 -1
- package/docs/dev-portal/documenting-mcp-servers.mdx +223 -0
- package/docs/dev-portal/zudoku/openapi-extensions/x-mcp-server.md +1 -1
- package/docs/guides/canary-routing-for-employees.mdx +3 -1
- package/docs/guides/user-based-backend-routing.mdx +3 -2
- package/docs/policies/api-key-inbound/schema.json +5 -0
- package/docs/programmable-api/environment.mdx +6 -5
- package/docs/programmable-api/zuplo-context.mdx +3 -3
- package/package.json +4 -4
|
@@ -46,9 +46,10 @@ are set in your terminal:
|
|
|
46
46
|
|
|
47
47
|
```bash
|
|
48
48
|
# Your Bucket ID (could be working-copy, preview, or production)
|
|
49
|
-
# (Found in Project Services > Bucket Details)
|
|
49
|
+
# (Found in Project Services > Bucket Details — https://portal.zuplo.com/+/account/project/services)
|
|
50
50
|
export BUCKET_ID=your-bucket-id
|
|
51
|
-
# Your Zuplo API Key (Found in Account Settings > Zuplo API Keys
|
|
51
|
+
# Your Zuplo API Key (Found in Account Settings > Zuplo API Keys —
|
|
52
|
+
# https://portal.zuplo.com/+/account/settings/api-keys)
|
|
52
53
|
export ZAPI_KEY=zpka_YOUR_API_KEY
|
|
53
54
|
```
|
|
54
55
|
|
|
@@ -45,15 +45,16 @@ API until their quota runs out. Clear and predictable for budgeting.
|
|
|
45
45
|
"rateCards": [
|
|
46
46
|
{
|
|
47
47
|
"type": "flat_fee",
|
|
48
|
-
"key": "
|
|
48
|
+
"key": "api_requests",
|
|
49
49
|
"name": "API Calls",
|
|
50
|
-
"featureKey": "
|
|
50
|
+
"featureKey": "api_requests",
|
|
51
51
|
"billingCadence": null,
|
|
52
52
|
"price": null,
|
|
53
53
|
"entitlementTemplate": {
|
|
54
54
|
"type": "metered",
|
|
55
55
|
"issueAfterReset": 1000,
|
|
56
|
-
"isSoftLimit": false
|
|
56
|
+
"isSoftLimit": false,
|
|
57
|
+
"usagePeriod": "P1M"
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
60
|
]
|
|
@@ -78,9 +79,9 @@ API until their quota runs out. Clear and predictable for budgeting.
|
|
|
78
79
|
"rateCards": [
|
|
79
80
|
{
|
|
80
81
|
"type": "flat_fee",
|
|
81
|
-
"key": "
|
|
82
|
+
"key": "api_requests",
|
|
82
83
|
"name": "API Calls",
|
|
83
|
-
"featureKey": "
|
|
84
|
+
"featureKey": "api_requests",
|
|
84
85
|
"billingCadence": "P1M",
|
|
85
86
|
"price": {
|
|
86
87
|
"type": "flat",
|
|
@@ -114,9 +115,9 @@ API until their quota runs out. Clear and predictable for budgeting.
|
|
|
114
115
|
"rateCards": [
|
|
115
116
|
{
|
|
116
117
|
"type": "flat_fee",
|
|
117
|
-
"key": "
|
|
118
|
+
"key": "api_requests",
|
|
118
119
|
"name": "API Calls",
|
|
119
|
-
"featureKey": "
|
|
120
|
+
"featureKey": "api_requests",
|
|
120
121
|
"billingCadence": "P1M",
|
|
121
122
|
"price": {
|
|
122
123
|
"type": "flat",
|
|
@@ -134,8 +135,9 @@ API until their quota runs out. Clear and predictable for budgeting.
|
|
|
134
135
|
}
|
|
135
136
|
```
|
|
136
137
|
|
|
137
|
-
**Stripe behavior:**
|
|
138
|
-
|
|
138
|
+
**Stripe behavior:** At the start of each billing period, Zuplo issues a Stripe
|
|
139
|
+
Invoice with a single fixed-price line item; Stripe collects the payment in
|
|
140
|
+
advance.
|
|
139
141
|
|
|
140
142
|
## Pay-as-you-go
|
|
141
143
|
|
|
@@ -173,9 +175,9 @@ pay for what they use. No quota limits, no hard caps.
|
|
|
173
175
|
"rateCards": [
|
|
174
176
|
{
|
|
175
177
|
"type": "usage_based",
|
|
176
|
-
"key": "
|
|
178
|
+
"key": "api_requests",
|
|
177
179
|
"name": "API Calls",
|
|
178
|
-
"featureKey": "
|
|
180
|
+
"featureKey": "api_requests",
|
|
179
181
|
"billingCadence": "P1M",
|
|
180
182
|
"price": {
|
|
181
183
|
"type": "unit",
|
|
@@ -199,7 +201,7 @@ quota and no hard limit — everything is billed per-unit.
|
|
|
199
201
|
|
|
200
202
|
```json
|
|
201
203
|
{
|
|
202
|
-
"key": "
|
|
204
|
+
"key": "paygograduated",
|
|
203
205
|
"name": "Pay As You Go",
|
|
204
206
|
"currency": "USD",
|
|
205
207
|
"billingCadence": "P1M",
|
|
@@ -211,9 +213,9 @@ quota and no hard limit — everything is billed per-unit.
|
|
|
211
213
|
"rateCards": [
|
|
212
214
|
{
|
|
213
215
|
"type": "usage_based",
|
|
214
|
-
"key": "
|
|
216
|
+
"key": "api_requests",
|
|
215
217
|
"name": "API Calls",
|
|
216
|
-
"featureKey": "
|
|
218
|
+
"featureKey": "api_requests",
|
|
217
219
|
"billingCadence": "P1M",
|
|
218
220
|
"price": {
|
|
219
221
|
"type": "tiered",
|
|
@@ -221,14 +223,16 @@ quota and no hard limit — everything is billed per-unit.
|
|
|
221
223
|
"tiers": [
|
|
222
224
|
{
|
|
223
225
|
"upToAmount": "10000",
|
|
226
|
+
"flatPrice": null,
|
|
224
227
|
"unitPrice": { "type": "unit", "amount": "0.10" }
|
|
225
228
|
},
|
|
226
229
|
{
|
|
227
230
|
"upToAmount": "100000",
|
|
231
|
+
"flatPrice": null,
|
|
228
232
|
"unitPrice": { "type": "unit", "amount": "0.05" }
|
|
229
233
|
},
|
|
230
234
|
{
|
|
231
|
-
"
|
|
235
|
+
"flatPrice": null,
|
|
232
236
|
"unitPrice": { "type": "unit", "amount": "0.01" }
|
|
233
237
|
}
|
|
234
238
|
]
|
|
@@ -244,9 +248,8 @@ quota and no hard limit — everything is billed per-unit.
|
|
|
244
248
|
}
|
|
245
249
|
```
|
|
246
250
|
|
|
247
|
-
**Stripe behavior:**
|
|
248
|
-
|
|
249
|
-
period.
|
|
251
|
+
**Stripe behavior:** At the end of each billing period, Zuplo issues a Stripe
|
|
252
|
+
Invoice with usage-based line items in arrears; Stripe collects the payment.
|
|
250
253
|
|
|
251
254
|
**Risk consideration:** Pay-as-you-go means you're extending credit. If a
|
|
252
255
|
customer racks up significant usage and their card declines at invoicing time,
|
|
@@ -285,9 +288,9 @@ overage:
|
|
|
285
288
|
"rateCards": [
|
|
286
289
|
{
|
|
287
290
|
"type": "usage_based",
|
|
288
|
-
"key": "
|
|
291
|
+
"key": "api_requests",
|
|
289
292
|
"name": "API Calls",
|
|
290
|
-
"featureKey": "
|
|
293
|
+
"featureKey": "api_requests",
|
|
291
294
|
"billingCadence": "P1M",
|
|
292
295
|
"price": {
|
|
293
296
|
"type": "tiered",
|
|
@@ -300,7 +303,7 @@ overage:
|
|
|
300
303
|
},
|
|
301
304
|
{
|
|
302
305
|
"flatPrice": null,
|
|
303
|
-
"unitPrice": { "type": "unit", "amount": "0.
|
|
306
|
+
"unitPrice": { "type": "unit", "amount": "0.0005" }
|
|
304
307
|
}
|
|
305
308
|
]
|
|
306
309
|
},
|
|
@@ -316,9 +319,20 @@ overage:
|
|
|
316
319
|
}
|
|
317
320
|
```
|
|
318
321
|
|
|
319
|
-
$499
|
|
320
|
-
A customer using 1,200,000 requests pays $499 + (200,000 x $0.
|
|
321
|
-
= $599.
|
|
322
|
+
$499 covers up to 1,000,000 requests. Requests beyond 1M are billed at $0.0005
|
|
323
|
+
each. A customer using 1,200,000 requests pays $499 + (200,000 x $0.0005) =
|
|
324
|
+
$499 + $100 = $599.
|
|
325
|
+
|
|
326
|
+
:::note
|
|
327
|
+
|
|
328
|
+
The $499 sits inside tier 1's `flatPrice`, not as a separate subscription fee.
|
|
329
|
+
It's charged unconditionally for the period (regardless of actual usage), but
|
|
330
|
+
**in arrears** — it appears on the invoice issued after the end of the billing
|
|
331
|
+
period, as part of the invoice's tiered usage line. To collect $499 at the
|
|
332
|
+
**start** of every billing period instead (a true in-advance subscription fee),
|
|
333
|
+
see [Example: Base fee in advance](#example-base-fee-in-advance) below.
|
|
334
|
+
|
|
335
|
+
:::
|
|
322
336
|
|
|
323
337
|
### Example: Graduated overage pricing
|
|
324
338
|
|
|
@@ -338,9 +352,9 @@ For high-volume APIs, you might want overage pricing that decreases at scale:
|
|
|
338
352
|
"rateCards": [
|
|
339
353
|
{
|
|
340
354
|
"type": "usage_based",
|
|
341
|
-
"key": "
|
|
355
|
+
"key": "api_requests",
|
|
342
356
|
"name": "API Calls",
|
|
343
|
-
"featureKey": "
|
|
357
|
+
"featureKey": "api_requests",
|
|
344
358
|
"billingCadence": "P1M",
|
|
345
359
|
"price": {
|
|
346
360
|
"type": "tiered",
|
|
@@ -353,10 +367,10 @@ For high-volume APIs, you might want overage pricing that decreases at scale:
|
|
|
353
367
|
},
|
|
354
368
|
{
|
|
355
369
|
"upToAmount": "5000000",
|
|
356
|
-
"unitPrice": { "type": "unit", "amount": "0.
|
|
370
|
+
"unitPrice": { "type": "unit", "amount": "0.0005" }
|
|
357
371
|
},
|
|
358
372
|
{
|
|
359
|
-
"unitPrice": { "type": "unit", "amount": "0.
|
|
373
|
+
"unitPrice": { "type": "unit", "amount": "0.0002" }
|
|
360
374
|
}
|
|
361
375
|
]
|
|
362
376
|
},
|
|
@@ -372,9 +386,101 @@ For high-volume APIs, you might want overage pricing that decreases at scale:
|
|
|
372
386
|
}
|
|
373
387
|
```
|
|
374
388
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
389
|
+
:::note
|
|
390
|
+
|
|
391
|
+
Like the previous example, the $499 sits inside tier 1's `flatPrice` and is
|
|
392
|
+
charged unconditionally for the period in arrears, as part of the invoice's
|
|
393
|
+
tiered usage line.
|
|
394
|
+
|
|
395
|
+
:::
|
|
396
|
+
|
|
397
|
+
### Example: Base fee in advance
|
|
398
|
+
|
|
399
|
+
If you need the $499 collected unconditionally at the start of every billing
|
|
400
|
+
period (a true subscription fee), split it into a separate `flat_fee` rate card
|
|
401
|
+
with `paymentTerm: "in_advance"` and set the usage-based rate card's tier 1 to
|
|
402
|
+
$0 per unit for the included quota:
|
|
403
|
+
|
|
404
|
+
```json
|
|
405
|
+
{
|
|
406
|
+
"key": "enterprise",
|
|
407
|
+
"name": "Enterprise",
|
|
408
|
+
"currency": "USD",
|
|
409
|
+
"billingCadence": "P1M",
|
|
410
|
+
"phases": [
|
|
411
|
+
{
|
|
412
|
+
"key": "default",
|
|
413
|
+
"name": "Enterprise Monthly",
|
|
414
|
+
"duration": null,
|
|
415
|
+
"rateCards": [
|
|
416
|
+
{
|
|
417
|
+
"type": "flat_fee",
|
|
418
|
+
"key": "subscription_fee",
|
|
419
|
+
"name": "Enterprise Subscription",
|
|
420
|
+
"billingCadence": "P1M",
|
|
421
|
+
"price": {
|
|
422
|
+
"type": "flat",
|
|
423
|
+
"amount": "499.00",
|
|
424
|
+
"paymentTerm": "in_advance"
|
|
425
|
+
}
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
"type": "usage_based",
|
|
429
|
+
"key": "api_requests",
|
|
430
|
+
"name": "API Calls",
|
|
431
|
+
"featureKey": "api_requests",
|
|
432
|
+
"billingCadence": "P1M",
|
|
433
|
+
"entitlementTemplate": {
|
|
434
|
+
"type": "metered",
|
|
435
|
+
"issueAfterReset": 1000000,
|
|
436
|
+
"isSoftLimit": true
|
|
437
|
+
},
|
|
438
|
+
"price": {
|
|
439
|
+
"type": "tiered",
|
|
440
|
+
"mode": "graduated",
|
|
441
|
+
"tiers": [
|
|
442
|
+
{
|
|
443
|
+
"upToAmount": "1000000",
|
|
444
|
+
"flatPrice": null,
|
|
445
|
+
"unitPrice": { "type": "unit", "amount": "0.00" }
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
"flatPrice": null,
|
|
449
|
+
"unitPrice": { "type": "unit", "amount": "0.0005" }
|
|
450
|
+
}
|
|
451
|
+
]
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
]
|
|
455
|
+
}
|
|
456
|
+
]
|
|
457
|
+
}
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
Both patterns charge the customer $499 for every billing period regardless of
|
|
461
|
+
usage. The differences are timing and how the fee appears on the invoice:
|
|
462
|
+
|
|
463
|
+
| Behavior | Tier-1 flat price (previous examples) | Separate flat-fee rate card (this example) |
|
|
464
|
+
| ------------------------ | ---------------------------------------------------- | ---------------------------------------------------------------------------------- |
|
|
465
|
+
| When the $499 is charged | End of period, in arrears | Start of period, in advance |
|
|
466
|
+
| Invoice presentation | Single tiered usage line item that includes the $499 | Distinct line items: one for the $499, one for usage |
|
|
467
|
+
| Best for | When end-of-period billing is acceptable | True subscriptions where the fee should be collected upfront and listed separately |
|
|
468
|
+
|
|
469
|
+
The `subscription_fee` rate card has no `featureKey` — it's a
|
|
470
|
+
[rate card without a feature](./rate-cards.mdx#rate-cards-without-features), the
|
|
471
|
+
right shape for a billing-only line item that doesn't grant any entitlement.
|
|
472
|
+
|
|
473
|
+
**Stripe behavior:** At the start of each billing period, Zuplo issues a single
|
|
474
|
+
Stripe Invoice that includes both:
|
|
475
|
+
|
|
476
|
+
- The $499 fixed-price line item from the `subscription_fee` rate card, charged
|
|
477
|
+
in advance for the period that's just starting.
|
|
478
|
+
- Any usage-based line items for overage above 1M from the **previous** billing
|
|
479
|
+
period, charged in arrears.
|
|
480
|
+
|
|
481
|
+
Stripe collects payment for the full invoice. The first billing period's invoice
|
|
482
|
+
contains only the $499, since there's no prior period to bill overage for. No
|
|
483
|
+
Stripe Subscription is created.
|
|
378
484
|
|
|
379
485
|
## Credits / tokens (prepaid)
|
|
380
486
|
|
|
@@ -76,8 +76,10 @@ Save and deploy. Once the plugin is enabled, ensure:
|
|
|
76
76
|
|
|
77
77
|
### Plan display order
|
|
78
78
|
|
|
79
|
-
Control plan display order
|
|
80
|
-
|
|
79
|
+
Control plan display order from your project's
|
|
80
|
+
[**Services**](https://portal.zuplo.com/+/account/project/services) page in the
|
|
81
|
+
Zuplo Portal — open the Monetization Service. Plans can be reordered using
|
|
82
|
+
drag-and-drop.
|
|
81
83
|
|
|
82
84
|
### Feature comparison matrix
|
|
83
85
|
|
|
@@ -158,7 +160,9 @@ use the same fonts, colors, and layout as the rest of your portal.
|
|
|
158
160
|
The Developer Portal runs at `https://your-project.zuplo.dev/docs` by default.
|
|
159
161
|
For production, configure a custom domain:
|
|
160
162
|
|
|
161
|
-
1.
|
|
163
|
+
1. Open
|
|
164
|
+
[**Account Settings → Custom Domains**](https://portal.zuplo.com/+/account/settings/custom-domains)
|
|
165
|
+
in the Zuplo Portal
|
|
162
166
|
2. Add your domain (e.g., `developers.your-company.com`)
|
|
163
167
|
3. Configure the DNS records as instructed
|
|
164
168
|
4. SSL is provisioned automatically
|
|
@@ -95,34 +95,6 @@ curl \
|
|
|
95
95
|
EOF
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
-
### Creating a Billing-Only Feature
|
|
99
|
-
|
|
100
|
-
Some plans charge a flat subscription fee that isn't tied to any entitlement — a
|
|
101
|
-
monthly access fee, a setup fee, or a fixed retainer. Model these the same way
|
|
102
|
-
as a static feature (no `meterSlug`), then attach them to a plan via a
|
|
103
|
-
`flat_fee` rate card with no `entitlementTemplate` and a price whose
|
|
104
|
-
`paymentTerm` is `"in_advance"`. Zuplo issues a Stripe Invoice for the fee at
|
|
105
|
-
the start of each billing period.
|
|
106
|
-
|
|
107
|
-
```shell
|
|
108
|
-
curl \
|
|
109
|
-
https://dev.zuplo.com/v3/metering/$BUCKET_ID/features \
|
|
110
|
-
--request POST \
|
|
111
|
-
--header "Authorization: Bearer $ZAPI_KEY" \
|
|
112
|
-
--header "Content-Type: application/json" \
|
|
113
|
-
--data @- << EOF
|
|
114
|
-
{
|
|
115
|
-
"key": "monthly_fee",
|
|
116
|
-
"name": "Monthly Fee"
|
|
117
|
-
}
|
|
118
|
-
EOF
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
Because the rate card carries no entitlement, the developer portal's
|
|
122
|
-
feature-comparison matrix doesn't render a row for the feature — the price rolls
|
|
123
|
-
into the plan's headline cost. See the Pro plan example in [Plans](./plans.mdx)
|
|
124
|
-
for the rate-card shape.
|
|
125
|
-
|
|
126
98
|
## API Reference
|
|
127
99
|
|
|
128
100
|
For complete API operations (list, get, archive), see the
|
|
@@ -43,8 +43,10 @@ Track the total number of API requests:
|
|
|
43
43
|
}
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
Each event
|
|
47
|
-
|
|
46
|
+
Each event identifies the subscription being metered, the actor that drove the
|
|
47
|
+
consumption, and how much to record. The `subscription` field carries the
|
|
48
|
+
subscription ID, the `subject` field identifies the actor, and `data.total`
|
|
49
|
+
carries the quantity:
|
|
48
50
|
|
|
49
51
|
```json
|
|
50
52
|
{
|
|
@@ -52,7 +54,7 @@ Each event contains the `subscription` ID linking it to a subscription and a
|
|
|
52
54
|
"specversion": "1.0",
|
|
53
55
|
"type": "api_requests",
|
|
54
56
|
"source": "monetization-policy",
|
|
55
|
-
"subject": "
|
|
57
|
+
"subject": "acme-prod",
|
|
56
58
|
"subscription": "01KNVXHQG356VA7T7W0V9N21GH",
|
|
57
59
|
"data": {
|
|
58
60
|
"total": 1
|
|
@@ -62,8 +64,13 @@ Each event contains the `subscription` ID linking it to a subscription and a
|
|
|
62
64
|
|
|
63
65
|
:::note
|
|
64
66
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
`subject` identifies _who_ consumed the subscription's entitlements on this
|
|
68
|
+
request — typically the API key's consumer name, the end-user id, or another
|
|
69
|
+
stable per-actor identifier. It is **not** the subscription id (use the
|
|
70
|
+
`subscription` field for that) and is not used to route billing. Its purpose is
|
|
71
|
+
to let you break down usage within a subscription so you can see which key,
|
|
72
|
+
user, or agent drove the consumption — a single subscription will commonly emit
|
|
73
|
+
events with many different `subject` values. See
|
|
67
74
|
[Monetization Policy](./monetization-policy.md) for how usage is recorded.
|
|
68
75
|
|
|
69
76
|
:::
|
|
@@ -96,7 +103,7 @@ consumed 50 tokens looks like this:
|
|
|
96
103
|
"specversion": "1.0",
|
|
97
104
|
"type": "tokens",
|
|
98
105
|
"source": "monetization-policy",
|
|
99
|
-
"subject": "
|
|
106
|
+
"subject": "acme-prod",
|
|
100
107
|
"subscription": "01KNVXHQG356VA7T7W0V9N21GH",
|
|
101
108
|
"data": {
|
|
102
109
|
"total": 50
|
|
@@ -126,7 +133,7 @@ Each event reports the number of bytes transferred:
|
|
|
126
133
|
"specversion": "1.0",
|
|
127
134
|
"type": "data_transfer",
|
|
128
135
|
"source": "monetization-policy",
|
|
129
|
-
"subject": "
|
|
136
|
+
"subject": "acme-prod",
|
|
130
137
|
"subscription": "01KNVXHQG356VA7T7W0V9N21GH",
|
|
131
138
|
"data": {
|
|
132
139
|
"total": 4096
|
|
@@ -138,7 +138,6 @@ curl \
|
|
|
138
138
|
"type": "flat_fee",
|
|
139
139
|
"key": "monthly_fee",
|
|
140
140
|
"name": "Monthly Fee",
|
|
141
|
-
"featureKey": "monthly_fee",
|
|
142
141
|
"billingCadence": "P1M",
|
|
143
142
|
"price": {
|
|
144
143
|
"type": "flat",
|
|
@@ -204,8 +203,7 @@ After the trial ends, customers automatically move to the default phase. The $99
|
|
|
204
203
|
monthly subscription fee is charged in advance at the start of each billing
|
|
205
204
|
period via the `monthly_fee` flat-fee rate card. The plan includes 10,000 API
|
|
206
205
|
requests per period; additional requests are billed at $0.01 each in arrears
|
|
207
|
-
(
|
|
208
|
-
next invoice).
|
|
206
|
+
(soft limit allows overage).
|
|
209
207
|
|
|
210
208
|
## Plan Properties
|
|
211
209
|
|
|
@@ -23,7 +23,8 @@ cards for subscriptions, setup fees, or access charges.
|
|
|
23
23
|
|
|
24
24
|
### Recurring Subscription
|
|
25
25
|
|
|
26
|
-
A monthly
|
|
26
|
+
A monthly subscription fee that recurs each billing period and is collected in
|
|
27
|
+
advance:
|
|
27
28
|
|
|
28
29
|
```json
|
|
29
30
|
{
|
|
@@ -33,11 +34,24 @@ A monthly platform fee that recurs each billing period:
|
|
|
33
34
|
"billingCadence": "P1M",
|
|
34
35
|
"price": {
|
|
35
36
|
"type": "flat",
|
|
36
|
-
"amount": "99.00"
|
|
37
|
+
"amount": "99.00",
|
|
38
|
+
"paymentTerm": "in_advance"
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
```
|
|
40
42
|
|
|
43
|
+
Each billing period — every month for `P1M` — Zuplo adds a $99.00 line item for
|
|
44
|
+
this rate card to the customer's Stripe Invoice. Because `paymentTerm` is
|
|
45
|
+
`in_advance` (the default for flat prices), the customer is charged at the start
|
|
46
|
+
of the period rather than the end.
|
|
47
|
+
|
|
48
|
+
The rate card's `billingCadence` must align with the plan's `billingCadence` —
|
|
49
|
+
see [Rate Cards → Billing Cadence](./rate-cards.mdx#billing-cadence) for the
|
|
50
|
+
alignment rule. A flat-fee rate card like this one doesn't need a `featureKey`
|
|
51
|
+
(see
|
|
52
|
+
[Rate Cards Without Features](./rate-cards.mdx#rate-cards-without-features)) —
|
|
53
|
+
the rate card's `key` and `name` appear directly on the customer's invoice.
|
|
54
|
+
|
|
41
55
|
### One-Time Setup Fee
|
|
42
56
|
|
|
43
57
|
A setup fee charged once when the subscription starts (no `billingCadence`):
|
|
@@ -62,7 +76,7 @@ Per-unit pricing charges a fixed amount for each unit of metered usage. Use
|
|
|
62
76
|
```json
|
|
63
77
|
{
|
|
64
78
|
"type": "usage_based",
|
|
65
|
-
"featureKey": "
|
|
79
|
+
"featureKey": "api_requests",
|
|
66
80
|
"billingCadence": "P1M",
|
|
67
81
|
"price": {
|
|
68
82
|
"type": "unit",
|
|
@@ -90,7 +104,7 @@ Each unit is charged according to the tier it falls into:
|
|
|
90
104
|
```json
|
|
91
105
|
{
|
|
92
106
|
"type": "usage_based",
|
|
93
|
-
"featureKey": "
|
|
107
|
+
"featureKey": "api_requests",
|
|
94
108
|
"billingCadence": "P1M",
|
|
95
109
|
"price": {
|
|
96
110
|
"type": "tiered",
|
|
@@ -125,7 +139,7 @@ All units are charged at the rate of the highest tier reached:
|
|
|
125
139
|
```json
|
|
126
140
|
{
|
|
127
141
|
"type": "usage_based",
|
|
128
|
-
"featureKey": "
|
|
142
|
+
"featureKey": "api_requests",
|
|
129
143
|
"billingCadence": "P1M",
|
|
130
144
|
"price": {
|
|
131
145
|
"type": "tiered",
|
|
@@ -157,7 +171,7 @@ common pattern for "X calls included, then $Y per additional call":
|
|
|
157
171
|
```json
|
|
158
172
|
{
|
|
159
173
|
"type": "usage_based",
|
|
160
|
-
"featureKey": "
|
|
174
|
+
"featureKey": "api_requests",
|
|
161
175
|
"billingCadence": "P1M",
|
|
162
176
|
"price": {
|
|
163
177
|
"type": "tiered",
|
|
@@ -185,7 +199,7 @@ Package pricing sells usage in fixed bundles rather than individual units:
|
|
|
185
199
|
```json
|
|
186
200
|
{
|
|
187
201
|
"type": "usage_based",
|
|
188
|
-
"featureKey": "
|
|
202
|
+
"featureKey": "api_requests",
|
|
189
203
|
"billingCadence": "P1M",
|
|
190
204
|
"price": {
|
|
191
205
|
"type": "package",
|
|
@@ -46,7 +46,8 @@ keeps your existing work safe from any breaking changes.
|
|
|
46
46
|
:::
|
|
47
47
|
|
|
48
48
|
1. Go to [portal.zuplo.com](https://portal.zuplo.com) and sign in.
|
|
49
|
-
2. Click **New Project** in the top right corner
|
|
49
|
+
2. Click **New Project** in the top right corner
|
|
50
|
+
([open](https://portal.zuplo.com/+/account/projects/new)).
|
|
50
51
|
3. Enter a **Project name** or use the randomly chosen name Zuplo provides.
|
|
51
52
|
4. Select **Starter Project (Recommended)** — it comes with endpoints ready to
|
|
52
53
|
monetize.
|
|
@@ -83,7 +84,8 @@ Add the monetization plugin to your Developer Portal configuration.
|
|
|
83
84
|
|
|
84
85
|
## Step 3: Configure the Monetization Service
|
|
85
86
|
|
|
86
|
-
1.
|
|
87
|
+
1. Open the [**Services**](https://portal.zuplo.com/+/account/project/services)
|
|
88
|
+
tab in your project.
|
|
87
89
|
2. Select the environment you want to configure. We will use **Working Copy**
|
|
88
90
|
for this quickstart.
|
|
89
91
|
3. Click **Configure** on the **Monetization Service** card.
|
|
@@ -26,7 +26,9 @@ A rate card consists of:
|
|
|
26
26
|
- **Feature** - Optional link to a feature from your product catalog
|
|
27
27
|
- **Price** - How much to charge (see [Pricing Models](./pricing-models.mdx))
|
|
28
28
|
- **Entitlement** - Optional usage limits or access controls
|
|
29
|
-
- **Billing Cadence** - How often
|
|
29
|
+
- **Billing Cadence** - How often this rate card produces a charge — distinct
|
|
30
|
+
from the plan's billing cadence, and constrained to align with it (see
|
|
31
|
+
[Billing Cadence](#billing-cadence) below)
|
|
30
32
|
|
|
31
33
|
## Rate Card Types
|
|
32
34
|
|
|
@@ -53,8 +55,9 @@ recurring fee. Use these for:
|
|
|
53
55
|
}
|
|
54
56
|
```
|
|
55
57
|
|
|
56
|
-
When `billingCadence` is set (e.g., `P1M`
|
|
57
|
-
|
|
58
|
+
When `billingCadence` is set (e.g., `P1M`), the flat fee recurs at that cadence
|
|
59
|
+
— see [Billing Cadence](#billing-cadence) for the constraint relative to the
|
|
60
|
+
plan's cadence. When `billingCadence` is `null`, the fee is charged once per
|
|
58
61
|
subscription phase.
|
|
59
62
|
|
|
60
63
|
The `paymentTerm` field controls when the charge is collected:
|
|
@@ -75,9 +78,9 @@ feature linked to a meter. Use these for:
|
|
|
75
78
|
```json
|
|
76
79
|
{
|
|
77
80
|
"type": "usage_based",
|
|
78
|
-
"key": "
|
|
81
|
+
"key": "api_requests",
|
|
79
82
|
"name": "API Calls",
|
|
80
|
-
"featureKey": "
|
|
83
|
+
"featureKey": "api_requests",
|
|
81
84
|
"billingCadence": "P1M",
|
|
82
85
|
"price": {
|
|
83
86
|
"type": "unit",
|
|
@@ -90,6 +93,36 @@ Usage-based rate cards support multiple pricing models. See
|
|
|
90
93
|
[Pricing Models](./pricing-models.mdx) for details on unit, tiered, package, and
|
|
91
94
|
dynamic pricing.
|
|
92
95
|
|
|
96
|
+
## Billing Cadence
|
|
97
|
+
|
|
98
|
+
A rate card's `billingCadence` controls how often this specific rate card
|
|
99
|
+
produces a charge. It's distinct from the **plan's** `billingCadence`, which
|
|
100
|
+
sets the overall invoice schedule for the subscription:
|
|
101
|
+
|
|
102
|
+
- For **flat-fee** rate cards, the cadence determines how often the flat fee
|
|
103
|
+
recurs. Set it to `null` to charge once per subscription phase (a setup fee,
|
|
104
|
+
onboarding charge, or other one-time payment).
|
|
105
|
+
- For **usage-based** rate cards, the cadence is required and determines the
|
|
106
|
+
period over which metered usage is aggregated and emitted as an invoice line.
|
|
107
|
+
|
|
108
|
+
### Alignment with the plan
|
|
109
|
+
|
|
110
|
+
The rate card's cadence must align with the plan's `billingCadence`. Two
|
|
111
|
+
cadences align when:
|
|
112
|
+
|
|
113
|
+
- They are identical (e.g., plan `P1M` and rate card `P1M`), or
|
|
114
|
+
- The shorter one divides the longer one without remainder (e.g., plan `P1M`
|
|
115
|
+
with a rate card at `P3M`, or plan `P1Y` with a rate card at `P1M`).
|
|
116
|
+
|
|
117
|
+
Plans accept these `billingCadence` values: `PT1H`, `P1D`, `P1W`, `P2W`, `P4W`,
|
|
118
|
+
`P1M`, `P3M`, `P6M`, `P12M`, `P1Y`. A rate card with a cadence that doesn't
|
|
119
|
+
align (for example, `P2M` on a `P3M` plan, where neither divides the other) is
|
|
120
|
+
rejected at plan creation.
|
|
121
|
+
|
|
122
|
+
This rule exists for invoice-generation correctness: it guarantees that every
|
|
123
|
+
rate-card cycle ends on a plan-invoice boundary, so a single charge from this
|
|
124
|
+
rate card lands on exactly one customer invoice rather than straddling two.
|
|
125
|
+
|
|
93
126
|
## Rate Cards With Features
|
|
94
127
|
|
|
95
128
|
When a rate card is linked to a feature via `featureKey`:
|
|
@@ -121,9 +154,9 @@ include:
|
|
|
121
154
|
```json
|
|
122
155
|
{
|
|
123
156
|
"type": "usage_based",
|
|
124
|
-
"key": "
|
|
157
|
+
"key": "api_requests",
|
|
125
158
|
"name": "API Calls",
|
|
126
|
-
"featureKey": "
|
|
159
|
+
"featureKey": "api_requests",
|
|
127
160
|
"billingCadence": "P1M",
|
|
128
161
|
"price": {
|
|
129
162
|
"type": "unit",
|