Skip to the content
wetalk
Start free

Billing

Credit, minutes and limits

Thirty euro an hour, counted by the second, spent only while an agent is actually talking. Everything below is in integer minor units with the currency beside it — never a float, never a bare cents number.

Paths, field names, enum values, headers and error codes in these samples are the real ones, checked against the API's own specification when this page is built. The ids, amounts and names in them are illustrative. `$WETALK_API_KEY` and `$AGENT` are shell variables you set yourself.

How talk time is counted

A conversation's billed seconds run from the moment the agent answers to the moment it ends. Ringing, queueing and holding are free — they are either before the answer or excluded outright. A voice test call is billed like any other minute and marked as a test in the analytics; a text test chat is free.

Pricing happens once a day, per agent, per day, per medium, and separately for tests. That is deliberate: pricing every conversation on its own would accumulate hundreds of separate roundings into a balance that does not reconcile. A two-minute twenty-two-second conversation contributes exactly 142 seconds to the day it belongs to.

  • talk_rate_minor_per_minute is 50 — EUR 0.50 a minute, EUR 30 an hour.
  • Every amount is amount_minor plus currency. The currency is EUR.
  • Rounding is a column in the price book, not a constant in the code.
GET /v1/billing/usage
curl -G https://api.wetalk.io/v1/billing/usage \
  -H "Authorization: Bearer $WETALK_API_KEY"
  --data-urlencode "from=2026-09-01" \
  --data-urlencode "to=2026-09-30"

Two balances, and only one of them stops a call

`balance_minor` is what has been charged and settled. `available_minor` is that figure minus today's unbilled seconds and minus what conversations still running have reserved. The second one is what the admission controller checks, so it is the one that decides whether the next caller is answered.

A trial grant is spent before credit is touched, which is why a trial account's balance does not move until the free seconds run out.

  • state is one of trial, in_credit, exhausted or hard_stopped.
  • exhausted and hard_stopped are different: one ran out, the other was switched off.
  • trial_second_remaining counts the free seconds left on the grant.
GET /v1/billing/balance
curl https://api.wetalk.io/v1/billing/balance \
  -H "Authorization: Bearer $WETALK_API_KEY"
What comes back
{
  "data": {
    "balance_minor": 15900,
    "unbilled_today_minor": 450,
    "reserved_minor": 200,
    "available_minor": 15250,
    "currency": "EUR",
    "trial_second_remaining": 0,
    "talk_rate_minor_per_minute": 50,
    "hard_stop_enabled": true,
    "state": "in_credit",
    "computed_at": "2026-09-14T19:22:31Z"
  }
}

Budgets, hard stops and auto-reload

A budget is a monthly amount, an alert threshold as a percentage, and a switch that decides whether hitting it stops the agents or only tells you. A hard stop pauses answering rather than overspending, and lifts the moment you raise the budget.

Auto-reload tops up by a fixed amount when the available figure falls below your threshold, charged to a saved card, with a monthly cap. The cap must be at least one top-up: a cap smaller than the top-up is a policy that can never charge, which would fail silently and is refused instead.

PUT /v1/billing/budget
curl https://api.wetalk.io/v1/billing/budget \
  -X PUT \
  -H "Authorization: Bearer $WETALK_API_KEY"
  -H "Content-Type: application/json" \
  -d '{
    "month_budget_minor": 50000,
    "alert_threshold_percent": 80,
    "hard_stop_enabled": true
  }'
PUT /v1/billing/auto-reload
curl https://api.wetalk.io/v1/billing/auto-reload \
  -X PUT \
  -H "Authorization: Bearer $WETALK_API_KEY"
  -H "Content-Type: application/json" \
  -d '{
    "enabled": true,
    "threshold_minor": 2000,
    "top_up_minor": 20000,
    "monthly_cap_minor": 100000,
    "payment_method_id": "0199f1c2-6b4a-7f9c-9add-c3a45fc618cb"
  }'

When money says no

Billing refusals are ordinary errors with their own codes, and they are worth handling separately because they are the ones a retry cannot fix. `payment_outcome_ambiguous` in particular means *go and look up what happened* — never *try again*: the reference we send the processor gives duplicate rejection, not idempotency, so a blind retry is how somebody gets charged twice.

  • credit_exhausted, trial_exhausted — nothing left to spend.
  • hard_stop_reached, budget_exceeded — a limit you set.
  • payment_declined, payment_requires_action, payment_requires_reauth — the card.
  • payment_outcome_ambiguous — look it up; do not retry.
GET /v1/billing/ledger
curl -G https://api.wetalk.io/v1/billing/ledger \
  -H "Authorization: Bearer $WETALK_API_KEY"
  --data-urlencode "limit=100"

How many at once

Your tier sets a ceiling on how many conversations run at the same time across the whole workspace, and each agent's own ceiling is part of its live version. A caller who arrives beyond the ceiling is queued, not turned away, and inbound callers are never displaced by outbound dialling.

GET /v1/agents/{voice_agent_id}/concurrency
curl https://api.wetalk.io/v1/agents/$AGENT/concurrency \
  -H "Authorization: Bearer $WETALK_API_KEY"