Fluxio
← Retour au blog

Billing When a User Closes the Tab Mid-Stream

Le prix des tokensEN

§1 Step 1: Define What a Disconnected Stream Means

A user starts an AI response, reads several lines, and closes the tab. Your billing workflow needs an explicit rule for that interruption. Do not define a charge simply as whatever text appeared on screen. For example, OpenAI documents that an interrupted stream may never deliver its final token-usage summary. Missing usage is therefore not evidence of zero usage. ([help.openai.com](https://help.openai.com/en/articles/10478918-reviewing-api-usage-and-costs?utm_source=openai))

Separate two decisions: what your upstream provider charges your application, and what your application charges its customer. Adopt a written customer policy for interrupted requests, including how you handle pending usage, credits, and retries. Avoid promising that closing a tab instantly stops every charge unless you have verified that behavior across your entire request path.

§2 Step 2: Create a Billing Record Before Streaming

Before opening the upstream stream, create a durable request record. Give the logical user action its own identifier, then assign a separate attempt identifier to each upstream execution. This design lets you distinguish a reconnect from a genuinely new generation.

  • – Record the account, conversation, selected model, and applicable pricing version.
  • – Store upstream request identifiers when available for later reconciliation.
  • – Track connection state separately from generation state and billing state.
  • – Reserve a bounded amount of credit if your product uses prepaid balances.

Treat reserved credit as a temporary hold, not a completed charge. Plan to release the unused portion when the request settles.

§3 Step 3: Propagate the Disconnect Upstream

Make cancellation a backend responsibility rather than relying on a final browser message. In a Node.js HTTP server, the response close event can indicate either normal completion or premature connection termination. Check completion state before treating it as an interruption. ([nodejs.org](https://nodejs.org/api/http.html))

On premature closure, mark the request as disconnected and trigger the cancellation mechanism supported by your upstream client. Node.js documents AbortSignal support for outgoing HTTP requests, providing one building block for this propagation. ([nodejs.org](https://nodejs.org/api/http.html))

Record cancellation as requested until you have stronger evidence of the terminal outcome. For a reconnectable product, consider a short, bounded grace period instead of immediate cancellation. Make that a deliberate product policy, with a spending limit, rather than an accidental consequence of backend behavior.

§4 Step 4: Capture Usage Without Depending on the Browser

Collect billing evidence on the server. For OpenAI Chat Completions, setting stream_options.include_usage to true requests an additional usage-bearing chunk near the end of the stream. Keep that accounting path independent of whether the browser remains connected. ([developers.openai.com](https://developers.openai.com/cookbook/examples/how_to_stream_completions?trk=article-ssr-frontend-pulse_little-text-block&utm_source=openai))

Still design for missing final usage: the API reference explicitly warns that interruption or cancellation can prevent that chunk from arriving. Put such requests into a pending-reconciliation state instead of automatically charging zero or inventing a final token count. ([developers.openai.com](https://developers.openai.com/api/reference/resources/chat/subresources/completions/streaming-events))

Prefer authoritative usage records when your provider makes them available. Keep any locally calculated estimate clearly labeled and separate from settled usage. If authoritative reconciliation is unavailable, apply your disclosed fallback policy and retain an audit trail.

§5 Step 5: Settle Each Attempt Once

Use an idempotent settlement operation keyed to the attempt identifier. Have it record confirmed usage, calculate the charge using the saved pricing version, and release any remaining credit hold. Prevent duplicate settlement events from creating duplicate ledger entries.

When a user returns, first check the existing request state. Reattach to saved output where your architecture supports it. If a new generation is necessary, create another attempt and make the distinction visible rather than silently treating it as a free continuation.

§6 Step 6: Validate Fluxio Routes and Interrupted Charges

Fluxio is worth considering when you want a streaming-first, pay-per-token relay with one key across multiple model providers. Use that shared integration point to standardize your request ledger, but verify cancellation behavior and usage reporting for each route before publishing billing guarantees. OpenAI-style compatibility alone should not be your acceptance criterion.

Test tab closure before the first token, halfway through output, and just before completion. Also test lost connections, delayed cancellation, missing usage, and repeated settlement events. Require every test to end with an explainable request state, charge, and released credit balance.

Sign up for Fluxio to build your streaming integration.

Créer un compte Fluxio →

Plus d'articles du courant