Get spans summary

The Spans Summary endpoint returns aggregated statistics for spans matching the given filters. This is useful for getting quick insights into your LLM usage without fetching all individual spans. <Note> Both `GET` and `POST` methods are supported. `POST` is recommended when using complex filters. </Note> ## Query parameters Same parameters as the [List spans endpoint](/api-reference/observe/logs/list-spans): - `start_time` *string*: The start time for filtering spans in ISO 8601 format. If not provided, defaults to 1 hour ago. **Example** ```json { "start_time": "2025-08-15T00:00:00Z" } ``` - `end_time` *string*: The end time for filtering spans in ISO 8601 format. If not provided, defaults to current time. **Example** ```json { "end_time": "2025-08-16T00:00:00Z" } ``` - `all_envs` *string*: Whether to include spans from all environments. `is_test` parameter will override this parameter. Options: `true`, `false`. - `is_test` *string*: Whether to include test spans only. This parameter will override the `all_envs` parameter. Options: `true`, `false`. ## Body parameters You can add filter parameters to the request body (same as [List spans endpoint](/api-reference/observe/logs/list-spans)): - `filters` *object*: The filters to be applied to the spans. <Note> If you want to filter your custom properties, add `metadata__` + your custom property name. For example, to filter `my_custom_property`, use `metadata__my_custom_property`. For a complete list of filter operators and examples, see the [Filters API Reference](/api-reference/reference/filters-api-reference). </Note> **Example** ```json { "model": { "operator": "", "value": ["gpt-4o"] }, "cost": { "operator": "gte", "value": [0.01] } } ``` ## URL-based Filtering Just like the List spans endpoint, you can use URL parameters for quick filtering: ```bash # Filter summary by customer GET /api/request-logs/summary/?customer_identifier=user_123 # Filter by custom metadata GET /api/request-logs/summary/?user_tier=premium&department=sales ``` See the [List spans endpoint](/api-reference/observe/logs/list-spans#url-based-filtering-quick-filters) for complete URL filtering documentation. ## Response All fields are returned at the top level (consistent with experiments API format): Total cost in USD for all filtered spans. Total tokens (prompt + completion) for all filtered spans. Total number of requests matching the filters. Aggregated score summaries grouped by evaluator_id. Each evaluator includes: UUID of the evaluator URL-friendly identifier for the evaluator Display name of the evaluator Type of score: `"numerical"`, `"percentage"`, or `"boolean"` Average score for numerical/percentage evaluators. `null` for boolean evaluators. Count of true values for boolean evaluators. `null` for numerical/percentage evaluators. Count of false values for boolean evaluators. `null` for numerical/percentage evaluators. <Note> **Score Type Behavior:** - **Numerical/Percentage evaluators**: Only `avg_score` is populated - **Boolean evaluators**: Only `true_count` and `false_count` are populated - **Other types**: String, categorical, and JSON evaluators are not included in aggregations </Note> ```python Python url = "https://api.respan.ai/api/request-logs/summary/" headers = { "Authorization": f"Bearer {YOUR_RESPAN_API_KEY}", "Content-Type": "application/json" } params = { "start_time": "2025-12-01T00:00:00Z", "end_time": "2025-12-31T23:59:59Z" } data = { "filters": { "model": { "operator": "", "value": ["gpt-4o"] } } } response = requests.post(url, headers=headers, params=params, json=data) print(response.json()) ``` ```typescript TypeScript const url = 'https://api.respan.ai/api/request-logs/summary/'; const params = new URLSearchParams({ start_time: '2025-12-01T00:00:00Z', end_time: '2025-12-31T23:59:59Z' }); const headers = { 'Authorization': `Bearer ${YOUR_RESPAN_API_KEY}`, 'Content-Type': 'application/json' }; const data = { filters: { model: { operator: '', value: ['gpt-4o'] } } }; fetch(`${url}?${params}`, { method: 'POST', headers: headers, body: JSON.stringify(data) }) .then(response => response.json()) .then(data => console.log(data)); ``` ```bash cURL curl -X POST "https://api.respan.ai/api/request-logs/summary/?start_time=2025-12-01T00:00:00Z&end_time=2025-12-31T23:59:59Z" \ -H "Authorization: Bearer YOUR_RESPAN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "filters": { "model": { "operator": "", "value": ["gpt-4o"] } } }' ``` ```bash cURL (GET with URL filters) # Quick summary with URL filters curl -X GET "https://api.respan.ai/api/request-logs/summary/?customer_identifier=user_123&start_time=2025-12-01T00:00:00Z" \ -H "Authorization: Bearer YOUR_RESPAN_API_KEY" ``` ```json 200 OK { "total_cost": 15.67, "total_tokens": 1250000, "number_of_requests": 8453, "scores": { "550e8400-e29b-41d4-a716-446655440000": { "evaluator_id": "550e8400-e29b-41d4-a716-446655440000", "evaluator_slug": "quality_v1", "evaluator_name": "Response Quality", "score_value_type": "numerical", "avg_score": 4.2, "true_count": null, "false_count": null }, "661e9511-f3ab-52e5-b827-557766551111": { "evaluator_id": "661e9511-f3ab-52e5-b827-557766551111", "evaluator_slug": "accuracy_v1", "evaluator_name": "Factual Accuracy", "score_value_type": "boolean", "avg_score": null, "true_count": 150, "false_count": 10 } } } ``` ## Use Cases **Monitor monthly costs** ```python # Get total cost for the current month import requests from datetime import datetime start_of_month = datetime.now().replace(day=1, hour=0, minute=0, second=0).isoformat() + "Z" response = requests.get( "https://api.respan.ai/api/request-logs/summary/", headers={"Authorization": f"Bearer {YOUR_API_KEY}"}, params={ "start_time": start_of_month, "environment": "prod" } ) data = response.json() print(f"Monthly cost: ${data['total_cost']:.2f}") print(f"Total requests: {data['number_of_requests']}") # Access score summaries if "scores" in data: for evaluator_id, score_data in data["scores"].items(): print(f"{score_data['evaluator_name']}: avg={score_data.get('avg_score', 'N/A')}") ``` **Compare model costs** ```python # Compare costs between different models models = ["gpt-4o", "gpt-4o-mini", "claude-3-5-sonnet-20241022"] for model in models: response = requests.post( "https://api.respan.ai/api/request-logs/summary/", headers={"Authorization": f"Bearer {YOUR_API_KEY}"}, json={ "filters": { "model": { "operator": "", "value": [model] } } } ) data = response.json() print(f"{model}: ${data['total_cost']:.2f}") ``` **Track customer usage** ```python # Get summary for a specific customer response = requests.get( "https://api.respan.ai/api/request-logs/summary/", headers={"Authorization": f"Bearer {YOUR_API_KEY}"}, params={ "customer_identifier": "customer_123", "start_time": "2025-12-01T00:00:00Z" } ) data = response.json() print(f"Customer cost: ${data['total_cost']:.2f}") print(f"Customer requests: {data['number_of_requests']}") ```

Authentication

AuthorizationBearer
API key authentication. Get your API key from https://platform.respan.ai/platform/api-keys

Query parameters

start_timestringOptional
The start time for filtering spans in ISO 8601 format. If not provided, defaults to 1 hour ago.
end_timestringOptional
The end time for filtering spans in ISO 8601 format. If not provided, defaults to current time.
all_envsstringOptionalDefaults to false

Whether to include spans from all environments. is_test parameter will override this parameter. Options: true, false.

is_teststringOptionalDefaults to false

Whether to include test spans only. This parameter will override the all_envs parameter. Options: true, false.

Request

This endpoint expects an object.
filtersobjectOptional
The filters to be applied to the spans.

Response

Successful response for Get spans summary
start_timestring

Errors

401
Unauthorized Error