Pricing Models
Configure how your extension charges tokens — free, per-action, or subscription
When you publish an extension, you pick one of three pricing models. You can change the model + values while the app is draft or suspended; once active, you must Pause first to edit.
free — no charge per call
pricing_model = "free"
pricing_config = {} # nothing else neededResolver short-circuits to (0, 0, 0). Your developer_earnings rows still get written with developer_share=0 for analytics, but no tokens flow.
Use when:
- Building audience / portfolio extensions
- Helper utilities that complement a paid extension you also publish
- Anything where the value-prop is "make Imperal more useful for free"
per_action — charge per function call
pricing_model = "per_action"
pricing_config = {
"tool_prices": {
"summarize_inbox": 5, # tokens per call
"draft_reply": 3,
"send_email": 10,
"list_messages": 1,
}
}
revenue_split_dev = 70 # explorer tier default; 80/85/95 at indie/studio/partnerFor each @chat.function, you set an integer token cost. Pricing maps to the base_price component; web-kernel adds platform_fee on top (model-tier-derived; zero for BYOLLM users).
Effective user-side cost per call:
Non-BYOLLM user: cost = tool_price + platform_fee (e.g. 5 + 2 = 7 tokens)
BYOLLM user: cost = tool_price (e.g. 5 tokens)Your earnings per call (at explorer tier 70%):
Non-BYOLLM: earned = floor(7 × 0.70) = 4 tokens
BYOLLM: earned = floor(5 × 0.70) = 3 tokensUpgrade to indie/studio/partner for higher % — see Developer Tiers for break-even math. BYOLLM impact in detail: BYOLLM Pricing.
Setting tool prices via the UI
- Open Dev Portal → My App → Pricing tab.
- Click Edit Pricing.
- Switch model to Per Action.
- For each discovered function, enter a token price (or 0 for free-per-function inside an otherwise-paid extension).
- Save → status flips to
draft(or stayssuspended) → admin re-approval needed before live.
Functions are discovered from disk — the Dev Portal lists every
@chat.functionit finds in your deployed extension. Add a new function → push to git → deploy → it appears in the price table on next refresh.
Tip: pricing by action type
A common pattern — price destructive more than write more than read. Defaults Imperal uses for first-party apps:
| action_type | default price |
|---|---|
read | 1 token |
write | 3 tokens |
destructive | 10 tokens |
You're free to pick your own numbers. Just remember users see the total including platform_fee — high prices push users away.
subscription — flat monthly fee per user
pricing_model = "subscription"
pricing_config = {
"monthly_price": 5000 # tokens per month per user
}
revenue_split_dev = 80Not yet enforced (gap G-4 — Extension Rental). The schema accepts subscription mode, but the web-kernel's
ExtensionRentalWorkflowis not yet wired. Stick toper_actionorfreefor now if you want predictable revenue.
When enforced, this will:
- Charge user's wallet
monthly_priceon subscription start AND every 30 days - Suspend access (revoke
user_extensions.status) if wallet can't cover - Resume on user top-up
Pricing internals — what gets stored where
When you save pricing in Dev Portal, two things happen synchronously:
- MySQL:
UPDATE developer_apps SET pricing_model=?, pricing_config=? WHERE app_id=? - Redis sync (
sync_pricing_to_redis):imperal:developer:app:{app_id}(HASH) ←developer_id, pricing_model, revenue_split_dev, statusimperal:billing:pricing:{app_id}(HASH) ← translated to web-kernel's resolver schema:free→{mode: "free"}per_action→{mode: "per_function", functions: JSON(tool_prices)}subscription→{mode: "subscription", monthly_price: int}
Web-kernel reads only the Redis key — your DB row is the source of truth for the Dev Portal UI + admin review.
Edit lifecycle
draft / suspended → edit prices freely → Submit for Review
│
▼
pending_review
│
(admin review)
│
┌─────────────────────┴────────────────┐
▼ ▼
approved rejected
│ │
▼ ▼
status='active' status='draft' + reason
Redis sync triggers you fix + resubmit
prices go LIVEActive = immutable. To change anything, Dev Portal → Pause → edit → Resubmit. This protects users from surprise price hikes.
Per-function pricing — when category isn't enough
If your extension has wildly different costs per tool (e.g. lookup is trivial but full_report calls a paid API on your backend), use per_action with per-function prices instead of relying on the action_type categories.
pricing_config = {
"tool_prices": {
"lookup": 1,
"summarize": 5,
"full_report": 50, # this one's expensive, charge accordingly
}
}Tools you don't list fall back to web-kernel's category defaults (price_read=1, price_write=3, price_destructive=10). To make a tool free, list it explicitly with 0.