Skip to main content

Billing

Every instance is either fixed (a recurring subscription) or prepaid (one-time credit bundles) — chosen when you create it, and switchable later.

What counts as "one message"​

One outbound send = one credit, regardless of type. A text, an image, a location pin, and a contact card each cost exactly 1 credit either way. Inbound messages and webhook deliveries are never billed. A send that's rejected before being accepted (validation error, opted-out recipient, disconnected session) is never charged — only a send that's actually queued debits anything.

Free trial​

Every new account gets a free trial — no card required — with a daily send quota and no restriction on billing mode, capped at one instance for the duration of the trial. Check GET /trial-status any time:

{ "inTrial": true, "trialEndsAt": "2026-11-01T00:00:00Z", "daysRemaining": 12, "dailyMessageQuota": 50, "sentToday": 3 }

The dashboard shows a trial banner with a link to upgrade once it's running low.

Fixed monthly / yearly​

A subscription tied to one instance. Pick a cycle at checkout:

curl -X POST https://app.tarceel.com/instances/<instanceId>/billing/checkout \
-H "Authorization: Bearer <account token>" \
-H "Content-Type: application/json" \
-d '{"billingCycle": "yearly"}'

Returns a Stripe Checkout URL — redirect your customer there to complete payment. While the subscription is active, sends are unlimited (subject to normal anti-spam rate limiting). If a renewal payment fails, further sends are rejected with 402 until it's resolved.

Current pricing:

curl https://app.tarceel.com/billing/plan-pricing -H "Authorization: Bearer <account token>"

Prepaid credit bundles​

A one-time payment grants a fixed number of credits that never expire.

curl https://app.tarceel.com/billing/credit-bundles -H "Authorization: Bearer <account token>"
{ "bundles": [{ "id": "...", "credits": 1000, "price": 5.00, "currency": "usd" }] }
curl -X POST https://app.tarceel.com/instances/<instanceId>/billing/checkout \
-H "Authorization: Bearer <account token>" \
-H "Content-Type: application/json" \
-d '{"bundleId": "<id from the list above>"}'

The balance only ever goes up via a completed payment, and down by exactly 1 per successfully sent message. At zero, sends are rejected with 402 until topped up — never silently queued.

Low-balance warning​

When a send drops the balance to or below the low-balance threshold (defaults to 20 credits) for the first time since the last top-up, a billing.low_balance webhook event fires once.

Checking usage​

curl https://app.tarceel.com/instances/<instanceId>/billing \
-H "Authorization: Bearer <account token>"
{ "billingMode": "prepaid", "creditBalance": 842, "lowBalanceThreshold": 20, "subscriptionStatus": null }
curl https://app.tarceel.com/instances/<instanceId>/billing/charges?limit=20 \
-H "Authorization: Bearer <account token>"

Returns a per-message charge ledger, most recent first — useful for reconciling exactly what each credit was spent on.

Self-serve billing management​

All of the following are account-auth routes under /instances/:instanceId/billing/... (or the equivalent dashboard Billing tab):

ActionWhat it does
Switch cycle (monthly ↔ yearly)Any amount owed is charged immediately — never deferred to a later invoice. A preview route (GET .../billing/preview-cycle-change) shows the exact amount before you commit.
Switch to pay-as-you-goCancels the subscription and credits any unused time toward your account balance, applied automatically to your next charge.
Switch to fixedConverts remaining prepaid credit into account balance, applied to the new plan's first charge.
Manage payment method / download receiptsPOST .../billing/portal hands you a link to Stripe's own hosted Billing Portal — Tarceel never touches your card details directly.
Invoice historyGET .../billing/invoices — works for both fixed (real Stripe invoices) and prepaid (purchase receipts).

Every one of these is previewed before you commit — the dashboard always shows the exact charge/credit amount in a confirmation dialog first.