Skip to content

Diagnostic LLM APIs

US inference geo is billing every token at 1.1x

Somebody in a procurement call last spring said that the data has to stay in the US, and somebody else, being helpful, went and set the workspace default that afternoon. Nobody wrote it down, because it took four seconds. The contract that prompted it was signed for one customer. The workspace serves all of them, and every token any of them has generated since has been billed at one and a tenth times the rate card.

Read-only key Python and Node.js Tests included
Two baristas smiling behind a counter
Photo by Vincent Leyva on Unsplash
The short answer

GET /v1/organizations/usage_report/messages?starting_at={T-30d}&bucket_width=1d&limit=31&group_by[]=inference_geo&group_by[]=workspace_id with an Admin API key. The inference_geo field comes back as "global", "us", "not_available" or null.

On Claude 4.6 and later, inference_geo: "us" applies a 1.1x multiplier to every token pricing category — input, output, cache writes and cache reads alike. Caching does not dilute it, because the cache rates are multiplied too.

Then find out who chose it. GET /v1/organizations/workspaces returns each workspace's data_residency block with default_inference_geo and allowed_inference_geos. The parameter can be set per request, but far more often it is inherited from that default, which means the premium is being paid by traffic whose callers never asked for it and cannot see it.

The problem in plain words

This is not a bug and not a mistake in the ordinary sense. US-only inference is a real product with a real reason to exist, and 10% is a reasonable price for it. The problem is that the decision is made once, in a workspace setting, on behalf of everything that will ever run in that workspace, and then it stops being visible to anyone.

The engineer writing the request does not set inference_geo and would not know it existed. The dashboard does not show it, because it is not a token count and not a model. The invoice shows a total that is 10% larger than a spreadsheet built from the public rate card, which reads as a rounding error, a mis-estimate, or someone's arithmetic being slightly off — three explanations that are all more comfortable than the real one.

And the blast radius is wrong. One customer's residency requirement is being satisfied by applying the premium to every customer's traffic, because the boundary that the requirement was scoped to is a contract and the boundary the setting applies to is a workspace, and nobody checked whether those two were the same shape.

One customerneeds USone contract, oneclauseWorkspacedefault setfour seconds,unrecordedAll trafficinherits itcallers neverasked1.1x on everycategorycache readsincludedInvoice runsten percentfiled as rounding
A ten percent gap against a spreadsheet built from the public rates reads as rounding, a mis-estimate, or somebody's arithmetic. Never as this.

Why it happens

The multiplier is on the rate, not on a volume. Every other cost note in this section is about how much of something you bought. This one is about what each unit cost. That means no amount of tuning volume fixes it and no amount of caching dilutes it: cache reads at 0.1x base become 0.11x base, which is exactly as much of a premium proportionally as everything else.

The premium is not ten percent of the bill. The billed amount already contains the multiplier, so recovering the premium from a US-attributed dollar figure is (1.1 - 1) / 1.1, about 9.09%, not 10%. Getting this backwards inflates the saving by a tenth in the one sentence a reader is going to quote at somebody.

The workspace default and a per-request parameter are different findings. If data_residency.default_inference_geo is us, the traffic is paying because of a configuration decision, and the fix is a conversation about which workspaces actually carry regulated traffic. If the default is global and US traffic is still appearing, callers are setting the parameter explicitly, and the fix is in code. Same premium, different owner, so the script never reports them as one thing.

not_available is not global. Models released before February 2026 do not support the parameter at all and report not_available. That traffic pays no premium and has no lever, so folding it in with global traffic quietly overstates how much of your workload you could move.

This is not the service-tier question. A tier decides what capacity serves you and how fast. inference_geo decides where the inference happens and multiplies the rate card. They are configured in different places, they fail in different directions, and a note about one is not a note about the other.

The fix, as a flow

Every other cost note in this section is about how much of something you bought. This one is about what each unit cost, which is why no amount of volume tuning or caching touches it. The fix asks who chose it, because a workspace default and a per request parameter are the same premium with two different owners.

inference_geo by workspaceagainst data_residencyDefault says usconfig decision, scope itCallers set it themselvesthe fix is in codeNo readable defaultread the workspace firstModel predates the fieldno premium, no lever
The premium is identical in the first two rows and the person who can fix it is not. Models that predate the parameter have no lever at all.

How to fix it

Group thirty days by inference_geo and workspace

GET /v1/organizations/usage_report/messages with group_by[]=inference_geo and group_by[]=workspace_id, bucket_width=1d, limit=31, starting_at floored to midnight UTC. You can also filter directly with inference_geo[]=us, but grouping gives you the share, and the share is what makes the number mean anything.

Sum every priced token category, not just input

The multiplier applies to all of them, so the measure has to be all of them: uncached_input_tokens, output_tokens, cache_read_input_tokens, and both nested fields under cache_creation. Reading cache_creation as if it were a number sums zero and understates a heavily cached workspace.

Read the residency block that decided it

GET /v1/organizations/workspaces and read data_residency.default_inference_geo and data_residency.allowed_inference_geos for every workspace that showed US traffic. This is the step that turns "we are paying a premium" into "this workspace is configured to, and here is when".

Price the premium out of the billed amount

GET /v1/organizations/cost_report?starting_at={T-30d}&limit=31&group_by[]=workspace_id gives spend per workspace. Multiply by the US token share and then by (1.1 - 1) / 1.1. The script states its assumption plainly: it takes the token mix as roughly the same across geos within one workspace, which is an approximation and is labelled as one.

Print the finding and leave the setting alone

For a workspace defaulting to us with no stated compliance reason, print the monthly premium and the two questions worth asking: which contract required it, and whether that contract's traffic could live in its own workspace. Then stop. Data residency is a compliance setting and an audit script has no business changing one.

How to check it worked

Move the regulated traffic into its own workspace, leave that one on us, set the rest back to global, and re-read the window. The US share should fall to roughly the regulated customers' share of volume rather than to zero.

python3 anthropic_inference_geo_premium_audit.py
# us-by-workspace-default  wrkspc_01Qy  98% of 412.4M priced token(s) on inference_geo us; data_residency.default_inference_geo is us
#   estimated premium about $874.31 of $10192.00 spend in this window
#   repair: confirm which contract requires US residency, and whether that traffic can live in its own workspace
# 4 workspace(s) checked, 1 finding(s)

The full code

Three GETs, all read-only, all against /v1/organizations/*, so ANTHROPIC_ADMIN_KEY has to be an Admin key. Six pure functions: normalising the geo value so a null does not become global, summing the five priced token fields including the nested cache-creation pair, folding into workspace and geo, computing the US share, backing the premium out of a billed amount rather than adding it on, and the verdict that keeps a workspace default and a per-request parameter as two separate findings.

Get this script on GitHub Follow @allanninal Python and Node.js, with tests. Read only, it never writes. One of 97 LLM API fixes, free and open source.
anthropic_inference_geo_premium_audit.py
"""Report Claude traffic paying the US inference geo premium.

Read only. GET requests and nothing else: ANTHROPIC_ADMIN_KEY must be an Admin
API key (sk-ant-admin...), which can be provisioned read-only. A workspace key
is rejected by every /v1/organizations/* path.

inference_geo "us" multiplies every token pricing category by 1.1 on Claude 4.6
and later. The parameter is usually not chosen per request: it is inherited from
a workspace's data_residency.default_inference_geo, which means the premium is
paid by traffic whose callers never asked for it.

The repair is printed, never applied. Data residency is a compliance setting.
"""
import argparse
import datetime as dt
import logging
import os
import sys

import requests

logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
log = logging.getLogger("anthropic_inference_geo_premium_audit")

API = "https://api.anthropic.com/v1"
VERSION = "2023-06-01"

# 1.1x on every token pricing category: input, output, cache writes and cache
# reads alike. Caching does not dilute it, because the cache rates move too.
GEO_MULTIPLIER = 1.1

# Every token field the multiplier touches. cache_creation is nested, and a flat
# read of it sums zero and understates a heavily cached workspace.
FLAT_TOKEN_FIELDS = ("uncached_input_tokens", "output_tokens",
                     "cache_read_input_tokens")
NESTED_TOKEN_FIELDS = ("ephemeral_5m_input_tokens", "ephemeral_1h_input_tokens")

FINDINGS = ("us-by-workspace-default", "us-by-request", "us-unexplained")


def geo_of(result):
    """Normalise the inference_geo value. Pure.

    A null becomes "unspecified" and never "global". They are different facts:
    one is traffic served globally, the other is traffic the report declined to
    place, and quietly merging them flatters the share in the wrong direction.
    """
    raw = str((result or {}).get("inference_geo") or "").strip().lower()
    if raw in ("us", "global", "not_available"):
        return raw
    return "unspecified"


def tokens_of(result):
    """Sum every priced token category on one usage result. Pure.

    All of them, because the multiplier applies to all of them. cache_creation
    is a nested object; reading it as a number is how a cached workspace comes
    out looking small.
    """
    total = 0
    for field in FLAT_TOKEN_FIELDS:
        try:
            total += int((result or {}).get(field) or 0)
        except (TypeError, ValueError):
            pass
    creation = (result or {}).get("cache_creation")
    if isinstance(creation, dict):
        for field in NESTED_TOKEN_FIELDS:
            try:
                total += int(creation.get(field) or 0)
            except (TypeError, ValueError):
                pass
    return total


def fold(pages):
    """Sum priced tokens into {workspace_id: {geo: tokens}}. Pure."""
    out = {}
    for page in pages:
        for bucket in page.get("data") or []:
            for result in bucket.get("results") or []:
                workspace = str(result.get("workspace_id") or "default workspace")
                geo = geo_of(result)
                per_geo = out.setdefault(workspace, {})
                per_geo[geo] = per_geo.get(geo, 0) + tokens_of(result)
    return out


def us_share(geo_totals):
    """The share of priced tokens served on inference_geo us. Pure."""
    total = sum(int(v or 0) for v in (geo_totals or {}).values())
    if total <= 0:
        return 0.0
    return int((geo_totals or {}).get("us") or 0) / float(total)


def premium_estimate(billed_dollars, share, multiplier=GEO_MULTIPLIER):
    """Back the premium out of an amount that already contains it. Pure.

    NOT billed * share * 0.1. The billed figure is already 1.1x the base rate,
    so the premium is (m - 1) / m of it, about 9.09%. Adding the multiplier on
    instead of removing it overstates the saving by a tenth, in the one sentence
    somebody is going to quote at whoever owns the budget.

    Assumes the token mix is roughly the same across geos inside one workspace,
    which is an approximation and is labelled as one wherever it is printed.
    """
    if multiplier <= 1.0:
        return 0.0
    dollars = max(0.0, float(billed_dollars or 0.0))
    fraction = min(1.0, max(0.0, float(share or 0.0)))
    return dollars * fraction * (multiplier - 1.0) / multiplier


def residency_default(workspace):
    """A workspace's configured default inference geo. Pure.

    Returns "us", "global", "not_available" or "unset". "unset" covers both a
    missing data_residency block and one this script cannot read, because the
    repair is the same in either case: go and look at the workspace.
    """
    block = (workspace or {}).get("data_residency")
    if not isinstance(block, dict):
        return "unset"
    value = str(block.get("default_inference_geo") or "").strip().lower()
    return value if value in ("us", "global", "not_available") else "unset"


def verdict(geo_totals, default_geo, min_tokens=1_000_000):
    """Classify one workspace. Pure. Returns (state, detail).

    A workspace default and an explicit per-request parameter are kept apart
    deliberately. The premium is identical; the owner of the fix is not.
    """
    totals = geo_totals or {}
    total = sum(int(v or 0) for v in totals.values())
    if total < min_tokens:
        return ("low-volume",
                "%d priced token(s) in the window, too few to conclude anything"
                % total)

    us = int(totals.get("us") or 0)
    if us <= 0:
        if int(totals.get("not_available") or 0) >= total:
            return ("geo-unsupported",
                    "%.1fM priced token(s), all on models that predate the "
                    "inference_geo parameter. No premium and no lever."
                    % (total / 1e6))
        return ("no-us-traffic",
                "%.1fM priced token(s) and none of it on inference_geo us"
                % (total / 1e6))

    share = us / float(total)
    shape = ("%.0f%% of %.1fM priced token(s) on inference_geo us"
             % (share * 100, total / 1e6))

    if default_geo == "us":
        return ("us-by-workspace-default",
                "%s; data_residency.default_inference_geo is us, so every "
                "caller pays the 1.1x whether or not any of them asked."
                % shape)
    if default_geo == "global":
        return ("us-by-request",
                "%s while the workspace default is global, so callers are "
                "setting inference_geo explicitly. The fix is in code, not in "
                "the workspace." % shape)
    return ("us-unexplained",
            "%s with no readable data_residency default. Read the workspace "
            "before deciding whether this is deliberate." % shape)


def get(session, path, params=None):
    r = session.get(API + path, params=params or {}, timeout=60)
    if r.status_code in (401, 403):
        raise SystemExit("%d from Anthropic: /v1/organizations/* needs an Admin "
                         "API key (sk-ant-admin...), not a workspace key"
                         % r.status_code)
    r.raise_for_status()
    return r.json()


def pages(session, path, params):
    """Walk the paginated usage or cost report."""
    params = dict(params)
    while True:
        page = get(session, path, params)
        yield page
        if not page.get("has_more") or not page.get("next_page"):
            return
        params["page"] = page["next_page"]


def workspaces(session):
    """Every workspace, keyed by id, including archived ones."""
    out = {}
    params = {"limit": 100, "include_archived": "true"}
    while True:
        page = get(session, "/organizations/workspaces", params)
        for item in page.get("data") or []:
            out[str(item.get("id"))] = item
        if not page.get("has_more") or not page.get("last_id"):
            return out
        params = dict(params, after_id=page["last_id"])


def spend_by_workspace(session, start):
    """Thirty days of spend per workspace. amount is a decimal string."""
    out = {}
    for page in pages(session, "/organizations/cost_report",
                      {"starting_at": start, "limit": 31,
                       "group_by[]": ["workspace_id"]}):
        for bucket in page.get("data") or []:
            for result in bucket.get("results") or []:
                workspace = str(result.get("workspace_id") or "default workspace")
                raw = result.get("amount")
                try:
                    out[workspace] = out.get(workspace, 0.0) + float(raw or 0.0)
                except (TypeError, ValueError):
                    pass
    return out


def window_start(days):
    """Floor to midnight UTC: starting_at must sit on a bucket boundary."""
    now = dt.datetime.now(dt.timezone.utc)
    midnight = now.replace(hour=0, minute=0, second=0, microsecond=0)
    return (midnight - dt.timedelta(days=days)).strftime("%Y-%m-%dT%H:%M:%SZ")


def main():
    ap = argparse.ArgumentParser(description=__doc__)
    ap.add_argument("--days", type=int, default=30,
                    help="days of daily buckets to read (default 30)")
    ap.add_argument("--min-tokens", type=int, default=1_000_000,
                    help="priced tokens below which no claim is made")
    args = ap.parse_args()

    admin = os.environ.get("ANTHROPIC_ADMIN_KEY")
    if not admin:
        log.error("set ANTHROPIC_ADMIN_KEY to an Admin API key (sk-ant-admin...); "
                  "a workspace key cannot read /v1/organizations/*")
        return 2

    s = requests.Session()
    s.headers.update({"x-api-key": admin, "anthropic-version": VERSION})

    start = window_start(args.days)
    rows = fold(pages(s, "/organizations/usage_report/messages",
                      {"starting_at": start, "bucket_width": "1d",
                       "limit": min(args.days + 1, 31),
                       "group_by[]": ["inference_geo", "workspace_id"]}))
    directory = workspaces(s)
    spend = spend_by_workspace(s, start)

    checked = 0
    bad = 0
    for workspace in sorted(rows, key=lambda w: -(rows[w].get("us") or 0)):
        totals = rows[workspace]
        default_geo = residency_default(directory.get(workspace))
        state, detail = verdict(totals, default_geo, args.min_tokens)
        checked += 1
        line = "%-24s %-16s %s" % (state, workspace, detail)

        if state not in FINDINGS:
            log.info(line)
            continue
        bad += 1
        log.warning(line)
        billed = spend.get(workspace, 0.0)
        log.warning("  estimated premium about $%.2f of $%.2f spend in this "
                    "window, assuming a similar token mix across geos",
                    premium_estimate(billed, us_share(totals)), billed)
        allowed = ((directory.get(workspace) or {}).get("data_residency")
                   or {}).get("allowed_inference_geos")
        if allowed:
            log.warning("  allowed_inference_geos: %s", ", ".join(map(str, allowed)))
        if state == "us-by-workspace-default":
            log.warning("  repair: confirm which contract requires US residency, "
                        "and whether that traffic can live in its own workspace "
                        "instead of every workspace paying for it")
        elif state == "us-by-request":
            log.warning("  repair: the callers are setting inference_geo "
                        "themselves. Find them before changing anything here.")
        else:
            log.warning("  repair: read this workspace's data_residency block "
                        "and record why it is set the way it is")
        log.warning("  do not change residency from a script: it is a "
                    "compliance setting with a named owner")

    log.info("%d workspace(s) checked, %d finding(s)", checked, bad)
    return 1 if bad else 0


if __name__ == "__main__":
    sys.exit(main())
anthropic-inference-geo-premium-audit.mjs
/**
 * Report Claude traffic paying the US inference geo premium.
 *
 * Read only. GET requests and nothing else against the Admin API, which needs
 * an Admin API key (sk-ant-admin...); a workspace key is rejected by every
 * /v1/organizations/* path.
 *
 * inference_geo "us" multiplies every token pricing category by 1.1 on Claude
 * 4.6 and later, and is usually inherited from a workspace's
 * data_residency.default_inference_geo rather than chosen per request. The
 * repair is printed, never applied: residency is a compliance setting.
 */
const API = 'https://api.anthropic.com/v1';
const VERSION = '2023-06-01';

// 1.1x on every token pricing category. Caching does not dilute it, because
// the cache rates are multiplied too.
const GEO_MULTIPLIER = 1.1;

// Every token field the multiplier touches. cache_creation is nested, and a
// flat read of it sums zero.
const FLAT_TOKEN_FIELDS = ['uncached_input_tokens', 'output_tokens',
                           'cache_read_input_tokens'];
const NESTED_TOKEN_FIELDS = ['ephemeral_5m_input_tokens', 'ephemeral_1h_input_tokens'];

const FINDINGS = ['us-by-workspace-default', 'us-by-request', 'us-unexplained'];

/**
 * Normalise the inference_geo value. Pure. A null becomes "unspecified" and
 * never "global": one is traffic served globally, the other is traffic the
 * report declined to place.
 */
export function geoOf(result) {
  const raw = String(result?.inference_geo ?? '').trim().toLowerCase();
  return ['us', 'global', 'not_available'].includes(raw) ? raw : 'unspecified';
}

/** Sum every priced token category on one usage result. Pure. */
export function tokensOf(result) {
  let total = 0;
  for (const field of FLAT_TOKEN_FIELDS) {
    const n = Number(result?.[field] ?? 0);
    if (Number.isFinite(n)) total += Math.trunc(n);
  }
  const creation = result?.cache_creation;
  if (creation !== null && typeof creation === 'object' && !Array.isArray(creation)) {
    for (const field of NESTED_TOKEN_FIELDS) {
      const n = Number(creation[field] ?? 0);
      if (Number.isFinite(n)) total += Math.trunc(n);
    }
  }
  return total;
}

/** Sum priced tokens into {workspace_id: {geo: tokens}}. Pure. */
export function fold(pages) {
  const out = {};
  for (const page of pages ?? []) {
    for (const bucket of page.data ?? []) {
      for (const result of bucket.results ?? []) {
        const workspace = String(result.workspace_id ?? 'default workspace');
        const geo = geoOf(result);
        if (!out[workspace]) out[workspace] = {};
        out[workspace][geo] = (out[workspace][geo] ?? 0) + tokensOf(result);
      }
    }
  }
  return out;
}

/** The share of priced tokens served on inference_geo us. Pure. */
export function usShare(geoTotals) {
  const values = Object.values(geoTotals ?? {}).map((v) => Number(v) || 0);
  const total = values.reduce((a, b) => a + b, 0);
  if (total <= 0) return 0;
  return (Number(geoTotals?.us) || 0) / total;
}

/**
 * Back the premium out of an amount that already contains it. Pure.
 *
 * NOT billed * share * 0.1. The billed figure is already 1.1x the base rate, so
 * the premium is (m - 1) / m of it, about 9.09%. Adding the multiplier on
 * instead of removing it overstates the saving by a tenth.
 */
export function premiumEstimate(billedDollars, share, multiplier = GEO_MULTIPLIER) {
  if (multiplier <= 1) return 0;
  const dollars = Math.max(0, Number(billedDollars ?? 0));
  const fraction = Math.min(1, Math.max(0, Number(share ?? 0)));
  return dollars * fraction * (multiplier - 1) / multiplier;
}

/**
 * A workspace's configured default inference geo. Pure. "unset" covers a
 * missing block and an unreadable one alike, because the repair is the same.
 */
export function residencyDefault(workspace) {
  const block = workspace?.data_residency;
  if (block === null || typeof block !== 'object' || Array.isArray(block)) return 'unset';
  const value = String(block.default_inference_geo ?? '').trim().toLowerCase();
  return ['us', 'global', 'not_available'].includes(value) ? value : 'unset';
}

/**
 * Classify one workspace. Pure. Returns [state, detail].
 * A workspace default and an explicit per-request parameter are kept apart:
 * the premium is identical, the owner of the fix is not.
 */
export function verdict(geoTotals, defaultGeo, minTokens = 1000000) {
  const totals = geoTotals ?? {};
  const total = Object.values(totals).reduce((a, b) => a + (Number(b) || 0), 0);
  if (total < minTokens) {
    return ['low-volume',
      `${total} priced token(s) in the window, too few to conclude anything`];
  }

  const us = Number(totals.us) || 0;
  if (us <= 0) {
    if ((Number(totals.not_available) || 0) >= total) {
      return ['geo-unsupported',
        `${(total / 1e6).toFixed(1)}M priced token(s), all on models that ` +
        'predate the inference_geo parameter. No premium and no lever.'];
    }
    return ['no-us-traffic',
      `${(total / 1e6).toFixed(1)}M priced token(s) and none of it on inference_geo us`];
  }

  const share = us / total;
  const shape = `${(share * 100).toFixed(0)}% of ${(total / 1e6).toFixed(1)}M ` +
                'priced token(s) on inference_geo us';

  if (defaultGeo === 'us') {
    return ['us-by-workspace-default',
      `${shape}; data_residency.default_inference_geo is us, so every caller ` +
      'pays the 1.1x whether or not any of them asked.'];
  }
  if (defaultGeo === 'global') {
    return ['us-by-request',
      `${shape} while the workspace default is global, so callers are setting ` +
      'inference_geo explicitly. The fix is in code, not in the workspace.'];
  }
  return ['us-unexplained',
    `${shape} with no readable data_residency default. Read the workspace ` +
    'before deciding whether this is deliberate.'];
}

async function get(key, path, params = {}) {
  const url = new URL(API + path);
  for (const [k, v] of Object.entries(params)) {
    if (Array.isArray(v)) for (const item of v) url.searchParams.append(k, String(item));
    else if (v !== undefined && v !== null) url.searchParams.set(k, String(v));
  }
  const res = await fetch(url, {
    headers: { 'x-api-key': key, 'anthropic-version': VERSION },
  });
  if (res.status === 401 || res.status === 403) {
    throw new Error(`${res.status} from Anthropic: /v1/organizations/* needs an ` +
                    'Admin API key (sk-ant-admin...), not a workspace key');
  }
  if (!res.ok) throw new Error(`${res.status} from ${path}`);
  return res.json();
}

async function readPages(key, path, params) {
  const out = [];
  let next = { ...params };
  for (;;) {
    const page = await get(key, path, next);
    out.push(page);
    if (!page.has_more || !page.next_page) return out;
    next = { ...next, page: page.next_page };
  }
}

async function readWorkspaces(key) {
  const out = {};
  let params = { limit: 100, include_archived: 'true' };
  for (;;) {
    const page = await get(key, '/organizations/workspaces', params);
    for (const item of page.data ?? []) out[String(item.id)] = item;
    if (!page.has_more || !page.last_id) return out;
    params = { ...params, after_id: page.last_id };
  }
}

async function spendByWorkspace(key, start) {
  const out = {};
  for (const page of await readPages(key, '/organizations/cost_report',
    { starting_at: start, limit: 31, 'group_by[]': ['workspace_id'] })) {
    for (const bucket of page.data ?? []) {
      for (const result of bucket.results ?? []) {
        const workspace = String(result.workspace_id ?? 'default workspace');
        const value = Number(result.amount ?? 0);
        if (Number.isFinite(value)) out[workspace] = (out[workspace] ?? 0) + value;
      }
    }
  }
  return out;
}

/** Floor to midnight UTC: starting_at must sit on a bucket boundary. */
function windowStart(days) {
  const midnight = new Date();
  midnight.setUTCHours(0, 0, 0, 0);
  midnight.setUTCDate(midnight.getUTCDate() - days);
  return midnight.toISOString().replace(/\.\d{3}Z$/, 'Z');
}

async function main() {
  const key = process.env.ANTHROPIC_ADMIN_KEY;
  if (!key) {
    console.error('set ANTHROPIC_ADMIN_KEY to an Admin API key (sk-ant-admin...); ' +
                  'a workspace key cannot read /v1/organizations/*');
    process.exitCode = 2;
    return;
  }

  const days = Number(process.env.DAYS ?? 30);
  const minTokens = Number(process.env.MIN_TOKENS ?? 1000000);
  const start = windowStart(days);

  const rows = fold(await readPages(key, '/organizations/usage_report/messages', {
    starting_at: start, bucket_width: '1d', limit: Math.min(days + 1, 31),
    'group_by[]': ['inference_geo', 'workspace_id'],
  }));
  const directory = await readWorkspaces(key);
  const spend = await spendByWorkspace(key, start);

  let checked = 0;
  let bad = 0;
  const ids = Object.keys(rows).sort((a, b) => (rows[b].us ?? 0) - (rows[a].us ?? 0));
  for (const workspace of ids) {
    const totals = rows[workspace];
    const defaultGeo = residencyDefault(directory[workspace]);
    const [state, detail] = verdict(totals, defaultGeo, minTokens);
    checked += 1;
    const line = `${state.padEnd(24)} ${workspace.padEnd(16)} ${detail}`;

    if (!FINDINGS.includes(state)) {
      console.log(line);
      continue;
    }
    bad += 1;
    console.warn(line);
    const billed = spend[workspace] ?? 0;
    console.warn(`  estimated premium about ` +
      `$${premiumEstimate(billed, usShare(totals)).toFixed(2)} of ` +
      `$${billed.toFixed(2)} spend in this window, assuming a similar token ` +
      'mix across geos');
    const allowed = directory[workspace]?.data_residency?.allowed_inference_geos;
    if (allowed) console.warn(`  allowed_inference_geos: ${allowed.join(', ')}`);
    if (state === 'us-by-workspace-default') {
      console.warn('  repair: confirm which contract requires US residency, and ' +
                   'whether that traffic can live in its own workspace instead ' +
                   'of every workspace paying for it');
    } else if (state === 'us-by-request') {
      console.warn('  repair: the callers are setting inference_geo themselves. ' +
                   'Find them before changing anything here.');
    } else {
      console.warn("  repair: read this workspace's data_residency block and " +
                   'record why it is set the way it is');
    }
    console.warn('  do not change residency from a script: it is a compliance ' +
                 'setting with a named owner');
  }

  console.log(`${checked} workspace(s) checked, ${bad} finding(s)`);
  process.exitCode = bad ? 1 : 0;
}

// Only run when invoked directly, so importing this module from the test file
// does not fire main() and fail on the missing key.
if (import.meta.url === `file://${process.argv[1]}`) {
  main().catch((err) => { console.error(err.message); process.exitCode = 2; });
}

Add a test

The test that earns its place is the arithmetic one: a billed figure already contains the multiplier, so the premium inside $1,100 is $100 and not $110, and getting that backwards inflates the number in the exact sentence somebody will repeat. After that the tests keep the three US states apart — workspace default, per-request parameter, unreadable configuration — and make sure a null geo does not quietly become global and a not_available workload does not get offered a lever it does not have.

test_anthropic_inference_geo_premium_audit.py
from anthropic_inference_geo_premium_audit import (fold, geo_of,
                                                   premium_estimate,
                                                   residency_default, tokens_of,
                                                   us_share, verdict)


def result(geo="us", workspace="wrkspc_01Qy", uncached=100_000_000,
           output=8_000_000, cache_read=0, write_5m=0, write_1h=0):
    """One result from the messages usage report."""
    return {"inference_geo": geo, "workspace_id": workspace,
            "uncached_input_tokens": uncached, "output_tokens": output,
            "cache_read_input_tokens": cache_read,
            "cache_creation": {"ephemeral_5m_input_tokens": write_5m,
                               "ephemeral_1h_input_tokens": write_1h}}


def page(*results):
    return {"data": [{"starting_at": "2026-08-01T00:00:00Z",
                      "results": list(results)}], "has_more": False}


def test_the_premium_is_inside_the_billed_amount_not_added_to_it():
    # $1,100 billed at 1.1x is $1,000 of base rate and $100 of premium. The
    # tempting arithmetic, 1100 * 0.1, gives $110 and is wrong by a tenth.
    assert abs(premium_estimate(1100.0, 1.0) - 100.0) < 1e-6
    assert abs(premium_estimate(1100.0, 0.5) - 50.0) < 1e-6
    assert premium_estimate(1100.0, 0.0) == 0.0
    assert premium_estimate(0.0, 1.0) == 0.0
    # A multiplier of 1 is no premium at all, not a division by zero.
    assert premium_estimate(1100.0, 1.0, multiplier=1.0) == 0.0


def test_a_workspace_default_and_a_per_request_parameter_are_two_findings():
    totals = {"us": 400_000_000, "global": 8_000_000}
    assert verdict(totals, "us")[0] == "us-by-workspace-default"
    assert verdict(totals, "global")[0] == "us-by-request"
    assert verdict(totals, "unset")[0] == "us-unexplained"
    detail = verdict(totals, "us")[1]
    assert "98% of 408.0M priced token(s)" in detail


def test_models_that_predate_the_parameter_are_not_a_finding():
    assert verdict({"not_available": 50_000_000}, "unset")[0] == "geo-unsupported"
    assert verdict({"global": 50_000_000}, "us")[0] == "no-us-traffic"
    assert verdict({"us": 900}, "us")[0] == "low-volume"


def test_a_null_geo_is_unspecified_and_never_global():
    assert geo_of({"inference_geo": None}) == "unspecified"
    assert geo_of({}) == "unspecified"
    assert geo_of({"inference_geo": "US"}) == "us"
    assert geo_of({"inference_geo": "global"}) == "global"
    assert geo_of({"inference_geo": "not_available"}) == "not_available"


def test_every_priced_category_counts_including_the_nested_cache_writes():
    # The multiplier applies to cache writes and reads too, so a flat read that
    # misses cache_creation understates a heavily cached workspace.
    assert tokens_of(result(uncached=10, output=5, cache_read=3,
                            write_5m=2, write_1h=1)) == 21
    assert tokens_of({"uncached_input_tokens": 10, "cache_creation": None}) == 10
    assert tokens_of({}) == 0


def test_folding_keeps_workspaces_and_geos_apart():
    folded = fold([page(result(geo="us", uncached=400_000_000, output=0),
                        result(geo="global", uncached=8_000_000, output=0),
                        result(geo="us", workspace="wrkspc_02Zz",
                               uncached=1_000_000, output=0))])
    assert folded["wrkspc_01Qy"] == {"us": 400_000_000, "global": 8_000_000}
    assert folded["wrkspc_02Zz"] == {"us": 1_000_000}
    assert abs(us_share(folded["wrkspc_01Qy"]) - 400 / 408) < 1e-9
    assert us_share({}) == 0.0


def test_residency_is_read_from_the_nested_block():
    assert residency_default({"data_residency":
                              {"default_inference_geo": "us"}}) == "us"
    assert residency_default({"data_residency":
                              {"default_inference_geo": "global"}}) == "global"
    assert residency_default({"data_residency": {}}) == "unset"
    assert residency_default({}) == "unset"
    assert residency_default(None) == "unset"
anthropic-inference-geo-premium-audit.test.mjs
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { fold, geoOf, premiumEstimate, residencyDefault, tokensOf, usShare,
         verdict } from './anthropic-inference-geo-premium-audit.mjs';

/** One result from the messages usage report. */
function result({ geo = 'us', workspace = 'wrkspc_01Qy', uncached = 100000000,
                  output = 8000000, cacheRead = 0, write5m = 0, write1h = 0 } = {}) {
  return {
    inference_geo: geo, workspace_id: workspace,
    uncached_input_tokens: uncached, output_tokens: output,
    cache_read_input_tokens: cacheRead,
    cache_creation: { ephemeral_5m_input_tokens: write5m,
                      ephemeral_1h_input_tokens: write1h },
  };
}

function page(...results) {
  return { data: [{ starting_at: '2026-08-01T00:00:00Z', results }], has_more: false };
}

test('the premium is inside the billed amount, not added to it', () => {
  assert.ok(Math.abs(premiumEstimate(1100.0, 1.0) - 100.0) < 1e-6);
  assert.ok(Math.abs(premiumEstimate(1100.0, 0.5) - 50.0) < 1e-6);
  assert.equal(premiumEstimate(1100.0, 0), 0);
  assert.equal(premiumEstimate(0, 1.0), 0);
  assert.equal(premiumEstimate(1100.0, 1.0, 1.0), 0);
});

test('a workspace default and a per-request parameter are two findings', () => {
  const totals = { us: 400000000, global: 8000000 };
  assert.equal(verdict(totals, 'us')[0], 'us-by-workspace-default');
  assert.equal(verdict(totals, 'global')[0], 'us-by-request');
  assert.equal(verdict(totals, 'unset')[0], 'us-unexplained');
  assert.match(verdict(totals, 'us')[1], /98% of 408\.0M priced token\(s\)/);
});

test('models that predate the parameter are not a finding', () => {
  assert.equal(verdict({ not_available: 50000000 }, 'unset')[0], 'geo-unsupported');
  assert.equal(verdict({ global: 50000000 }, 'us')[0], 'no-us-traffic');
  assert.equal(verdict({ us: 900 }, 'us')[0], 'low-volume');
});

test('a null geo is unspecified and never global', () => {
  assert.equal(geoOf({ inference_geo: null }), 'unspecified');
  assert.equal(geoOf({}), 'unspecified');
  assert.equal(geoOf({ inference_geo: 'US' }), 'us');
  assert.equal(geoOf({ inference_geo: 'global' }), 'global');
  assert.equal(geoOf({ inference_geo: 'not_available' }), 'not_available');
});

test('every priced category counts, including the nested cache writes', () => {
  assert.equal(tokensOf(result({ uncached: 10, output: 5, cacheRead: 3,
                                 write5m: 2, write1h: 1 })), 21);
  assert.equal(tokensOf({ uncached_input_tokens: 10, cache_creation: null }), 10);
  assert.equal(tokensOf({}), 0);
});

test('folding keeps workspaces and geos apart', () => {
  const folded = fold([page(
    result({ geo: 'us', uncached: 400000000, output: 0 }),
    result({ geo: 'global', uncached: 8000000, output: 0 }),
    result({ geo: 'us', workspace: 'wrkspc_02Zz', uncached: 1000000, output: 0 }),
  )]);
  assert.deepEqual(folded.wrkspc_01Qy, { us: 400000000, global: 8000000 });
  assert.deepEqual(folded.wrkspc_02Zz, { us: 1000000 });
  assert.ok(Math.abs(usShare(folded.wrkspc_01Qy) - 400 / 408) < 1e-9);
  assert.equal(usShare({}), 0);
});

test('residency is read from the nested block', () => {
  assert.equal(residencyDefault({ data_residency: { default_inference_geo: 'us' } }), 'us');
  assert.equal(residencyDefault({ data_residency: { default_inference_geo: 'global' } }),
               'global');
  assert.equal(residencyDefault({ data_residency: {} }), 'unset');
  assert.equal(residencyDefault({}), 'unset');
  assert.equal(residencyDefault(null), 'unset');
});

FAQ

Does the 1.1x apply to cached tokens too?

Yes, to every token pricing category: input, output, cache writes and cache reads. That is why caching does not help you here. A cache read at 0.1x base becomes 0.11x base, which is proportionally exactly the same premium as everything else. Caching is still worth doing for its own reasons; it just does not touch this.

Why isn't the premium ten percent of the US spend?

Because the US spend already includes it. If the base cost was $1,000, the billed figure is $1,100, and the premium inside that is $100 — which is 9.09% of $1,100, not 10%. Multiplying the billed amount by 0.1 gives $110 and overstates the saving by a tenth. It is a small error in a number people quote out loud, which is the worst kind.

What does not_available mean on the inference_geo field?

That the model serving those requests predates the parameter. Models released before February 2026 do not support inference_geo at all, so that traffic pays no premium and has no geography lever to pull. The script reports it as its own state rather than folding it in with global, because a workload with nothing to change should not appear in a list of things you could change.

Should I just set everything back to global?

No, and the script deliberately will not do it for you. Somebody chose US residency for a reason, and that reason may be a signed contract. The useful question is a scoping one: if one customer requires US inference and the workspace serves four hundred, the premium is being paid four hundred times over for one obligation, and a separate workspace for the regulated traffic satisfies the requirement at a fraction of the cost. That is a conversation, not a config change.

Is this the same thing as the service tier note?

No. A service tier decides what capacity serves your requests and how quickly, and it fails by silently downgrading you to the standard tier. inference_geo decides where inference happens and multiplies the rate card by 1.1. Different setting, different failure, different fix — and the fast-mode note covers the tier side.

Related field notes

Sources

Every figure in this note is traced to one of these. Prices are list rates and change — check them for your own region before acting.

Stuck on a tricky one?

If your setup is misbehaving in a way this note does not cover, message me on LinkedIn with what you are seeing.