sipi.bot integration
sipi.bot + Google Gemini API
Integrate sipi.bot with the Google Gemini API. sipi.bot enforces per-call cost ceilings, daily budget caps, and multi-turn conversation spend limits on Gemini calls.
Very large context changes which rule matters
Most spend advice assumes many small calls. Gemini's long context windows break that assumption: a single request carrying a large document can cost more than hundreds of ordinary calls put together. If your only protection is a rate limit, one call slips through it untouched and the rate limit was never the control you thought it was.
On this integration per_transaction does the load-bearing work. It is
the rule that notices a single request is enormous, which is precisely the failure
mode a long-context model makes cheap to trigger and expensive to survive.
Retrieval turns a bug into a bill. When context is assembled programmatically, a retrieval step that returns too much does not raise an error. It just makes the next call larger, and it will keep doing so every time it runs.
Context caching is a second cost axis
Cached context is billed for how long it is stored, not only for the calls that use it. A cache created and forgotten keeps costing money while your agent does nothing at all — and that spend never passes through a per-call check, because there is no call to intercept.
Record cache creation as its own transaction with its own category, and treat cache lifetime as a budget decision rather than an implementation detail. This is the one part of a Gemini integration where a pre-call firewall genuinely does not help by itself, and it is better to say so than to imply coverage that is not there.
Wiring the check in
import requests
from google import genai
client = genai.Client()
def guarded_generate(model, contents, **kw):
d = requests.post(
"https://sipi.bot/v1/transactions/evaluate",
headers={"Authorization": f"Bearer {SIPI_KEY}"},
json={"amount": price_context(model, contents),
"merchant": "google", "category": "llm",
"description": f"{model} ctx={token_count(contents)}"},
timeout=5,
).json()
if d["decision"] != "APPROVED":
raise RuntimeError(f"{d['decision']}: {d['reason']}")
return client.models.generate_content(
model=model, contents=contents, **kw)
Count the context before you price it. On a long-context model the token count is the whole story, and an estimate that ignores it is not an estimate.
Rule priorities for Gemini
| Rule type | What it does on this integration |
|---|---|
per_transaction | First priority. One long-context call is the characteristic expensive event on this integration. |
category_limit | Keeps context-cache storage on a separate budget line from generation, since the two accrue differently. |
daily_total | Bounds the aggregate when many medium-sized calls each stay under the per-call ceiling. |
approval_threshold | Sends the genuinely large document run to a human rather than blocking work that may well be justified. |
The free-tier trap
Development against a free tier teaches you nothing about production cost, and the switch to a billed key is usually a one-line change made by someone who is not thinking about spend at that moment. The same code that was free on Friday can bill on Monday. Put the policy in place while it is still free — that is the cheapest time to discover your estimates are wrong.
Questions
Does the check understand multimodal input?
Only through the amount you submit. Images, audio and video convert to tokens at their own rates, so price them with the provider's current conversion before submitting rather than assuming a text-token equivalence.
Can I cap spend per document instead of per call?
Give the document-processing path its own agent identity. Its ceiling then applies to the whole job rather than to any one request inside it.