SpendGuard
A 2-line wrapper around your OpenAI or Anthropic client that blocks an over-budget API call before it happens — no surprises at the end of the month.
from spendguard import SpendGuard
guard = SpendGuard(workspace="my-app", ceiling_usd=20.0)
client = guard.wrap_openai(OpenAI()) # or wrap_anthropic(Anthropic())
# Call the client exactly as normal — SpendGuard intercepts transparently.
# If the estimated cost would push cumulative spend past 25% of the $20 ceiling,
# it raises BudgetExceededError before the API call is made.
response = client.chat.completions.create(model="gpt-4o", messages=[...])
Install
pip install spendguard
For more accurate pre-call token counting on OpenAI models:
pip install spendguard[tiktoken]
How it works
SpendGuard wraps your existing client object. Every call goes through two steps:
- Pre-call estimate — approximates the input token count and adds the max output tokens × the model's per-token rate. If
cumulative_spend + estimate > ceiling × threshold_pct, it raisesBudgetExceededErrorbefore the network call. - Post-call commit — reads the provider's actual usage numbers from the response and records the real cost.
The default threshold is 25% of the ceiling (threshold_pct=0.25). This means a single call can consume at most 25% of your monthly budget — it is a guardrail against a single runaway call, not a hard cap at 100%.
Supported providers and models
| Provider | Client wrapper | Models gated by default |
|---|---|---|
| OpenAI | wrap_openai() |
gpt-4o, gpt-4o-mini, and all models in the pricing config |
| Anthropic | wrap_anthropic() |
claude-3-5-sonnet, claude-3-opus, haiku, and all models in the pricing config |
Usage
Basic setup
from openai import OpenAI
from spendguard import SpendGuard
guard = SpendGuard(workspace="my-product", ceiling_usd=20.0)
client = guard.wrap_openai(OpenAI())
try:
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}],
max_tokens=512,
)
except BudgetExceededError as e:
print(f"Blocked: {e}")
Anthropic
from anthropic import Anthropic
from spendguard import SpendGuard
guard = SpendGuard(workspace="my-product", ceiling_usd=20.0)
client = guard.wrap_anthropic(Anthropic())
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
)
Overriding a block on purpose
When you explicitly want to allow a call that would be blocked (e.g., a one-time large batch job), use track() with override=True:
with guard.track(override=True):
response = client.chat.completions.create(...) # never blocked
The override only applies inside the with block and does not persist.
Inspecting current spend
summary = guard.get_summary()
# {"ceiling_usd": 20.0, "spent_usd": 1.23, "reserved_usd": 0.0, "threshold_pct": 0.25}
Workspace isolation
Each SpendGuard instance is scoped to a workspace string. When you run multiple products or feature flags, give each its own workspace so their budgets are tracked independently.
Out of scope for v0.1
- Streaming calls (
stream=True) — explicitly rejected with a clear error. - Embeddings, images, audio, and other non-chat/messages endpoints.
- Persistent spend across process restarts (resets on
SpendGuard()construction).
Persistence and streaming support are planned for v1.0.
Feedback
Found a bug or have a feature request? Open an issue — all feedback welcome.
License
MIT
Metadata
Release files for spendguard 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| spendguard-0.1.0.tar.gz | 18.3 kB | With provenance | Details for spendguard-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| spendguard-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for spendguard-0.1.0-py3-none-any.whl |
Total release size: 37.9 kB
Release files / spendguard-0.1.0.tar.gz
| Download URL | spendguard-0.1.0.tar.gz |
|---|---|
| Size | 18.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2e1edd8e95a6f2a3648d13dc97cff6071329a5c6b6c8619fbb59fecdedfdb601
|
|
BLAKE2b-256 checksum How to use checksums |
21d9f6a0d064dc3be78710d63d8483474f035a71fdb7976ec73087ed834e15c1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 28, 2026.
Transparency logRelease files / spendguard-0.1.0-py3-none-any.whl
| Download URL | spendguard-0.1.0-py3-none-any.whl |
|---|---|
| Size | 19.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
90526c95400e1cfde27a4561e587153f92bd9093de5f1b9e97345a8f0ed3d9c1
|
|
BLAKE2b-256 checksum How to use checksums |
cdd0a0d8429f34da94de815843764a7c1925531e5cac7dbdd5b4b9565325cdb2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 28, 2026.
Transparency logSecurity for spendguard 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for spendguard-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 28, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.