---
title: "Get shadow evaluation metrics for a binding"
method: GET
path: "/zones/{zone_id}/policy-bindings/{binding_id}/metrics"
tags: ["PolicyBindings"]
---

# Get shadow evaluation metrics for a binding

`GET /zones/{zone_id}/policy-bindings/{binding_id}/metrics`

## Request

- Base URL: `https://docs.keycard.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://docs.keycard.ai/zones/{zone_id}/policy-bindings/{binding_id}/metrics`
- Auth: one of:
  - HTTP bearer
  - OAuth 2
    - Client credentials
    - Token URL: `/service-account-token`

Returns shadow evaluation metrics for a specific binding. Use query parameters to change scope:
- `scope=zone` — zone-level aggregate across all pairings
- `psv_id=<id>` — metrics for a specific policy set version (in any role),

  including per-pairing breakdown

## Path parameters

- `zone_id` string, required
- `binding_id` string, required

## Query parameters

- `scope` 'binding' | 'zone'
- `policy_set_id` string
- `psv_id` string
- `since` string, date-time

## Headers

- `X-API-Version` string
- `X-Client-Request-ID` string, uuid

## Response `200`

Shadow evaluation metrics

- PdpPolicySetShadowMetricsSummary
  - `total_evaluations` integer, required
  - `agree_count` integer, required
  - `shadow_allow_active_deny_count` integer, required
  - `shadow_deny_active_allow_count` integer, required
  - `agreement_rate` number, float: Fraction of evaluations where active and shadow decisions agreed (0.0–1.0)
  - `avg_shadow_duration_ms` integer
  - `stddev_shadow_duration_ms` integer
  - `since` string, date-time, required
  - `pairings` PdpPolicySetShadowPairingSummary[]: Per-pairing breakdown. Present when querying by PSV.
    - `active_psv_id` string, required
    - `shadow_psv_id` string, required
    - `total` integer, required
    - `agree_count` integer, required
    - `first_eval` string, date-time, required
    - `last_eval` string, date-time, required

## Other responses

- `400`: bad request error response when caller supplied invalid input data
- `401`: unauthorized error response when caller session is not authenticated
- `403`: forbidden error response when caller does not have permissions to a resource
- `404`: not found error response when caller does not have permission to see a resource or the resource does not exist
- `429`: rate limit exceeded error response when caller has exhausted api limits for the given time period
- `500`: internal server error response when server encountered error of its own creation
- `default`: internal server error response when server encountered error of its own creation

## Changes

- **2026-10-16** `0cfaff865771`: 14 breaking, 7 warning, 70 info
  - the response property `details/items/field` became optional for the status `400`
  - the response property `details/items/field` became optional for the status `401`
  - the response property `details/items/field` became optional for the status `403`
  - the response property `details/items/field` became optional for the status `404`
  - …87 more
- **2026-04-20** `932699a5ea16`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/keycardai/apis/untitled-api/changes/zones/:zone_id/policy-bindings/:binding_id/metrics/get.md)

---

[API](https://skmtc.dev/keycardai/apis/untitled-api.md) - [All operations](https://skmtc.dev/keycardai/apis/untitled-api/llms.txt) - [OpenAPI document](https://skmtc.dev/keycardai/apis/untitled-api/revisions/0dee67e0a73a?raw)
