{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://raw.githubusercontent.com/api-evangelist/tale-dev/main/json-schema/tale-dev-run-summary-schema.json",
  "title": "RunSummary",
  "description": "One run as a listing reports it — identity, scope, status and timing. The input, output, trace, effects and checkpoints of the full `Run` are inlined only when `include` names them; the single read answers the full row.",
  "x-generated": "2026-10-09",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/tale-dev-openapi.yml#/components/schemas/RunSummary",
  "type": "object",
  "required": [
    "id",
    "runId",
    "name",
    "version",
    "projectId",
    "status",
    "mode",
    "startedBy",
    "startedAt"
  ],
  "properties": {
    "id": {
      "type": "string",
      "description": "The run id — the name the full read uses; `runId` carries the same value"
    },
    "runId": {
      "type": "string",
      "description": "The run id again, under the name the start answered — one value under both names"
    },
    "name": {
      "type": "string",
      "description": "The automation the run was started as. Runs outlive their automation: after `DELETE /api/v1/automations/{name}` the rows stay listed and readable by id under this name, which `GET /api/v1/automations/{name}` then answers 404 for."
    },
    "version": {
      "type": "integer"
    },
    "projectId": {
      "type": [
        "string",
        "null"
      ],
      "description": "URL project for a project run; null for an organization run"
    },
    "status": {
      "type": "string",
      "enum": [
        "queued",
        "running",
        "waiting",
        "quarantined",
        "success",
        "failed",
        "cancelled"
      ]
    },
    "mode": {
      "type": "string",
      "enum": [
        "mock",
        "live"
      ]
    },
    "startedBy": {
      "type": "string",
      "description": "What started the run — one of four forms: `api-key:<userId>` (a start through this API or the MCP endpoint), `user:<userId>` (a start from the product), `trigger:<triggerId>` (a schedule, webhook or event — the id the trigger read answers), or a bare user id on runs the in-product builder recorded before it prefixed them. Split on the first `:`; treat a value without one as a user id."
    },
    "startedVia": {
      "type": "string",
      "enum": [
        "schedule",
        "webhook",
        "event"
      ],
      "description": "Which kind of trigger started a `trigger:<id>` run — read off the run’s own input, so it stays true after the binding changes kind. Absent on a run a person or an API key started."
    },
    "detail": {
      "type": "string",
      "description": "The failure or wait reason, when the run has one. While `waiting` it names the park: `approval:<approvalId>`, `agent:<nodeId>`, `room:<nodeId>`, `repeat:<nodeId>` or `in_doubt:<nodeId>` — `waitingFor` is the field to branch on; when `failed`, the failure sentence, and `failureCode` the stable cause — the sentence is not contractual."
    },
    "failureCode": {
      "type": "string",
      "enum": [
        "node_error",
        "connector_error",
        "llm_output_invalid",
        "approval_rejected",
        "execution_limit",
        "automation_deleted",
        "engine_incompatible",
        "effect_in_doubt",
        "missing_api_key",
        "credit_exhausted",
        "model_not_entitled",
        "auth_error",
        "model_not_found",
        "unsupported_parameter",
        "output_cap_too_high",
        "token_limit",
        "rate_limited",
        "content_filter",
        "context_length",
        "provider_unreachable",
        "provider_error",
        "budget_exceeded",
        "harness_error",
        "turn_crashed",
        "session_gone",
        "start_failed",
        "harvest_failed",
        "resume_failed",
        "deadline",
        "ask_expired"
      ],
      "description": "Why a `failed` run failed — present only with `status: \"failed\"` on a run that failed on a build that records it. See `Run.failureCode` for the vocabulary and which codes are worth a retry."
    },
    "waitingFor": {
      "type": "string",
      "enum": [
        "approval",
        "ask",
        "in_doubt",
        "agent",
        "room",
        "repeat"
      ],
      "description": "Present only while `status` is `waiting`: what the run is parked on. `approval` — a person’s decision on a gate; `ask` — a question a person has to answer; `in_doubt` — a write the run was making when its server stopped may or may not have reached its service, and a person must decide how to continue (in the app: run it again, skip it, or fail the run); `agent` — an agent turn still running, no one to page; `room` — an agent turn whose start waits for sandbox room, no one to page; `repeat` — a node polling until its `repeatUntil` condition holds, no one to page. \"Runs that need a human\" is `waitingFor` in (`approval`, `ask`, `in_doubt`), never `status=waiting` alone."
    },
    "legacyQuarantine": {
      "$ref": "#/$defs/LegacyRunQuarantine"
    },
    "resumeCount": {
      "type": "integer",
      "minimum": 0,
      "description": "How often the run moved to another server: a server that was being updated or restarted handed it on, or another one took it over after its own stopped responding. Steps it had finished never run again. `Run` always carries it; `RunSummary` omits it while it is 0."
    },
    "lastResume": {
      "type": "object",
      "required": [
        "reason",
        "at"
      ],
      "additionalProperties": false,
      "description": "Why and when the run last moved to another server; absent while it never did. `shutdown` — its server was being updated or restarted and handed it on; `lease_expired` — its server stopped responding and another one took it over.",
      "properties": {
        "reason": {
          "type": "string",
          "enum": [
            "shutdown",
            "lease_expired"
          ]
        },
        "at": {
          "type": "integer",
          "minimum": 0,
          "description": "Epoch milliseconds"
        }
      }
    },
    "stalled": {
      "type": "boolean",
      "description": "True while a `running` run waits for a server to take it over after its own stopped (the app reads it as “Interrupted — resuming”): nothing is working on it right now, and another server picks it up within about a minute and a half. `Run` always carries it; `RunSummary` carries it only while true."
    },
    "startedAt": {
      "type": "integer",
      "minimum": 0,
      "description": "Epoch milliseconds"
    },
    "finishedAt": {
      "type": "integer",
      "minimum": 0,
      "description": "Epoch ms; absent while the run is not terminal"
    },
    "input": {
      "description": "With `include=input`"
    },
    "output": {
      "description": "With `include=output`"
    },
    "trace": {
      "description": "With `include=trace`"
    },
    "effects": {
      "description": "With `include=effects`"
    },
    "checkpoints": {
      "description": "With `include=checkpoints`"
    }
  },
  "$defs": {
    "LegacyRunQuarantine": {
      "type": "object",
      "additionalProperties": false,
      "description": "A legacy execution whose external effects or termination cannot be proven. Present on held runs. A recorded stop request does not resolve the hold or establish that work stopped.",
      "required": [
        "reason",
        "observedAt",
        "claimEpoch",
        "priorStatus",
        "resolution"
      ],
      "properties": {
        "reason": {
          "type": "string",
          "enum": [
            "legacy_execution_unproven"
          ]
        },
        "observedAt": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "claimEpoch": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "priorStatus": {
          "type": "string",
          "enum": [
            "queued",
            "running",
            "waiting"
          ]
        },
        "resolution": {
          "type": [
            "object",
            "null"
          ],
          "additionalProperties": false,
          "required": [
            "action",
            "actor",
            "at"
          ],
          "properties": {
            "action": {
              "type": "string",
              "enum": [
                "stop"
              ]
            },
            "actor": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            "at": {
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            }
          }
        }
      }
    }
  }
}