marginal-sdk
Marginal SDK for Python — send AI cost events and see where your AI spend goes, sliced by customer, feature, environment, model, or any field you define.
pip install marginal-sdk
Python 3.9+, stdlib only (zero dependencies).
Quickstart
One call per LLM request: name the provider, paste the response's model and
usage — Marginal detects the provider's usage shape and computes the cost
server-side against its model price catalog.
import os
from marginal import Marginal
marginal = Marginal(api_key=os.environ["MARGINAL_API_KEY"])
response = client.chat.completions.create(...)
marginal.track(
provider="openai",
model=response.model,
usage=response.usage.model_dump(),
fields={"customer": "acme-corp", "feature": "support-bot"},
)
For non-LLM spend (voice, images, pre-computed costs), send dollars directly:
marginal.track(cost=0.05, fields={"customer": "acme-corp"})
track() is synchronous and never raises: events are buffered and flushed by
a daemon worker thread (every 5 s or at 100 events), with retries on network
errors, 429s, and 5xx. Errors are reported to an on_error callback (a
warning print by default). Buffered events are flushed automatically at
interpreter exit; call marginal.flush() to force one earlier. Fork-safe:
the worker restarts in the child after os.fork().
Delivery guarantees
Best-effort, at-most-once. Events are buffered in memory (no disk
persistence), so a hard crash — kill -9, OOM, an unhandled exception —
loses what's still buffered: at most ~5 seconds or 100 events with the
defaults. On a clean interpreter exit the remaining events are flushed via
atexit (disable with flush_on_exit=False). Note that atexit does not
run on an unhandled SIGTERM — call marginal.shutdown() from your own
signal handler if you need that. A batch whose retries are exhausted is
dropped and reported through on_error — the SDK never blocks or crashes
your app to save an event. Every event carries an event_id idempotency key
(a UUID stamped at track() time, or pass your own), so a retried batch
whose response was lost after the server accepted it never lands twice
(0.2.0+, 30-day dedupe window).
Options
Marginal(
api_key="mgl_...", # required — server-side only
on_error=lambda err: ..., # delivery/validation errors (never raised)
flush_on_exit=True, # default; False disables the atexit flush
base_url="https://api.marginalhq.com", # default
)
Docs
- Quickstart
- Event shape & API
- Integrations cookbook — OpenAI, Anthropic, Gemini, Bedrock, streaming
- llms.txt — paste into your coding assistant to instrument a codebase automatically
Metadata
Release files for marginal-sdk 0.2.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 | |
|---|---|---|---|
| marginal_sdk-0.2.0.tar.gz | 17.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| marginal_sdk-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 27.5 kB
Release files / marginal_sdk-0.2.0.tar.gz
| Download URL | marginal_sdk-0.2.0.tar.gz |
|---|---|
| Size | 17.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8afda766980b823a170e972cb44de41aec7d302b2e7b7a77efb03166ba954312
|
|
BLAKE2b-256 checksum How to use checksums |
31ce7117233537d4e5477bf7ef74396ca6dbb3ee241a800a5dd942744d327ecc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.15
|
Release files / marginal_sdk-0.2.0-py3-none-any.whl
| Download URL | marginal_sdk-0.2.0-py3-none-any.whl |
|---|---|
| Size | 9.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cc519e2581139fa370aec1639bd9f10c0802d691ff0beefac3d624f2dfa836ea
|
|
BLAKE2b-256 checksum How to use checksums |
24b6e018be080a531aed56d1f691d9c59612c98553d82de3bcf8f6342e9b86d4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.15
|