SPEND AND ESTATE

AI spend and subscriptions

What you were billed and what you were metered, recorded as two numbers and never added into one.

Give each AI subscription and API account a vendor, tool, team and named owner. Map your finance export to the billing import template, then validate and preview the CSV before committing it. You can also post the fields as JSON. No vendor billing credential needed. Billed charges and metered token estimates stay separate, with each currency reported as billed.
What you supply
Mapped charge lines; ten required fields, two optional
Import bounds
1,000 lines; CSV uploads up to 2 MB, API JSON bodies up to 2 MiB
Charge kinds
Subscription and API, reported separately
Currency conversion
None. Each currency reported as billed
What an import cannot findA subscription that is on no invoice you give it
the problem

One blended AI total reconciles against nothing

Ask what AI costs the business this month and the answer is a number with a shrug attached. Some of it is monthly subscriptions on the corporate card, one per tool, signed up for by whoever needed them first. Some of it is metered API usage on an account somebody in engineering owns. Some of it is a seat still being paid for by a person who left in March.

Most tooling makes that worse, because it produces one confident total. Add a £120 subscription to £340 of estimated tokens and you get £460, a figure that appears nowhere else in your business, on no vendor invoice and in no gateway. On a spend question somebody always checks.

the mechanism

How it works

  1. 01

    Register the subscription against a named owner

    Each entry names a vendor, a tool, a team and an owner email, normalised so the same service registered twice does not become two entries. Reads need viewer rank, writes need operator rank, and every mutation is audited.
  2. 02

    Map your finance export onto the import template

    Ten required CSV headers: externalId, vendor, tool, team, kind, currency, amount, chargedAt, periodStart and periodEnd. ownerEmail and subscriptionId are optional. Upload or paste the CSV, validate it and review the preview before committing. The API accepts the same fields as JSON.
  3. 03

    Reject an import rather than half-apply it

    An unrecognised column, a missing required one, a credential in metadata or an invalid period fails validation. Each import accepts up to 1,000 lines. CSV file uploads are capped at 2 MB (2,000,000 bytes); the API caps the JSON request body at 2 MiB (2,097,152 bytes). One line reusing an existing identity with different data rolls the whole batch back.
  4. 04

    Report billed and metered side by side

    Subscription and API amounts are reported per currency with their evidence counts, and nothing is converted: a euro charge is reported in euros. Actual API invoices are never added to token-price estimates, and a report that hit its row cap says so on the result. The same figures reach an agent over MCP under the same team scope, to a caller holding an explicit report grant.
no credential, no vendor console

You map the charge lines out of your own finance export onto the import template, and the dashboard validates the file and shows you the parsed lines before anything is written.

01  map your export onto the template
12 columns · 10 required · 2 optional
  • externalId
  • vendor
  • tool
  • team
  • ownerEmail optional
  • subscriptionId optional
  • kind
  • currency
  • amount
  • chargedAt
  • periodStart
  • periodEnd
02  validate and preview
3 validated charge lines

File totals before duplicate detection. Nothing is written yet.

invoice linetool / teamkindamountcharged
INV-2026-09-001chat assistant Marketingsubscription1,240.00 USD2026-09-01
INV-2026-09-002coding agent Engineeringapi806.40 USD2026-09-01
INV-2026-09-014meeting notetaker Salessubscription276.50 GBP2026-09-01
03  import
Imported.

Repeat imports are recognised by team, source and invoice-line identifier, so re-importing an export you already loaded skips the lines it already holds rather than doubling the bill.

what you never handed over
  • A billing credential
  • A login to a vendor console
  • A connector for somebody to review

Column names and bounds are the product’s own; the lines are illustrative. Timestamps are UTC, kind is subscription or api, currency is three uppercase letters, and an import is capped at 1,000 lines and 2 MB. Import charge lines once, never a bill total alongside the lines that make it up.

Billed and metered stay two numbers

A subscription invoice is a fact about money that has already moved. A token-price estimate is a calculation over observed traffic against a price table. Only one of them will ever appear on a bank statement, so adding them produces the single figure an executive asks for and a number nobody can trace to a source document. Currencies are held apart for the same reason: a converted total embeds a rate and a date the report would have to defend.

Billed
What an invoice line says, per currency, with its source, charge date and service period. Retained without proration: a period straddling a reporting window is not sliced.
Estimated
What metered traffic through the gateway is calculated to have cost, recorded separately and never folded into the billed figure.
Unknown
A source nobody has connected. Coverage is its own axis, so an unconnected source reads as unknown rather than as zero, because those look identical on a chart and mean opposite things.
three figures, and the total that is not there
The AI subscriptions and spend screen. Billed subscriptions read 1,239.00 USD, billed API charges 35.00 USD and the recorded API cost estimate $0.0003, standing as three separate cards with no combined figure anywhere; the banner under them reads that gateway costs and API invoices are separate views of potentially overlapping usage and are not added together. The subscription register beneath lists claude as Approved and unapproved-assistant as Prohibited, each against its team and owner email, counted as 1 approved, 1 prohibited, 0 awaiting review.

Sample data in the real Token Observe interface, recorded from a local evaluation with a temporary database, a mock provider and one request. No live provider key was used. The product stamps its own demo rows SYNTHETIC EVALUATION DATA in these pixels.

Importing the same invoice twice adds nothing

Finance exports get run more than once: somebody re-checks a figure, a scheduled job retries after a timeout, two people import the same file on the same afternoon. A ledger that treats each of those as new charges doubles the total and takes a while to be noticed.

Identity is team, source and external id, and it is expected to be stable across exports. An identical reimport adds no spend. One that reuses an identity with different data is a conflict rather than an update, because the same reference carrying a different amount is something a person should look at. Corrections are issued as separately identified credit lines rather than by editing history.

One charge line, posted as JSON
POST /api/estate/charges/import
{
  "source": "finance-export",
  "lines": [{
    "externalId": "invoice-2026-09-line-1",
    "vendor": "anthropic",
    "tool": "claude",
    "team": "Engineering",
    "ownerEmail": "owner@example.com",
    "kind": "subscription",
    "currency": "GBP",
    "amount": 120,
    "chargedAt": "2026-09-01T00:00:00Z",
    "periodStart": "2026-09-01T00:00:00Z",
    "periodEnd": "2026-10-01T00:00:00Z"
  }]
}

Each line closes off an assumption a reader would otherwise carry into a proof of concept.

What this does not do

What do I have to supply to import a month of spend?

Map the charge lines from your finance export onto the dashboard's import template. It has ten required columns and two optional ones, ownerEmail and subscriptionId. Use the exact headers shown above. Upload or paste the CSV, validate it, then review the preview before committing. You need no vendor billing credential or vendor console login; your organisation decides how to review the data you import.

What happens if the same invoice is imported twice?

Nothing is added. Import identity is team, source and external id, and an identical reimport is recognised and ignored. The same identity arriving with different data is a conflict rather than an update: the import errors and rolls back completely, because the same reference carrying a different amount is something a person should look at. Corrections are issued as separately identified credit lines.

Will it find AI subscriptions nobody told us about?

Not from invoices, which list only what they list. Unregistered services surface through the observation side of the product instead, and that is evidence about a destination rather than proof of a subscription: a hostname without a verified owner cannot establish whose subscription it is. Treat the register as the record you build deliberately and observations as leads to investigate.

Ask about this capability
Ask how this one works, where it sits in the request path, or what it will not do. Answers stay inside what this page claims.

Prefer to ask a person? Write to James

Your next step

Bring us the agent you are least comfortable with.

Create a cloud account and workspace. No card or server installation. Model calls and Google BigQuery scans can incur separate provider charges.