---
title: "Get deploy operation snapshot"
method: GET
path: "/apply/v1/operations/{operation_id}"
tags: ["Apply"]
---

# Get deploy operation snapshot

`GET /apply/v1/operations/{operation_id}`

## Request

- Base URL: `https://api.run402.com`
- URL: `https://api.run402.com/apply/v1/operations/{operation_id}`
- Auth: API key in header `apikey`

Snapshot the deploy operation: status, progress, structured error, payment requirement. Read-only. Polled by the SDK during long-running commits.

## Path parameters

- `operation_id` string, required

## Response `200`

Operation snapshot

- DeployOperationSnapshot
  - `static_continuity` StaticContinuity: Automatic one-hour origin availability for previously direct-public non-HTML paths absent from the active release. Cached copies may outlive the deadline. Plans omit the deadline until supersession.
    - `mode` 'absent_public_paths', required
    - `origin_retention_seconds` 3600, required
    - `scope` 'previously_public_non_html', required
    - `source_release_id` string, nullable, required
    - `source_release_generation` integer, nullable, required
    - `retained_path_count` integer, required
    - `origin_available_until` string, date-time, nullable: Omitted for candidate supersessions; null for an active release.
  - `project_id` string, required: Run402 project ID. Public IDs are not UUIDs.
  - `plan_id` string, required
  - `base_release_id` string, nullable
  - `target_release_id` string, nullable
  - `status` 'planning' | 'uploading' | 'committing' | 'staging' | 'gating' | 'migrating' | 'schema_settling' | 'activating' | 'activation_pending' | 'needs_repair' | 'ready' | 'failed' | 'rolled_back', required
  - `actor` OperationActorSnapshot
    - `schema_version` 1, required
    - `principal` PrincipalSnapshot, required
      - `principal_id` string, required
      - `principal_type` string, required
      - `display_name_at_capture` string, nullable, required
      - `linked_identities_at_capture` LinkedIdentitySnapshot[], required
        - `identity_link_id` string, required
        - `kind` string, required
        - `public_subject` string, required
        - `display_subject` string, required
        - `verified_at` string, date-time, required
        - `status_at_capture` 'active', required
    - `authenticator` AuthenticatorSnapshot, required
      - `authenticator_id` string, required
      - `kind` string, required
      - `public_subject` string, required
    - `authority` AuthoritySnapshot, required: Discriminated immutable action-time authority: organization_membership, project_grant, grant_key, ci, system, legacy, or a preserved future kind. A link is never an authority kind.
      - `kind` string, required
      - `org_id` string, nullable
      - `project_id` string, nullable
      - `membership_id` string, nullable
      - `grant_id` string, nullable
      - `grant_key_id` string, nullable
      - `credential_id` string, nullable
      - `role` string, nullable
      - `scope` string[]
      - `reason_code` string, nullable
    - `captured_at` string, date-time, required
  - `payment_required` DeployPaymentRequired
    - `amount` string, required
    - `asset` string, required
    - `payTo` string, required
    - `reason` string, required
  - `error` DeployErrorEnvelope
    - `code` string, required
    - `phase` string
    - `resource` string
    - `message` string, required
    - `retryable` boolean
    - `operation_id` string
    - `plan_id` string
    - `fix` object
    - `logs` string[]
  - `activate_attempts` integer, required
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required
  - `operation_id` string, required
  - `release_id` string, nullable
  - `subdomain_bindings` SubdomainBindingFreshness[], required: Managed subdomains serving this project, including claim time and confirmed KVS source-write time.
    - `host` string, required
    - `claimed_at` string, date-time, required
    - `kvs_synced_at` string, date-time, nullable, required: When the edge-store source write was confirmed. Null means the write has not been confirmed yet.
  - `rehearsal_report` ApplyRehearsalReport
    - `kind` 'rehearsal_report', required
    - `status` 'passed' | 'failed', required
    - `operation_id` string, required
    - `source_project_id` string, required: The source project's Run402 project ID.
    - `plan_id` string, required
    - `plan_fingerprint` string, required: Pure reviewed-plan content fingerprint bound to this rehearsal. Re-planning unchanged facts reproduces it.
    - `base_release_id` string, nullable, required: Concrete live release observed at rehearsal start.
    - `data_as_of` string, date-time, nullable, required: Snapshot capture time for the branch data; null only when orchestration failed before snapshot capture.
    - `branch_project_id` string, nullable
    - `branch_url` string, uri, nullable
    - `branch_plan_id` string, nullable
    - `branch_operation_id` string, nullable
    - `snapshot_id` string, nullable
    - `started_at` string, date-time, required
    - `completed_at` string, date-time, required
    - `duration_ms` integer, required
    - `migrations` object[], required
      - `id` string, required
      - `status` 'passed' | 'failed' | 'skipped', required
      - `error` string
    - `checks` RehearsalCheckResult[], required
      - `name` string, required
      - `type` 'migration' | 'commit' | 'static' | 'function' | 'declared', required
      - `status` 'passed' | 'failed' | 'skipped', required
      - `target` string
      - `method` string
      - `expected_status` union
        - integer
        - integer[]
      - `actual_status` integer, nullable
      - `duration_ms` integer, required
      - `error` string
    - `teardown` object, required
      - `policy` 'keep' | 'on_pass' | 'always', required
      - `action` 'kept' | 'deleted' | 'delete_failed' | 'skipped', required
      - `error` string
    - `fidelity` object, required
      - `secrets` 'absent', required
      - `parent_secret_keys` string[], required: Parent secret key names only; values are never copied or returned.
      - `email_mode` 'sandbox' | 'off', required
      - `scheduled_functions` 'paused', required
    - `next_actions` NextAction[], required
      - `type` string, required: Advisory machine-readable action type such as retry, authenticate, submit_payment, fund_wallet, renew_tier, check_usage, resume_deploy, edit_request, edit_migration, contact_support, upgrade_client, poll (poll the project events feed — appended when the envelope carries a correlated_platform_incident), or hand_to_member (on a commit/promote response that just activated a public site: show the human urls.site and urls.console, relay Run402's offer to promote the build on @run402com, and ask yes or no — see `credited_as` below).
      - `method` string
      - `path` string
      - `auth` string
      - `why` string
      - `credited_as` string, nullable: `hand_to_member` only. The caller's own live presence name in the project's default room, else that room's most recently active live presence, else `null` — in which case `why` tells the agent that joining the room with a name (`run402 rooms join --name ...`) is how the promotion credits it.
      - `body` object: `hand_to_member` only. A ready-to-send `POST /feedback/v1` template: `{ project_id, message: "promote: yes", handle? }`.
    - `error` DeployErrorEnvelope
      - `code` string, required
      - `phase` string
      - `resource` string
      - `message` string, required
      - `retryable` boolean
      - `operation_id` string
      - `plan_id` string
      - `fix` object
      - `logs` string[]
  - `urls` object, nullable: `site` is the project's public URL, present when the project owns at least one subdomain. `console` is the project's page in the console (`https://console.run402.com/orgs/{org_id}/projects/{project_id}`), present exactly when `site` is present; a function-only project with no site carries no `console` key either.
  - `next_actions` NextAction[]: On `status: "ready"` this includes a `poll` entry into the project events feed, and, when `urls.site` is present and the project has no recorded promotion consent yet, one `hand_to_member` entry: show the human `urls.site` and `urls.console`, tell them Run402 would like to promote what they built on @run402com for free, and ask yes or no. Its `body` is a ready-to-send `POST /feedback/v1` template (`project_id`, `message: "promote: yes"`, and the optional `handle` and `return_address` the agent asks the human for); its `credited_as` is the deploying caller's live presence name in the project's default room, else the room's most recently active presence, else `null` (in which case `why` tells the agent to join the room with a name to be credited). Absent once a `feedback_sent` fact with `promotion_consent: true` exists for the project. When Run402 holds no verified email for the project's organization, a `register_contact` entry (`POST /agent/v1/contact`) follows it.
    - `type` string, required: Advisory machine-readable action type such as retry, authenticate, submit_payment, fund_wallet, renew_tier, check_usage, resume_deploy, edit_request, edit_migration, contact_support, upgrade_client, poll (poll the project events feed — appended when the envelope carries a correlated_platform_incident), or hand_to_member (on a commit/promote response that just activated a public site: show the human urls.site and urls.console, relay Run402's offer to promote the build on @run402com, and ask yes or no — see `credited_as` below).
    - `method` string
    - `path` string
    - `auth` string
    - `why` string
    - `credited_as` string, nullable: `hand_to_member` only. The caller's own live presence name in the project's default room, else that room's most recently active live presence, else `null` — in which case `why` tells the agent that joining the room with a name (`run402 rooms join --name ...`) is how the promotion credits it.
    - `body` object: `hand_to_member` only. A ready-to-send `POST /feedback/v1` template: `{ project_id, message: "promote: yes", handle? }`.
  - `edge` EdgeBlock
    - `checked_at` string, date-time: When the activation-time edge summary was computed.
    - `state` 'converging' | 'coherent' | 'unknown' | 'not_applicable', required
    - `expected_max_lag_seconds` integer, nullable
    - `pointer_updates` EdgePointerUpdates, required: Map keyed by edge pointer target. Missing keys mean no outbox row exists for that target.
    - `verify_url` string, nullable
  - `vault` VaultResult: Vault provenance for one apply operation — ABSENT for a vaultless project's operation, so pre-vault responses are unchanged. Carried on the commit response, on an operation snapshot, and on the operations list.
    - `policy` 'required' | 'grandfathered', nullable
    - `outcome` 'DEPLOYED_AND_VAULTED' | 'DEPLOY_BLOCKED_PUSH_FAILED' | 'DEPLOY_FAILED_VAULTED' | 'DEPLOY_FAILED_UNVAULTED' | 'DEPLOYED_UNVAULTED_OVERRIDE', nullable: The protocol's CLOSED five-outcome deploy enum, derived from the operation row; `null` while the operation is still in flight. `DEPLOYED_AND_VAULTED` — activated with a consumed activation token: app live and source captured. `DEPLOY_BLOCKED_PUSH_FAILED` — refused at the gate (no consumable token and no authorized override); nothing activated. `DEPLOY_FAILED_VAULTED` — the push succeeded, so the source IS captured, but the deploy failed afterwards. `DEPLOY_FAILED_UNVAULTED` — failed under an override, so nothing was captured either. `DEPLOYED_UNVAULTED_OVERRIDE` — activated through the audited override; the advisory persists until the capture is reported.
    - `vault_generation` string, nullable: 16 lowercase hex — the admitted generation this deploy activated from.
    - `capture_id` string, nullable
    - `activation_token_id` string, nullable
    - `activation_token_consumed` boolean
    - `admission_receipt` object, nullable: The consumed `capture_receipt`, exactly as journaled.
    - `policy_version_at_activation` integer, nullable
    - `unvaulted_override` boolean
    - `unvaulted_override_reason` string, nullable
    - `unvaulted_override_actor_principal_id` string, nullable
    - `unvaulted_override_journal_state` 'open' | 'completed', nullable: `open` until the matching capture receipt is accepted at `POST /vaults/v1/{vault_id}/override-completions`.

## Other responses

- `404`: Operation not found or not owned by project

---

[API](https://skmtc.dev/run402/apis/run402-api.md) · [All operations](https://skmtc.dev/run402/apis/run402-api/llms.txt) · [OpenAPI document](https://skmtc.dev/run402/apis/run402-api/revisions/893607557f50?raw)
