Skip to content

Quickstart

View as Markdown

Send one AI call and see what it cost. This takes about five minutes.

Sign up at app.ai-tally.com. When asked, create an organization. An organization is your team’s shared space in ai-tally. You are its admin.

In the dashboard, open API Keys under Organization. Type a name, leave Scope set to write, and click Create key.

Copy the key right away. It is shown only once. In your terminal, save it:

export TALLY_KEY="paste-your-key-here"

Pick one of the ways below. You only need one.

Python app, no code change: tally run (preview)

Section titled “Python app, no code change: tally run (preview)”

tally run records the AI calls of a Python app with no change to its code. It is a preview, so its options and output may change.

Save this as first_call.py. It is a plain OpenAI call with no ai-tally code in it:

from openai import OpenAI
reply = OpenAI().chat.completions.create( # reads OPENAI_API_KEY
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Say hi"}],
)
print(reply.choices[0].message.content)

Install the SDK in the same environment, then put tally run -- in front of the command that runs it. It needs Python 3.10 or later.

Terminal window
pip install ai-tally openai
tally run -- python first_call.py

The script prints its reply as usual, and a line on stderr says what tally run records. The call is sent to ai-tally when the script exits.

For your real app, put tally run -- in front of the command that starts it, in the one place you start it today:

  • Shell, script or systemd: tally run -- uvicorn main:app --host 0.0.0.0
  • Dockerfile: CMD exec tally run -- uvicorn main:app --host 0.0.0.0. Docker is optional.
  • Procfile: web: tally run -- gunicorn app:app

To set a variable or change directory first, write env VAR=1 tally run -- ... or cd app && exec tally run -- ....

tally run records your openai, anthropic, google-genai and Bedrock calls, and Celery and RQ jobs. It names each feature after your web route, and a tally.toml setting tells it where your customer id is. It sends counts, costs and hashed ids. Your prompts and answers stay in your app. Set TALLY_DISABLED=1 to turn it off with the same command. The Python SDK page has the settings and the details.

The SDK can also be set up in code, with one line at startup. It then records your OpenAI, Anthropic, Gemini and Bedrock calls in the background, and your calls run exactly as before.

Save this as first_call.py, then run python first_call.py. It needs Python 3.10 or later.

# pip install ai-tally openai
import aitally
from openai import OpenAI
aitally.init() # reads your key from TALLY_KEY
reply = OpenAI().chat.completions.create( # reads OPENAI_API_KEY
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Say hi"}],
)
print(reply.choices[0].message.content)
aitally.flush() # sends the record right away

The package is called ai-tally, and you import it as aitally.

With the proxy, your app sends its AI requests through ai-tally on their way to the AI provider. ai-tally reads what each call used, then passes the call on unchanged.

  1. On the API Keys page, turn on Zero-code proxy. It starts off for every new organization.
  2. Wait about a minute. That is how long a new key and the switch take to reach the proxy.
  3. Run the curl below, using your own OpenAI key. It is the same example the dashboard shows you when you create a key. Put the key you saved in step 2 where it says YOUR_TALLY_KEY.
Terminal window
# Point the OpenAI SDK at the AI Tally proxy
export OPENAI_BASE_URL="https://ingest.ai-tally.com/openai/v1"
# AI Tally identifies your org by this ingest key, sent as the X-Tenant-Key header:
# X-Tenant-Key: YOUR_TALLY_KEY
# e.g. a raw request:
curl "https://ingest.ai-tally.com/openai/v1/chat/completions" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "X-Tenant-Key: YOUR_TALLY_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"hi"}]}'

A brand-new key can take a few seconds to attribute while the proxy picks it up. Your provider key is forwarded to the provider unchanged and is not recorded. On the proxy path it does reach AI Tally in transit; the SDK and OpenTelemetry paths never send it at all.

The only differences from a normal OpenAI call are the URL and the X-Tenant-Key header. Anthropic and Gemini work the same way.

Because the call now goes through ai-tally, your Authorization header reaches the proxy. The proxy forwards it to OpenAI unchanged and does not record it or log it. To keep your provider key entirely inside your own infrastructure, use the Python SDK or OpenTelemetry: both send their records separately, so your provider key stays with you.

OpenTelemetry is a common standard for tracing, which means recording what your app does. If your app already sends traces, ai-tally can read the AI calls in them.

To try it without touching your app, send one sample trace. It describes one gpt-4o-mini call that used 12 input tokens and 5 output tokens. Tokens are the units AI providers charge for.

Terminal window
curl https://ingest.ai-tally.com/v1/otlp/traces \
-H "Authorization: Bearer $TALLY_KEY" \
-H "Content-Type: application/json" \
-d '{"resourceSpans":[{"scopeSpans":[{"spans":[{
"traceId":"5b8efff798038103d269b633813fc60c","spanId":"eee19b7ec3c1b174",
"name":"chat","startTimeUnixNano":"'"$(date +%s)000000000"'",
"attributes":[
{"key":"gen_ai.system","value":{"stringValue":"openai"}},
{"key":"gen_ai.operation.name","value":{"stringValue":"chat"}},
{"key":"gen_ai.request.model","value":{"stringValue":"gpt-4o-mini"}},
{"key":"gen_ai.usage.input_tokens","value":{"intValue":"12"}},
{"key":"gen_ai.usage.output_tokens","value":{"intValue":"5"}}]}]}]}]}'

A reply that includes "status": "accepted" means ai-tally stored it.

In the dashboard, open Setup under Configure. It shows First trace received. Then open Cost Explorer under Diagnostics. Your call is listed under LLM, with its cost.