> 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.

# Get execution detail

GET https://api.runtype.com/v1/agents/{id}/executions/{executionId}

Get full details for a single agent execution including final output, iteration details, and loop configuration.

Reference: https://docs.runtype.com/api-reference/runtype-api/agents/get-execution-detail

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

### Path parameters

- `id` (string, required)
- `executionId` (string, required)

## Response

### 200

Execution detail

- `agentId` (string, required, nullable)
- `agentSource` (string, required, nullable)
- `agentTargetResolution` (enum, required) — How the run selected its definition: `alias` or `version` for a request that named a selector, `legacy-live-row` for a run that read the mutable agent row.
  - Allowed values: `alias`, `version`, `legacy-live-row`
- `agentVersion` (V1AgentsIdExecutionsExecutionIdGetResponsesContentApplicationJsonSchemaAgentVersion, required, nullable) — Version number and label for `agentVersionId`, joined from `agent_versions`. `null` exactly when `agentVersionId` is `null`.
- `agentVersionId` (string, required, nullable) — The `agent_versions` row this run was recorded against, or `null`. `null` means the surface that admitted the run stamps no version (A2A, Product API, A2A pause admission and the Product MCP capability path record none today) or the run predates version stamping. It is never a claim that the run executed an unversioned configuration.
- `budgetExhausted` (boolean, required, nullable) — Whether the agent loop ended by exhausting its `maxTurns` budget. Read this rather than inferring truncation from `stopReason`: a single-turn loop publishes `end_turn` on a budget end to preserve its original payload shape, and several clean success paths publish that same value. `null` means UNKNOWN — a run recorded before this field existed, or one executed by a lane that reports no per-iteration breakdown (external agents, Claude Managed) — and must not be read as `false`.
- `cancelRequestedAt` (string, required, nullable)
- `completedAt` (string, required, nullable)
- `conversationId` (string, required, nullable) — The conversation thread this run belongs to, so consumers can group a multi-turn conversation's runs without a per-run log query. This is the run's OWN thread, distinct from `parentConversationId` (subagent lineage, the conversation of the run that spawned it). `null` on stateless surfaces (webhook, schedule, eval, one-shot API) and on runs persisted before the column existed.
- `createdAt` (string, required)
- `executionId` (string, required)
- `executionLane` (enum, required) — Which substrate actually ran this turn. `durable` means a Durable Object owned it: a Runtype session for an attached turn (the only lane that sets the `X-Runtype-Execution-Driver` response header), or the run owner a detached run is handed to. `in_process` means the request worker ran it to completion. Read back from the run's own admission-time record, so it reports what happened rather than what the current routing policy would choose now. `executionMode` cannot answer this on its own: both lanes record `attached` for an attached turn. One routing rule is worth knowing when comparing runs: `POST /v1/dispatch` keeps a request that sets `options.debugMode: true` on `in_process`.
  - Allowed values: `durable`, `in_process`
- `executionMode` (enum, required)
  - Allowed values: `attached`, `detached`
- `expiresAt` (string, required, nullable)
- `externalObservedApprovals` (ExternalObservedApprovals, required) — Read-only approval observations within producer traces. Null means history unavailable; an empty lifecycle list means none observed. Structural history survives ingest-fact expiry and is retained when verbose logging is off.
- `externalTelemetry` (V1AgentsIdExecutionsExecutionIdGetResponsesContentApplicationJsonSchemaExternalTelemetry, required, nullable) — Bounded state of the authorized external OTLP trace. Null means no matching trace state is available; it never means complete. This contains no trace facts or captured content.
- `id` (string, required)
- `iterations` (integer, required, nullable)
- `lastHeartbeatAt` (string, required, nullable)
- `notificationMode` (enum, required)
  - Allowed values: `none`, `narrate`, `react`
- `parentAgentId` (string, required, nullable)
- `parentConversationId` (string, required, nullable)
- `parentExecutionId` (string, required, nullable)
- `parentToolCallId` (string, required, nullable)
- `pendingApproval` (V1AgentsIdExecutionsExecutionIdGetResponsesContentApplicationJsonSchemaPendingApproval, required, nullable)
- `retryOfExecutionId` (string, required, nullable)
- `rootExecutionId` (string, required, nullable)
- `startedAt` (string, required, nullable)
- `status` (enum, required)
  - Allowed values: `queued`, `running`, `paused`, `completed`, `failed`, `cancelled`, `interrupted`
- `stopReason` (string, required, nullable)
- `surfaceType` (string, required, nullable)
- `totalCost` (string, required, nullable)
- `agentSpec` (any, optional)
- `finalOutput` (any, optional)
- `inputMessages` (any, optional)
- `iterationDetails` (any, optional)
- `loopConfig` (any, optional)
- `progress` (any, optional)
- `totalTokens` (any, optional)

## Errors

### 400 Bad Request Error

Invalid ID format

- `error` (string, required)
- `code` (string, optional) — Stable error code. `insufficient_scope` marks an API key that lacks a scope this request needs.
- `details` (list of ErrorDetailsItems, optional)
- `requiredScopes` (list of string, optional) — On `insufficient_scope`: every API key scope this request needs.

### 401 Unauthorized Error

Unauthorized

- `error` (string, required)
- `code` (string, optional) — Stable error code. `insufficient_scope` marks an API key that lacks a scope this request needs.
- `details` (list of ErrorDetailsItems, optional)
- `requiredScopes` (list of string, optional) — On `insufficient_scope`: every API key scope this request needs.

### 403 Forbidden Error

Insufficient permissions

- `error` (string, required)
- `code` (string, optional) — Stable error code. `insufficient_scope` marks an API key that lacks a scope this request needs.
- `details` (list of ErrorDetailsItems, optional)
- `requiredScopes` (list of string, optional) — On `insufficient_scope`: every API key scope this request needs.

### 404 Not Found Error

Execution not found

- `error` (string, required)
- `code` (string, optional) — Stable error code. `insufficient_scope` marks an API key that lacks a scope this request needs.
- `details` (list of ErrorDetailsItems, optional)
- `requiredScopes` (list of string, optional) — On `insufficient_scope`: every API key scope this request needs.

### 500 Internal Server Error

Internal server error

- `error` (string, required)
- `code` (string, optional) — Stable error code. `insufficient_scope` marks an API key that lacks a scope this request needs.
- `details` (list of ErrorDetailsItems, optional)
- `requiredScopes` (list of string, optional) — On `insufficient_scope`: every API key scope this request needs.

## Types

### V1AgentsIdExecutionsExecutionIdGetResponsesContentApplicationJsonSchemaAgentVersion

Version number and label for `agentVersionId`, joined from `agent_versions`. `null` exactly when `agentVersionId` is `null`.

- `id` (string, required)
- `label` (string, required, nullable)
- `versionNumber` (integer, required)

### ExternalObservedApprovals

Read-only approval observations within producer traces. Null means history unavailable; an empty lifecycle list means none observed. Structural history survives ingest-fact expiry and is retained when verbose logging is off.

- `availability` (enum, required)
  - Allowed values: `observed`
- `lifecycles` (list of ExternalObservedApprovalsLifecyclesItems, required)
- `version` (enum, required)
  - Allowed values: `1`
- `truncated` (boolean, optional)

### V1AgentsIdExecutionsExecutionIdGetResponsesContentApplicationJsonSchemaExternalTelemetry

Bounded state of the authorized external OTLP trace. Null means no matching trace state is available; it never means complete. This contains no trace facts or captured content.

- `completeness` (enum, required)
  - Allowed values: `partial`, `complete`, `conflicted`, `expired`
- `source` (enum, required)
  - Allowed values: `otlp`
- `terminalRecorded` (boolean, required)

### V1AgentsIdExecutionsExecutionIdGetResponsesContentApplicationJsonSchemaPendingApproval

- `approvalId` (string, required)
- `requestedAt` (string, required)
- `toolCallId` (string, required)
- `toolName` (string, required)
- `toolType` (string, required)
- `description` (string, optional)
- `parameters` (any, optional)
- `reason` (string, optional)
- `timeout` (double, optional)

### 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, …).

### ExternalObservedApprovalsLifecyclesItems

- `decision` (enum, required)
  - Allowed values: `requested`, `approved`, `denied`, `conflicted`
- `key` (string, required)
- `observations` (list of ExternalObservedApprovalsLifecyclesItemsObservationsItems, required)
- `rawStates` (list of enum, required)
  - Allowed values: `requested`, `approved`, `denied`
- `toolCallId` (string, required)
- `sourceConflict` (boolean, optional)
- `toolName` (string, optional)
- `toolType` (string, optional)

### ExternalObservedApprovalsLifecyclesItemsObservationsItems

- `key` (string, required)
- `source` (ExternalObservedApprovalsLifecyclesItemsObservationsItemsSource, required)
- `state` (enum, required)
  - Allowed values: `requested`, `approved`, `denied`
- `observedAt` (datetime, optional)

### ExternalObservedApprovalsLifecyclesItemsObservationsItemsSource

- `attribute` (enum, required)
  - Allowed values: `cloudflare.agents.tool.approval.state`
- `kind` (enum, required)
  - Allowed values: `cloudflare-agents`
- `spanId` (string, required)
- `traceId` (string, required)

## Examples

**Response**

```json
{
  "agentId": "string",
  "agentSource": "string",
  "agentTargetResolution": "alias",
  "agentVersion": {
    "id": "string",
    "label": "string",
    "versionNumber": 1
  },
  "agentVersionId": "string",
  "budgetExhausted": true,
  "cancelRequestedAt": "string",
  "completedAt": "string",
  "conversationId": "string",
  "createdAt": "string",
  "executionId": "string",
  "executionLane": "durable",
  "executionMode": "attached",
  "expiresAt": "string",
  "externalObservedApprovals": {
    "availability": "observed",
    "lifecycles": [
      {
        "decision": "requested",
        "key": "string",
        "observations": [
          {
            "key": "string",
            "source": {
              "attribute": "cloudflare.agents.tool.approval.state",
              "kind": "cloudflare-agents",
              "spanId": "string",
              "traceId": "string"
            },
            "state": "requested",
            "observedAt": "2024-01-15T09:30:00Z"
          }
        ],
        "rawStates": [
          "requested"
        ],
        "toolCallId": "string",
        "sourceConflict": true,
        "toolName": "string",
        "toolType": "string"
      }
    ],
    "version": 1,
    "truncated": true
  },
  "externalTelemetry": {
    "completeness": "partial",
    "source": "otlp",
    "terminalRecorded": true
  },
  "id": "string",
  "iterations": 1,
  "lastHeartbeatAt": "string",
  "notificationMode": "none",
  "parentAgentId": "string",
  "parentConversationId": "string",
  "parentExecutionId": "string",
  "parentToolCallId": "string",
  "pendingApproval": {
    "approvalId": "string",
    "requestedAt": "string",
    "toolCallId": "string",
    "toolName": "string",
    "toolType": "string",
    "description": "string",
    "reason": "string",
    "timeout": 1.1
  },
  "retryOfExecutionId": "string",
  "rootExecutionId": "string",
  "startedAt": "string",
  "status": "queued",
  "stopReason": "string",
  "surfaceType": "string",
  "totalCost": "string"
}
```

**SDK Code**

```python
import requests

url = "https://api.runtype.com/v1/agents/id/executions/executionId"

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

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

print(response.json())
```

```javascript
const url = 'https://api.runtype.com/v1/agents/id/executions/executionId';
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/agents/id/executions/executionId"

	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/agents/id/executions/executionId")

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/agents/id/executions/executionId")
  .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/agents/id/executions/executionId', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

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

```csharp
using RestSharp;

var client = new RestClient("https://api.runtype.com/v1/agents/id/executions/executionId");
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/agents/id/executions/executionId")! 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()
```