# Get a test invocation run

Return one run with its terminal result, transcript, tool evidence, criteria, model usage, latency, tokens, and cost.

## Endpoint

`GET /api/v1/workspaces/{workspace_id}/test-invocations/{invocation_id}/runs/{run_id}`

## Authentication

| Class | Authentication | Minimum role | API key |
| --- | --- | --- | --- |
| customer-api | Bearer API key or dashboard session cookie; dashboard mutations also require X-CX-Request: 1. | member | Allowed |

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `workspace_id` | path | `string` | Yes | — |
| `invocation_id` | path | `string` | Yes | — |
| `run_id` | path | `string` | Yes | — |

## Request body

This operation has no request body.

## Example

```bash
curl --request GET 'https://operade.ai/api/v1/workspaces/ws_demo/test-invocations/invo_demo/runs/testrun_demo' \
  --header 'Authorization: Bearer YOUR_API_KEY'
```

## Responses

| Status | Description | Content |
| --- | --- | --- |
| 4XX | Handled client error | application/json: `ErrorResponse` |
| 200 | Successful Response | application/json: `RunDetail` |

### 4XX application/json response schema

| Field path | Type | Reference | Format | Nullable | Required | Enum | Description |
| --- | --- | --- | --- | --- | --- | --- | --- |
| `$` | `object` | ErrorResponse | — | No | Yes | — | — |
| `error` | `object` | ErrorItem | — | No | Yes | — | — |
| `error.code` | `string` | — | — | No | Yes | — | — |
| `error.details` | `object` | — | — | No | No | — | — |
| `error.message` | `string` | — | — | No | Yes | — | — |

### 200 application/json response schema

| Field path | Type | Reference | Format | Nullable | Required | Enum | Description |
| --- | --- | --- | --- | --- | --- | --- | --- |
| `$` | `object` | RunDetail | — | No | Yes | — | — |
| `allows_real_tools` | `boolean` | — | — | No | Yes | — | — |
| `completed_at` | `string or null` | — | date-time | Yes | Yes | — | — |
| `conversation_id` | `string or null` | — | — | Yes | No | — | — |
| `cost_usd` | `number` | — | — | No | Yes | — | — |
| `events` | `array<PublicConversationEvent>` | — | — | No | Yes | — | — |
| `events[]` | `object` | PublicConversationEvent | — | No | Yes | — | — |
| `events[].created_at` | `string` | — | date-time | No | Yes | — | — |
| `events[].payload` | `object` | — | — | No | Yes | — | Sanitized public event payload. Private Agent snapshots, dynamic variables, tool snapshots, and internal Guardrail details are removed by the API. |
| `events[].seq` | `integer` | — | — | No | Yes | — | — |
| `events[].type` | `string` | — | — | No | Yes | — | — |
| `id` | `string` | — | — | No | Yes | — | — |
| `input_tokens` | `integer` | — | — | No | Yes | — | — |
| `invocation_item_id` | `string` | — | — | No | Yes | — | — |
| `output_tokens` | `integer` | — | — | No | Yes | — | — |
| `repeat_index` | `integer` | — | — | No | Yes | — | — |
| `result` | `object` | SimulationRunResult or NextReplyRunResult or ToolInvocationRunResult or RunFailureResult or PendingRunResult | — | No | Yes | — | — |
| `result.conversation_id` | `string or null` | — | — | Yes | No | — | — |
| `result.evaluations` | `array<TestEvaluation>` | — | — | No | Yes | — | — |
| `result.evaluations[]` | `object` | TestEvaluation | — | No | Yes | — | — |
| `result.evaluations[].rationale` | `string` | — | — | No | Yes | — | — |
| `result.evaluations[].status` | `string` | — | — | No | Yes | "success", "failure" | — |
| `result.failure_code` | `string or null` | — | — | Yes | No | "evaluator_error", "mock_not_matched", "quota_exceeded", "runtime_error", "tool_unavailable" | — |
| `result.evaluation` | `object or null` | TestEvaluation | — | Yes | No | — | — |
| `result.evaluation.rationale` | `string` | — | — | No | Yes | — | — |
| `result.evaluation.status` | `string` | — | — | No | Yes | "success", "failure" | — |
| `result.response` | `string` | — | — | No | Yes | — | — |
| `result.calls` | `array<ToolCallEvidence>` | — | — | No | Yes | — | — |
| `result.calls[]` | `object` | ToolCallEvidence | — | No | Yes | — | — |
| `result.calls[].arguments` | `object or null` | — | — | Yes | Yes | — | — |
| `result.calls[].arguments_raw` | `string or null` | — | — | Yes | No | — | — |
| `result.calls[].name` | `string` | — | — | No | Yes | — | — |
| `result.calls[].origin` | `string` | — | — | No | Yes | "llm", "workflow", "built_in", "transition" | — |
| `result.calls[].tool_id` | `string` | — | — | No | Yes | — | — |
| `result.calls[].tool_type` | `string` | — | — | No | Yes | "system", "webhook", "google_sheets", "client", "workflow", "api_integration_webhook", "mcp", "code", "workflow_transition" | — |
| `result.parameter_results` | `array<ParameterEvaluation> or null` | — | — | Yes | No | — | — |
| `result.parameter_results[]` | `object` | ParameterEvaluation | — | No | Yes | — | — |
| `result.parameter_results[].error` | `string or null` | — | — | Yes | No | — | — |
| `result.parameter_results[].matched` | `boolean` | — | — | No | Yes | — | — |
| `result.parameter_results[].reason` | `string` | — | — | No | Yes | — | — |
| `result.passed` | `boolean or null` | — | — | Yes | No | — | — |
| `started_at` | `string or null` | — | date-time | Yes | Yes | — | — |
| `status` | `string` | — | — | No | Yes | "pending", "running", "passed", "failed", "interrupted" | — |
| `transcript` | `array<PublicTranscriptEntry>` | — | — | No | Yes | — | — |
| `transcript[]` | `object` | PublicTranscriptEntry | — | No | Yes | — | — |
| `transcript[].role` | `string` | — | — | No | Yes | "user", "agent" | — |
| `transcript[].seq` | `integer` | — | — | No | Yes | — | — |
| `transcript[].text` | `string` | — | — | No | Yes | — | — |
| `updated_at` | `string` | — | date-time | No | Yes | — | — |

### Response example

```json
{
  "id": "string",
  "invocation_item_id": "string",
  "repeat_index": 0,
  "status": "pending",
  "allows_real_tools": false,
  "result": {
    "evaluations": []
  },
  "input_tokens": 0,
  "output_tokens": 0,
  "cost_usd": 0,
  "started_at": "2026-01-01T00:00:00Z",
  "completed_at": "2026-01-01T00:00:00Z",
  "updated_at": "2026-01-01T00:00:00Z",
  "transcript": [],
  "events": []
}
```

## Errors

Reviewed common and route-declared errors are summarized here; the list is not exhaustive. Start with the [distributed error index](/docs/reference/api/errors) to find each code's canonical domain page.

| Status | Code | Description |
| --- | --- | --- |
| 401 | `unauthenticated` | Authentication is missing, invalid, or revoked. |
| 403 | `forbidden` | The authenticated caller does not have access to this operation. |
| 404 | `not_found` | The requested workspace resource was not found. |
| 422 | `validation_failed` | The request did not pass field or business validation. |

## Related operations

- [Run agent tests](/docs/api-reference/test-invocations/create-test-invocation) — `POST /api/v1/workspaces/{workspace_id}/agents/{agent_id}/test-invocations`
- [Get a test invocation](/docs/api-reference/test-invocations/get-test-invocation) — `GET /api/v1/workspaces/{workspace_id}/test-invocations/{invocation_id}`
- [List test invocation runs](/docs/api-reference/test-invocations/list-test-invocation-runs) — `GET /api/v1/workspaces/{workspace_id}/test-invocations/{invocation_id}/runs`
