> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.runtype.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.runtype.com/_mcp/server.

# Count runs

GET https://api.runtype.com/v1/runs/stats

Totals, failures, latency percentiles and cost over exactly the runs `GET /v1/runs` lists for the same filters and window, grouped by flow, agent and surface. `failed` uses the list's own `status=failed` predicate, so a count and the rows it describes cannot disagree. `traffic` narrows to live, test or eval runs; `byTraffic` reports all three before that filter. Cost never counts an unknown run as zero: `cost.unpricedRuns` says how many settled runs have no known cost.

Reference: https://docs.runtype.com/api-reference/runtype-api/runs/count-runs

## Authentication

- `Authorization` header (bearer token, required) — API key or Clerk session token

## Servers

- `https://api.runtype.com` (Production, default)
- `https://api.runtype-staging.com` (Staging)

## Request

### Query parameters

- `agentId` (V1RunsStatsGetParametersAgentId, optional) — Filter by agent id; repeat for a set.
- `flowId` (V1RunsStatsGetParametersFlowId, optional) — Filter by flow id; repeat for a set.
- `conversationId` (string, optional) — Filter by conversation id.
- `surfaceId` (string, optional) — Filter by surface id.
- `surfaceType` (string, optional) — Filter by surface family.
- `recordId` (string, optional) — Filter by record id.
- `batchExecutionId` (V1RunsStatsGetParametersBatchExecutionId, optional) — Filter by batch id; repeat for a set.
- `includeChildren` (enum, optional) — true restores the flat enumeration on the UNSCOPED feed, in which a subagent run and a nested-flow run list beside their parent. The unscoped feed is roots only by default: a row whose parentExecutionId is set folds under its parent and is read with parentExecutionId=\<executionId>. Any filter that scopes to a resource — agentId, flowId, conversationId, surfaceId, recordId, batchExecutionId, parentExecutionId, rootExecutionId or executionId — is already an explicit selection and never folds, so an agent that only ever runs as a subagent still lists under agentId. This parameter changes nothing on a scoped request.
  - Allowed values: `true`, `false`
- `source` (enum, optional) — Filter by producing lane.
  - Allowed values: `hosted`, `ingested`
- `status` (enum, optional) — status accepts only running, completed or failed. queued, awaiting and cancelled exist only in the live overlay, which may never change which rows a page holds, so the server cannot filter on them.
  - Allowed values: `running`, `completed`, `failed`
- `traffic` (enum, optional) — live keeps runs real users and integrations started; test keeps runs started from the dashboard (Test, step tests, Ask); eval keeps eval-batch runs; all, or omitted, keeps every run. A schedule run is live, and an eval batch run is eval whoever started it.
  - Allowed values: `live`, `test`, `eval`, `all`
- `from` (string, optional) — Window start (ISO 8601). Defaults to 24 hours ago.
- `to` (string, optional) — Window end (ISO 8601). Defaults to now.

## Response

### 200

Run counts returned

- `data` (RunStats, required)
- `window` (V1RunsStatsGetResponsesContentApplicationJsonSchemaWindow, required) — The started_at window the query resolved to, after defaults.

## Errors

### 400 Bad Request Error

Invalid request, including a filter whose value could not be read

- `error` (string, required)
- `details` (list of ErrorDetailsItems, optional)

### 401 Unauthorized Error

Unauthorized

- `error` (string, required)
- `details` (list of ErrorDetailsItems, optional)

### 403 Forbidden Error

Insufficient API key permissions

- `error` (string, required)
- `details` (list of ErrorDetailsItems, optional)

### 500 Internal Server Error

Internal server error

- `error` (string, required)
- `details` (list of ErrorDetailsItems, optional)

### 503 Service Unavailable Error

Run store temporarily unavailable; nothing could be read. Retry after the `Retry-After` interval (seconds).

- `error` (string, required)
- `code` (enum, required)
  - Allowed values: `RUN_STORE_UNAVAILABLE`
- `details` (list of RunStoreUnavailableErrorDetailsItems, optional)

## Types

### V1RunsStatsGetParametersAgentId

Filter by agent id; repeat for a set.

### V1RunsStatsGetParametersFlowId

Filter by flow id; repeat for a set.

### V1RunsStatsGetParametersBatchExecutionId

Filter by batch id; repeat for a set.

### RunStats

- `byAgentId` (map from string to RunStatsByAgentId, required) — Runs grouped by agent id.
- `byAgentSurface` (map from string to RunStatsByAgentSurface, required) — Runs grouped by agent and surface, keyed `<agentId>:<surfaceId>`.
- `byFlowId` (map from string to RunStatsByFlowId, required) — Runs grouped by flow id.
- `byFlowSurface` (map from string to RunStatsByFlowSurface, required) — Runs grouped by flow and surface, keyed `<flowId>:<surfaceId>`.
- `bySurfaceId` (map from string to RunStatsBySurfaceId, required) — Runs grouped by surface id.
- `byTraffic` (RunStatsByTraffic, required) — The same runs before the `traffic` filter, split by kind, so a live view can say "plus 4 test runs".
- `totals` (RunStatsTotals, required) — Every run the filters match, `traffic` included.

### V1RunsStatsGetResponsesContentApplicationJsonSchemaWindow

The started_at window the query resolved to, after defaults.

- `from` (string, required)
- `to` (string, required)

### ErrorDetailsItems

- `message` (string, required)
- `code` (string, optional) — Stable Runtype validation code (e.g. MISSING_REQUIRED_FIELD, INVALID_ENUM).
- `path` (string, optional) — Dotted JSON path to the offending field.
- `suggestion` (string, optional) — Actionable hint (allowed values, accepted range, …).

### RunStoreUnavailableErrorDetailsItems

- `message` (string, required)
- `code` (string, optional) — Stable Runtype validation code (e.g. MISSING_REQUIRED_FIELD, INVALID_ENUM).
- `path` (string, optional) — Dotted JSON path to the offending field.
- `suggestion` (string, optional) — Actionable hint (allowed values, accepted range, …).

### RunStatsByAgentId

- `cost` (RunStatsByAgentIdCost, required)
- `failed` (integer, required) — Runs that read as failed in `/v1/runs` (the same predicate as `status=failed`).
- `lastStartedAt` (string, required, nullable) — Start of the newest run in the bucket (ISO 8601).
- `p50DurationMs` (double, required, nullable) — Median duration of settled runs, or null when none settled.
- `p95DurationMs` (double, required, nullable) — 95th percentile duration of settled runs, or null when none settled.
- `running` (integer, required) — Runs still running.
- `total` (integer, required) — Runs in the bucket.

### RunStatsByAgentSurface

- `cost` (RunStatsByAgentSurfaceCost, required)
- `failed` (integer, required) — Runs that read as failed in `/v1/runs` (the same predicate as `status=failed`).
- `lastStartedAt` (string, required, nullable) — Start of the newest run in the bucket (ISO 8601).
- `p50DurationMs` (double, required, nullable) — Median duration of settled runs, or null when none settled.
- `p95DurationMs` (double, required, nullable) — 95th percentile duration of settled runs, or null when none settled.
- `running` (integer, required) — Runs still running.
- `total` (integer, required) — Runs in the bucket.

### RunStatsByFlowId

- `cost` (RunStatsByFlowIdCost, required)
- `failed` (integer, required) — Runs that read as failed in `/v1/runs` (the same predicate as `status=failed`).
- `lastStartedAt` (string, required, nullable) — Start of the newest run in the bucket (ISO 8601).
- `p50DurationMs` (double, required, nullable) — Median duration of settled runs, or null when none settled.
- `p95DurationMs` (double, required, nullable) — 95th percentile duration of settled runs, or null when none settled.
- `running` (integer, required) — Runs still running.
- `total` (integer, required) — Runs in the bucket.

### RunStatsByFlowSurface

- `cost` (RunStatsByFlowSurfaceCost, required)
- `failed` (integer, required) — Runs that read as failed in `/v1/runs` (the same predicate as `status=failed`).
- `lastStartedAt` (string, required, nullable) — Start of the newest run in the bucket (ISO 8601).
- `p50DurationMs` (double, required, nullable) — Median duration of settled runs, or null when none settled.
- `p95DurationMs` (double, required, nullable) — 95th percentile duration of settled runs, or null when none settled.
- `running` (integer, required) — Runs still running.
- `total` (integer, required) — Runs in the bucket.

### RunStatsBySurfaceId

- `cost` (RunStatsBySurfaceIdCost, required)
- `failed` (integer, required) — Runs that read as failed in `/v1/runs` (the same predicate as `status=failed`).
- `lastStartedAt` (string, required, nullable) — Start of the newest run in the bucket (ISO 8601).
- `p50DurationMs` (double, required, nullable) — Median duration of settled runs, or null when none settled.
- `p95DurationMs` (double, required, nullable) — 95th percentile duration of settled runs, or null when none settled.
- `running` (integer, required) — Runs still running.
- `total` (integer, required) — Runs in the bucket.

### RunStatsByTraffic

The same runs before the `traffic` filter, split by kind, so a live view can say "plus 4 test runs".

- `eval` (RunStatsByTrafficEval, required)
- `live` (RunStatsByTrafficLive, required)
- `test` (RunStatsByTrafficTest, required)

### RunStatsTotals

Every run the filters match, `traffic` included.

- `cost` (RunStatsTotalsCost, required)
- `failed` (integer, required) — Runs that read as failed in `/v1/runs` (the same predicate as `status=failed`).
- `lastStartedAt` (string, required, nullable) — Start of the newest run in the bucket (ISO 8601).
- `p50DurationMs` (double, required, nullable) — Median duration of settled runs, or null when none settled.
- `p95DurationMs` (double, required, nullable) — 95th percentile duration of settled runs, or null when none settled.
- `running` (integer, required) — Runs still running.
- `total` (integer, required) — Runs in the bucket.

### RunStatsByAgentIdCost

- `known` (double, required) — Sum of total cost over runs whose cost is known. Never includes an unknown cost as 0.
- `pricedRuns` (integer, required) — Settled runs with a known cost.
- `unpricedRuns` (integer, required) — Settled runs with no known cost, usually a model or tool with no price set. When this is above 0, `known` is a lower bound.

### RunStatsByAgentSurfaceCost

- `known` (double, required) — Sum of total cost over runs whose cost is known. Never includes an unknown cost as 0.
- `pricedRuns` (integer, required) — Settled runs with a known cost.
- `unpricedRuns` (integer, required) — Settled runs with no known cost, usually a model or tool with no price set. When this is above 0, `known` is a lower bound.

### RunStatsByFlowIdCost

- `known` (double, required) — Sum of total cost over runs whose cost is known. Never includes an unknown cost as 0.
- `pricedRuns` (integer, required) — Settled runs with a known cost.
- `unpricedRuns` (integer, required) — Settled runs with no known cost, usually a model or tool with no price set. When this is above 0, `known` is a lower bound.

### RunStatsByFlowSurfaceCost

- `known` (double, required) — Sum of total cost over runs whose cost is known. Never includes an unknown cost as 0.
- `pricedRuns` (integer, required) — Settled runs with a known cost.
- `unpricedRuns` (integer, required) — Settled runs with no known cost, usually a model or tool with no price set. When this is above 0, `known` is a lower bound.

### RunStatsBySurfaceIdCost

- `known` (double, required) — Sum of total cost over runs whose cost is known. Never includes an unknown cost as 0.
- `pricedRuns` (integer, required) — Settled runs with a known cost.
- `unpricedRuns` (integer, required) — Settled runs with no known cost, usually a model or tool with no price set. When this is above 0, `known` is a lower bound.

### RunStatsByTrafficEval

- `failed` (integer, required) — Failed runs of this traffic kind in the window.
- `total` (integer, required) — Runs of this traffic kind in the window.

### RunStatsByTrafficLive

- `failed` (integer, required) — Failed runs of this traffic kind in the window.
- `total` (integer, required) — Runs of this traffic kind in the window.

### RunStatsByTrafficTest

- `failed` (integer, required) — Failed runs of this traffic kind in the window.
- `total` (integer, required) — Runs of this traffic kind in the window.

### RunStatsTotalsCost

- `known` (double, required) — Sum of total cost over runs whose cost is known. Never includes an unknown cost as 0.
- `pricedRuns` (integer, required) — Settled runs with a known cost.
- `unpricedRuns` (integer, required) — Settled runs with no known cost, usually a model or tool with no price set. When this is above 0, `known` is a lower bound.

## Examples

**Response**

```json
{
  "data": {
    "byAgentId": {},
    "byAgentSurface": {},
    "byFlowId": {},
    "byFlowSurface": {},
    "bySurfaceId": {},
    "byTraffic": {
      "eval": {
        "failed": 1,
        "total": 1
      },
      "live": {
        "failed": 1,
        "total": 1
      },
      "test": {
        "failed": 1,
        "total": 1
      }
    },
    "totals": {
      "cost": {
        "known": 1.1,
        "pricedRuns": 1,
        "unpricedRuns": 1
      },
      "failed": 1,
      "lastStartedAt": "string",
      "p50DurationMs": 1.1,
      "p95DurationMs": 1.1,
      "running": 1,
      "total": 1
    }
  },
  "window": {
    "from": "string",
    "to": "string"
  }
}
```

**SDK Code**

```python
import requests

url = "https://api.runtype.com/v1/runs/stats"

headers = {"Authorization": "Bearer <token>"}

response = requests.get(url, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.runtype.com/v1/runs/stats';
const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.runtype.com/v1/runs/stats"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.runtype.com/v1/runs/stats")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.runtype.com/v1/runs/stats")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.runtype.com/v1/runs/stats', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.runtype.com/v1/runs/stats");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.runtype.com/v1/runs/stats")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```