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

# Connect Services

> Add integrations, secrets, and filesystems to a Capsule app.

Real apps need credentials and durable storage. Capsule separates those into three primitives:

* integrations for credentials that belong to the app user
* secrets for credentials that belong to the workspace or app operator
* filesystems for mounted durable files

## 1. Create workspace resources

```bash theme={null}
capsule secret create OPENAI_API_KEY=sk-...
capsule fs create reports
```

Secrets and filesystems are workspace resources. The app opts into them in code.

## 2. Inject secrets and mount filesystems

```python theme={null}
app = cpsl.App(
    name="connected-app",
    image=cpsl.Image(python_packages=["openai"]),
    secrets=["OPENAI_API_KEY"],
    filesystems={"/data": cpsl.FileSystem("reports")},
)
```

Inside the runtime, `/data` behaves like a normal mounted directory.

## 3. Declare user integrations

Use integrations when the credential belongs to the signed-in app user.

```python theme={null}
app.add_integration(
    cpsl.GitHub(
        client_id=cpsl.Secret.from_name("GITHUB_CLIENT_ID"),
        client_secret=cpsl.Secret.from_name("GITHUB_CLIENT_SECRET"),
        scopes=["repo", "read:user"],
    )
)
```

Known secret-form integrations can be declared directly:

```python theme={null}
app.add_integration(cpsl.AWS())
```

## 4. Prompt at runtime

```python theme={null}
@app.message()
async def handle(session: cpsl.Session, msg: cpsl.Message):
    github = await session.require_integration(
        cpsl.Integration.GITHUB,
        reason="Connect GitHub so I can inspect repositories.",
    )
    await session.reply(f"Connected GitHub with scopes: {github.scopes}")
```

Use `show_integration(...)` instead when the connection is optional and you only want to render a non-blocking card.

## 5. Save files

```python theme={null}
with open("/data/report.txt", "w") as f:
    f.write("Generated by Capsule\n")
```

Use collections for queryable records and filesystems for durable files, generated artifacts, uploads, and large intermediate outputs.

## Next steps

* Add long-running work with [Background Work](/build/background-work).
* See [Integrations](/features/integrations), [Secrets](/features/secrets), and [Filesystems](/features/filesystems).
