query_api_requests
Retrieve and filter API request data from Kong Konnect Gateway by specifying time ranges, HTTP methods, status codes, consumer IDs, services, and routes for detailed analytics and monitoring.
Instructions
Query and analyze Kong API Gateway requests with customizable filters. Before calling this it's necessary to have a controlPlaneID and a serviceID or routeID. These can be obtained using the list-control-planes, list-services, and list-routes tools.
INPUT:
timeRange: String - Time range for data retrieval (15M, 1H, 6H, 12H, 24H, 7D)
statusCodes: Number[] (optional) - Filter by specific HTTP status codes
excludeStatusCodes: Number[] (optional) - Exclude specific HTTP status codes
httpMethods: String[] (optional) - Filter by HTTP methods (e.g., GET, POST)
consumerIds: String[] (optional) - Filter by consumer IDs
serviceIds: String[] (optional) - Filter by service IDs. The format of this field must be ":".
routeIds: String[] (optional) - Filter by route IDs. The format of this field must be "controlPlaneID:routeID"
maxResults: Number - Maximum number of results to return (1-1000)
OUTPUT:
metadata: Object - Contains totalRequests, timeRange, and applied filters
requests: Array - List of request objects with details including:
requestId: String - Unique request identifier
timestamp: String - When the request occurred
httpMethod: String - HTTP method used (GET, POST, etc.)
uri: String - Request URI path
statusCode: Number - HTTP status code of the response
consumerId: String - ID of the consumer making the request
serviceId: String - ID of the service handling the request
routeId: String - ID of the matched route
latency: Object - Response time metrics
clientIp: String - IP address of the client
and many more detailed fields...
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| consumerIds | No | Filter by consumer IDs | |
| excludeStatusCodes | No | Exclude specific HTTP status codes (e.g. [400, 401, 500]) | |
| httpMethods | No | Filter by HTTP methods (e.g. ['GET', 'POST', 'DELETE']) | |
| maxResults | No | Number of items to return per page | |
| routeIds | No | Filter by route IDs (from list-routes tool) | |
| serviceIds | No | Filter by service IDs | |
| statusCodes | No | Filter by specific HTTP status codes (e.g. [200, 201, 404]) | |
| timeRange | No | Time range for data retrieval (15M = 15 minutes, 1H = 1 hour, etc.) | 1H |
Implementation Reference
- src/operations/analytics.ts:20-191 (handler)The primary handler function for the 'query_api_requests' tool. It transforms tool parameters into API filters, invokes the low-level API client, and formats the response with enriched metadata and structured request data.export async function queryApiRequests( api: KongApi, timeRange: string, statusCodes?: number[], excludeStatusCodes?: number[], httpMethods?: string[], consumerIds?: string[], serviceIds?: string[], routeIds?: string[], maxResults = 100 ) { try { // Build filters array const filters: ApiRequestFilter[] = []; // Add status code filters if (statusCodes && statusCodes.length > 0) { filters.push({ field: "status_code", operator: "in", value: statusCodes }); } if (excludeStatusCodes && excludeStatusCodes.length > 0) { filters.push({ field: "status_code", operator: "not_in", value: excludeStatusCodes }); } // Add HTTP method filters if (httpMethods && httpMethods.length > 0) { filters.push({ field: "http_method", operator: "in", value: httpMethods }); } // Add consumer filters if (consumerIds && consumerIds.length > 0) { filters.push({ field: "consumer", operator: "in", value: consumerIds }); } // Add service filters if (serviceIds && serviceIds.length > 0) { filters.push({ field: "gateway_service", operator: "in", value: serviceIds }); } // Add route filters if (routeIds && routeIds.length > 0) { filters.push({ field: "route", operator: "in", value: routeIds }); } const result = await api.queryApiRequests(timeRange, filters, maxResults); // Format the response with a consistent structure return { metadata: { totalRequests: result.meta.size, timeRange: { start: result.meta.time_range.start, end: result.meta.time_range.end, }, filters: filters }, requests: result.results.map(req => ({ requestId: req.request_id, timestamp: req.request_start, httpMethod: req.http_method, uri: req.request_uri, statusCode: req.status_code || req.response_http_status, consumerId: req.consumer, serviceId: req.gateway_service, routeId: req.route, latency: { totalMs: req.latencies_response_ms, gatewayMs: req.latencies_kong_gateway_ms, upstreamMs: req.latencies_upstream_ms }, clientIp: req.client_ip, apiProduct: req.api_product, apiProductVersion: req.api_product_version, applicationId: req.application, authType: req.auth_type, headers: { host: req.header_host, userAgent: req.header_user_agent }, dataPlane: { nodeId: req.data_plane_node, version: req.data_plane_node_version }, controlPlane: { id: req.control_plane, group: req.control_plane_group }, rateLimiting: { enabled: req.ratelimit_enabled, limit: req.ratelimit_limit, remaining: req.ratelimit_remaining, reset: req.ratelimit_reset, byTimeUnit: { second: { enabled: req.ratelimit_enabled_second, limit: req.ratelimit_limit_second, remaining: req.ratelimit_remaining_second }, minute: { enabled: req.ratelimit_enabled_minute, limit: req.ratelimit_limit_minute, remaining: req.ratelimit_remaining_minute }, hour: { enabled: req.ratelimit_enabled_hour, limit: req.ratelimit_limit_hour, remaining: req.ratelimit_remaining_hour }, day: { enabled: req.ratelimit_enabled_day, limit: req.ratelimit_limit_day, remaining: req.ratelimit_remaining_day }, month: { enabled: req.ratelimit_enabled_month, limit: req.ratelimit_limit_month, remaining: req.ratelimit_remaining_month }, year: { enabled: req.ratelimit_enabled_year, limit: req.ratelimit_limit_year, remaining: req.ratelimit_remaining_year } } }, service: { port: req.service_port, protocol: req.service_protocol }, requestBodySize: req.request_body_size, responseBodySize: req.response_body_size, responseHeaders: { contentType: req.response_header_content_type, contentLength: req.response_header_content_length }, traceId: req.trace_id, upstreamUri: req.upstream_uri, upstreamStatus: req.upstream_status, recommendations: [ "Use 'get-consumer-requests' tool with consumerId from top failing consumers for more details", "Check 'query-api-requests' with specific status codes for deeper investigation" ] })) }; } catch (error) { throw error; } }
- src/parameters.ts:26-47 (schema)Zod schema defining the input parameters and validation for the query_api_requests tool, including timeRange, filters, and pagination.export const queryApiRequestsParameters = () => z.object({ timeRange: timeRangeSchema, statusCodes: z.array(z.number().int().min(100).max(599)) .optional() .describe("Filter by specific HTTP status codes (e.g. [200, 201, 404])"), excludeStatusCodes: z.array(z.number().int().min(100).max(599)) .optional() .describe("Exclude specific HTTP status codes (e.g. [400, 401, 500])"), httpMethods: z.array(z.string()) .optional() .describe("Filter by HTTP methods (e.g. ['GET', 'POST', 'DELETE'])"), consumerIds: z.array(z.string()) .optional() .describe("Filter by consumer IDs"), serviceIds: z.array(z.string()) .optional() .describe("Filter by service IDs"), routeIds: z.array(z.string()) .optional() .describe("Filter by route IDs (from list-routes tool)"), maxResults: pageSizeSchema, });
- src/tools.ts:17-23 (registration)Tool specification registration in the tools array, defining method name, description from prompts, parameters schema, and category.{ method: "query_api_requests", name: "Query API Requests", description: prompts.queryApiRequestsPrompt(), parameters: parameters.queryApiRequestsParameters(), category: "analytics" },
- src/index.ts:48-60 (registration)MCP server tool registration routing: switch case that maps tool calls to the analytics handler function.case "query_api_requests": result = await analytics.queryApiRequests( this.api, args.timeRange, args.statusCodes, args.excludeStatusCodes, args.httpMethods, args.consumerIds, args.serviceIds, args.routeIds, args.maxResults ); break;
- src/api.ts:87-98 (helper)Low-level API client helper that constructs the request body and makes the HTTP POST to Kong's /api-requests analytics endpoint.async queryApiRequests(timeRange: string, filters: ApiRequestFilter[] = [], maxResults = 100): Promise<ApiRequestsResponse> { const requestBody = { time_range: { type: "relative", time_range: timeRange } as TimeRange, filters: filters, size: maxResults }; return this.kongRequest<ApiRequestsResponse>("/api-requests", "POST", requestBody); }