# Models: R

> API models starting with R.

## `RawUsage`

The vendor's own usage object, exactly as it reported it. Only with `include=rawUsage`.

- `provider: str`
- `model: str`
- `usage: dict[str, Any]`

## `Reason`

- `verdict: Literal['yes', 'no']`
- `reason: str`
- `judge_class_id: str | None` (`judgeClassId` on the wire) (optional)
- `restricted: Optional[Literal[True]]` (optional)

## `RecordDeploymentProblemBody`

- `code: Literal['endpoint-url-invalid', 'endpoint-host-not-allowed', 'endpoint-name-mismatch', 'endpoint-unreachable', 'endpoint-info-mismatch', 'image-not-allowed', 'tenant-not-provisioned', 'capacity-unavailable', 'service-start-failed']`

## `RecordedSecretScope1`

Where a secret an item names is read, recorded when the item is registered: the first of the item's own scope, its project's org and the tenant that has the secret and that the registrant administers (else the broadest they administer). The runtime reads the secret there only: a secret removed from it is missing, never read from a broader scope, and one set later elsewhere changes nothing until it's recorded again: a tool by publishing a new version, an MCP endpoint by unregistering it and registering it again, a webhook trigger by an update that names its secret.

- `kind: Literal['tenant']`

## `RecordedSecretScope2`

Where a secret an item names is read, recorded when the item is registered: the first of the item's own scope, its project's org and the tenant that has the secret and that the registrant administers (else the broadest they administer). The runtime reads the secret there only: a secret removed from it is missing, never read from a broader scope, and one set later elsewhere changes nothing until it's recorded again: a tool by publishing a new version, an MCP endpoint by unregistering it and registering it again, a webhook trigger by an update that names its secret.

- `kind: Literal['org']`
- `org_id: uuid.UUID` (`orgId` on the wire)

## `RecordedSecretScope3`

Where a secret an item names is read, recorded when the item is registered: the first of the item's own scope, its project's org and the tenant that has the secret and that the registrant administers (else the broadest they administer). The runtime reads the secret there only: a secret removed from it is missing, never read from a broader scope, and one set later elsewhere changes nothing until it's recorded again: a tool by publishing a new version, an MCP endpoint by unregistering it and registering it again, a webhook trigger by an update that names its secret.

- `kind: Literal['project']`
- `project_id: uuid.UUID` (`projectId` on the wire)

## `Reference`

- `name: str`
- `ref: str`
- `version: int`

## `RefreshResult`

- `session_token: str` (`sessionToken` on the wire)
- `session_id: str` (`sessionId` on the wire)
- `expires_at: AwareDatetime` (`expiresAt` on the wire)

## `RefusedItem`

- `path: str`
- `message: str`

## `RegisterGuardrailBody`

Guardrail spec. Validated server-side via `@kindgi/guardrails.validateGuardrailSpec`. Metadata-only registration: the `check` id must reference an implementation already available to the runtime.

- `id: str`
- `project_id: uuid.UUID` (`projectId` on the wire)
- `name: str | None` (optional)
- `description: str | None` (optional)
- `kind: str`
- `check: str`
- `config: dict[str, Any] | None` (optional)
- `action: kindgi.client.GuardrailAction`
- `severity: Optional[Literal['info', 'warn', 'error', 'critical']]` (optional)
- `scope: kindgi.client.GuardrailScope | None` (optional)
- `budget: kindgi.client.Budget | None` (optional)
- `judge_capabilities: dict[str, Any] | None` (`judgeCapabilities` on the wire) (optional)

## `RegisterGuardrailResult`

- `guardrail_id: str` (`guardrailId` on the wire)

## `RegisterIdentityProviderBody`

- `root: kindgi.client.OidcIdentityProviderConfig | kindgi.client.SamlIdentityProviderConfig`

## `RegisterIdentityProviderResult`

- `provider_id: str` (`providerId` on the wire)
- `provider: kindgi.client.OidcIdentityProviderConfig | kindgi.client.SamlIdentityProviderConfig | None` (optional)

## `RegisterMCPEndpointBody`

- `endpoint_id: str` (`endpointId` on the wire)
- `name: str`
- `transport: Literal['stdio', 'http-sse', 'streamable-http']`
- `config: kindgi.client.Config3 | kindgi.client.Config4 | kindgi.client.Config5`
- `secret_ref: kindgi.client.MCPEndpointSecretRef | None` (`secretRef` on the wire) (optional)
- `auth: kindgi.client.MCPBasicAuth | kindgi.client.MCPOAuth2ClientCredentialsAuth | kindgi.client.MCPHeaderAuth | None` (optional)
- `instructions: str | None` (optional)
- `metadata: dict[str, Any] | None` (optional)
- `send_traceparent: bool | None` (`sendTraceparent` on the wire) (optional)
- `scope_kind: Literal['tenant', 'org', 'project']` (`scopeKind` on the wire)
- `scope_id: str | None` (`scopeId` on the wire) (optional)

## `RegisterMCPEndpointResult`

- `endpoint_id: str` (`endpointId` on the wire)

## `RegisterProviderBody`

- `metadata: kindgi.client.ProviderMetadata`
- `adapter_id: str`
- `secret_ref: kindgi.client.SecretRef | None` (optional)
- `adapter_config: dict[str, str | float | bool] | None` (optional)
- `send_traceparent: bool | None` (optional)

## `RegisterProviderResult`

- `provider_id: str` (`providerId` on the wire)

## `RegisterReviewerBody`

Register a reviewer for the caller's tenant. Idempotent w\.r.t. `(tenantId, userId)` — re-registering rotates role/displayName rather than inserting a duplicate.

- `user_id: uuid.UUID` (`userId` on the wire)
- `role: Literal['standard', 'senior', 'admin']`
- `display_name: str | None` (`displayName` on the wire) (optional)

## `RegisterScheduleBody`

Name what it runs: `flowId` with `flowVersion`, `agentId` (with an optional `agentVersion`), or `improve` (improvement passes). Registering needs `write` on the project and `execute` on what it runs (`publish` on the agent for `improve`); its runs act as the caller.

- `flow_id: str | None` (`flowId` on the wire) (optional)
- `flow_version: str | None` (`flowVersion` on the wire) (optional)
- `agent_id: str | None` (`agentId` on the wire) (optional)
- `agent_version: str | None` (`agentVersion` on the wire) (optional)
- `improve: kindgi.client.ImproveScheduleTarget | None` (optional)
- `project_id: uuid.UUID | None` (`projectId` on the wire) (optional)
- `config: kindgi.client.Config6`
- `catch_up: Optional[Literal['latest', 'skip']]` (`catchUp` on the wire) (optional)
- `overlap: Optional[Literal['skip', 'allow']]` (optional)
- `starting_deadline_seconds: int | None` (`startingDeadlineSeconds` on the wire) (optional)
- `label: str | None` (optional)

## `RegisterToolBody`

ToolManifest — Tool minus its runtime `handler`. Validated server-side via `@kindgi/tools.validateToolManifest`. Metadata-only registration: the handler is not uploaded and must already be available to the runtime.

- `id: str`
- `project_id: uuid.UUID` (`projectId` on the wire)
- `description: str`
- `version: str | None` (optional)
- `input: dict[str, Any]`
- `output: dict[str, Any]`
- `needs: list[kindgi.client.ToolNeed] | None` (optional)
- `effects: list[kindgi.client.ToolEffect] | None` (optional)
- `transport: Optional[Literal['auto', 'native', 'mcp']]` (optional)
- `mcp_endpoint: str | None` (`mcpEndpoint` on the wire) (optional)
- `metadata: dict[str, Any] | None` (optional)
- `mutating: bool | None` (optional)
- `sandbox: Optional[Literal['none', 'context-isolated', 'strict']]` (optional)
- `limits: kindgi.client.RuntimeLimits | None` (optional)
- `network: kindgi.client.NetworkPolicy1 | kindgi.client.NetworkPolicy2 | None` (optional)
- `needs_spec: kindgi.client.TypedNeeds | None` (`needsSpec` on the wire) (optional)
- `code_artifact_ref: kindgi.client.CodeArtifactRef1 | kindgi.client.CodeArtifactRef2 | None` (`codeArtifactRef` on the wire) (optional)
- `spec: kindgi.client.ToolSpec | None` (optional)

## `RegisterToolResult`

- `tool_id: str` (`toolId` on the wire)

## `RegisterWebhookTriggerBody`

- `flow_id: str` (`flowId` on the wire)
- `flow_version: str` (`flowVersion` on the wire)
- `project_id: uuid.UUID | None` (`projectId` on the wire) (optional)
- `config: kindgi.client.Config8 | None` (optional)
- `hmac_secret_name: str` (`hmacSecretName` on the wire)
- `generate_secret: bool | None` (`generateSecret` on the wire) (optional)
- `signature: kindgi.client.WebhookSignature1 | kindgi.client.WebhookSignature2 | None` (optional)
- `delivery_id_header: str | None` (`deliveryIdHeader` on the wire) (optional)
- `body_limit_bytes: int | None` (`bodyLimitBytes` on the wire) (optional)
- `rate_limit_per_minute: int | None` (`rateLimitPerMinute` on the wire) (optional)
- `label: str | None` (optional)

## `ReinstateAgentVersionResult`

- `agent_id: str` (`agentId` on the wire)
- `version: str`
- `was_tombstoned: bool` (`wasTombstoned` on the wire)

## `ReinstateBlockResult`

- `block_id: str` (`blockId` on the wire)
- `version: str`
- `was_tombstoned: bool` (`wasTombstoned` on the wire)

## `ReinstateEvalSuiteVersionResult`

- `suite_id: str` (`suiteId` on the wire)
- `version: str`
- `was_tombstoned: bool` (`wasTombstoned` on the wire)

## `ReinstateFlowVersionResult`

- `flow_id: str` (`flowId` on the wire)
- `version: str`
- `was_tombstoned: bool` (`wasTombstoned` on the wire)

## `ReinstatePolicyVersionResult`

- `policy_id: str` (`policyId` on the wire)
- `version: str`
- `was_tombstoned: bool` (`wasTombstoned` on the wire)

## `ReinstateToolVersionResult`

- `tool_id: str` (`toolId` on the wire)
- `version: str`
- `was_tombstoned: bool` (`wasTombstoned` on the wire)

## `Remember`

Lets the agent remember: its turns offer the built-in tool `kindgi_remember` (built-in tools are `kindgi_<verb>`; an agent cannot list one in `tools`, and a published tool cannot use the prefix). The model picks the type, the text (up to 2,000 characters), an optional slot `key` and when it stops being true; the scope comes from here and the run. Every remembered fact is `unverified`, attributed to the agent version and the call that wrote it, and expires after `keepDays` unless a person verifies it. A person approves it before any read sees it when the scope is wider than one person (`same-project`, `tenant`) or the text reads like an instruction.

- `types: list[kindgi.client.Type]`
- `scope: Literal['same-user', 'same-conversation', 'same-project', 'tenant']`
- `keep_days: int | None` (`keepDays` on the wire) (optional)

## `Replay`

Each knob left out of the block is 0. No block: no replay checks.

- `max_diverged: int | None` (`maxDiverged` on the wire) (optional)
- `max_errors: int | None` (`maxErrors` on the wire) (optional)
- `max_refused_writes: int | None` (`maxRefusedWrites` on the wire) (optional)
- `max_stopped: int | None` (`maxStopped` on the wire) (optional)

## `ReplayMemoryErasuresBody`

- `erasures: list[kindgi.client.MemoryErasureLedgerEntry]`

## `ReplayMemoryErasuresResult`

- `replayed: list[uuid.UUID]`
- `restored: list[uuid.UUID]`
- `unmatched: list[kindgi.client.UnmatchedItem]`

## `RequestedApproval`

The approval an `approval.requested` event names. What it is about stays behind sign-in: no `context`, no tool call or run input.

- `approval_id: str` (`approvalId` on the wire)
- `project_id: str | None` (`projectId` on the wire) (optional)
- `required_role: Literal['standard', 'senior', 'admin']` (`requiredRole` on the wire)
- `title: str | None` (optional)
- `assigned_to: str | None` (`assignedTo` on the wire) (optional)
- `created_at: AwareDatetime` (`createdAt` on the wire)
- `expires_at: AwareDatetime | None` (`expiresAt` on the wire) (optional)
- `url: str | None` (optional)

## `RequestedBy`

- `kind: Literal['user', 'service']`
- `id: str`

## `RescoreEvalRunBody`

Body of `POST /v1/eval-runs/{runId}/rescore`: optional.

- `project_id: str | None` (`projectId` on the wire) (optional)

## `Restricted`

The same weights, counting only judgments recorded while their class was restricted (`Judgment.restricted`), for a comparison weighted `restricted-only`. Absent from a test set built before restrictions.

- `yes_weight: float` (`yesWeight` on the wire)
- `total_weight: float` (`totalWeight` on the wire)

## `Resume`

How the run went on, when this call resumed it (the runtime resumes inline): `ok`, or `failed` with the run's error, e.g. `tool-version-unresolvable` when a tool version the turn started with is gone, or `rate-limit-exceeded` when a budget kept per tenant refused work the turn needed. The decision stands either way.

- `kind: Literal['ok']`

## `Resume1`

How the run went on, when this call resumed it (the runtime resumes inline): `ok`, or `failed` with the run's error, e.g. `tool-version-unresolvable` when a tool version the turn started with is gone, or `rate-limit-exceeded` when a budget kept per tenant refused work the turn needed. The decision stands either way.

- `kind: Literal['failed']`
- `code: str`
- `message: str`

## `ResumeMemoryErasureBody`

- `force: bool | None` (optional)

## `ResumeRunBody`

- `waitpoint_id: str` (`waitpointId` on the wire)
- `value: Any | None` (optional)

## `Retention`

- `keep_until: AwareDatetime | None` (`keepUntil` on the wire) (optional)
- `keep_days: int | None` (`keepDays` on the wire) (optional)
- `legal_hold: bool | None` (`legalHold` on the wire) (optional)

## `RetentionPolicyConflict`

- `domain: Literal['org', 'agent', 'flow', 'tool', 'eval_suite', 'guardrail', 'mcp_endpoint', 'env', 'secret', 'run', 'artifact', 'policy', 'judgment', 'judge_class', 'provider', 'memory', 'conversation', 'api_key', 'service_account', '*']`
- `policy_ids: list[str]` (`policyIds` on the wire)
- `applied_policy_id: str` (`appliedPolicyId` on the wire)

## `RetentionScheduledItem`

- `domain: Literal['org', 'agent', 'flow', 'tool', 'eval_suite', 'guardrail', 'mcp_endpoint', 'env', 'secret', 'run', 'artifact', 'policy', 'judgment', 'judge_class', 'provider', 'memory', 'conversation', 'api_key', 'service_account', '*']`
- `id: str`
- `unregistered_at: AwareDatetime` (`unregisteredAt` on the wire)
- `purge_at: AwareDatetime` (`purgeAt` on the wire)
- `past_grace: bool` (`pastGrace` on the wire)
- `policy_id: str` (`policyId` on the wire)
- `policy_version: str` (`policyVersion` on the wire)
- `grace_seconds: int` (`graceSeconds` on the wire)

## `RetentionScheduledPage`

- `data: list[kindgi.client.RetentionScheduledItem]`
- `has_more: bool | None` (`hasMore` on the wire) (optional)
- `next_cursor: str | None` (`nextCursor` on the wire) (optional)
- `domains_missing_adapter: list[Literal['org', 'agent', 'flow', 'tool', 'eval_suite', 'guardrail', 'mcp_endpoint', 'env', 'secret', 'run', 'artifact', 'policy', 'judgment', 'judge_class', 'provider', 'memory', 'conversation', 'api_key', 'service_account', '*']]` (`domainsMissingAdapter` on the wire)
- `unpoliced_domains: list[Literal['org', 'agent', 'flow', 'tool', 'eval_suite', 'guardrail', 'mcp_endpoint', 'env', 'secret', 'run', 'artifact', 'policy', 'judgment', 'judge_class', 'provider', 'memory', 'conversation', 'api_key', 'service_account', '*']]` (`unpolicedDomains` on the wire)
- `conflicts: list[kindgi.client.RetentionPolicyConflict] | None` (optional)

## `RetentionSweepBody`

- `domain: Optional[Literal['org', 'agent', 'flow', 'tool', 'eval_suite', 'guardrail', 'mcp_endpoint', 'env', 'secret', 'run', 'artifact', 'policy', 'judgment', 'judge_class', 'provider', 'memory', 'conversation', 'api_key', 'service_account', '*']]` (optional)
- `max_per_domain: int | None` (`maxPerDomain` on the wire) (optional)

## `RetentionSweepDomainBody`

- `max_per_domain: int | None` (`maxPerDomain` on the wire) (optional)

## `RetentionSweepResult`

- `per_domain: list[kindgi.client.PerDomainItem]` (`perDomain` on the wire)
- `total_purged: int` (`totalPurged` on the wire)
- `conflicts: list[kindgi.client.RetentionPolicyConflict] | None` (optional)

## `RetrievalHit`

- `fact: kindgi.client.Fact`
- `score: float | None` (optional)

## `RetrievalIntent`

- `source: Optional[Literal['facts', 'conversations']]` (optional)
- `types: list[str] | None` (optional)
- `roles: list[Literal['user', 'agent']] | None` (optional)
- `scope: Literal['same-conversation', 'same-user', 'same-segment', 'same-project', 'tenant']`
- `limit: int | None` (optional)
- `mode: Optional[Literal['keyword', 'semantic', 'both']]` (optional)

## `RetrieveIntent`

Retrieval intent — mirrors `RetrievalIntent` from `@kindgi/agents`, widened for direct-HTTP use. `mode: "list"` returns a plain scoped list (no query), newest first. `mode: "keyword"` runs full-text search. `mode: "semantic"` searches by meaning — it needs embeddings on the deployment; without them the route answers `422 semantic-unavailable`. `mode: "both"` runs both and fuses them by rank (reciprocal rank fusion), as `semantic` needing embeddings.

- `mode: Literal['list', 'keyword', 'semantic', 'both']`
- `query: str | None` (optional)
- `type: str | None` (optional)
- `scope: kindgi.client.FactScope | None` (optional)
- `limit: int | None` (optional)
- `embedding_model: str | None` (`embeddingModel` on the wire) (optional)

## `RetrieveMemoryBody`

Retrieval intent — mirrors `RetrievalIntent` from `@kindgi/agents`, widened for direct-HTTP use. `mode: "list"` returns a plain scoped list (no query), newest first. `mode: "keyword"` runs full-text search. `mode: "semantic"` searches by meaning — it needs embeddings on the deployment; without them the route answers `422 semantic-unavailable`. `mode: "both"` runs both and fuses them by rank (reciprocal rank fusion), as `semantic` needing embeddings.

- `mode: Literal['list', 'keyword', 'semantic', 'both']`
- `query: str | None` (optional)
- `type: str | None` (optional)
- `scope: kindgi.client.FactScope | None` (optional)
- `limit: int | None` (optional)
- `embedding_model: str | None` (`embeddingModel` on the wire) (optional)

## `RetrieveMemoryResult`

- `results: list[kindgi.client.RetrievalHit]`

## `Retry`

- `max_attempts: int` (`maxAttempts` on the wire)

## `ReviewDecision`

- `id: str`
- `approval_id: uuid.UUID` (`approvalId` on the wire)
- `reviewer_id: uuid.UUID` (`reviewerId` on the wire)
- `decision: Literal['approve', 'reject', 'escalate', 'withdraw']`
- `rationale: str | None` (optional)
- `reviewer_role_at_decision: Literal['standard', 'senior', 'admin']` (`reviewerRoleAtDecision` on the wire)
- `decided_at: AwareDatetime` (`decidedAt` on the wire)

## `ReviewDecisionKind`

- `root: Literal['approve', 'reject', 'escalate', 'withdraw']`

## `Reviewer`

Reviewer roster row. Deactivation is soft (audit trail survives offboarding). `deactivatedAt` present → reviewer no longer receives approvals.

- `id: uuid.UUID`
- `tenant_id: uuid.UUID` (`tenantId` on the wire)
- `user_id: uuid.UUID` (`userId` on the wire)
- `role: Literal['standard', 'senior', 'admin']`
- `display_name: str | None` (`displayName` on the wire) (optional)
- `created_at: AwareDatetime` (`createdAt` on the wire)
- `deactivated_at: AwareDatetime | None` (`deactivatedAt` on the wire) (optional)

## `ReviewerCollectionPage`

- `data: list[kindgi.client.Reviewer]`
- `next_cursor: str | None` (`nextCursor` on the wire) (optional)
- `has_more: bool` (`hasMore` on the wire)

## `RevokeSessionsResult`

- `user_id: str` (`userId` on the wire)
- `revoked_count: int` (`revokedCount` on the wire)

## `RevokeSigningKeyBody`

- `reason: str | None` (optional)

## `RevokeSigningKeyResult`

- `key_id: str` (`keyId` on the wire)
- `revoked: bool`

## `RevokeSystemKeyResult`

The revoked system key, and the keys revoked with it because they were minted from it.

- `id: str`
- `label: str | None` (optional)
- `scopes: list[Literal['system:tenants', 'system:tenants:create', 'system:tenants:image-prefix', 'system:tenants:production', 'system:tenants:limits', 'system:tenants:contacts', 'system:tenants:purge', 'system:suspend', 'system:deployments', 'system:license', 'kindgi:system']]`
- `created_at: AwareDatetime` (`createdAt` on the wire)
- `expires_at: AwareDatetime | None` (`expiresAt` on the wire) (optional)
- `revoked_at: AwareDatetime | None` (`revokedAt` on the wire) (optional)
- `minted_by: str` (`mintedBy` on the wire)
- `also_revoked: list[str]` (`alsoRevoked` on the wire)

## `RevokeTokenResult`

- `token_id: uuid.UUID` (`tokenId` on the wire)
- `revoked: Literal[True]`

## `RoleActions`

What a project role allows on the project and on every object of each type in it, by object type.

- `project: list[Literal['read', 'write', 'admin', 'delete']]`
- `agent: list[Literal['read', 'write', 'delete', 'admin', 'execute', 'publish', 'promote']]`
- `flow: list[Literal['read', 'write', 'delete', 'admin', 'execute', 'publish']]`
- `tool: list[Literal['read', 'write', 'delete', 'admin', 'invoke']]`
- `guardrail: list[Literal['read', 'write', 'delete', 'admin']]`
- `eval_suite: list[Literal['read', 'write', 'delete', 'admin', 'execute', 'publish']]`
- `trigger: list[Literal['read', 'write', 'delete', 'admin', 'fire']]`
- `conversation: list[Literal['read', 'write', 'delete', 'admin']]`
- `secret: list[Literal['read', 'write', 'delete', 'admin', 'rotate']]`
- `env: list[Literal['read', 'write', 'delete', 'admin']]`
- `mcp_endpoint: list[Literal['read', 'write', 'delete', 'admin']]`
- `run: list[Literal['read', 'cancel', 'delete']]`

## `RoleCapabilities`

What each project role allows, worked out by the runtime from its authorization model. A client decides an action as `capabilities[project.role][type]` holding it; the server still checks every call. An object can grant more on itself (an agent's own editor), never less, so this is what the caller may do at the least.

- `owner: kindgi.client.RoleActions`
- `admin: kindgi.client.RoleActions`
- `editor: kindgi.client.RoleActions`
- `viewer: kindgi.client.RoleActions`

## `RollbackBody`

- `scope: kindgi.client.LiveScopeTenant | kindgi.client.LiveScopeOrg | kindgi.client.LiveScopeProject | kindgi.client.LiveScopeSegment`
- `to_version: str | None` (`toVersion` on the wire) (optional)
- `reason: str | None` (optional)

## `RolledBack`

- `at: AwareDatetime`
- `promotion_id: str` (`promotionId` on the wire)
- `by: str`
- `reason: str | None` (optional)

## `RotationStatus`

- `rotation_id: uuid.UUID` (`rotationId` on the wire)
- `status: Literal['pending', 'succeeded', 'failed']`
- `started_at: AwareDatetime` (`startedAt` on the wire)
- `updated_at: AwareDatetime` (`updatedAt` on the wire)
- `new_version_id: int | None` (`newVersionId` on the wire) (optional)
- `old_version_id: int | None` (`oldVersionId` on the wire) (optional)
- `error: str | None` (optional)

## `Run`

- `id: uuid.UUID`
- `tenant_id: uuid.UUID` (`tenantId` on the wire)
- `project_id: uuid.UUID | None` (`projectId` on the wire) (optional)
- `flow_id: str` (`flowId` on the wire)
- `flow_version: str` (`flowVersion` on the wire)
- `status: Literal['pending', 'running', 'suspended', 'completed', 'failed', 'cancelled']`
- `dry_run: bool` (`dryRun` on the wire)
- `created_at: AwareDatetime` (`createdAt` on the wire)
- `updated_at: AwareDatetime` (`updatedAt` on the wire)
- `completed_at: AwareDatetime | None` (`completedAt` on the wire) (optional)
- `failure_message: str | None` (`failureMessage` on the wire) (optional)
- `failure: kindgi.client.RunFailure | None` (optional)
- `output: Any | None` (optional)
- `content_erased_at: AwareDatetime | None` (`contentErasedAt` on the wire) (optional)
- `parent_run_id: uuid.UUID | None` (`parentRunId` on the wire) (optional)
- `parent_node_id: str | None` (`parentNodeId` on the wire) (optional)
- `agent: kindgi.client.RunAgent | None` (optional)
- `waiting_for: kindgi.client.RunWaitingFor | None` (`waitingFor` on the wire) (optional)
- `trigger: kindgi.client.RunTrigger | None` (optional)
- `replay_of: uuid.UUID | None` (`replayOf` on the wire) (optional)
- `eval_run_id: str | None` (`evalRunId` on the wire) (optional)
- `versions: kindgi.client.FlowVersionOverrides | None` (optional)
- `segments: list[kindgi.client.ScopeSegment] | None` (optional)
- `trace_id: str | None` (`traceId` on the wire) (optional)
- `public_access_token: str | None` (`publicAccessToken` on the wire) (optional)
- `public_access_token_expires_at: AwareDatetime | None` (`publicAccessTokenExpiresAt` on the wire) (optional)

## `RunAgent`

Set on an agent's turn (an agent run, or the turn a flow's agent step started): the agent, the version that ran and the conversation. Absent on other runs, and on turns that ran before Kindgi 0.1.3.

- `id: str`
- `version: str`
- `conversation_id: uuid.UUID` (`conversationId` on the wire)
- `via: Optional[Literal['explicit', 'flow-pin', 'conversation', 'live', 'latest']]` (optional)
- `live_scope: kindgi.client.LiveScopeTenant | kindgi.client.LiveScopeOrg | kindgi.client.LiveScopeProject | kindgi.client.LiveScopeSegment | None` (`liveScope` on the wire) (optional)

## `RunCollectionPage`

- `data: list[kindgi.client.Datum]`
- `next_cursor: str | None` (`nextCursor` on the wire) (optional)
- `has_more: bool` (`hasMore` on the wire)

## `RunEvent`

- `event_id: str` (`eventId` on the wire)
- `run_id: str` (`runId` on the wire)
- `tenant_id: str` (`tenantId` on the wire)
- `timestamp: AwareDatetime`
- `kind: Literal['run.queued', 'run.started', 'run.step-started', 'run.step-completed', 'run.step-failed', 'run.step-retry-scheduled', 'run.iteration-started', 'run.iteration-completed', 'run.tool-invoked', 'run.tool-result', 'run.model-token', 'run.artifact-produced', 'run.guardrail-violated', 'run.wait-suspended', 'run.wait-resumed', 'run.approval-requested', 'run.approval-completed', 'run.completed', 'run.failed', 'run.cancelled']`
- `sequence: int | None` (optional)
- `node_id: str | None` (`nodeId` on the wire) (optional)
- `payload: Any | None` (optional)

## `RunFailure`

Why a failed run failed; present only on a `failed` run. An agent turn's failure carries its own code (`budget-exceeded`, `capability-routing-failed`, `model-invocation-failed`, …; `rate-limit-exceeded` when a budget kept per tenant refused work the turn needed, with `details` naming the budget); any other failure is `run-failed`, with the run's failure message.

- `code: str`
- `message: str`
- `cause: Any | None` (optional)
- `reason: str | None` (optional)
- `details: dict[str, Any] | None` (optional)

## `RunFailureGroups`

- `from_: AwareDatetime` (`from` on the wire)
- `to: AwareDatetime`
- `groups: list[kindgi.client.FailureGroup]`
- `outcomes: list[kindgi.client.FailureGroup]`
- `unrecorded: list[kindgi.client.FailureGroup]`
- `total: int`

## `RunFinishedEvent`

- `id: str`
- `type: Literal['run.finished']`
- `created_at: AwareDatetime` (`createdAt` on the wire)
- `data: kindgi.client.Data`

## `RunId`

- `root: str`

## `RunJournalPage`

- `data: list[kindgi.client.Datum1]`
- `has_more: bool` (`hasMore` on the wire)
- `next_cursor: str | None` (`nextCursor` on the wire) (optional)

## `RunProgress`

A run's progress: status and timing, without its input, output, failure message or tenant. Safe to show in a browser.

- `id: uuid.UUID`
- `flow_id: str` (`flowId` on the wire)
- `flow_version: str` (`flowVersion` on the wire)
- `status: Literal['pending', 'running', 'suspended', 'completed', 'failed', 'cancelled']`
- `created_at: AwareDatetime` (`createdAt` on the wire)
- `updated_at: AwareDatetime` (`updatedAt` on the wire)
- `completed_at: AwareDatetime | None` (`completedAt` on the wire) (optional)
- `parent_run_id: uuid.UUID | None` (`parentRunId` on the wire) (optional)

## `RunProgressEvent`

A run event without its payload: what happened, on which node, when.

- `event_id: str` (`eventId` on the wire)
- `run_id: str` (`runId` on the wire)
- `timestamp: AwareDatetime`
- `kind: str`
- `sequence: int`
- `node_id: str | None` (`nodeId` on the wire) (optional)

## `RunStatus`

- `root: Literal['pending', 'running', 'suspended', 'completed', 'failed', 'cancelled']`

## `RunTreeUsage`

The model calls of the run tree (this run and every run it started) that the cost ledger had recorded when this run finished: a child run still running then isn't in it. `calls` counts failed calls too. Absent when the runtime records no usage.

- `calls: int`
- `cost_usd: float` (`costUsd` on the wire)
- `tokens: kindgi.client.CostTokenTotals`

## `RunTrigger`

Set on a run a trigger started: the trigger and the fire that started it. Absent on other runs. The runtime fires schedules only; `event` and `webhook` are kept for event triggers and inbound webhooks, which aren't served yet.

- `trigger_id: uuid.UUID` (`triggerId` on the wire)
- `kind: Literal['schedule', 'event', 'webhook']`
- `fire_id: str` (`fireId` on the wire)
- `scheduled_for: AwareDatetime | None` (`scheduledFor` on the wire) (optional)

## `RunWaitingApproval`

An approval the run waits for, as a run reader sees it: its identity and state. Its subject's details, description, context and decision stay on `GET /v1/approvals/{approvalId}`, behind the reviewer gate.

- `approval_id: uuid.UUID` (`approvalId` on the wire)
- `status: str`
- `required_role: str` (`requiredRole` on the wire)
- `title: str | None` (optional)
- `created_at: AwareDatetime` (`createdAt` on the wire)
- `expires_at: AwareDatetime | None` (`expiresAt` on the wire) (optional)
- `subject_kind: str` (`subjectKind` on the wire)
- `tool: kindgi.client.Tool | None` (optional)

## `RunWaitingFor`

Set on a suspended run by `GET /v1/runs/{runId}` (not the list): what it waits for, its journal's open waits. `approvals`: those still to be decided, linked to the waits. `other`: the rest. Absent from a runtime before Kindgi 0.1.6, or when the journal can't be read; `kindgi runs resume` then works it out itself.

- `approvals: list[kindgi.client.RunWaitingApproval]`
- `other: list[kindgi.client.OtherItem]`

## `RuntimeLimits`

Sandbox-enforced resource caps at dispatch. Optional additive field.

- `mem_mb: int` (`memMB` on the wire)
- `cpu_ms: int` (`cpuMs` on the wire)
