Using function calling to let a model call a couple of internally-metered functions (each call has a real cost behind it). The model is good about deciding when to call them, but I don’t have a clean way to say “this thread/run can spend at most $X before you need my confirmation” — it’s all enforced by me manually checking usage after the fact.

I know there’s usage-based billing alerts at the account level, but that’s aggregate, not per-run or per-agent. Is there a recommended pattern for enforcing a spend ceiling scoped to a single run or a single user session, short of writing my own accounting layer around every function call?

Would also be curious if anyone’s tried this with the Assistants API’s function calling vs. raw chat completions — does one make it easier to intercept before the call executes?

Hi and welcome to the community!

Please note:

The API will be shut down and removed on August 26, 2026. OpenAI recommends migrating existing integrations to the Responses API before then.

Here’s the official Assistants API → Responses API migration guide:

On your second question first: raw chat completions (or Responses) is easier,
and it isn’t close. You’re the one running the tool loop there, so there is no
interception step - you just don’t call the paid thing until you’ve checked the
budget. Assistants puts its own run lifecycle in the middle. You can still catch
it at requires_action before you submit_tool_outputs, but you’re working inside
their orchestration rather than your own.

For the confirmation part, don’t cancel the run when it goes over. Cancelling
leaves the user with an answer that stops and nothing on screen saying why. We
check the budget before executing, and if it’s over we submit a tool output like
{“error”: “budget_exceeded”, “spent”: 4.10, “limit”: 5.00} and let the model
explain it in its own words. The approval case is the same shape: hold the call,
show the user the arguments and what it will cost, then either run it and submit
the real result, or submit the refusal.

Worth adding since the reply above is about migrating: all of this lives in your
code rather than the API, so it carries over to Responses unchanged.

Yuk!

Build a quota system that automatically if retrospectively costs every round.

You’ll have to accept that it might go over quota in a single round, but at least you can detect that and stop further spend and perform whatever mitigation you prefer (rate limits or lower model or reasoning quality)

I did that in my Discourse Chatbot.

An AI bot with RAG capability for Topics, Chat & Customer Support in Discourse, currently powered by OpenAI