Billing and usage
Every Jelliu workspace runs on a plan. Plans do not differ by which features they unlock: every product capability is available on every paid plan, with one exception (custom cloned voices, Enterprise only). Plans differ by how much you can use: call minutes, AI replies on text channels, agents, campaigns, contacts, phone numbers, concurrent calls, knowledge base size and connected apps.
This page shows how to read that from the API so your integration can check headroom before it acts, and how to handle the responses when a limit is reached.
How it works
Limits are checked at two moments:
- When you create something that counts against the plan (an agent, a campaign, contacts, a knowledge file, a connected app, a phone number). If the cap is reached, creation fails with
403 BILLING_ERROR. - When the platform consumes something (a call is placed or answered, an agent replies on a text channel). If the allowance is used up, the call is refused or the agent does not reply.
Endpoints
Usage, limits, invoices, charges and payment methods are financial information, restricted to workspace administrators and the billing role. For an API key that means the full scope; a read or write key receives 403 with This operation requires an API key with the 'full' scope. See API keys.
All /api/billing routes share a limit of 15 requests per minute per workspace. Read limits once and cache them rather than calling before every operation.
Get the subscription
GET /api/billing/subscription
Get usage
GET /api/billing/usage
Without an active plan, every number is 0 and channels is ["voice"]. The response is cached for up to 30 seconds.
Get limits
GET /api/billing/limits returns the effective limits for the workspace, including purchased agent add-ons, and the plan’s feature flags. It is cached for up to 5 minutes (Cache-Control: private, max-age=300), so a plan change can take that long to show.
The example shows a subset of features; the real object has more flags. A negative value (-1) means unlimited. Very large values such as 9999 are also effectively unlimited.
When the workspace has no active plan (the trial ended, the plan was cancelled, or it never subscribed), tier is "none", every count limit is 0 and channels is empty. The workspace can still use the dashboard and choose a plan, but it cannot create resources, place calls or get AI replies, and several features are refused. See Without an active subscription.
Plan limits
The limits in effect when this page was written. Read /api/billing/limits for the values that apply to your workspace; they are the ones Jelliu enforces.
Agent add-ons raise the agent limit on Starter, Growth and Business; maxAgents in /api/billing/limits already includes them.
How consumption works
Call minutes
- Included minutes are a monthly allowance. On an annual plan, the usage window is the current month inside the annual period, so minutes reset every month.
- Minute packs add bonus minutes on top of the plan’s included minutes.
- Past included plus bonus minutes, calls continue as overage, billed automatically to the card on file.
- Overage has a ceiling. On Starter, Growth and Business, calls are refused once usage reaches the included minutes plus purchased pack minutes plus half of the included minutes again (for example, 300 minutes on a 200-minute plan with no packs). Buying a minute pack or upgrading raises the ceiling; otherwise it resets with the next usage window. Enterprise has no ceiling.
- Trials are capped at 15 minutes of calls and never generate overage. A single call is also cut off when the trial minutes run out.
AI replies on text channels
- Each AI reply on WhatsApp, email, web chat, Instagram or Messenger counts against
includedChatMessages. A reply is counted only after it is actually produced for delivery, so failed sends do not consume allowance. - The allowance is not billed per message and has no overage. When it is used up, the agent stops replying on text channels until the window renews or the plan is upgraded. Voice calls are not affected.
- Separately, WhatsApp and email have a daily per-workspace send cap as a safety limit. See WhatsApp and Email.
Notifications
The workspace receives in-app notifications at 80% and 100% of both call minutes and AI replies, and when calls are paused at the overage ceiling. There is no webhook for usage thresholds yet: usage.threshold_reached appears in the event catalog but cannot be subscribed to until it is marked available there. Poll /api/billing/usage if you need to react programmatically.
Handling limit errors
Plan limits return BILLING_ERROR. The HTTP status is 403 for most limits and 402 for phone numbers and for plan changes without a payment method. Branch on error.code, and use metadata to show the user what happened.
Resource caps
Creating an agent, campaign, contact, knowledge file, connected app or MCP server assignment beyond the plan’s cap:
A bulk contact import that would cross the cap is rejected as a whole, and reports the batch size:
Messages you may see, verbatim:
Calls refused
POST /api/calls is refused with 403 BILLING_ERROR when the workspace has no active plan, the trial minutes are used up, or the overage ceiling is reached:
This route returns the same message for an exhausted trial and for a paid plan that reached its overage ceiling. Do not rely on the wording: check /api/billing/usage (isTrialing, minutesUsed, includedMinutes, bonusMinutes) to tell the cases apart.
Campaign calls are checked the same way before each dial. Concurrency is separate: exceeding the plan’s concurrent calls returns 429 MAX_CONCURRENT_CALLS_REACHED and is safe to retry. See Errors.
AI replies exhausted
When the AI reply allowance is used up, the agent does not answer on text channels. The workspace gets an in-app notification, and the error recorded for the conversation is in Spanish, as it is shown to the workspace owner:
- With a plan:
Llegaste al límite mensual de mensajes de IA (… mensajes del plan …). Sube de plan en Ajustes → Plan. - Without a plan:
Tu plan no está activo, así que la IA no está respondiendo en este canal. Elige un plan en Ajustes → Plan para volver a activarla.
Visitors on the web chat widget never see this text; the widget shows its own neutral message.
Phone numbers
Adding a phone number beyond maxPhoneNumbers returns 402 BILLING_ERROR:
The wording depends on the path (provisioning, bringing your own number, or when the plan still allows buying add-on numbers), so rely on the code and status. See Phone numbers.
Feature gates
A few routes check a plan feature flag. When a paid plan does not include it, they return 403 BILLING_ERROR with metadata.tier and a message such as La función «Analítica avanzada» no está disponible en el plan Starter. Sube de plan para usarla. All current plans include these features, so on a paid plan these gates refuse nobody today. A workspace without an active subscription is refused by all of them, with a different response: see Without an active subscription.
features also still carries objectionHandlers and escalationRules. Since 2026-09-15 neither gates anything: the plan check on saving objectionHandlers was removed, and escalationRules was retired from the API. Ignore both flags when deciding what your integration may do.
The one feature that differs by plan is custom cloned voices. Assigning a cloned voice to an agent outside Enterprise returns 403 BILLING_ERROR: La clonación de voz es parte del plan Enterprise. Actualiza tu plan para usar una voz propia.
Without an active subscription
A workspace has an active subscription while its status is active, trialing or past_due (a card being retried is still active). When the trial ends without a plan, or the plan is cancelled or finally unpaid, GET /api/billing/limits reports tier: "none" and the rules below apply until a plan is chosen in Settings → Plan. Nothing is deleted.
What is refused
Features that do work for the workspace, or that push its data somewhere else, need a subscription:
Objection handlers are no longer gated (2026-09-15). Saving a non-empty objectionHandlers on an agent used to be refused without an active subscription. Every paid tier already allowed it, so in practice the gate only ever caught unsubscribed workspaces — and what it blocked was a customer supplying their own answers instead of ours, which is the same capability either way. It is gone: every plan can save its own objection answers. escalationRules, which was listed here alongside it, was retired from the API on the same day.
Creating agents, campaigns, contacts, knowledge files, connected apps and phone numbers is also refused, because every count limit is 0 (see Resource caps), and so are calls and AI replies.
The REST routes answer 403 with BILLING_ERROR. metadata.kind is subscription_required, which tells this refusal apart from a plan that lacks a feature. The message names the feature, for example for webhooks:
The feature names in the message are Webhooks salientes, Analítica avanzada, Reportes personalizados, Exportación de analítica, Servidores MCP, Pruebas A/B and Reintentos automáticos de llamada. Branch on metadata.kind, not on the message. (Manejo de objeciones and Reglas de escalamiento used to appear here; neither is refused any more.)
The MCP server answers 403 with a JSON-RPC error instead:
Webhook deliveries are paused
While there is no subscription, events are not delivered to any webhook. Each delivery is canceled before it is sent and shows in the delivery log with status: canceled and last_error: subscription_inactive. A canceled delivery is not a failure: it is not retried, does not count toward the automatic disabling of the webhook and leaves is_active unchanged. Events that happen during that time are not sent later on their own, but they are kept for 30 days: once the workspace subscribes again, POST /api/webhooks/{webhookId}/replay re-sends them. New events are delivered again, with no change to the webhook, as soon as the workspace has an active subscription.
What stays available, and why
Your data belongs to you whether or not you pay. Without a subscription you can still:
- read contacts, calls, conversations, transcripts, the audit log and the agent action ledger;
- export that data (
calls,contacts,conversations,agent_actions,audit_log) and download exports; - remove configuration that holds a credential or points outside Jelliu: delete webhooks, MCP servers and MCP server assignments;
- use erasure and compliance endpoints, manage API keys, and use the billing routes to choose a plan.
The line is drawn so that stopping payment never traps data inside Jelliu: what is refused is new work and new outbound traffic, never access to, portability of, or removal of what the workspace already has.
In-product AI credits
The dashboard’s AI assistant and prompt generator have their own weekly budget, separate from agent replies. GET /api/billing/ai-usage returns it in credits (1 credit is 1,000 tokens):
limit and remaining are -1 when unlimited. When a budget is used up, those features return 429 AI_WEEKLY_CAP_REACHED with metadata.kind, metadata.tier, metadata.weekStart and metadata.limitTokens. Your agents keep working.
Invoices and charges
GET /api/billing/invoices and GET /api/billing/charges return the 24 most recent items, newest first. Amounts are in the smallest currency unit (cents).
Both return [] if the workspace has no billing account yet. Responses are sent with Cache-Control: no-store.
Changing the plan and buying add-ons
Choosing or changing a plan, buying minute packs, agent add-ons or extra phone numbers, and managing cards are done in the dashboard under Settings → Plan. These operations are restricted to the workspace owner and the billing role, are not available through the MCP server, and several of them hand off to a hosted payment page that a person must complete. Do not automate them from an integration.
A good integration pattern: read /api/billing/limits once when your integration starts (and again after any BILLING_ERROR), check /api/billing/usage before launching a large campaign, and surface BILLING_ERROR messages to an administrator with a link to Settings → Plan rather than retrying.
Errors
BILLING_ERROR is not retryable: the same request fails until the plan, the usage window or the resource count changes.

