Mihe

Usage and billing

See what your app spends, and read it from your own backend to bill your users.

Credit

Mihe is prepaid. Your organisation buys credit, and every typed turn and every second of voice is taken from it at the prices on the pricing page. There are no plans, seats or monthly fees. The dashboard's Billing page shows the balance, what each app and each mode has spent, and your payments.

  • Before it runs out, choose the balances you want to be warned at, and every owner is emailed as each is crossed.
  • If it runs out, the assistant stops answering in your apps and tells your users to ask an administrator. Nothing else in your app is affected, and it answers again as soon as you top up.

The usage pages

Each app has a Usage tab, and the organisation has a Usage page across all its apps. They list every typed turn and voice session with what it used:

  • tokens in, cached and out, split into text and audio;
  • voice seconds and the seconds transcribed;
  • the voice tier;
  • the cost.

Filter by date, typed or spoken, voice tier, your user id, conversation or app, and by a minimum and maximum on any metric. Sort by any metric, group the totals by day, user, conversation, kind, tier or app, and export what you have filtered as CSV.

The organisation's page is for members who can see all of its apps. A member limited to some apps uses each app's tab.

What a screen costs

Every answer re-sends the assistant's instructions, the definition of each tool the user may call on that screen, and what the screen declares. In a typed conversation most of it is cached and costs little. In voice it is re-sent on every spoken answer, so a large screen makes every voice minute dearer.

Turn on debug while you build to see the size of each screen in the browser console:

<AssistantProvider debug={process.env.NODE_ENV === "development"} /* … */ />

After each screen change it logs something like:

[mihe] Each answer on `orders.list` re-sends about:
  typed: 6,410 tokens — instructions 2,231, 38 tools 4,060, this screen 119
  voice: 8,279 tokens — instructions 2,231, 41 tools 5,952, this screen 96
  largest tools: mark_order_delivered 439, edit_draft_order_items 320, …

The figures are estimates, at about four characters a token. When a screen is large, it is almost always the tools: scope actions to the screens they belong on, and keep their descriptions and schemas to what the model needs. Leave debug off in production.

The usage feed

If you charge your own users for the assistant, read what each of them used from the usage feed. It lists every metered event, oldest first, with your own user id on it.

It takes a server key (srv_…), which you create on the app's page in the dashboard. The server key only reads usage. Do not use the secret key: that key can sign tokens for any user, and it has no business travelling on every request.

curl "https://runtime.mihe.dev/v1/usage/events?since=0&limit=100" \
  -H "Authorization: Bearer $MIHE_SERVER_KEY"
{
  "events": [
    {
      "id": 4812,
      "occurred_at": "2026-09-30T10:42:07+00:00",
      "kind": "chat_turn",
      "conversation_id": "conv_…",
      "turn_id": "turn_…",
      "external_user_id": "user_123",
      "input_tokens": 4012,
      "output_tokens": 231,
      "cached_input_tokens": 3008,
      "voice_seconds": 0,
      "cost_micro_usd": 17160
    }
  ],
  "next_cursor": 4812
}
  • kind is chat_turn or voice_session.
  • external_user_id is the sub from the token you signed.
  • cost_micro_usd is what the event cost you, in millionths of a dollar. It is the figure on your bill, so mark it up from there.

Polling

Poll on a timer. Keep the last next_cursor and send it back as since: you get everything after it, exactly once, in order. An empty page echoes your cursor, so there is nothing to special-case.

limit defaults to 100 and is capped at 1,000. Events appear a few seconds after they happen. Poll too fast and you get 429 with how long to wait.

The feed keeps working if an app is switched off or archived, so you can bill for its last month, and stops if the organisation is closed.

On this page