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

# Containers

> Create a sandbox, run a command, move files and publish a port.

# Containers

The hosted container API requires the operator's `BOAT_API_KEY` and durable D1
storage. Without the provider key, endpoints return `501 boat_not_configured`.
The consumer agent's optional Cloudflare sandbox is a separate execution backend.

```bash theme={null}
lupin containers create --name first-sandbox
lupin containers list
lupin containers run --container-id CONTAINER_ID --command 'pwd'
lupin containers upload --container-id CONTAINER_ID --file ./hello.txt --path /tmp/hello.txt
lupin containers download --container-id CONTAINER_ID --path /tmp/hello.txt --output ./copy.txt
lupin containers ports --container-id CONTAINER_ID
lupin containers stop --container-id CONTAINER_ID
lupin containers resume --container-id CONTAINER_ID
```

Names contain lowercase letters, numbers and dashes (up to 63 characters).
Files use base64 transport with a roughly 2 MB limit; split larger data or use
external object storage. Parent traversal (`..`) is rejected. Commands run
synchronously; inspect `exit_code`, `stdout`, `stderr` and `status` rather than
assuming HTTP success means command success. Use `runs` for command history.

## Public ports and shell

```ts theme={null}
const container = await lupin.containers.create({ name: "preview" });
const result = await lupin.containers.run(container.container_id, { command: "pwd", timeout_seconds: 30 });
console.log(result.exit_code, result.stdout);
// After starting your server in the container:
const published = await lupin.containers.publishPort(container.container_id, 3000);
console.log(published.url);
console.log(await lupin.containers.ports(container.container_id));
```

Publishing exposes a public HTTPS endpoint. Apply application authentication
before exposing private data. `containers.shell(id)` returns a temporary,
credential-bearing desktop URL; handle it as a secret. Start/resume the
container before requesting a shell. The current API supports stop/resume and
port publication; deletion and port revocation are not exposed.

`usage_seconds` includes completed runtime and the current running interval.
Stop idle containers to limit runtime. Billing depends on the configured
provider and plan; inspect current billing terms before creating resources.
On `502`, inspect the provider error, check container status, and avoid blindly
retrying commands with side effects. For partial file transfers, verify size
and contents before continuing.


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