APIPurse
Open APIPurse

Support & documentation

Everything you need to connect your APIs, set budgets and get alerted before you overspend.

Note:The code examples on this page are sample code for illustration and general support only, provided as is without warranty. Review, test and secure them yourself before using them in production. See section 9 of the Terms of Service. Terms

Getting started

Create your account

APIPurse tracks what you spend on APIs such as OpenAI, Anthropic, Stripe, AWS and Twilio in one place, and warns you before you pass a budget.

The sign-up form. Illustration. Your screen may differ slightly.
  1. 1Open the sign-up page, enter your email and a password, tick the box to accept the Terms and Privacy Policy, and click Sign up.
  2. 2Open the confirmation email and click the link. If you cannot find it within a couple of minutes, check your spam folder.
  3. 3Log in. You will see an empty dashboard. The next step is to connect your first provider.
Tip:The Free plan includes one provider, budget alerts by email and 30 days of history. You can upgrade any time under Settings.

Reading your dashboard

The dashboard shows your total spend for the current month and one card per provider.

The dashboard with its summary and provider cards. Illustration. Your screen may differ slightly.
  • The top figure is the total across all providers, converted into your display currency, with a daily bar chart below it.
  • Each provider card shows spend so far, its budget, the number of requests and a progress bar. The bar turns amber when you pass your lowest alert threshold and red when you pass the highest.
  • Cards reset at the start of every calendar month. The Recent activity table lists individual line items.

Connect your APIs

Connect OpenAI

APIPurse reads your organisation's cost data through an Admin API key. A regular project key cannot read costs.

Connecting OpenAI under Settings. Illustration. Your screen may differ slightly.
  1. 1Ask the owner of your OpenAI organisation to create an Admin API key at platform.openai.com under Settings, Organization, Admin keys.
  2. 2In APIPurse, go to Settings and open Connect OpenAI. Give the connection a name, paste the key and optionally set a monthly budget and an alert threshold.
  3. 3Click Connect. The key is encrypted immediately and is never shown again.
  4. 4Usage syncs automatically every 6 hours. The first data can take up to 6 hours to appear.
Tip:For instant cost data and alerts, use real-time tracking (see Tracking & data).

Connect Anthropic

Same idea as OpenAI: you need an Admin API key, which starts with sk-ant-admin-.

Connecting Anthropic under Settings. Illustration. Your screen may differ slightly.
  1. 1An organisation owner or admin creates the key at console.anthropic.com under Settings, Admin keys.
  2. 2In APIPurse, go to Settings, open Connect Anthropic, name the connection and paste the key.
  3. 3Click Connect. Usage syncs automatically every 6 hours.

Connect Stripe

APIPurse tracks Stripe's own processing fees, meaning the amount Stripe keeps from each charge. It does not track your customers' payments.

Connecting Stripe with a restricted key. Illustration. Your screen may differ slightly.
  1. 1In your Stripe Dashboard go to Developers, API keys and create a restricted key.
  2. 2Give it only the permission Balance Transactions: Read. Do not use a full secret key.
  3. 3In APIPurse, go to Settings, open Connect Stripe and paste the restricted key.
  4. 4For instant tracking, click Set up real-time webhook on your Stripe provider. Copy the URL shown into Stripe under Developers, Webhooks, Add endpoint, select the charge.succeeded event, then paste the signing secret (starts with whsec_) back into APIPurse.
Tip:Each charge is recorded only once, even if Stripe delivers the same event again.

Connect AWS

APIPurse reads your total AWS bill (all services combined) through Cost Explorer. Use a dedicated IAM user, never your root account.

Connecting AWS with an IAM user. Illustration. Your screen may differ slightly.
  1. 1In the AWS Console go to IAM, Users, Create user (for example apipurse-readonly). Skip console access.
  2. 2Attach a custom policy with only the permission shown below.
  3. 3Open the user, go to Security credentials and create an access key. Copy the Access key ID and the Secret access key straight away, because the secret is shown only once.
  4. 4In APIPurse, go to Settings, open Connect AWS and paste both values.

Note: The code examples on this page are sample code for illustration and general support only, provided as is without warranty. Review, test and secure them yourself before using them in production. See section 9 of the Terms of Service.

IAM policy

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ce:GetCostAndUsage",
      "Resource": "*"
    }
  ]
}
Tip:Cost Explorer must be enabled in your AWS account (Billing, Cost Explorer). On a brand-new account it can take up to 24 hours.

Connect Twilio

APIPurse reads calls, SMS and other usage-based charges through Twilio's usage API.

Connecting Twilio. Illustration. Your screen may differ slightly.
  1. 1In the Twilio Console, copy the Account SID and the Auth token from the main dashboard.
  2. 2In APIPurse, go to Settings, open Connect Twilio and paste both.
  3. 3Usage syncs automatically every 6 hours.
Tip:You can use a Twilio API key with limited scope instead of your primary Auth token.

Add a custom or internal API

For any API that APIPurse does not connect to natively, add it manually and send usage from your own code.

A custom provider with its ID and your ingest token. Illustration. Your screen may differ slightly.
  1. 1Go to Settings, Add a provider (manual / custom). Enter a name, choose the type custom and optionally set a budget.
  2. 2Copy the provider ID from the list of providers, and your personal ingest token from the box near the top of Settings.
  3. 3Send usage from your code, a script or a scheduled job with a request like the one below. Send it per call, per batch or on any schedule. APIPurse simply adds up what you send.

Note: The code examples on this page are sample code for illustration and general support only, provided as is without warranty. Review, test and secure them yourself before using them in production. See section 9 of the Terms of Service.

curl

curl -X POST https://www.apipurse.com/api/ingest \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_INGEST_TOKEN" \
  -d '{"provider_id": "YOUR_PROVIDER_ID", "cost_usd": 0.42, "request_count": 12}'
Tip:Treat the ingest token like a password. Anyone who has it can write usage data to your account. If it is exposed, contact support.

Tracking & data

Real-time trackingPro and Team plans

The connectors sync every 6 hours. For instant costs and alerts, report usage yourself right after each API call.

  • Send the model name and token counts. APIPurse looks up the current price for that model and calculates the cost, so you never maintain pricing yourself.
  • This works for any model in LiteLLM's price list, including Mistral, Groq, Cohere, Bedrock, Azure OpenAI and Gemini. Add a custom provider with that name and send its model name.
  • Behind an API gateway or middleware? Buffer records and flush up to 1000 per request to the batch endpoint instead of one request per call.
  • Your prompts and completions never pass through APIPurse. Only the final cost report is sent.
Note:Costs calculated by real-time tracking are estimates. They use a third-party price list that is refreshed daily and the token counts you report. Your provider's own invoice and usage reports are always the authoritative source for what you owe.

Note: The code examples on this page are sample code for illustration and general support only, provided as is without warranty. Review, test and secure them yourself before using them in production. See section 9 of the Terms of Service.

curl

curl -X POST https://www.apipurse.com/api/track/completion \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_INGEST_TOKEN" \
  -d '{"provider_id": "YOUR_PROVIDER_ID", "model": "gpt-4o", "input_tokens": 512, "output_tokens": 128}'

batch

curl -X POST https://www.apipurse.com/api/ingest/batch \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_INGEST_TOKEN" \
  -d '{"records": [
    {"provider_id": "...", "cost_usd": 0.42, "request_count": 12},
    {"provider_id": "...", "cost_usd": 0.08, "request_count": 3}
  ]}'
Tip:Real-time tracking is available on Pro and Team.

SDKsPro and Team plans

Official SDKs exist for 7 languages. They remove the need to write the request yourself.

  • TypeScript, Python and Ruby: wrap your OpenAI or Anthropic client once at startup and every later call is reported automatically.
  • Java, C#, Go and PHP: create the client once and add one line after each completion call.
  • Each package has its own README with copy-and-paste examples.
LanguageAfter setupInstall
TypeScriptAutomatic: wrap your client oncenpm install @apipurse/sdk
PythonAutomatic: wrap your client oncepip install apipurse-sdk
RubyAutomatic: wrap your client oncegem install apipurse-sdk
JavaOne line after each completion callio.github.yelmorab:apipurse-sdk:0.1.0 (Maven)
C# / .NETOne line after each completion calldotnet add package Apipurse.Sdk
GoOne line after each completion callgo get github.com/yelmorab/apipurse-sdks/sdk-go/apipurse@v0.1.0
PHPOne line after each completion callcomposer require apipurse/apipurse-sdk
›TypeScript
import OpenAI from "openai";
import { APIPurse, wrapOpenAI } from "@apipurse/sdk";

const apipurse = new APIPurse({
  ingestToken: process.env.APIPURSE_INGEST_TOKEN!,
  providerId: process.env.APIPURSE_PROVIDER_ID!,
  baseUrl: "https://www.apipurse.com",
});

// Wrap the client ONCE, at startup:
const openai = wrapOpenAI(new OpenAI(), apipurse);

// Every call is now tracked automatically, nothing else to add:
const completion = await openai.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: "Hello" }],
});

// Anthropic works the same way:
// import { wrapAnthropic } from "@apipurse/sdk";
// const anthropic = wrapAnthropic(new Anthropic(), apipurse);
›Python
import os
from openai import OpenAI
from apipurse import APIPurse, wrap_openai

apipurse = APIPurse(
    ingest_token=os.environ["APIPURSE_INGEST_TOKEN"],
    provider_id=os.environ["APIPURSE_PROVIDER_ID"],
    base_url="https://www.apipurse.com",
)

# Wrap the client ONCE, at startup:
client = wrap_openai(OpenAI(), apipurse)

# Every call is now tracked automatically, nothing else to add:
completion = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello"}],
)

# Anthropic works the same way:
# from anthropic import Anthropic
# from apipurse import wrap_anthropic
# client = wrap_anthropic(Anthropic(), apipurse)
›Ruby
require "apipurse"
require "openai"

apipurse = Apipurse::Client.new(
  ingest_token: ENV["APIPURSE_INGEST_TOKEN"],
  provider_id: ENV["APIPURSE_PROVIDER_ID"],
  base_url: "https://www.apipurse.com"
)

# Wrap the client ONCE, at startup:
client = Apipurse::WrapOpenAI.call(OpenAI::Client.new, apipurse)

# Every call is now tracked automatically, nothing else to add:
completion = client.chat.completions.create(
  model: "gpt-4o",
  messages: [{ role: "user", content: "Hello" }]
)

# Anthropic works the same way:
# client = Apipurse::WrapAnthropic.call(Anthropic::Client.new, apipurse)
›Java
import com.apipurse.sdk.APIPurse;

// Create the client ONCE, at startup:
APIPurse apipurse = new APIPurse(
    System.getenv("APIPURSE_INGEST_TOKEN"),
    System.getenv("APIPURSE_PROVIDER_ID"),
    "https://www.apipurse.com",
    true // silent: never throws if APIPurse is unreachable
);

// Right after each of your own completion calls, add ONE line:
ChatCompletion completion = client.chat().completions().create(params);
apipurse.trackCompletion(
    completion.model(),
    completion.usage().promptTokens(),
    completion.usage().completionTokens()
);
›C# / .NET
using Apipurse.Sdk;

// Create the client ONCE, at startup:
var apipurse = new ApiPurse(
    ingestToken: Environment.GetEnvironmentVariable("APIPURSE_INGEST_TOKEN")!,
    providerId: Environment.GetEnvironmentVariable("APIPURSE_PROVIDER_ID")!,
    baseUrl: "https://www.apipurse.com"
);

// Right after each of your own completion calls, add ONE line:
ChatCompletion completion = await client.CompleteChatAsync(messages);
await apipurse.TrackCompletionAsync(
    completion.Model,
    completion.Usage.InputTokenCount,
    completion.Usage.OutputTokenCount
);
›Go
import (
	"context"
	"os"

	"github.com/yelmorab/apipurse-sdks/sdk-go/apipurse"
)

// Create the client ONCE, at startup:
client := apipurse.New(os.Getenv("APIPURSE_INGEST_TOKEN"), os.Getenv("APIPURSE_PROVIDER_ID"))
client.BaseURL = "https://www.apipurse.com"

// Right after each of your own completion calls, add ONE call:
client.TrackCompletion(context.Background(), apipurse.TrackCompletionInput{
	Model:        resp.Model,
	InputTokens:  resp.Usage.PromptTokens,
	OutputTokens: resp.Usage.CompletionTokens,
})
›PHP
<?php
use Apipurse\ApiPurse;

// Create the client ONCE, at startup:
$apipurse = new ApiPurse(
    ingestToken: getenv("APIPURSE_INGEST_TOKEN"),
    providerId: getenv("APIPURSE_PROVIDER_ID"),
    baseUrl: "https://www.apipurse.com"
);

// Right after each of your own completion calls, add ONE line:
$completion = $client->chat()->completions()->create($params);
$apipurse->trackCompletion(
    $completion->model,
    $completion->usage->promptTokens,
    $completion->usage->completionTokens
);

Note: The code examples on this page are sample code for illustration and general support only, provided as is without warranty. Review, test and secure them yourself before using them in production. See section 9 of the Terms of Service.

Reports

The Reports page lists your raw usage records, filtered by date range and provider.

Reports with filters. Illustration. Your screen may differ slightly.
  1. 1Open Reports in the sidebar and choose a date range and, optionally, a provider.
  2. 2Costs appear in your display currency. The original amount is shown underneath when it differs.
Tip:The Free plan shows the last 30 days, Pro shows 365 days and Team shows the full history.

Export your data and connect a BI toolPro and Team plans

Download your usage as a file or pull it into a reporting tool.

  1. 1On the Reports page, click Download CSV to export everything that matches your filters. The file contains the original and the converted amounts.
  2. 2To feed Power BI, Tableau, Looker or a similar tool, use the web or JSON data source with the URL below and an Authorization header set to Bearer YOUR_INGEST_TOKEN.
  3. 3Add from, to or provider_id to the URL to filter on the server. Refresh in your tool whenever you want the latest numbers.

Note: The code examples on this page are sample code for illustration and general support only, provided as is without warranty. Review, test and secure them yourself before using them in production. See section 9 of the Terms of Service.

BI / export URL

https://www.apipurse.com/api/export?format=json&from=2026-01-01&to=2026-01-31
Tip:Export is available on Pro and Team. Data is pulled on demand, not pushed live.

Budgets & alerts

Budgets and alerts

Every provider can have a monthly budget in USD and one or more alert thresholds, for example 50%, 80% and 100%.

Provider cards showing three budget states. Illustration. Your screen may differ slightly.
  1. 1Go to Settings, Your providers, and click Set budget (or Edit budget) next to the provider.
  2. 2Enter the monthly limit and choose one or more thresholds. Click Clear budget to remove a budget again.
  3. 3When your spend for the calendar month crosses a threshold, you receive an email and the card on your dashboard turns amber or red.
  • Each threshold fires at most once per month, so you are not warned every hour.
  • Budgets are always set in USD. A provider that bills in another currency is converted at the day's exchange rate before comparing.
  • On the Team plan, alerts are also posted to Slack, and every team member gets the email.

Budgets per API keyPro and Team plans

Split one provider by team, project or environment by giving each its own budget on top of the overall one.

A provider budget with two key-scoped budgets. Illustration. Your screen may differ slightly.
  1. 1In Settings, click Add key-scoped budget next to the provider and type a label of your choice, such as prod, staging or team-a.
  2. 2Set the monthly limit and threshold for that label.
  3. 3Send the same label as api_key_label when you report usage, as shown below.

Note: The code examples on this page are sample code for illustration and general support only, provided as is without warranty. Review, test and secure them yourself before using them in production. See section 9 of the Terms of Service.

curl

curl -X POST https://www.apipurse.com/api/ingest \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_INGEST_TOKEN" \
  -d '{"provider_id": "YOUR_PROVIDER_ID", "cost_usd": 0.42, "api_key_label": "prod"}'
Tip:The label is only a tag you choose, not a real API key. Usage with a label counts toward both that key's budget and the provider's overall budget. Usage without a label counts only toward the overall budget.

Spend-spike alertsPro and Team plans

Once a day APIPurse compares each provider's spend from yesterday with its normal 7-day average, even if you set no budget.

A spend-spike alert email. Illustration. Your screen may differ slightly.
  • If yesterday was at least 3 times the usual level and the amounts are large enough to matter, you receive an email.
  • This catches runaway prompt loops and leaked keys early, usually within a day.
  • You get at most one spike email per provider per day.
Tip:Spend-spike alerts are available on Pro and Team.

Alert History

Alert History lists every budget and spend-spike alert sent for your account.

The Alert History page. Illustration. Your screen may differ slightly.
  • See when each alert was sent, for which provider, of what kind, and whether it reached you by email and by Slack.
  • A checkmark means delivered, a dash means not sent, and n/a means the alert is older than per-channel tracking.
  • On Pro and Team you can download the whole log as CSV.

Slack alertsTeam plan

Post every budget and spend-spike alert to a Slack channel as well as by email.

Saving a Slack webhook and sending a test. Illustration. Your screen may differ slightly.
  1. 1At api.slack.com/apps, create an app, enable Incoming Webhooks and choose Add New Webhook to Workspace. Copy the webhook URL.
  2. 2In APIPurse, go to Settings and paste the URL into the Slack field.
  3. 3Click Send test to confirm the message arrives in your channel.
Tip:Slack alerts are available on the Team plan. If Slack stops working, the webhook may have been revoked in Slack. Send a test and check Alert History for the delivery status per channel.

Account & team

Invite your teamTeam plan

On the Team plan you can invite as many colleagues as you like at no extra cost. They get the same access as you.

Inviting a colleague under Settings, Team. Illustration. Your screen may differ slightly.
  1. 1Go to Settings, Team, and enter a colleague's email.
  2. 2They receive an email with a sign-in link, set a password and immediately see the same providers, budgets, alerts and settings.
  3. 3If an invite link expired or was already used, remove the person and send a fresh invite. The newest email always works.
Tip:Only managing the subscription and inviting or removing members stays with the account owner.

Display currency

Choose the currency in which the dashboard shows your totals.

Choosing a display currency. Illustration. Your screen may differ slightly.
  1. 1Go to Settings and pick a currency under Display currency.
  2. 2Every provider's spend stays stored in its real currency. The dashboard converts it for display using a daily exchange rate.
Tip:When a provider's currency differs from your display currency, its card also shows the original amount in smaller text.

Change the language

APIPurse is available in English, Dutch, French, German, Spanish, Portuguese and Japanese.

The language menu. Illustration. Your screen may differ slightly.
  1. 1Open the language menu at the bottom of the sidebar. On the home page it is in the header.
  2. 2Your choice is saved straight away and also decides the language of your alert emails.
Tip:Code examples and technical instructions always stay in English.

Plans, billing and cancelling

Manage your subscription under Settings, in the plan section.

Plan and billing section. Illustration. Your screen may differ slightly.
  • Free: 1 provider, 30 days of history and budget alerts by email.
  • Pro (59 euro per month): unlimited providers, 365 days of history, real-time tracking, spend-spike alerts, per-key budgets and export.
  • Team (299 euro per month): everything in Pro plus unlimited history, Slack alerts and unlimited team members.
  • To upgrade, change plan or cancel, click Manage billing. This opens the billing portal of our payment provider.
  • Cancelling takes effect at the end of the current billing period, so you keep access until then.
  • For refunds and your right of withdrawal, see section 5 of the Terms of Service.

Frequently asked questions

›I connected a provider but I see no data yet.

Connected providers sync every 6 hours, so the first data can take a while. Data you send yourself through the ingest, batch or real-time endpoints appears immediately.

›Is APIPurse really real-time?

Usage you push yourself, and Stripe with the webhook set up, is real-time. The OpenAI and Anthropic connectors check every 6 hours, and the providers do not finalise a day's cost instantly either. Use real-time tracking if instant alerts matter.

›Why does cost data for the last day or two sometimes change?

OpenAI, Anthropic and Stripe finalise costs after the fact. APIPurse re-reads the last 8 days on every sync so the numbers stay accurate.

›Is my API key safe?

Keys are encrypted before they are stored and are never shown again after you paste them. If you suspect a key was exposed, revoke it with the provider itself. Removing it from APIPurse does not invalidate it.

›Do you read my prompts or customer data?

No. APIPurse only receives cost, token-count and amount figures. Your prompts and completions go straight to your provider.

›Can I remove a provider?

Yes. In Settings, find it under Your providers and choose Remove. This deletes its usage history and budget.

›Is old usage data ever deleted?

Data older than 90 days is rolled up into one summary line per provider per day. Totals stay exactly the same, only per-call detail is condensed.

›Can a team member see everything I see?

Yes, on the Team plan. Members share providers, budgets, alerts and settings. Managing the subscription and inviting or removing members stays with the owner.

›How do I cancel my subscription?

Go to Settings, click Manage billing and cancel there. You keep access until the end of the billing period you already paid for.

›Can I get a refund?

See section 5 of the Terms of Service. Consumers in the EU have a 14-day right of withdrawal. Write to support and we will help.

›Where is my data stored and who processes it?

In the EU (Frankfurt), with a few providers for hosting, email and monitoring. The Privacy Policy lists them all, and businesses can use our Data Processing Agreement.

›How do I delete my account and data?

Email privacy@apipurse.com from your account address. We answer within one month. Billing records are kept for the period required by tax law.

Troubleshooting

ProblemUnauthorized when connecting a provider.

SolutionCheck you use the right kind of key. OpenAI and Anthropic need an Admin key, not a regular key. For Stripe, the restricted key needs the permission Balance Transactions: Read.

ProblemI did not receive an alert email.

SolutionCheck your spam folder and mark the message as not spam. Each threshold fires only once per month, so a threshold that already fired will not repeat. Alert History shows whether the email was sent.

ProblemThe ingest request returns an error.

SolutionCheck the Authorization header (Bearer, then your ingest token), that provider_id is the ID from Settings, and that the body is valid JSON with cost_usd as a number.

ProblemA Slack alert did not arrive but the email did.

SolutionUse Send test in Settings. If it fails, create a new Incoming Webhook in Slack and save it again. Alert History shows the status per channel.

ProblemMy budget percentage looks wrong or shows a missing rate.

SolutionBudgets are in USD and other currencies are converted with a daily exchange rate. If a rate has not synced yet, the card says so. It resolves itself after the next daily sync.

ProblemThe confirmation or invite email did not arrive.

SolutionCheck spam. For a team invite, remove the person in Settings and send a new invite. The newest email always works.

ProblemMy plan did not change after paying.

SolutionRefresh the page or log out and in again. If the plan is still wrong after a few minutes, email support with your account address.

ProblemReal-time tracking returns a plan error.

SolutionReal-time tracking, spend-spike alerts, per-key budgets and export need Pro or Team. Upgrade under Settings.

Still need help?

Write to us and include your account email and a short description of what you see. Please never send API keys or passwords.

General support: support@apipurse.com

Privacy and data requests: privacy@apipurse.com

We usually reply within one to two business days.

Terms · Privacy · DPA