get_token_analytics
Retrieve time-series token analytics with summary and per-bucket counts of total, prompt, and completion tokens for consumption trend analysis.
Instructions
Get token-usage time-series data with summary.total_tokens, summary.prompt_tokens, summary.completion_tokens, and per-bucket total/prompt/completion counts. Use this for consumption trends; use get_cost_analytics when you need spend instead of token volume. Enterprise-gated. Returns 403 on non-Enterprise Portkey plans.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| time_of_generation_min | Yes | Start time for the analytics period (ISO8601 format, e.g., '2024-01-01T00:00:00Z') | |
| time_of_generation_max | Yes | End time for the analytics period (ISO8601 format, e.g., '2024-02-01T00:00:00Z') | |
| total_units_min | No | Minimum number of total tokens to filter by | |
| total_units_max | No | Maximum number of total tokens to filter by | |
| cost_min | No | Minimum cost in cents to filter by | |
| cost_max | No | Maximum cost in cents to filter by | |
| prompt_token_min | No | Minimum number of prompt tokens | |
| prompt_token_max | No | Maximum number of prompt tokens | |
| completion_token_min | No | Minimum number of completion tokens | |
| completion_token_max | No | Maximum number of completion tokens | |
| status_code | No | Legacy Portkey query param for HTTP status codes. Comma-separated string; prefer status_codes for structured inputs. | |
| weighted_feedback_min | No | Minimum weighted feedback score (-10 to 10) | |
| weighted_feedback_max | No | Maximum weighted feedback score (-10 to 10) | |
| virtual_keys | No | Legacy Portkey query param for virtual key slugs. Comma-separated string; prefer virtual_key_slugs for structured inputs. | |
| configs | No | Legacy Portkey query param for config slugs. Comma-separated string; prefer config_slugs for structured inputs. | |
| status_codes | No | Structured alias for status_code. Use an array of HTTP status codes; normalized to the legacy comma-separated Portkey query param. | |
| virtual_key_slugs | No | Structured alias for virtual_keys. Use an array of virtual key slugs; normalized to the legacy comma-separated Portkey query param. | |
| config_slugs | No | Structured alias for configs. Use an array of config slugs; normalized to the legacy comma-separated Portkey query param. | |
| workspace_slug | No | Filter by specific workspace | |
| api_key_ids | Yes | Legacy Portkey query param for API key UUIDs. Comma-separated string; request_analytics also accepts an array and normalizes it to this form. | |
| metadata | No | Legacy Portkey query param for metadata filtering. Stringified JSON object, e.g. '{"env":"prod","app":"myapp"}'; prefer metadata_filter for structured inputs. | |
| ai_org_model | No | Legacy Portkey query param for provider/model pairs. Format: 'provider__model' with double underscore, e.g. 'openai__gpt-4' or 'anthropic__claude-3-opus'. Comma-separated string; prefer provider_models for structured inputs. | |
| provider_models | No | Structured alias for ai_org_model. Use provider__model strings in an array; normalized to the legacy comma-separated Portkey query param. | |
| trace_id | No | Legacy Portkey query param for trace IDs. Comma-separated string; prefer trace_ids for structured inputs. | |
| trace_ids | No | Structured alias for trace_id. Use an array of trace IDs; normalized to the legacy comma-separated Portkey query param. | |
| span_id | No | Legacy Portkey query param for span IDs. Comma-separated string; prefer span_ids for structured inputs. | |
| span_ids | No | Structured alias for span_id. Use an array of span IDs; normalized to the legacy comma-separated Portkey query param. | |
| metadata_filter | No | Structured alias for metadata. Use an object such as { env: 'prod' }; normalized to a JSON string before the request is sent. | |
| prompt_slug | No | Filter by prompt slug |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| ok | Yes | Whether the tool call succeeded and returned structured data | |
| data | No | Structured success payload when ok is true | |
| error | No | Structured error payload when ok is false |
Implementation Reference
- src/tools/analytics.tools.ts:482-516 (handler)The MCP tool handler for 'get_token_analytics' that registers the tool with server.tool(). It calls service.analytics.getTokenAnalytics(), maps data points to total/prompt/completion, and formats the response with summary.total_tokens, prompt_tokens, and completion_tokens.
server.tool( "get_token_analytics", "Get token-usage time-series data with summary.total_tokens, summary.prompt_tokens, summary.completion_tokens, and per-bucket total/prompt/completion counts. Use this for consumption trends; use get_cost_analytics when you need spend instead of token volume.", baseAnalyticsSchema, async (params) => { const analytics = await service.analytics.getTokenAnalytics( normalizeAnalyticsParams(params as Record<string, unknown>), ); const dataPoints = analytics.data_points.map((point) => ({ timestamp: point.timestamp, total: point.total, prompt: point.prompt, completion: point.completion, })); return { content: [ { type: "text", text: JSON.stringify( formatGraphAnalytics( { total_tokens: analytics.summary.total, prompt_tokens: analytics.summary.prompt, completion_tokens: analytics.summary.completion, }, dataPoints, ), null, 2, ), }, ], }; }, ); - src/tools/analytics.tools.ts:15-180 (schema)Input schema (baseAnalyticsSchema) used by get_token_analytics. Defines all filter parameters including time range, token counts, cost, status codes, virtual keys, configs, metadata, provider models, trace IDs, span IDs, and more.
const baseAnalyticsSchema = { time_of_generation_min: z .string() .describe( "Start time for the analytics period (ISO8601 format, e.g., '2024-01-01T00:00:00Z')", ), time_of_generation_max: z .string() .describe( "End time for the analytics period (ISO8601 format, e.g., '2024-02-01T00:00:00Z')", ), total_units_min: z.coerce .number() .positive() .optional() .describe("Minimum number of total tokens to filter by"), total_units_max: z.coerce .number() .positive() .optional() .describe("Maximum number of total tokens to filter by"), cost_min: z.coerce .number() .positive() .optional() .describe("Minimum cost in cents to filter by"), cost_max: z.coerce .number() .positive() .optional() .describe("Maximum cost in cents to filter by"), prompt_token_min: z.coerce .number() .positive() .optional() .describe("Minimum number of prompt tokens"), prompt_token_max: z.coerce .number() .positive() .optional() .describe("Maximum number of prompt tokens"), completion_token_min: z.coerce .number() .positive() .optional() .describe("Minimum number of completion tokens"), completion_token_max: z.coerce .number() .positive() .optional() .describe("Maximum number of completion tokens"), status_code: z .string() .optional() .describe( "Legacy Portkey query param for HTTP status codes. Comma-separated string; prefer status_codes for structured inputs.", ), weighted_feedback_min: z.coerce .number() .min(-10) .max(10) .optional() .describe("Minimum weighted feedback score (-10 to 10)"), weighted_feedback_max: z.coerce .number() .min(-10) .max(10) .optional() .describe("Maximum weighted feedback score (-10 to 10)"), virtual_keys: z .string() .optional() .describe( "Legacy Portkey query param for virtual key slugs. Comma-separated string; prefer virtual_key_slugs for structured inputs.", ), configs: z .string() .optional() .describe( "Legacy Portkey query param for config slugs. Comma-separated string; prefer config_slugs for structured inputs.", ), status_codes: z .array(z.string()) .optional() .describe( "Structured alias for status_code. Use an array of HTTP status codes; normalized to the legacy comma-separated Portkey query param.", ), virtual_key_slugs: z .array(z.string()) .optional() .describe( "Structured alias for virtual_keys. Use an array of virtual key slugs; normalized to the legacy comma-separated Portkey query param.", ), config_slugs: z .array(z.string()) .optional() .describe( "Structured alias for configs. Use an array of config slugs; normalized to the legacy comma-separated Portkey query param.", ), workspace_slug: z .string() .optional() .describe("Filter by specific workspace"), api_key_ids: z .preprocess((value) => { if (value == null) { return value; } if (Array.isArray(value)) { return value.map((item) => String(item)).join(","); } return value; }, z.string().optional()) .describe( "Legacy Portkey query param for API key UUIDs. Comma-separated string; request_analytics also accepts an array and normalizes it to this form.", ), metadata: z .string() .optional() .describe( 'Legacy Portkey query param for metadata filtering. Stringified JSON object, e.g. \'{"env":"prod","app":"myapp"}\'; prefer metadata_filter for structured inputs.', ), ai_org_model: z .string() .optional() .describe( "Legacy Portkey query param for provider/model pairs. Format: 'provider__model' with double underscore, e.g. 'openai__gpt-4' or 'anthropic__claude-3-opus'. Comma-separated string; prefer provider_models for structured inputs.", ), provider_models: z .array(z.string()) .optional() .describe( "Structured alias for ai_org_model. Use provider__model strings in an array; normalized to the legacy comma-separated Portkey query param.", ), trace_id: z .string() .optional() .describe( "Legacy Portkey query param for trace IDs. Comma-separated string; prefer trace_ids for structured inputs.", ), trace_ids: z .array(z.string()) .optional() .describe( "Structured alias for trace_id. Use an array of trace IDs; normalized to the legacy comma-separated Portkey query param.", ), span_id: z .string() .optional() .describe( "Legacy Portkey query param for span IDs. Comma-separated string; prefer span_ids for structured inputs.", ), span_ids: z .array(z.string()) .optional() .describe( "Structured alias for span_id. Use an array of span IDs; normalized to the legacy comma-separated Portkey query param.", ), metadata_filter: z .record(z.string(), z.unknown()) .optional() .describe( "Structured alias for metadata. Use an object such as { env: 'prod' }; normalized to a JSON string before the request is sent.", ), prompt_slug: z.string().optional().describe("Filter by prompt slug"), }; - src/tools/index.ts:110-130 (registration)Registration: 'get_token_analytics' is listed in the ENTERPRISE_GATED_TOOL_NAMES set in src/tools/index.ts, marking it as an enterprise-gated tool.
const ENTERPRISE_GATED_TOOL_NAMES = new Set([ "get_cost_analytics", "get_request_analytics", "get_token_analytics", "get_latency_analytics", "get_error_analytics", "get_error_rate_analytics", "get_cache_hit_latency", "get_cache_hit_rate", "get_users_analytics", "get_error_stacks_analytics", "get_error_status_codes_analytics", "get_user_requests_analytics", "get_rescued_requests_analytics", "get_feedback_analytics", "get_feedback_models_analytics", "get_feedback_scores_analytics", "get_feedback_weighted_analytics", "get_analytics_group_users", "get_analytics_group_models", "get_analytics_group_metadata", - Service-layer helper: getTokenAnalytics() in AnalyticsService makes a GET request to '/analytics/graphs/tokens' with built analytics params.
async getTokenAnalytics( params: BaseAnalyticsParams, ): Promise<TokenAnalyticsResponse> { return this.get<TokenAnalyticsResponse>( "/analytics/graphs/tokens", this.buildAnalyticsParams(params), ); } - Type definitions: TokenDataPoint (timestamp, total, prompt, completion), TokenSummary (total, prompt, completion), and TokenAnalyticsResponse interface.
export interface TokenDataPoint { timestamp: string; total: number; prompt: number; completion: number; } export interface TokenSummary { total: number; prompt: number; completion: number; } export interface TokenAnalyticsResponse { object: "analytics-graph"; data_points: TokenDataPoint[]; summary: TokenSummary; }