Contents

Run it

Billing

Plan IDs are configuration values, not the names shown on the public pricing page. Billing is off unless billing.plan is set and metering.db is configured.

Config plan IDs

Plan IDIncluded usage
free50 replies per UTC day; the avatar shows a watermark
streamer20,000 replies and 20 hours of TTS per UTC month
studioUnlimited replies, up to 10 personas, and the API flag

billing.plans merges overrides onto these defaults. For example:

{
  "billing": {
    "plan": "free",
    "plans": {
      "free": {
        "replies_per_day": 30
      }
    }
  }
}

Usage limits

At 80% usage, one heads-up is included with a reply. At 100%, one plan-used-up message is sent, then the bridge is silent until the next period. Both notices pass through JEV. The limits.max_replies_per_hour and limits.max_tts_seconds_per_day caps still apply.

Webhooks and payment provider

The webhook is POST /billing/webhook on the dashboard listener. Sign requests with Stream-Mate-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, "<t>.<body>")>; timestamps are accepted within five minutes. The JSON body contains id, account, plan, and days. Set BILLING_WEBHOOK_SECRET to at least 16 bytes or every webhook is rejected.

Only the stub provider exists; live payments are not wired. A webhook replay with the same ID is a no-op. Repeating the current plan extends it from paid_until; a different plan starts immediately. After expiry, billing returns to billing.plan.

Usage report

Run -usage-report for a month to write a JSON report with totals by channel and plan and payment data.

./bridge -config config.json -usage-report 2026-10