> ## Documentation Index
> Fetch the complete documentation index at: https://rakumux.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Revive a dead or exited session.

> Starts a new terminal for the session (same id, cwd and command) and runs its resume command (a known agent resumes its conversation). The body is optional; without one the terminal gets the daemon's default size (an attaching controller resizes it). Answers `{"session": Session}`, the same envelope as the other session routes. A live session is a 400.




## OpenAPI

````yaml /api-reference/openapi.yaml post /v1/sessions/{id}/revive
openapi: 3.1.0
info:
  title: Rakumux external API
  version: '1'
  summary: Sessions and folders of the local Rakumux daemon, over HTTP.
  description: >
    `rakumux-api` exposes a subset of the session operations of the running

    Rakumux daemon (`rakumux-ptyd`). It listens on **127.0.0.1** and, with

    remote access on, on a **remote listener** too (see below). It is a thin

    adapter: the daemon decides permissions and folder confinement.


    **Discovery.** While it runs, the API writes

    `<RAKUMUX_HOME or ~/.rakumux>/api.json` (mode 0600):

    `{"url": "http://127.0.0.1:<port>", "token": "<64 hex>", "pid": <int>,
    "version": "<x.y.z>", "remote_urls": ["http://<addr>:<port>"]}`

    (`remote_urls` only while a remote listener runs). A file whose `pid` no

    longer exists is stale.


    **Authentication.** Every route except `GET /v1/health` needs

    `Authorization: Bearer <token>`. On the loopback listener the token is

    api.json's; requests whose `Host` is not a loopback name (`127.0.0.1`,

    `localhost`, `[::1]`, any port) and requests carrying an `Origin` or

    `Sec-Fetch-Site` header (browsers) are refused with 403. No CORS headers

    are ever sent.


    **Remote access.** `rakumux remote on` writes

    `<home>/remote.json` (mode 0600):

    `{"enabled": true, "port": 7337, "token": "<26 chars a-z2-7>", "listen":
    []}`.

    While it is enabled the API adds a remote listener on every Tailscale

    address of the machine (IPv4 in `100.64.0.0/10`, IPv6 in

    `fd7a:115c:a1e0::/48`) at `port`, or on `remote.json`'s `listen` /

    `--remote-listen ADDR:PORT` addresses instead. There the bearer is the

    remote token (constant-time compared); `Host` isn't checked and `Origin`

    is allowed; the caller is always the user, so the identity headers below

    are refused (403 `permission_denied`). The loopback listener keeps its

    rules. Same routes on both.


    **Streams.** `GET /v1/events` and `GET /v1/sessions/{id}/attach` are

    WebSockets (RFC 6455, version 13) on the same port, with the same checks;

    errors before the upgrade are ordinary JSON answers, and a request

    without the upgrade headers gets 426 `upgrade_required`. Their messages

    are the `EventMessage`, `AttachMessage` and `AttachCommand` schemas. The

    server pings every 30 s and drops a client that didn't answer the

    previous ping; it closes the socket when the stream ends.


    **Identity.** Without identity headers the API acts as the user. With both

    `X-Rakumux-Session-Id` and `X-Rakumux-Session-Token` (the

    `RAKUMUX_SESSION_ID` / `RAKUMUX_SESSION_TOKEN` of a process running in

    a Rakumux session) it acts as that session: the daemon confines it to

    its own folder and applies its agent policy (today: read anything in the

    folder, create sessions in it within limits, rename only itself). With

    both `X-Rakumux-Agent` and `X-Rakumux-Agent-Conversation` instead

    (for agents whose tool calls don't carry the session's environment, such

    as OpenCode 2.x) it acts as the running session that bound that

    conversation with `rakumux session bind`; 401 if none did. That needs

    the daemon's `auth.delegated` capability (501 without it).


    **Folders.** A session's folder is the canonical directory it was started

    in (the daemon's protocol calls it `scope`, and its folder operations

    `project_*`). Wherever a `folder` is accepted it may be an absolute

    directory (`~/` is expanded) or the name of a known folder; names and

    listing every folder need the daemon's `projects` capability (see

    `GET /v1/health`), and answer 501 / 400 until it has it.


    **Deprecated `project` names.** Earlier builds said "project": they are

    still accepted and returned. `GET /v1/projects` is an alias of

    `GET /v1/folders`; the `project` query parameter and body field are

    aliases of `folder` (`folder` wins; both given and naming different

    folders is a 400); responses carry `project` next to `folder` and

    `projects` next to `folders`, with the same values.


    **Errors** use one envelope, `{"error": {"code", "message", "details"?}}`.

    Daemon error codes map to statuses: `not_found` 404, `invalid_argument`

    400, `unauthenticated` 401, `out_of_scope` and `permission_denied` 403,

    `session_not_live` and `session_in_use` 409, `limit_exceeded` 429,

    `timeout` 504,

    `daemon_unavailable` 503, `unsupported` 501, anything else 500. The API's

    own codes: `method_not_allowed` 405, `payload_too_large` 413,

    `unsupported_media_type` 415, `upgrade_required` 426.


    **Compatibility.** Fields may be added to responses; clients must ignore

    unknown fields. Request bodies reject unknown fields, and routes reject

    unknown query parameters (400), so typos never pass silently.
servers:
  - url: http://127.0.0.1:{port}
    variables:
      port:
        default: '0'
        description: The port in api.json.
  - url: http://{host}:{port}
    description: The remote listener (remote access on); see api.json `remote_urls`.
    variables:
      host:
        default: machine.tailnet.ts.net
        description: The machine's MagicDNS name or Tailscale address.
      port:
        default: '7337'
        description: remote.json `port`.
security:
  - bearer: []
tags:
  - name: health
  - name: folders
  - name: sessions
  - name: streams
paths:
  /v1/sessions/{id}/revive:
    parameters:
      - $ref: '#/components/parameters/SessionId'
      - $ref: '#/components/parameters/SessionIdentityId'
      - $ref: '#/components/parameters/SessionIdentityToken'
      - $ref: '#/components/parameters/AgentIdentityKind'
      - $ref: '#/components/parameters/AgentIdentityConversation'
    post:
      tags:
        - sessions
      summary: Revive a dead or exited session.
      description: >
        Starts a new terminal for the session (same id, cwd and command) and
        runs its resume command (a known agent resumes its conversation). The
        body is optional; without one the terminal gets the daemon's default
        size (an attaching controller resizes it). Answers `{"session":
        Session}`, the same envelope as the other session routes. A live session
        is a 400.
      operationId: reviveSession
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ReviveSession'
      responses:
        '200':
          description: The session, live again.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SessionEnvelope'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '503':
          $ref: '#/components/responses/DaemonUnavailable'
components:
  parameters:
    SessionId:
      name: id
      in: path
      required: true
      description: >-
        Opaque session id (letters, digits, `-`, `_`). Never derive anything
        from it.
      schema:
        type: string
        pattern: ^[A-Za-z0-9_-]{1,128}$
    SessionIdentityId:
      name: X-Rakumux-Session-Id
      in: header
      required: false
      description: Act as this session (with X-Rakumux-Session-Token).
      schema:
        type: string
    SessionIdentityToken:
      name: X-Rakumux-Session-Token
      in: header
      required: false
      description: The session's RAKUMUX_SESSION_TOKEN.
      schema:
        type: string
    AgentIdentityKind:
      name: X-Rakumux-Agent
      in: header
      required: false
      description: >
        Act for the session that bound this agent's conversation (with
        X-Rakumux-Agent-Conversation), e.g. `opencode`. Not with the session
        headers.
      schema:
        type: string
        pattern: ^[a-z0-9_-]{1,32}$
    AgentIdentityConversation:
      name: X-Rakumux-Agent-Conversation
      in: header
      required: false
      description: The agent's conversation id, e.g. OpenCode's `ses_…`.
      schema:
        type: string
  schemas:
    ReviveSession:
      type: object
      additionalProperties: false
      description: Optional body of `POST /v1/sessions/{id}/revive`.
      properties:
        cols:
          type: integer
          minimum: 0
          maximum: 65535
          description: 0 or omitted → default.
        rows:
          type: integer
          minimum: 0
          maximum: 65535
          description: 0 or omitted → default.
    SessionEnvelope:
      type: object
      required:
        - session
      properties:
        session:
          $ref: '#/components/schemas/Session'
    Session:
      type: object
      required:
        - id
        - name
        - folder
        - cwd
        - status
        - lifecycle
        - created_by
        - created_at
        - last_active_at
      properties:
        id:
          type: string
          description: Opaque id.
        name:
          type: string
          description: Unique within the folder.
        folder:
          type: string
          description: The folder (directory) the session was started in.
        project:
          type: string
          deprecated: true
          description: Deprecated alias of `folder` (the same path).
        cwd:
          type: string
          description: Current working directory (absolute).
        status:
          type: string
          enum:
            - live
            - exited
            - dead
            - unknown
          description: >
            `live`: terminal running. `exited`: process ended, final screen
            kept. `dead`: record without terminal (after a crash, a reboot or
            `rakumux daemon stop`).
        exit_code:
          type: integer
        lifecycle:
          type: string
          enum:
            - working
            - blocked
            - done
            - idle
            - unknown
            - none
          description: >-
            What the program (usually a coding agent) is doing; `none` = no
            agent.
        agent:
          type: object
          required:
            - kind
          properties:
            kind:
              type: string
              examples:
                - claude
                - codex
                - opencode
                - pi
            session_id:
              type: string
              description: The agent's own conversation id.
        reported:
          type: object
          description: >-
            What the session reported about itself. Written by its own program;
            untrusted.
          required:
            - at
          properties:
            state:
              type: string
              enum:
                - working
                - blocked
                - done
                - idle
            text:
              type: string
            summary:
              type: string
            files:
              type: array
              items:
                type: string
            at:
              type: string
              format: date-time
        activity:
          type: object
          description: >-
            Fresh agent-hook metadata; absent when unavailable, expired or not
            live. Subagents are agent-internal, not Rakumux children.
          required:
            - phase
            - active_subagents
            - updated_at
          properties:
            phase:
              type: string
              enum:
                - working
                - waiting_for_response
                - running_tool
                - needs_input
                - idle
                - done
                - unknown
            active_subagents:
              type: integer
              minimum: 0
              maximum: 64
            updated_at:
              type: string
              format: date-time
        created_by:
          type: object
          required:
            - kind
          properties:
            kind:
              type: string
              enum:
                - user
                - session
            id:
              type: string
              description: The creating session (kind `session`).
        parent_id:
          type: string
        depth:
          type: integer
        children:
          type: array
          items:
            type: string
        command:
          type: array
          items:
            type: string
          description: argv the session runs; absent for the user's login shell.
        startup_commands:
          type: array
          items:
            type: string
        resume_command:
          type: array
          items:
            type: string
        pinned:
          type: boolean
        git:
          $ref: '#/components/schemas/Git'
        description:
          type: string
        notes:
          type: string
        labels:
          type: object
          additionalProperties:
            type: string
        private:
          type: boolean
        is_self:
          type: boolean
          description: The caller (identity headers) is this session.
        auto_named:
          type: boolean
          description: The name was generated by Rakumux.
        created_at:
          type: string
          format: date-time
        last_active_at:
          type: string
          format: date-time
        terminal:
          type: object
          description: Present while the session is live.
          required:
            - cols
            - rows
          properties:
            pid:
              type: integer
            foreground_process:
              type: string
            title:
              type: string
            cols:
              type: integer
            rows:
              type: integer
            controlled:
              type: boolean
              description: A client holds input control.
            alternate_screen:
              type: boolean
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              examples:
                - not_found
                - invalid_argument
                - unauthenticated
                - out_of_scope
                - unsupported
            message:
              type: string
            details: {}
    Git:
      type: object
      required:
        - repo_root
      properties:
        repo_root:
          type: string
        branch:
          type: string
        detached_at:
          type: string
          description: Short commit id when HEAD is detached.
        worktree:
          type: string
          description: Linked worktree name; absent in the main worktree.
        repo:
          type: string
          description: >
            The repository's name, for display: its `origin` remote's (the URL's
            last path component without `.git`), else its main working tree's
            folder name. Absent from older daemons.
  responses:
    BadRequest:
      description: '`invalid_argument`: bad parameters or body, or a half-sent identity.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthenticated:
      description: >-
        `unauthenticated`: missing or wrong API token, or a session identity the
        daemon rejects.
      headers:
        WWW-Authenticate:
          schema:
            type: string
            const: Bearer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: >
        `permission_denied` (non-loopback Host, browser request, or the daemon's
        policy) or `out_of_scope` (a session acting outside its folder).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: '`not_found`: no such session, folder or route.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    UnsupportedMediaType:
      description: '`unsupported_media_type`: the body is not `application/json`.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    DaemonUnavailable:
      description: >-
        `daemon_unavailable`: the daemon is not running and could not be
        started.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    bearer:
      type: http
      scheme: bearer
      description: >
        The `token` from api.json on the loopback listener; the remote token
        from remote.json (`rakumux remote token`) on the remote listener.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.