# Run agent tests

Create a durable invocation for 1 to 5,000 visible test entries against an explicit Main Draft or Live snapshot, repeated 1 to 50 times.

## Endpoint

`POST /api/v1/workspaces/{workspace_id}/agents/{agent_id}/test-invocations`

## 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 | — |
| `agent_id` | path | `string` | Yes | — |

## Request body

### application/json request schema

| Field path | Type | Reference | Format | Nullable | Required | Enum | Description |
| --- | --- | --- | --- | --- | --- | --- | --- |
| `$` | `object` | InvocationBody | — | No | Yes | — | — |
| `branch_id` | `string or null` | — | — | Yes | No | — | — |
| `confirm_google_sheets_append` | `boolean` | — | — | No | No | — | — |
| `override_config` | `object or null` | — | — | Yes | No | — | — |
| `repeat_count` | `integer` | — | — | No | Yes | — | — |
| `target` | `string` | — | — | No | Yes | "draft", "live" | — |
| `tests` | `array<object>` | — | — | No | Yes | — | — |
| `tests[]` | `object` | — | — | No | Yes | — | — |
| `tests[].test_id` | `string` | — | — | No | Yes | — | — |
| `tests[].workflow_node_id` | `string or null` | — | — | Yes | No | — | — |
| `tests[].root_folder_id` | `string` | — | — | No | Yes | — | — |
| `tests[].root_folder_name` | `string or null` | — | — | Yes | No | — | — |

## Example

```bash
curl --request POST 'https://operade.ai/api/v1/workspaces/ws_demo/agents/agt_demo/test-invocations' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{"tests":[{"test_id":"test_demo"}],"repeat_count":3,"target":"live"}'
```

## Responses

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

### 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 | — | — |

### 201 application/json response schema

| Field path | Type | Reference | Format | Nullable | Required | Enum | Description |
| --- | --- | --- | --- | --- | --- | --- | --- |
| `$` | `object` | InvocationCreatedResponse | — | No | Yes | — | — |
| `branch_id` | `string` | — | — | No | Yes | — | — |
| `bucketing_status` | `string` | — | — | No | Yes | "pending", "not_applicable" | — |
| `id` | `string` | — | — | No | Yes | — | — |
| `items` | `array<InvocationItem>` | — | — | No | Yes | — | — |
| `items[]` | `object` | InvocationItem | — | No | Yes | — | — |
| `items[].display_snapshot` | `object` | InvocationDisplaySnapshot | — | No | Yes | — | — |
| `items[].display_snapshot.folder_path` | `array<string>` | — | — | No | Yes | — | — |
| `items[].display_snapshot.folder_path[]` | `string` | — | — | No | Yes | — | — |
| `items[].display_snapshot.name` | `string` | — | — | No | Yes | — | — |
| `items[].display_snapshot.type` | `string` | — | — | No | Yes | "simulation", "llm", "tool" | — |
| `items[].id` | `string` | — | — | No | Yes | — | — |
| `items[].ordinal` | `integer` | — | — | No | Yes | — | — |
| `items[].root_folder_id` | `string or null` | — | — | Yes | Yes | — | — |
| `items[].root_folder_name` | `string or null` | — | — | Yes | Yes | — | — |
| `items[].test_id` | `string` | — | — | No | Yes | — | — |
| `items[].test_revision_id` | `string` | — | — | No | Yes | — | — |
| `items[].workflow_node_id` | `string or null` | — | — | Yes | Yes | — | — |
| `repeat_count` | `integer` | — | — | No | Yes | — | — |
| `run_count` | `integer` | — | — | No | Yes | — | — |
| `status` | `string` | — | — | No | Yes | "pending" | — |
| `target` | `string` | — | — | No | Yes | "draft", "live" | — |

### Response example

```json
{
  "id": "string",
  "target": "draft",
  "repeat_count": 0,
  "branch_id": "string",
  "status": "pending",
  "bucketing_status": "pending",
  "run_count": 0,
  "items": []
}
```

## 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. |
| 403 | `workspace_not_activated` | An Operade operator must activate the workspace and set a positive daily allowance before tests can run. |
| 429 | `quota_exceeded` | The workspace has reached its daily model-usage allowance before the invocation was created. |

## Related operations

- [Get a test invocation](/docs/api-reference/test-invocations/get-test-invocation) — `GET /api/v1/workspaces/{workspace_id}/test-invocations/{invocation_id}`
- [Get a test invocation run](/docs/api-reference/test-invocations/get-test-invocation-run) — `GET /api/v1/workspaces/{workspace_id}/test-invocations/{invocation_id}/runs/{run_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`
