Receipts for your AI API calls.

Tabslip runs locally between your app and its AI provider. It keeps signed receipts with the usage and cost your provider reports.

Free and open source for Linux, macOS and Windows.

Set up with your coding agent

Copy this into your coding agent inside the project you want to connect.

Set up Tabslip for this project.
Use https://github.com/vincentsch/tabslip: read its AGENTS.md and follow
the steps. Route this project's AI API calls through it, make one real call,
and show me the receipt.

Your provider and keys stay the same. The agent makes one call that may cost money, then shows you the receipt. What the agent changes

Calls · tabslip demo Full image Full image
Calls page with simulated demo calls: models, tokens, costs, timing and findings

What changes in my app?

Your app keeps its SDK and its API key. Start the gateway with tabslip serve, then point the SDK’s base URL at a local Tabslip route. The call goes on to the same provider.

  • OpenAI /openai/v1
  • Anthropic /anthropic
  • OpenRouter /openrouter/v1
  • Ollama /ollama/v1

Default gateway http://127.0.0.1:4545

Connection options

Start the gateway

tabslip serve

OpenAI Python

from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:4545/openai/v1")
response = client.chat.completions.create(
    model="gpt-4.1", messages=[{"role": "user", "content": "Hello"}])
print(response.choices[0].message.content)

OpenAI JavaScript

import OpenAI from 'openai';
const client = new OpenAI({baseURL: 'http://127.0.0.1:4545/openai/v1'});
const response = await client.chat.completions.create({
  model: 'gpt-4.1', messages: [{role: 'user', content: 'Hello'}]});
console.log(response.choices[0].message.content);

Anthropic Python

from anthropic import Anthropic
client = Anthropic(base_url="http://127.0.0.1:4545/anthropic")
response = client.messages.create(model="claude-sonnet-4-6", max_tokens=64,
    messages=[{"role": "user", "content": "Hello"}])
print(response.content[0].text)

These snippets call your provider and may cost money. The Anthropic SDK adds /v1/messages itself, so its base URL leaves out /v1.

What is on a receipt?

Your Tabslip signs each receipt with an Ed25519 key created on your computer. The receipt separates what the provider reports from what Tabslip measures.

All receipt fields

Which model did the provider report?

The receipt keeps the model you requested and the one the provider reported. It flags a difference.

What did it cost?

Cost comes from the provider when available. Tabslip can also estimate it for supported providers.

How long did it take?

Tabslip measures how long each call takes, including the wait for the first byte.

Did the router use a fallback?

In this example you ask for demo/large and the provider reports demo/small. These responses are simulated. The receipt flags the fallback and the model difference.

For real OpenRouter calls, Tabslip can fetch the provider’s routing details afterward. It signs them separately and leaves the original receipt unchanged. If the lookup fails, the receipt stays usable.

Signed supplements
Receipt · tabslip demo Full image Full image
Simulated fallback receipt with its signed stamp, the requested and reported models and two findings

What did the calls cost?

The Spend page groups costs by model. You can also group them by upstream or tag. For direct OpenAI and Anthropic calls, Tabslip can also estimate the cost from a versioned price table.

Without a reported cost or a usable estimate, the cost is unknown. Unknown usage and cost never count as zero.

How costs are calculated

Reported spend · last 30 days

0.000603USD

8 calls · 5 with unknown cost

  • demo/small 3 calls 0.000603 USD reported
  • demo/messages 2 calls unknown
  • demo/embedding 1 call unknown
  • demo/error 1 call unknown
  • demo/no-usage 1 call unknown
Demo data from the Spend page. Unknown cost never counts as zero.

Can someone else check the receipts?

Export a signed bundle and your public key. The recipient checks the bundle offline, without contacting a provider.

They should confirm the key or its fingerprint with you through a separate channel. The key inside a bundle does not confirm its signer, so without a confirmed key the check ends with exit 11.

A valid signature shows the record has not changed since your Tabslip signed it. It does not prove the provider’s numbers, and the key owner can also invent a receipt.

Offline verification
terminal · tabslip demo
$ tabslip export --data-dir ~/projects/acme/demo-data --out calls.tabslip.json8 receipts · 2026-10-22T15:12:46.345Z → 2026-10-22T15:12:51.084ZTags: acme-shop, blog-toolModels: demo/embedding, demo/error, demo/large, demo/messages, demo/no-usage, demo/smallUpstreams: demoNo prompt or answer text is included.Wrote bundle to calls.tabslip.json.

exit 0

$ tabslip key export --data-dir ~/projects/acme/demo-data --out tabslip.pubWrote public key to tabslip.pub.

exit 0

$ tabslip verify calls.tabslip.json --data-dir ~/projects/acme/confirmed-recipient --key tabslip.pubSignatures: 9 of 9 envelopes valid.Signer: Trusted: the key matches the key you gave with --key.Limits: Model names, token counts and provider cost come from the provider. Tabslip did not check the model itself.

exit 0

$ tabslip verify calls.tabslip.json --data-dir ~/projects/acme/unconfirmed-recipientSignatures: 9 of 9 envelopes valid.Signer: Not confirmed: ask the sender for their public key or key id through another channel. Bundle signer: ts_2cfac7ca189be0ce.Limits: Model names, token counts and provider cost come from the provider. Tabslip did not check the model itself.

exit 11

Commands and results from the demo. Paths are shortened.

What stays on my computer?

Records stay on your computer. By default they hold metadata and body hashes, without prompt or answer text. API keys pass through and are never stored.

The gateway listens on 127.0.0.1 by default, the loopback address of your computer. There is no telemetry.

Metadata can still reveal details about your work. A hash can be compared with a known body; it is not encryption.

Storage and privacy

Network contacts

  • Your selected upstream receives the call with your credentials.
  • OpenRouter generation lookup can make up to three attempts total. Turn it off with enrich_openrouter: false.
  • tabslip prices update downloads LiteLLM’s public price file when you run it.
  • tabslip doctor makes key-free reachability checks to upstream roots and checks local health.
  • The shell installer downloads binaries and checksums from GitHub.

The built-in demo makes no external requests.

Questions

Which calls get receipts?

Tabslip records POST calls to the chat completions and Responses APIs. It also records embeddings and Anthropic Messages. All except embeddings support streaming. Other paths forward without receipts.

If the recording queue fills or a write fails, forwarding may still succeed. The page shows an unrecorded-call counter, which resets on restart. API coverage.

Does it change my requests?

Direct OpenAI and Ollama streaming chat can add stream_options.include_usage=true. The receipt records that change. OpenRouter requests stay unchanged. Tabslip forwards your credentials and does not retry provider calls. Forwarding behavior.

What do exports include?
  • Signed bundles keep the signatures for offline checks.
  • CSV, JSONL and HTML exports are unsigned.
  • No export includes locally stored prompt or answer text.
  • Interrupted calls can leave incomplete records. Capture limits explain what Tabslip can record.
Can I use it on Windows?

The shell installer supports Windows through Git Bash. For native Windows, download your architecture’s .exe and checksums.txt from GitHub Releases. Compare the full SHA-256 hash before running it, and confirm the publisher separately.

Can I run it on a server?

Tabslip can run beside your app on a server. Point the app at its local gateway and use SSH port forwarding to open the page on your computer. See server setup for the commands.

What does it cost, and what is the license?

Tabslip is free and open source under the MIT license. Your provider’s API charges still apply.

Try it without an API key

The demo starts its own gateway and sends eight simulated calls. Some show what happens when a call fails or usage is missing. Open the Page URL it prints to see the receipts.

Install Tabslip

curl -fsSL https://raw.githubusercontent.com/vincentsch/tabslip/main/install.sh | sh

If the installer prints a PATH command, run it first. Then start the demo:

Run the demo

tabslip demo