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

# Manage Running Processes in a Wrenn Capsule

> List and kill processes running inside a capsule. GET /v1/capsules/{id}/processes lists all processes; DELETE kills by PID or tag.

Background processes — started with `background: true` on the exec endpoint — continue running inside the capsule until they exit or you stop them. The processes endpoints let you inspect what is running, send signals to terminate processes, and attach a streaming WebSocket to a process that is already underway.

## List processes

```
GET https://app.wrenn.dev/api/v1/capsules/{id}/processes
```

Returns all processes currently running inside the capsule, including background processes started via the API and any processes launched by the capsule's init scripts or template.

### Authentication

<ParamField header="X-API-Key" type="string" required>
  Your team's API key.
</ParamField>

### Path parameters

<ParamField path="id" type="string" required>
  The capsule ID.
</ParamField>

### Response (200)

<ResponseField name="processes" type="object[]">
  Array of process objects.

  <Expandable title="process fields">
    <ResponseField name="pid" type="integer">
      Operating system PID of the process inside the capsule.
    </ResponseField>

    <ResponseField name="tag" type="string">
      Stable tag for this process. Auto-generated when the process was started via the API; empty for init/template processes.
    </ResponseField>

    <ResponseField name="cmd" type="string">
      The command used to start the process.
    </ResponseField>

    <ResponseField name="args" type="string[]">
      Arguments the process was started with.
    </ResponseField>
  </Expandable>
</ResponseField>

```json theme={null}
{
  "processes": [
    {
      "pid": 42,
      "tag": "bg-a1b2c3d4",
      "cmd": "python",
      "args": ["-u", "server.py"]
    },
    {
      "pid": 7,
      "tag": "",
      "cmd": "/usr/sbin/sshd",
      "args": ["-D"]
    }
  ]
}
```

### Python SDK

```python theme={null}
with Capsule(wait=True) as capsule:
    procs = capsule.commands.list()
    for p in procs:
        print(p.pid, p.tag, p.cmd)
```

***

## Kill a process

```
DELETE https://app.wrenn.dev/api/v1/capsules/{id}/processes/{selector}
```

Sends a signal to a running process. You can identify the process by its numeric PID or by its string tag.

### Path parameters

<ParamField path="id" type="string" required>
  The capsule ID.
</ParamField>

<ParamField path="selector" type="string" required>
  A numeric PID (e.g. `42`) or a string tag (e.g. `bg-a1b2c3d4`).
</ParamField>

### Query parameters

<ParamField query="signal" type="string" default="SIGKILL">
  Signal to send to the process. Accepted values: `SIGKILL` (immediate termination) or `SIGTERM` (graceful shutdown request).
</ParamField>

### Response

Returns HTTP 204 with no body on success.

### Examples

Kill by PID with the default signal (SIGKILL):

```bash theme={null}
curl -X DELETE \
  "https://app.wrenn.dev/api/v1/capsules/cap_abc123/processes/42" \
  -H "X-API-Key: wrn_your_api_key_here"
```

Kill by tag with SIGTERM:

```bash theme={null}
curl -X DELETE \
  "https://app.wrenn.dev/api/v1/capsules/cap_abc123/processes/bg-a1b2c3d4?signal=SIGTERM" \
  -H "X-API-Key: wrn_your_api_key_here"
```

### Python SDK

`kill()` accepts a PID. To send `SIGTERM` instead of the default `SIGKILL`, use the REST API directly with the `?signal=SIGTERM` query parameter — the SDK always sends `SIGKILL`.

```python theme={null}
with Capsule(wait=True) as capsule:
    capsule.commands.kill(pid=1234)
```

***

## Stream a running process

```
GET https://app.wrenn.dev/api/v1/capsules/{id}/processes/{selector}/stream
```

Opens a WebSocket connection to attach to a background process that is already running. You receive stdout and stderr from the point of connection onwards, plus an `exit` message when the process terminates.

<Note>
  This endpoint attaches to an existing process. To start a new process and stream it from the beginning, use the [exec/stream endpoint](/api-reference/execution/exec-stream) instead.
</Note>

### Path parameters

<ParamField path="id" type="string" required>
  The capsule ID.
</ParamField>

<ParamField path="selector" type="string" required>
  A numeric PID or string tag identifying the process to attach to.
</ParamField>

### Server messages

Once connected, the server streams the same message format as the exec/stream endpoint:

| `type`   | Fields               | When sent            |
| -------- | -------------------- | -------------------- |
| `start`  | `pid: integer`       | Attached to process. |
| `stdout` | `data: string`       | A chunk of stdout.   |
| `stderr` | `data: string`       | A chunk of stderr.   |
| `exit`   | `exit_code: integer` | Process exited.      |
| `error`  | `data: string`       | An error occurred.   |

### Python SDK

```python theme={null}
with Capsule(wait=True) as capsule:
    handle = capsule.commands.run("python", args=["-u", "server.py"], background=True)

    # Later — attach to the running process
    for event in capsule.commands.connect(handle.pid):
        if event.type == "stdout":
            print(event.data, end="")
        elif event.type == "exit":
            print(f"Exited: {event.exit_code}")
```

***

## Errors

| Status | Meaning                                                                      |
| ------ | ---------------------------------------------------------------------------- |
| `404`  | Capsule not found, or the process identified by the selector does not exist. |
| `409`  | Capsule is not in the `running` state.                                       |
