diff --git a/profile/README.md b/profile/README.md
index fb66df0..517cbed 100644
--- a/profile/README.md
+++ b/profile/README.md
@@ -14,9 +14,9 @@ Find the best models & prices for your prompts — through a single, OpenAI-comp
-
-
-
+
+
+
[](https://openrouter.ai)
[](https://openrouter.ai/docs)
diff --git a/profile/assets/stat-tokens-dark.gif b/profile/assets/stat-tokens-dark.gif
index a218fe8..8cd04f2 100644
Binary files a/profile/assets/stat-tokens-dark.gif and b/profile/assets/stat-tokens-dark.gif differ
diff --git a/profile/assets/stat-tokens-light.gif b/profile/assets/stat-tokens-light.gif
index fa65471..9a13f68 100644
Binary files a/profile/assets/stat-tokens-light.gif and b/profile/assets/stat-tokens-light.gif differ
diff --git a/stats-cards/scripts/fetch-stats.mjs b/stats-cards/scripts/fetch-stats.mjs
index a6b76d2..6d9c2b9 100644
--- a/stats-cards/scripts/fetch-stats.mjs
+++ b/stats-cards/scripts/fetch-stats.mjs
@@ -10,7 +10,8 @@ const get = async (url) => {
const [models, providers, rankings] = await Promise.all([
get('https://openrouter.ai/api/v1/models'),
get('https://openrouter.ai/api/v1/providers'),
- get('https://openrouter.ai/api/frontend/v1/rankings/models?view=week').catch(
+ // Monthly window to match the homepage's canonical "Monthly Tokens" stat.
+ get('https://openrouter.ai/api/frontend/v1/rankings/models?view=month').catch(
() => null // undocumented endpoint — tolerate failure
),
]);
@@ -18,14 +19,25 @@ const [models, providers, rankings] = await Promise.all([
const modelCount = models.data.length;
const providerCount = providers.data.length;
-let tokensT = 40; // conservative fallback
-if (rankings?.data) {
- const total = rankings.data.reduce(
- (sum, r) =>
- sum + (r.total_completion_tokens ?? 0) + (r.total_prompt_tokens ?? 0),
- 0
+let tokensT = 100; // conservative fallback
+if (rankings?.data?.length) {
+ // The response contains multiple date buckets; only the latest one is
+ // the trailing-month window. Summing all rows would double-count
+ // stale partial buckets.
+ const latest = rankings.data.reduce(
+ (max, r) => (r.date > max ? r.date : max),
+ rankings.data[0].date
);
- if (total > 1e12) tokensT = Math.round((total / 1e12) * 10) / 10;
+ // Canonical "tokens processed" formula (site's getTotalTokens):
+ // prompt + completion, excluding reasoning/cached columns.
+ const total = rankings.data
+ .filter((r) => r.date === latest)
+ .reduce(
+ (sum, r) =>
+ sum + (r.total_prompt_tokens ?? 0) + (r.total_completion_tokens ?? 0),
+ 0
+ );
+ if (total > 1e12) tokensT = Math.round(total / 1e12);
}
await mkdir('out', {recursive: true});
@@ -33,7 +45,7 @@ await mkdir('out', {recursive: true});
const props = {
models: {value: modelCount, suffix: '+', label: 'Models'},
providers: {value: providerCount, suffix: '+', label: 'Providers'},
- tokens: {value: tokensT, suffix: 'T', label: 'Tokens / week'},
+ tokens: {value: tokensT, suffix: 'T', label: 'Tokens / month'},
};
for (const [id, p] of Object.entries(props)) {
diff --git a/stats-cards/src/Root.tsx b/stats-cards/src/Root.tsx
index c407d04..0307443 100644
--- a/stats-cards/src/Root.tsx
+++ b/stats-cards/src/Root.tsx
@@ -27,9 +27,9 @@ const STATS = [
},
{
id: 'tokens',
- value: 46.8,
+ value: 189,
suffix: 'T',
- label: 'Tokens / week',
+ label: 'Tokens / month',
sub: 'routed across the network',
},
] as const;