> This page is for API Reference & Tools.

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

# Cancel an eval run and clean up

POST https://api.moveworks.ai/rest/v1alpha1/eval_runs/{eval_run_id}/cancel

Stops the run, tears down the configuration copy ported for it and releases the PurpleSuite instances it
provisioned. `lifecycle.status` becomes `EVAL_RUN_STATUS_CANCELED` at once; `lifecycle.phase` reads
`EVAL_RUN_PHASE_CLEANING_UP` while `lifecycle.cleanup.status` is `CLEANUP_STATUS_RUNNING`, and
`lifecycle.cleanup.status` then reports the outcome, including anything that could not be removed;
`lifecycle.finished_at` is set once cleanup is terminal. A run canceled before anything was ported reports
`CLEANUP_STATUS_SUCCEEDED` at once. Cleanup has no deadline: a cleanup that Moveworks could not start stays
`CLEANUP_STATUS_RUNNING` until an operator restarts it. The run stops counting toward the active-run limits
at once, when it becomes canceled. Your live configuration was never modified, so there is nothing else to
undo.

A run that is `EVAL_RUN_STATUS_COMPLETED` or `EVAL_RUN_STATUS_FAILED` answers `409`.
Cancelling an `EVAL_RUN_STATUS_CANCELED` run is a no-op (`200`). Visible to the credential's user that created
the run and to the eval admins Moveworks designates for the org; any other id answers `404`.


Reference: https://docs.moveworks.com/api-reference/alpha-eval-api/eval-runs/cancel-eval-run

## Authentication

- `Authorization` header (bearer token, required) — OAuth 2.0 client-credentials bearer from `POST /oauth/v1/token` (same as the Conversations API). The token is issued to one org and bound to one user; the run executes in that org and its conversations run as that user. If the eval config names a `source_org`, it must be the same org. An org that is not enabled for the Eval API sees `404 NOT_FOUND` ("API not found") on every route. An enabled org whose credential is not entitled to run evals receives `403 REQUEST_ACCESS_DENIED`. `submitted_by.email_addr` is the email of the user the credential is bound to.

## Request

### Path parameters

- `eval_run_id` (string, required) — The run id returned by the submit call.

## Response

### 200

Canceled, or already canceled and unchanged; the body is the run. `cleanup.status` is `CLEANUP_STATUS_RUNNING` until the teardown of the ported copy reports; poll `GET` for the outcome.

- `metadata` (EvalRunMetadata, required) — What a run is, fixed when the submission is accepted; a `validate_only` preview carries it without `id`.
- `lifecycle` (EvalRunLifecycle, optional) — What moves while the run executes; absent on a `validate_only` preview.
- `warnings` (list of RunWarning, optional) — Non-blocking findings about the run, the twin of the validation `issues[]`. Absent when there are none, never null, never changes `lifecycle.status`. Carried on the create (202, or 200 on a `validate_only` dry run) and on the get, list and cancel responses; findings a pipeline step records later are merged in on later reads.

## Errors

### 400 Bad Request Error

`INVALID_REQUEST`: a malformed `eval_run_id`. `BAD_REQUEST`: a body that is not valid JSON or is larger than 64 KiB; send no body or `{}`.

- `error` (ErrorError, required)

### 401 Unauthorized Error

Missing or invalid credentials.

- `error` (ErrorError, required)

### 403 Forbidden Error

The config names a `source_org` other than the token's org, the caller is not entitled, or the token's user is not provisioned for the Conversations API in the org (or the org has no Conversations API bot); in the last case the message names the org and user and says to ask a Moveworks admin.

- `error` (ErrorError, required)

### 404 Not Found Error

No run with this id is visible to the caller (`RESOURCE_NOT_FOUND`); a run is visible to the user who created it and to the eval admins Moveworks designates for the org, never across orgs. An org without the Eval API enabled, any unknown path and any method a path does not serve answer `NOT_FOUND` with the message `API not found`.

- `error` (ErrorError, required)

### 409 Conflict Error

The run already finished.

- `error` (ErrorError, required)

### 429 Too Many Requests Error

Per-org rate limit. The body is `{"error":"Rate limit exceeded"}`, a string rather than the envelope; no `Retry-After` header is sent.

- `error` (string, optional)

### 500 Internal Server Error

Unexpected failure.

- `error` (ErrorError, required)

## Types

### EvalRunMetadata

What a run is, fixed when the submission is accepted; a `validate_only` preview carries it without `id`.

- `tasks` (EvalRunMetadataTasks, required) — Counts of tasks (one task = one simulated conversation, one `---` document of a task file), never of task files. Fixed at submit, so the dry run, the 202 and every later read report the same numbers; `submitted` = `accepted` + `skipped`.
- `id` (string, optional)
- `title` (string, optional) — `title` from the eval config.
- `submitted_by` (EvalRunMetadataSubmittedBy, optional) — The user the credential resolved to when the run was created; only `email_addr` is populated (no other field of the platform User type is ever set). Output only: ignored on input; absent on runs created outside this API.
- `scoped_agent_id` (string, optional)
- `skipped_tasks` (list of TaskVerdict, optional) — Tasks dropped under `on_invalid_task: ON_INVALID_TASK_SKIP`, with their issues. Absent otherwise.

### EvalRunLifecycle

What moves while the run executes; absent on a `validate_only` preview.

- `status` (enum, required) — Lifecycle of the eval itself. Report availability and cleanup are separate fields. - `EVAL_RUN_STATUS_QUEUED` — accepted, waiting for a per-submitter or system active-run slot; with a per-submitter limit of 1 it waits until the cleanup of the submitter's earlier run is terminal, which is minutes after that run's report is available. `lifecycle.queue_reason` says which limit it waits on. Cancel is allowed. - `EVAL_RUN_STATUS_RUNNING` — `lifecycle.phase` is `EVAL_RUN_PHASE_PREPARING` or `EVAL_RUN_PHASE_RUNNING_TASKS`; `lifecycle.report.status` stays `REPORT_STATUS_PENDING`. - `EVAL_RUN_STATUS_COMPLETED` — the eval produced its report. Terminal for the eval; `lifecycle.cleanup.status` may still be `CLEANUP_STATUS_RUNNING`. - `EVAL_RUN_STATUS_FAILED` — the eval did not produce a report. Terminal. `lifecycle.error.code` says why and whether resubmitting the same files makes sense (see `RunErrorCode`). - `EVAL_RUN_STATUS_CANCELED` — stopped by the caller or an operator. Terminal. No report; a run whose report was ready is `EVAL_RUN_STATUS_COMPLETED` instead, whatever happened to it afterwards. `lifecycle.phase` is set while `EVAL_RUN_STATUS_RUNNING`, and reads `EVAL_RUN_PHASE_CLEANING_UP` on an `EVAL_RUN_STATUS_FAILED` or `EVAL_RUN_STATUS_CANCELED` run while `lifecycle.cleanup.status` is `CLEANUP_STATUS_RUNNING`; `EVAL_RUN_STATUS_COMPLETED` never carries a phase. Transitions: `EVAL_RUN_STATUS_QUEUED → EVAL_RUN_STATUS_RUNNING → EVAL_RUN_STATUS_COMPLETED | EVAL_RUN_STATUS_FAILED`; `cancel` moves any non-terminal state to `EVAL_RUN_STATUS_CANCELED`. Later versions may add values.
  - Allowed values: `EVAL_RUN_STATUS_QUEUED`, `EVAL_RUN_STATUS_RUNNING`, `EVAL_RUN_STATUS_COMPLETED`, `EVAL_RUN_STATUS_FAILED`, `EVAL_RUN_STATUS_CANCELED`
- `created_at` (datetime, required)
- `report` (ReportState, required) — The report is the JSON body of `GET /rest/v1alpha1/eval_runs/{eval_run_id}/report`; there is no link.
- `cleanup` (CleanupState, required) — Outcome of removing what the run provisioned: the configuration copy ported into your org and the PurpleSuite instances seeded for its tasks. Kept separate from `lifecycle.status` so a run whose eval succeeded but whose copy or instances could not be fully removed is visible; anything left is listed in `remaining`.
- `phase` (enum, optional) — Set while `status` is `EVAL_RUN_STATUS_RUNNING`, and while cleanup is still running after a cancel or failure.
  - Allowed values: `EVAL_RUN_PHASE_PREPARING`, `EVAL_RUN_PHASE_RUNNING_TASKS`, `EVAL_RUN_PHASE_CLEANING_UP`
- `started_at` (datetime, optional) — First step started.
- `finished_at` (datetime, optional) — Set when both the eval and cleanup are terminal.
- `error` (RunError, optional) — Present when `lifecycle.status` is `EVAL_RUN_STATUS_FAILED`. Never contains raw exception text.
- `queue_reason` (enum, optional) — Set while `status` is `EVAL_RUN_STATUS_QUEUED` and the run waits on an active-run limit, on `GET /eval_runs/{id}`, on every queued item of `GET /eval_runs` and on the create response; cancel and `validate_only` responses never carry it.
  - Allowed values: `QUEUE_REASON_SUBMITTER_LIMIT`, `QUEUE_REASON_SYSTEM_LIMIT`

### RunWarning

A non-blocking finding about a submission or a run. Branch on `code`; show `message`; use `path` to point the author at the config entry. A warning never turns a submission into a `VALIDATION_FAILED` error and never changes `lifecycle.status`; `issues[]` block, `warnings[]` do not.

- `code` (enum, required) — Code of a non-blocking finding. Treat a code this version does not list as `WARNING_CODE_OTHER`. - `WARNING_CODE_AS_IS_CONNECTOR_WRITES` — the eval config declares at least one `connector_map` entry with `mode: as_is`, so conversations in this run may read from and write to the real systems behind those connectors; `path` names the first such entry. - `WARNING_CODE_UNMAPPED_CONNECTOR_SKIPPED` — the scoped agent calls a connector that `connector_map` omits, so the port skipped it: an HTTP connector's actions call an inert dummy that never reaches the real system, an MCP connector's servers are left out and their tools are absent from the eval. One warning per such connector; `message` names it and the servers it lost, `path` is `connector_map`. Present on every read once the port step has succeeded; validation cannot see the agent, so the create response and a `validate_only` dry run never carry it. - `WARNING_CODE_OTHER` — a finding without a dedicated code yet; read `message`. Today every accepted submission carries one, with no `path`: *This run uses your own org: native plugins your agent carries, such as ticket updates, password resets and handoffs, run for real in your org.* It appears on the dry run, the 202 and every later read, even when every connector is `mocked`. Later versions may add values.
  - Allowed values: `WARNING_CODE_AS_IS_CONNECTOR_WRITES`, `WARNING_CODE_UNMAPPED_CONNECTOR_SKIPPED`, `WARNING_CODE_OTHER`
- `message` (string, required) — Customer-safe, states the finding and the config values it applies to.
- `path` (string, optional) — Dotted path into the eval config with list indices, e.g. `connector_map[0]`. Absent when the warning is about the submission as a whole.

### ErrorError

- `code` (enum, required) — | code | HTTP | meaning | | ------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `INVALID_REQUEST` | 400, 409 | 400: a required field is empty (`eval_config.content`, `task_files[i].file_id`), a `limit` outside 1 to 100, or a malformed `cursor` or `eval_run_id`; raised by the service. 409: the run's state forbids the call (report not ready, run ended without a report, cancel of a COMPLETED or FAILED run); the message names the state. | | `VALIDATION_FAILED` | 400 | Submission rejected, nothing started; `message` opens with the rejected-of-submitted task file counts (files, not tasks), then lists the issues (file, task index, code, path, line), at most 20 lines then `+N more`; a `validate_only` dry run answers the same error. | | `FIELD_TOO_LARGE` | 400 | The task files referenced by id exceed 256 MiB together. | | `REQUEST_ACCESS_DENIED` | 403 | Config names a `source_org` other than the token's org, the caller is not entitled, or the token's user is not provisioned for the Conversations API in the org (or the org has no Conversations API bot). | | `RESOURCE_NOT_FOUND` | 404 | No run with this id is visible to the caller: a run is visible to the user who created it and to the eval admins Moveworks designates for the org. Used instead of 403 so run ids do not leak across users or orgs. | | `RESOURCE_ALREADY_EXISTS` | 409 | Not expected: extra runs wait as `EVAL_RUN_STATUS_QUEUED` (see `lifecycle.queue_reason`). Listed for completeness. | | `BAD_REQUEST` | 400 | The body is not valid JSON, a field has the wrong type, a reserved field is set, or a cancel body exceeds 64 KiB; raised by the gateway before the request reaches the service. | | `UNAUTHORIZED` | 401 | Missing or invalid bearer token. | | `NOT_FOUND` | 404 | Unknown path or method, or the Eval API feature is off for the org ("API not found"). | | `INTERNAL_SERVER_ERROR` | 500 | Unexpected failure. | A rate-limited request (429) carries the string body `{"error":"Rate limit exceeded"}`, not this envelope.
  - Allowed values: `INVALID_REQUEST`, `VALIDATION_FAILED`, `FIELD_TOO_LARGE`, `REQUEST_ACCESS_DENIED`, `RESOURCE_NOT_FOUND`, `RESOURCE_ALREADY_EXISTS`, `BAD_REQUEST`, `UNAUTHORIZED`, `NOT_FOUND`, `INTERNAL_SERVER_ERROR`
- `message` (string, required) — Human-readable, customer-safe. Not stable; branch on `code`.

### EvalRunMetadataTasks

Counts of tasks (one task = one simulated conversation, one `---` document of a task file), never of task files. Fixed at submit, so the dry run, the 202 and every later read report the same numbers; `submitted` = `accepted` + `skipped`.

- `submitted` (integer, required) — Tasks across all task files, whether accepted or skipped.
- `accepted` (integer, required) — Tasks the run executes.
- `skipped` (integer, required) — Tasks dropped from the run; non-zero only with `on_invalid_task: ON_INVALID_TASK_SKIP`.

### EvalRunMetadataSubmittedBy

The user the credential resolved to when the run was created; only `email_addr` is populated (no other field of the platform User type is ever set). Output only: ignored on input; absent on runs created outside this API.

- `email_addr` (string, optional)

### TaskVerdict

Per-task validation outcome. `file` + `index` locate the task in the submission; `goal_id` is present when the document parsed far enough to have one.

- `file` (string, required) — Task file name (the upload filename); the file id when the upload name is unknown.
- `index` (integer, required) — 0-based position of the task's YAML document in the file.
- `accepted` (boolean, required)
- `goal_id` (string, optional)
- `issues` (list of ValidationIssue, optional) — Every issue found in this task, in document order. Empty when accepted. `line` is relative to the file, not the document.

### ReportState

The report is the JSON body of `GET /rest/v1alpha1/eval_runs/{eval_run_id}/report`; there is no link.

- `status` (enum, required) — `REPORT_STATUS_AVAILABLE` = fetch it now, even if cleanup is still running. `REPORT_STATUS_UNAVAILABLE` = the run ended without one. Later versions may add values.
  - Allowed values: `REPORT_STATUS_PENDING`, `REPORT_STATUS_AVAILABLE`, `REPORT_STATUS_UNAVAILABLE`
- `available_at` (datetime, optional)

### CleanupState

Outcome of removing what the run provisioned: the configuration copy ported into your org and the PurpleSuite instances seeded for its tasks. Kept separate from `lifecycle.status` so a run whose eval succeeded but whose copy or instances could not be fully removed is visible; anything left is listed in `remaining`.

- `status` (enum, required) — Outcome of releasing what the run provisioned, independent of `lifecycle.status`. Later versions may add values.
  - Allowed values: `CLEANUP_STATUS_NOT_STARTED`, `CLEANUP_STATUS_RUNNING`, `CLEANUP_STATUS_SUCCEEDED`, `CLEANUP_STATUS_FAILED`
- `finished_at` (datetime, optional)
- `deleted_count` (integer, optional) — Objects removed. Omitted when 0.
- `remaining` (list of CleanupStateRemainingItems, optional) — Provisioned resources that could not be released. Moveworks is alerted on every non-empty list and releases them; listed here so you can verify.
- `message` (string, optional)

### RunError

Present when `lifecycle.status` is `EVAL_RUN_STATUS_FAILED`. Never contains raw exception text.

- `code` (enum, required) — Grouped by who has to act. **Fix your input and resubmit** | code | meaning | `details` (reserved shape; not populated today) | | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | | `RUN_ERROR_CODE_AGENT_NOT_FOUND` | `scoped_agent_id` does not resolve in the token's org. | `{scoped_agent_id}` | | `RUN_ERROR_CODE_CONNECTOR_UNRESOLVABLE` | A `connector_map` entry resolved at submit but the agent's actions reference a connector that no longer matches at run time. | `{connectors: [{name, original_url, candidates: [{integration_id, base_url, auth_type}], hint}]}` | | `RUN_ERROR_CODE_MOCK_ENDPOINT_UNREACHABLE` | The PurpleSuite app behind a `mocked` connector failed its preflight. | `{connector, url, http_status}` | | `RUN_ERROR_CODE_SEED_DATA_REJECTED` | Reserved, not produced today. Kept for seed data that passed validation but the simulated environment refused; seeding failures are caught per task, so the task fails and the run still completes. | `{task_files: [{name, reason}]}` | | `RUN_ERROR_CODE_EVAL_USER_UNAVAILABLE` | Reserved, not produced today. Kept for a run-as user that passed submit-time validation but could not be resolved when the run started (removed or deprovisioned since); the run-as user is resolved at submit. | `{email}` | **Moveworks-side; resubmitting the same files may succeed** | code | meaning | `details` (reserved shape; not populated today) | | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | | `RUN_ERROR_CODE_ENVIRONMENT_SETUP_FAILED` | Porting the configuration copy into the org, or provisioning or seeding the PurpleSuite instances, failed. Also produced today when the run's seed data exceeds the simulated environment's upload limits, and for an MCP-backed agent submitted with `platform: minerva`; both cases need an input change, not a resubmit. | `{}` | | `RUN_ERROR_CODE_DISPATCH_FAILED` | The run could not be started after retries. | `{}` | | `RUN_ERROR_CODE_EVAL_RUN_FAILED` | The conversation run failed as a whole (not a per-task failure; those are in the report). | `{}` | | `RUN_ERROR_CODE_TIMED_OUT` | The run exceeded the maximum duration (6 h). | `{limit_seconds}` | | `RUN_ERROR_CODE_INTERNAL_ERROR` | Anything else. Quote `reference` to support. | `{}` | Later versions may add values.
  - Allowed values: `RUN_ERROR_CODE_AGENT_NOT_FOUND`, `RUN_ERROR_CODE_CONNECTOR_UNRESOLVABLE`, `RUN_ERROR_CODE_MOCK_ENDPOINT_UNREACHABLE`, `RUN_ERROR_CODE_SEED_DATA_REJECTED`, `RUN_ERROR_CODE_EVAL_USER_UNAVAILABLE`, `RUN_ERROR_CODE_ENVIRONMENT_SETUP_FAILED`, `RUN_ERROR_CODE_DISPATCH_FAILED`, `RUN_ERROR_CODE_EVAL_RUN_FAILED`, `RUN_ERROR_CODE_TIMED_OUT`, `RUN_ERROR_CODE_INTERNAL_ERROR`
- `message` (string, required) — Customer-safe, templated per code.
- `phase` (enum, required) — Coarse progress while `lifecycle.status` is `EVAL_RUN_STATUS_RUNNING`, or while cleanup is still going after a cancel or failure. `EVAL_RUN_PHASE_PREPARING` = resolving the agent and connectors, porting the configuration copy into the org, provisioning and seeding the PurpleSuite instances, registering the run; `EVAL_RUN_PHASE_RUNNING_TASKS` = conversations in flight; `EVAL_RUN_PHASE_CLEANING_UP` = tearing down the ported copy and releasing the PurpleSuite instances. Later versions may add values.
  - Allowed values: `EVAL_RUN_PHASE_PREPARING`, `EVAL_RUN_PHASE_RUNNING_TASKS`, `EVAL_RUN_PHASE_CLEANING_UP`
- `occurred_at` (datetime, required)
- `reference` (string, required) — Identifier to quote to Moveworks support (the run id today).
- `details` (RunErrorDetails, optional) — Code-specific; see `RunErrorCode`.

### ValidationIssue

One problem in one file. A file can carry many. Branch on `code`; show `message`; use `path`/`line` to point the author at the spot.

- `code` (enum, required) — An `IssueCode`; the container says where the issue sits (a `TaskVerdict` for a task file, none for the eval config).
  - Allowed values: `ISSUE_CODE_MALFORMED_YAML`, `ISSUE_CODE_MISSING_REQUIRED_FIELD`, `ISSUE_CODE_UNKNOWN_FIELD`, `ISSUE_CODE_FILE_NOT_FOUND`, `ISSUE_CODE_FILE_WRONG_PURPOSE`, `ISSUE_CODE_FILE_TOO_LARGE`, `ISSUE_CODE_REQUESTOR_NOT_EVAL_USER`, `ISSUE_CODE_UNMAPPED_CONNECTOR`, `ISSUE_CODE_CONNECTOR_UNRESOLVABLE`, `ISSUE_CODE_CONNECTOR_MODE_INVALID`, `ISSUE_CODE_NO_MOCK_AVAILABLE`, `ISSUE_CODE_AS_IS_CONNECTOR_NOT_ALLOWED`, `ISSUE_CODE_INVALID_MCP_ENABLED_APP`, `ISSUE_CODE_UNSUPPORTED_PLATFORM`, `ISSUE_CODE_UNSUPPORTED_BOT`, `ISSUE_CODE_PAYLOAD_TOO_LARGE`, `ISSUE_CODE_TOO_MANY_TASK_FILES`, `ISSUE_CODE_NO_TASK_FILES`, `ISSUE_CODE_ALL_TASKS_REJECTED`, `ISSUE_CODE_UNSUPPORTED_TARGET_ORG`, `ISSUE_CODE_MISSING_GOAL_ID`, `ISSUE_CODE_DUPLICATE_GOAL_ID`, `ISSUE_CODE_INVALID_FROZEN_TIME`, `ISSUE_CODE_INVALID_SQL`, `ISSUE_CODE_UNKNOWN_COMPARISON_TYPE`, `ISSUE_CODE_UNPREFIXED_JUDGE_ASSERTION`, `ISSUE_CODE_DUPLICATE_GRADER_NAME`, `ISSUE_CODE_UNSUPPORTED_CASE_TYPE`, `ISSUE_CODE_TASK_FILE_TOO_LARGE`, `ISSUE_CODE_INVALID_TASK_FILE_NAME`, `ISSUE_CODE_DUPLICATE_TASK_FILE_NAME`, `ISSUE_CODE_SEED_DATA_TOO_LARGE`, `ISSUE_CODE_TOO_MANY_SEED_RECORDS`, `ISSUE_CODE_OTHER`
- `message` (string, required) — Customer-safe, one sentence, states the rule and the offending value.
- `path` (string, optional) — Dotted path into the YAML document with list indices, e.g. `connector_map[2].mode`, `graders[0].query`. Absent when the whole document is at fault.
- `line` (integer, optional) — Line in the file. Absent when the issue has no position in the document; never emitted as 0.
- `column` (integer, optional) — Absent when the issue has no position in the document; never emitted as 0.

### CleanupStateRemainingItems

- `kind` (string, required) — Free-form resource type. `purple_suite_instance` for a seeded instance; ported entities use a kind such as `ported_connector` (example, not an enumeration).
- `name` (string, required)
- `reason` (string, optional)

### RunErrorDetails

Code-specific; see `RunErrorCode`.

## Examples

**Response**

```json
{
  "metadata": {
    "tasks": {
      "submitted": 40,
      "accepted": 40,
      "skipped": 0
    },
    "id": "b3d1a9e2-6f7c-4d2e-9a1b-2c3d4e5f6a7b",
    "title": "Calendar Eval",
    "submitted_by": {
      "email_addr": "alice.chen@example.com"
    },
    "scoped_agent_id": "sa_01J..."
  },
  "lifecycle": {
    "status": "EVAL_RUN_STATUS_CANCELED",
    "created_at": "2026-10-01T17:02:11Z",
    "report": {
      "status": "REPORT_STATUS_PENDING"
    },
    "cleanup": {
      "status": "CLEANUP_STATUS_RUNNING"
    },
    "phase": "EVAL_RUN_PHASE_CLEANING_UP",
    "started_at": "2026-10-01T17:02:40Z"
  },
  "warnings": [
    {
      "code": "WARNING_CODE_AS_IS_CONNECTOR_WRITES",
      "message": "`hr_directory` runs with `mode: as_is`; conversations in this run may read from and write to the real system behind it.",
      "path": "connector_map[1]"
    },
    {
      "code": "WARNING_CODE_OTHER",
      "message": "This run uses your own org: native plugins your agent carries, such as ticket updates, password resets and handoffs, run for real in your org."
    }
  ]
}
```

**SDK Code**

```python Eval runs_cancelEvalRun_example
import requests

url = "https://api.moveworks.ai/rest/v1alpha1/eval_runs/eval_run_id/cancel"

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

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

print(response.json())
```

```javascript Eval runs_cancelEvalRun_example
const url = 'https://api.moveworks.ai/rest/v1alpha1/eval_runs/eval_run_id/cancel';
const options = {method: 'POST', 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 Eval runs_cancelEvalRun_example
package main

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

func main() {

	url := "https://api.moveworks.ai/rest/v1alpha1/eval_runs/eval_run_id/cancel"

	req, _ := http.NewRequest("POST", 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 Eval runs_cancelEvalRun_example
require 'uri'
require 'net/http'

url = URI("https://api.moveworks.ai/rest/v1alpha1/eval_runs/eval_run_id/cancel")

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

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

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

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

HttpResponse<String> response = Unirest.post("https://api.moveworks.ai/rest/v1alpha1/eval_runs/eval_run_id/cancel")
  .header("Authorization", "Bearer <token>")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.moveworks.ai/rest/v1alpha1/eval_runs/eval_run_id/cancel', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

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

```csharp Eval runs_cancelEvalRun_example
using RestSharp;

var client = new RestClient("https://api.moveworks.ai/rest/v1alpha1/eval_runs/eval_run_id/cancel");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift Eval runs_cancelEvalRun_example
import Foundation

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

let request = NSMutableURLRequest(url: NSURL(string: "https://api.moveworks.ai/rest/v1alpha1/eval_runs/eval_run_id/cancel")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
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()
```