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

# Private Networks

> Connect sandboxes to each other over a private, rule-controlled network

## What are Private Networks?

A private network lets your sandboxes talk to each other directly. Each member is reachable from the others at `<sandbox-id>.sandbox.internal`, and the network's rules decide who may connect to whom, and on which ports. Nothing outside the network can reach its members this way.

**Common use cases:**

* Run a client and a server in separate sandboxes, such as an agent and the service it is being evaluated against
* Split a workload into tiers, for example `web` sandboxes that may reach a `db` sandbox on port 5432 and nothing else
* Spin up a small cluster for distributed tests without exposing anything to the internet

<Note>
  Private networks connect running VM sandboxes that belong to the same team,
  or to you personally if you are not using a team. A network and all of its
  members must belong to the same owner.
</Note>

## Complete Example

Here's a full working example: one sandbox serves HTTP on port 8000, and a second sandbox reaches it by name.

**1. Create two sandboxes**

```bash theme={null}
prime sandbox create python:3.11-slim --name web
prime sandbox create python:3.11-slim --name db
```

**2. Create a network and add both sandboxes**

<CodeGroup>
  ```python Python SDK theme={null}
  from prime_sandboxes import APIClient, SandboxClient

  client = SandboxClient(APIClient())

  network = client.create_lan_network("demo")
  client.add_lan_member(network.id, "<web-sandbox-id>", tags=["web"])
  client.add_lan_member(network.id, "<db-sandbox-id>", tags=["db"])
  ```

  ```bash CLI theme={null}
  prime sandbox network create demo
  prime sandbox network add <network-id> <web-sandbox-id> --tag web
  prime sandbox network add <network-id> <db-sandbox-id> --tag db
  ```
</CodeGroup>

**3. Start a server in one sandbox and call it from the other**

```bash theme={null}
# Serve HTTP on port 8000 in the db sandbox
prime sandbox run <db-sandbox-id> -- bash -c 'nohup python -m http.server 8000 >/dev/null 2>&1 &'

# Reach it by name from the web sandbox
prime sandbox run <web-sandbox-id> -- python -c "import urllib.request; print(urllib.request.urlopen('http://<db-sandbox-id>.sandbox.internal:8000/').status)"
```

A new network allows every member to reach every other member on every port, so the request returns `200`.

## Rules

Rules narrow who may connect to whom. Each rule is **directed** and **allow-only**: it lets members matching `from` open TCP connections to members matching `to`, on the listed ports. A connection that no rule allows is refused.

A selector is either `*` (every member) or `tag:<name>` (members carrying that tag). Leave out the ports to allow every port.

<CodeGroup>
  ```python Python SDK theme={null}
  from prime_sandboxes import LanRule

  # web may reach db on 5432 and 6379; nothing else is allowed
  client.set_lan_rules(
      network.id,
      [LanRule(from_="tag:web", to="tag:db", ports=[5432, 6379])],
  )
  ```

  ```bash CLI theme={null}
  # Rules are written FROM->TO[@PORT,...]
  prime sandbox network rules <network-id> -r 'tag:web->tag:db@5432,6379'
  ```
</CodeGroup>

Each call **replaces** the whole rule list. Pass several rules to allow several paths:

```bash theme={null}
prime sandbox network rules <network-id> \
  -r 'tag:web->tag:db@5432' \
  -r 'tag:worker->tag:db@5432' \
  -r 'tag:web->tag:worker@8080'
```

A few things to keep in mind:

* **Rules are directed.** `tag:web->tag:db` lets `web` connect to `db`, not the other way around. Replies on an allowed connection flow normally.
* **The default is open.** A new network starts with the single rule `*->*`. Replace it to restrict traffic.
* **An empty rule list blocks everything.** Members stay in the network but cannot connect to each other.

## Tags

Tags are labels on a member that rules select with `tag:<name>`. Set them when you add a sandbox. Adding a sandbox that is already a member replaces its tags.

```bash theme={null}
# Add with tags, or replace the tags of an existing member
prime sandbox network add <network-id> <sandbox-id> --tag web --tag frontend
```

Tags use lowercase letters, digits, `.`, `_` and `-`, start with a letter or digit, and are at most 63 characters long.

## Reaching Other Members

Inside a member sandbox, every other member resolves at `<sandbox-id>.sandbox.internal`. Use that name as the host for any TCP client:

```bash theme={null}
curl http://<sandbox-id>.sandbox.internal:8000/
psql -h <sandbox-id>.sandbox.internal -p 5432 -U postgres
```

* Names resolve to private addresses in `198.18.0.0/15`. These addresses are per sandbox and may change, so always connect by name.
* Only TCP is supported between members.
* A sandbox can belong to several networks at once. It can connect to a member of any of them, as each network's rules allow.

## Managing Networks

<CodeGroup>
  ```python Python SDK theme={null}
  # List networks, with sync status
  for n in client.list_lan_networks():
      print(n.id, n.name, n.synced)

  # Show rules and members
  network = client.get_lan_network(network.id)
  for member in network.members:
      print(member.sandbox_id, member.tags, member.synced)

  # Remove one sandbox, or delete the whole network
  client.remove_lan_member(network.id, "<sandbox-id>")
  client.delete_lan_network(network.id)
  ```

  ```bash CLI theme={null}
  # List networks
  prime sandbox network list

  # Show rules and members
  prime sandbox network get <network-id>

  # Remove one sandbox, or delete the whole network
  prime sandbox network remove <network-id> <sandbox-id>
  prime sandbox network delete <network-id>
  ```
</CodeGroup>

Changes apply within a few seconds. Until they do, the network or member shows as not yet synced, and Prime keeps retrying in the background.

Removing a sandbox from a network cuts it off right away. Its connections to the other members are refused, including connections to addresses it looked up earlier. A sandbox that stops running leaves its networks automatically.

`AsyncSandboxClient` has the same methods for async code. Pass `team_id` to `create_lan_network` and `list_lan_networks` (or `--team-id` on the CLI) to work with a specific team. Otherwise your configured team is used.

## Limits

| Resource | Limit |
| - | - |
| Networks per sandbox | 32 |
| Rules per network | 256 |
| Ports per rule | 64 |
| Tags per member | 16 |
| Network name length | 128 characters |

## Quick Troubleshooting

* **"Only running sandboxes can join a network"**: wait until the sandbox is `RUNNING`, then add it.
* **"Only VM sandboxes can join a network"**: private networks are available for VM sandboxes only.
* **"The sandbox and the network must belong to the same team or user"**: create the network under the same team as the sandbox, or switch your configured team.
* **Name does not resolve**: names resolve only inside a sandbox that belongs to a network. Check that `prime sandbox network get <network-id>` lists the sandbox as a synced member.
* **Connection refused or reset**: no rule allows that path. Check the direction and ports with `prime sandbox network get <network-id>`.


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