curl --request POST \
--url https://api.promptlayer.com/api/public/v2/requests/analytics/custom-analytics \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <api-key>' \
--data '
{
"filter_group": {
"logic": "AND",
"filters": [
{
"field": "request_start_time",
"operator": "between",
"value": [
"2025-06-01T00:00:00Z",
"2025-06-08T00:00:00Z"
]
}
]
},
"customCharts": [
{
"id": "cost_by_model",
"title": "Cost by Model",
"chartType": "bar",
"metric": "sum",
"metricField": "cost",
"groupByField": "engine",
"limit": 10
}
]
}
'
{
"success": true,
"customCharts": [
{
"id": "cost_by_model",
"title": "Cost by Model",
"chartType": "bar",
"series": [
{
"key": "value",
"label": "Cost",
"unit": "currency"
}
],
"data": [
{
"label": "gpt-4o",
"value": 8.42
},
{
"label": "claude-sonnet-4-6",
"value": 3.91
}
]
}
]
}{
"success": false,
"message": "<string>",
"error": "<string>"
}{
"success": false,
"message": "<string>",
"error": "<string>"
}{
"success": false,
"message": "<string>",
"error": "<string>"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Tracking
Request Analytics — Custom Queries
POST
/
api
/
public
/
v2
/
requests
/
analytics
/
custom-analytics
curl --request POST \
--url https://api.promptlayer.com/api/public/v2/requests/analytics/custom-analytics \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <api-key>' \
--data '
{
"filter_group": {
"logic": "AND",
"filters": [
{
"field": "request_start_time",
"operator": "between",
"value": [
"2025-06-01T00:00:00Z",
"2025-06-08T00:00:00Z"
]
}
]
},
"customCharts": [
{
"id": "cost_by_model",
"title": "Cost by Model",
"chartType": "bar",
"metric": "sum",
"metricField": "cost",
"groupByField": "engine",
"limit": 10
}
]
}
'
{
"success": true,
"customCharts": [
{
"id": "cost_by_model",
"title": "Cost by Model",
"chartType": "bar",
"series": [
{
"key": "value",
"label": "Cost",
"unit": "currency"
}
],
"data": [
{
"label": "gpt-4o",
"value": 8.42
},
{
"label": "claude-sonnet-4-6",
"value": 3.91
}
]
}
]
}{
"success": false,
"message": "<string>",
"error": "<string>"
}{
"success": false,
"message": "<string>",
"error": "<string>"
}{
"success": false,
"message": "<string>",
"error": "<string>"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Run custom aggregations over your request logs. Define what to measure and how to slice it; the API returns structured data you can use however you want — feed it into a chart, run analysis on it, pipe it into a dashboard, or process it programmatically.
Each query in the
Supported metric fields (
Group-by fields (
customCharts array specifies a metric and optionally a breakdown dimension or time bucketing:
| Shape | Fields required |
|---|---|
| Single aggregate | metric (and metricField unless metric is count) |
| Grouped breakdown | Add groupByField or groupByMetadataKey |
| Over time | Add timeSeries: true |
| Multiple metrics at once | Replace metric/metricField with a series array |
Metrics
metric controls the aggregation function:
| Value | Description |
|---|---|
count | Number of matching requests (no metricField needed) |
sum | Total of a numeric field |
avg | Average of a numeric field |
min | Minimum value |
max | Maximum value |
percentile | Arbitrary percentile — requires percentile (0–100) |
Supported metric fields (metricField)
input_tokens, output_tokens, cost, latency_ms, prompt_version_number, turn_count, tool_call_count, cached_tokens, thinking_tokens
Latency values are returned in seconds (converted from milliseconds internally).
Group-by fields (groupByField)
engine, provider_type, prompt_id, prompt_version_number, status, error_type, tags, metadata_keys, output_keys, input_variable_keys, tool_names
Use groupByMetadataKey instead to break down by values of a specific metadata key (e.g. "environment" or "user_id").
Filters
All filter fields from Search Request Logs are supported (filter_group, q, sort_by, sort_order). Filters are applied before aggregation.
Response shape
Each entry in the responsecustomCharts array contains:
id— echoes the id you sentseries— array of series descriptors:{ key, label, unit }— describes what each numeric key in the data rows representsdata— array of rows, each with alabeland one numeric key per series. Time-bucketed rows also includebucketKey(ISO date string).derivedInsights— (multi-metric only) pre-computed ratio summaries
chartType and title are also echoed back but are optional hints — use them if you’re rendering a chart, ignore them if you’re just processing the numbers.
Behavior Notes
sort_by/sort_orderare accepted for compatibility but do not affect aggregated output.- Overall aggregates (no
timeSeries, nogroupByField) return a single row withlabel: "Overall". - Multi-metric grouped time-series is not supported — use multiple single-metric queries instead.
serieskeys must be unique within a query;idvalues must be unique within the request.
Related
Authorizations
Body
application/json
Request body for POST /api/public/v2/requests/analytics/custom-analytics. Inherits all filter fields from RequestLogQuery and adds customCharts.
One or more chart definitions to compute. Chart ids must be unique.
Minimum array length:
1Show child attributes
Show child attributes
Nested filter group with AND/OR logic.
Show child attributes
Show child attributes
Free-text search query.
Accepted for compatibility; does not affect aggregated output.
Available options:
request_start_time, input_tokens, output_tokens, cost, latency_ms, status Available options:
asc, desc Was this page helpful?

