Features & Add-ons
Features describe what a plan entitles a customer to — a switch, a quota, or a metered counter. You attach features to plans and then enforce them at runtime with the entitlement API. Add-ons are extra charge lines attached to a single subscription — a one-time setup fee or a recurring seat pack — billed on that subscription's invoices.
All endpoints below use your secret key as a Bearer token and live under https://api-gateway.lunixi.com/api/v1/subscriptions. List endpoints use cursor pagination (pageSize, pageToken).
Feature types
| Type | Behavior | resetPeriodDays |
|---|---|---|
BOOLEAN | On/off capability — the customer either has it or not (e.g. "SSO login") | — |
QUOTA | A fixed allowance the customer consumes; entitlement checks fail once the allowance is used up | Optional — allowance resets every N days (e.g. 30 for a monthly quota) |
METERED_USAGE | An open-ended counter; you report consumption and it is rated onto the invoice | Optional — counter window resets every N days |
QUOTA answers "may this customer still do X?" — it is a limit. METERED_USAGE answers "how much X did they do?" — it is a billing meter. See Usage & Entitlements for how each type behaves at runtime.
Create a feature
curl -X POST https://api-gateway.lunixi.com/api/v1/subscriptions/features \
-H "Authorization: Bearer at_live_5f3e2b1a..." \
-H "Content-Type: application/json" \
-d '{
"code": "api-calls",
"name": "API calls",
"type": "METERED_USAGE",
"resetPeriodDays": 30
}'{
"id": "feat_01JX4A7Q2K",
"code": "api-calls",
"name": "API calls",
"type": "METERED_USAGE",
"resetPeriodDays": 30
}The code is what you reference later — in plan configuration, in usage/record and in usage/check-entitlement. Keep it stable; treat it like an API identifier, not a display label.
Manage features
| Method | Path | What it does |
|---|---|---|
POST | /subscriptions/features | Create a feature |
GET | /subscriptions/features | List features (cursor pagination) |
PATCH | /subscriptions/features/:id | Update name, resetPeriodDays, etc. |
DELETE | /subscriptions/features/:id | Remove a feature |
Translations
Feature display names are localizable — the customer portal and hosted pricing surfaces pick the viewer's locale automatically:
| Method | Path | What it does |
|---|---|---|
GET | /subscriptions/features/:id/translations | List all translations of a feature |
PATCH | /subscriptions/features/:id/translations/:locale | Upsert the translation for one locale |
curl -X PATCH https://api-gateway.lunixi.com/api/v1/subscriptions/features/feat_01JX4A7Q2K/translations/tr \
-H "Authorization: Bearer at_live_5f3e2b1a..." \
-H "Content-Type: application/json" \
-d '{ "name": "API çağrıları" }'Add-ons
An add-on is a charge line bound to one subscription (subscriptionId), not to a plan. Use it for anything that varies per customer: an onboarding fee, extra seats, a premium support tier.
- Required fields:
subscriptionId,code(your stable identifier for the line),nameandunitAmount. unitAmountis a minor-unit integer —25000means ₺250,00.isRecurring: false→ billed once, on the next invoice.isRecurring: true→ billed on every period invoice until the add-on is deleted.
All amounts across the API are minor-unit (kuruş) integers. "unitAmount": 25000 is ₺250,00 — never send decimals.
Create an add-on
curl -X POST https://api-gateway.lunixi.com/api/v1/subscriptions/addons \
-H "Authorization: Bearer at_live_5f3e2b1a..." \
-H "Content-Type: application/json" \
-d '{
"subscriptionId": "sub_01JX5B8R3M",
"code": "extra-seats-5",
"name": "Extra seat pack (5)",
"unitAmount": 25000,
"isRecurring": true
}'{
"id": "addon_01JX5C1T9P",
"subscriptionId": "sub_01JX5B8R3M",
"code": "extra-seats-5",
"name": "Extra seat pack (5)",
"unitAmount": 25000,
"isRecurring": true
}Manage add-ons
| Method | Path | What it does |
|---|---|---|
POST | /subscriptions/addons | Attach an add-on to a subscription |
GET | /subscriptions/addons | List add-ons (cursor pagination) |
PATCH | /subscriptions/addons/:id | Update amount, name or recurrence |
DELETE | /subscriptions/addons/:id | Remove — recurring add-ons stop appearing on future invoices |
Errors
| Status | Meaning | What to do |
|---|---|---|
400 | Validation failed (unknown type, non-integer unitAmount, missing code) | Fix the request body; amounts are minor-unit integers |
401 | Missing/invalid Bearer key | Check the Authorization header and key environment |
404 | Feature, add-on or subscriptionId not found | Verify the id belongs to your account |
409 | Duplicate feature code | Feature codes are unique — reuse the existing feature or pick a new code |
Webhooks
Feature and add-on CRUD does not emit dedicated webhook events. Their effects surface through related events instead:
| Event | When |
|---|---|
usage.recorded | A metered feature received a usage record |
invoice.created | A period invoice was generated — add-on lines appear here |
plan.updated | A plan (including its feature configuration) changed |
See Webhooks for delivery and signature verification.
Next steps
- Usage & Entitlements — record consumption and enforce quotas at runtime
- Plans — attach features to plans and set pricing
- Subscriptions — create the subscription your add-ons attach to
- Invoices — where add-on charges land