List metrics

Your org's AI overview board over a window: totals (generations, prompt and completion tokens, cost in cents, errors, success rate, distinct models and users), a gap-filled time series, a per-model breakdown with the long tail folded into "other", and latency percentiles read from the GenAI spans.

GET /v1/eval/metrics

Addresshttps://api.hanzo.ai/v1/eval/metrics
MethodGET
Operationget_eval_metrics
AuthAuthorization: Bearer $HANZO_API_KEY

Your org's AI overview board over a window: totals (generations, prompt and completion tokens, cost in cents, errors, success rate, distinct models and users), a gap-filled time series, a per-model breakdown with the long tail folded into "other", and latency percentiles read from the GenAI spans.

The window the answer was actually computed over is echoed back, so a client never has to infer it. A platform admin sees the board across ALL orgs; everyone else sees their own.

The board is HONEST-EMPTY where it cannot be computed: with no datastore wired, or under a named project scope the usage ledger does not yet carry, it answers a valid board with zero totals and a flat series rather than a fabricated number or a 500. Requires a validated principal; 401 without one.

Request

2 fields.

FieldInTypeRequiredDescription
rangequerystring—Range is 24h (the default), 7d or 30d.
intervalquerystring—Interval overrides the bucket the series is grouped into: "hour" or "day".

Response

StatusBodyMeaning
200eval.Boardok
defaultproblem-detailsrefused

200 body — 60 fields.

FieldInTypeAlwaysDescription
byModelbodyeval.ModelStat[]—the top models by spend
byModel[].completionTokensbodyinteger (int64)—tokens it answered with
byModel[].costCentsbodyinteger (int64)—what this model cost, in cents
byModel[].costPctbodynumber (double)—share of total spend, 0..100
byModel[].errorRatebodynumber (double)—share of its calls that failed, 0..1
byModel[].errorsbodyinteger (int64)—calls to it that did not succeed
byModel[].modelbodystring—the model this row is about, or "other" for the fold
byModel[].modelCountbodyinteger (int64)—>0 only on the "other" fold
byModel[].p50Msbodynumber (double)—median latency, null when no spans carry it
byModel[].p95Msbodynumber (double)—95th-percentile latency, null when unknown
byModel[].p99Msbodynumber (double)—99th-percentile latency, null when unknown
byModel[].promptTokensbodyinteger (int64)—tokens sent to it
byModel[].providerbodystring—who serves it
byModel[].requestsbodyinteger (int64)—calls to this model in the window
byModel[].totalTokensbodyinteger (int64)—prompt plus completion
latencybodyeval.LatencyStat—
latency.availablebodyboolean—false when no GenAI spans carry timing; the percentiles are then null
latency.p50Msbodynumber (double)—median latency over the window
latency.p95Msbodynumber (double)—95th-percentile latency
latency.p99Msbodynumber (double)—99th-percentile latency
otherbodyeval.ModelStat—
other.completionTokensbodyinteger (int64)—tokens it answered with
other.costCentsbodyinteger (int64)—what this model cost, in cents
other.costPctbodynumber (double)—share of total spend, 0..100
other.errorRatebodynumber (double)—share of its calls that failed, 0..1
other.errorsbodyinteger (int64)—calls to it that did not succeed
other.modelbodystring—the model this row is about, or "other" for the fold
other.modelCountbodyinteger (int64)—>0 only on the "other" fold
other.p50Msbodynumber (double)—median latency, null when no spans carry it
other.p95Msbodynumber (double)—95th-percentile latency, null when unknown
other.p99Msbodynumber (double)—99th-percentile latency, null when unknown
other.promptTokensbodyinteger (int64)—tokens sent to it
other.providerbodystring—who serves it
other.requestsbodyinteger (int64)—calls to this model in the window
other.totalTokensbodyinteger (int64)—prompt plus completion
rangebodyeval.BoardRange—
range.endbodystring—RFC3339 (UTC)
range.intervalbodystring—hour | day
range.rangebodystring—echoed label (24h | 7d | 30d | custom)
range.startbodystring—RFC3339 (UTC)
scopebodyeval.BoardScope—
scope.allOrgsbodyboolean—true when a platform admin is seeing every org at once
scope.orgbodystring—the org the board covers; "" when it covers all of them
scope.projectbodystring—the sub-scope within the org; "" is the whole org
seriesbodyeval.BoardPoint[]—one gap-filled bucket per interval, so a chart never breaks
series[].costCentsbodyinteger (int64)—what this bucket cost, in cents
series[].errorsbodyinteger (int64)—calls in this bucket that did not succeed
series[].generationsbodyinteger (int64)—model calls in this bucket
series[].tbodystring—RFC3339 (UTC) bucket start
series[].totalTokensbodyinteger (int64)—tokens in this bucket
totalsbodyeval.BoardTotals—
totals.completionTokensbodyinteger (int64)—tokens the models answered with
totals.costCentsbodyinteger (int64)—what the window cost, in cents
totals.errorsbodyinteger (int64)—calls that did not succeed
totals.generationsbodyinteger (int64)—how many model calls the window holds
totals.modelsbodyinteger (int64)—how many distinct models were called
totals.promptTokensbodyinteger (int64)—tokens sent to the models
totals.successRatebodynumber (double)—share of calls that succeeded, 0..1
totals.totalTokensbodyinteger (int64)—prompt plus completion
totals.usersbodyinteger (int64)—how many distinct users called them

Failure carries the platform error shape — see Errors.

Examples

hanzo eval metrics
import { Configuration, EvalApi } from 'hanzoai';

const api = new EvalApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.getEvalMetrics();
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import EvalApi

client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = EvalApi(client).get_eval_metrics()
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.EvalAPI.GetEvalMetrics(context.Background()).Execute()
if err != nil {
	return err
}
use hanzo_client::apis::{configuration::Configuration, eval_api};

let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();

let result = eval_api::get_eval_metrics(&cfg, Default::default()).await?;
import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.EvalApi;

ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));

var result = new EvalApi(client).getEvalMetrics();
curl https://api.hanzo.ai/v1/eval/metrics \
  -H "Authorization: Bearer $HANZO_API_KEY"

MCP reaches eval through the eval tool, which names its 16 operations with its own verbs — this one among them, under a name only MCP declares. describe explains any of them:

curl -X POST https://api.hanzo.ai/v1/mcp \
  -H "Content-Type: application/json" \
  -d '{
       "jsonrpc": "2.0",
       "id": 1,
       "method": "tools/call",
       "params": {
         "name": "describe",
         "arguments": {
           "op": "list_eval_datasets"
         }
       }
     }'

Eval API · All Hanzo APIs · Interactive reference

Was this page useful?