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

# Blueprint reference

> Complete field reference for blueprints: sections, step types, GitHub Actions, environment variables, secrets, and file attachments.

<Info>
  This is the full field reference for blueprints. For an introduction to blueprints and how they fit into Devin's environment, see [Declarative environment configuration](/onboard-devin/environment/blueprints).
</Info>

A blueprint defines how Devin's environment is configured: what tools to install, how to keep dependencies up to date, and what commands Devin should know about.

## Overview

A blueprint has three core top-level sections, plus optional `runs-on`, `shell`, and `includes` fields, a `post-build` section for organization- and enterprise-level blueprints, and a `clone` section for repository-level blueprints:

```yaml theme={null}
initialize: ...   # Install tools and runtimes
maintenance: ...  # Install project dependencies
knowledge: ...    # Reference info for Devin (never executed)
runs-on: ...      # Platforms to build for (default: ["default"])
shell: ...        # Shell for `run` steps on Windows (default: "default")
includes: ...     # (Git-backed repository root blueprint only) Workspace blueprints
post-build: ...   # (Organization/enterprise only) Commands that run after all setup
clone: ...        # (Repository-level only) Override git-clone defaults
```

| Section | Purpose | Executed? |
| - | - | - |
| `initialize` | Install system tools, language runtimes, global CLIs | During full builds and for rebuilt workspaces |
| `maintenance` | Install and update project dependencies | Yes, during builds. Surfaced to the agent at session start (not auto-executed). |
| `knowledge` | Tell Devin how to lint, test, build, and other project-specific info | No, provided as reference |
| `runs-on` | Select one or more build platforms | Used to create one snapshot build per platform |
| `shell` | Select the shell for `run` steps on Windows | Applied to `initialize`, `maintenance`, and `post-build` `run` steps during builds on Windows; ignored on Linux and macOS |
| `includes` | Discover workspace blueprints from a repository root blueprint | Git-backed repository root blueprints only |
| `post-build` | Commands that run after all repositories are cloned and set up (organization/enterprise only) | Yes, during builds — a non-zero exit code fails the build |
| `clone` | Override how the repository is cloned into the snapshot (repository-level only) | Applied during the build's clone step |

All sections are optional. You can include any combination.

`initialize` runs during full builds and for workspaces rebuilt from scratch. Results are saved in the snapshot. In a [differential build](/onboard-devin/environment/differential-builds), inherited workspaces skip `initialize`, pull the latest code, and run only `maintenance`. Write `maintenance` so it is self-contained and can run independently on top of the existing snapshot without requiring `initialize` to run immediately beforehand or relying on environment variables that `initialize` previously wrote to `$ENVRC`. At the start of every session, `maintenance` commands are **not auto-executed** — instead, they are surfaced to the agent as context so it knows which dependency commands to run if needed (e.g. after pulling latest code). Commands should still be fast and incremental. Builds run automatically when your blueprint changes and periodically (every \~24 hours).

## initialize

Use `initialize` for installing tools and runtimes that don't depend on the specific state of your code: language runtimes, system packages, global CLIs.

### Simple form

For straightforward shell commands, use a block scalar:

```yaml theme={null}
initialize: |
  curl -LsSf https://astral.sh/uv/install.sh | sh
  apt-get update && apt-get install -y build-essential
  npm install -g pnpm
```

### Structured form

For named steps, environment variables, or GitHub Actions, use a list:

```yaml theme={null}
initialize:
  - name: "Install Python 3.12"
    uses: github.com/actions/setup-python@v5
    with:
      python-version: "3.12"

  - name: "Install system packages"
    run: |
      apt-get update
      apt-get install -y libpq-dev

  - name: "Install global tools"
    run: pip install uv
    env:
      PIP_BREAK_SYSTEM_PACKAGES: "1"
```

Both forms can be mixed. The simple form is equivalent to a single step with `run`.

### When to use initialize vs maintenance

| Put in `initialize` | Put in `maintenance` |
| - | - |
| Language runtime installation | `npm install` / `pip install` |
| System packages (`apt-get`) | `bundle install` |
| Global CLI tools | `go mod download` |
| One-time configuration | Dependency cache updates |
| GitHub Actions (`setup-python`, etc.) | Repo-specific setup scripts |

Both sections run during full builds. In differential builds, inherited workspaces skip `initialize` and run only `maintenance` after pulling the latest code. Tools and runtimes go in `initialize`; dependency commands that track your code's lock files go in `maintenance`.

## maintenance

Use `maintenance` for dependency installation and other commands that should run after your code is cloned. These commands run during builds and are surfaced to the agent at session start so it can re-run them if dependencies have changed. This is where `npm install`, `pip install`, `uv sync`, and similar commands belong.

```yaml theme={null}
maintenance: |
  npm install
  pip install -r requirements.txt
```

Or in structured form:

```yaml theme={null}
maintenance:
  - name: "Install npm dependencies"
    run: npm install

  - name: "Install Python dependencies"
    run: uv sync
    env:
      UV_CACHE_DIR: /tmp/uv-cache
```

<Info>
  For repo-level blueprints, `maintenance` commands run from the repository root directory. For org-level blueprints, they run from the home directory (`~`).
</Info>

## knowledge

The `knowledge` section is **not executed**. It provides reference information that Devin uses when working in your project. This is how you tell Devin the correct commands for linting, testing, building, and any other project-specific workflows.

```yaml theme={null}
knowledge:
  - name: lint
    contents: |
      Run linting with:
      npm run lint

      For auto-fix:
      npm run lint -- --fix

  - name: test
    contents: |
      Run the full test suite:
      npm test

      Run a single test file:
      npm test -- path/to/test.ts

  - name: build
    contents: |
      npm run build

      Build output goes to dist/
```

Each knowledge item has:

| Field | Type | Description |
| - | - | - |
| `name` | string | Identifier for this knowledge item (e.g., `lint`, `test`, `build`) |
| `contents` | string | Free-form text with commands, instructions, or notes |

The `name` field is a label. By convention, `lint`, `test`, and `build` are the standard names. Devin references these when verifying its work. You can add any additional knowledge items with custom names:

```yaml theme={null}
knowledge:
  - name: lint
    contents: ...
  - name: test
    contents: ...
  - name: build
    contents: ...
  - name: deploy
    contents: |
      Deploy to staging:
      npm run deploy:staging
  - name: database
    contents: |
      Run migrations:
      npm run db:migrate

      Seed test data:
      npm run db:seed
```

## runs-on

The optional top-level `runs-on` field accepts a string or a list of strings. Its default is `["default"]`. The `default` and `linux` labels are case-insensitive aliases for the default Linux platform. Any other label must match a machine configuration registered on your account, such as `windows` or `macos`.

When a block lists multiple platform labels, Devin creates one snapshot build per platform and runs the same steps for each platform. Two blocks in the same file cannot resolve to the same platform; this includes the `default` and `linux` aliases.

For platform-specific setup, see [Windows support](/onboard-devin/environment/windows-support) and [macOS support](/onboard-devin/environment/macos-support).

## shell

The optional top-level `shell` field selects the shell that runs the block's `run` steps on Windows machines. It applies to every `run` step in the block's `initialize`, `maintenance`, and `post-build` sections.

| Value | Behavior on Windows | Behavior on Linux and macOS |
| - | - | - |
| `default` (default) | `run` steps execute in Git Bash | `run` steps execute in bash |
| `bash` | Alias for `default` | Alias for `default` |
| `powershell` | `run` steps execute in Windows PowerShell | Ignored; `run` steps execute in bash |

Values are case-insensitive. Any other value is rejected with `shell: must be 'default', 'bash', or 'powershell'`.

```yaml theme={null}
runs-on: windows
shell: powershell

initialize:
  - name: "Install .NET SDK"
    run: |
      choco install dotnet-sdk -y
      New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\tools" | Out-Null

maintenance: |
  dotnet restore
```

With `shell: powershell`:

* Secrets, step-level `env` variables, variables that earlier steps wrote to `$ENVRC`, and the working directory are the same as for bash steps. Read environment variables with PowerShell syntax (`$env:NAME`).
* The [cross-step `$ENVRC` examples](#cross-step-environment-variables-envrc) are written for bash steps. In a PowerShell step, `$env:ENVRC` holds the Git Bash-style path of the file (`/c/...`), so those examples don't apply as written; keep steps that need to persist variables to later steps in a block that uses the default shell.
* Use native Windows paths (`C:\Users\...`) rather than the Git Bash `/c/...` form.
* A PowerShell error (for example, a failing cmdlet or an unknown command) stops the step.
* For native executables, only the exit code of the last one the script runs determines the step result. Check `$LASTEXITCODE` after earlier native commands whose failure should stop the step.
* `uses` steps (GitHub Actions) are not affected.

The setting only affects build steps. Windows sessions still use Git Bash as the default shell. Because `shell` is set per block, a [multi-document blueprint](/onboard-devin/environment/windows-support#multi-platform-blueprint) can use `shell: powershell` in its Windows document without affecting the Linux document. In a block that lists multiple platforms in `runs-on`, the same `run` bodies execute in PowerShell on Windows and in bash everywhere else, so they must be valid in both shells.

## includes

The optional `includes` field only applies to [git-backed blueprints](/onboard-devin/environment/git-backed-blueprints): Devin resolves it when it discovers a repository's root `.devin/blueprint.yaml` file. It is ignored in blueprints authored in the Settings editor, and it is not allowed in an included workspace blueprint.

It accepts a string or a list of strings. Each entry identifies a workspace subdirectory; Devin looks for `<dir>/.devin/blueprint.yaml`, and the full file path also works. Paths cannot contain `..`.

Nested includes are rejected, and each workspace path can appear only once. If an included file is missing, Devin treats that workspace as removed.

## post-build

The `post-build` section is available on **organization-level and enterprise-level blueprints only** (it is not supported in repository-level blueprints). Its steps run during the build **after all repositories have been cloned and their `initialize` and `maintenance` steps have completed**, but before the health check and the snapshot image is created. This makes it the right place for cross-repository validation and health checks that need the fully assembled environment.

Because it runs late in the build with the whole environment in place, a `post-build` step can see every cloned repository and every tool installed by the enterprise, organization, and repository blueprints.

```yaml theme={null}
post-build: |
  # Verify the assembled environment is healthy
  node --version
  python --version
  test -d ~/repos/my-service
```

Or in structured form:

```yaml theme={null}
post-build:
  - name: "Verify toolchain"
    run: |
      node --version
      uv --version

  - name: "Smoke-test the workspace"
    run: ~/repos/my-service/scripts/healthcheck.sh
```

<Warning>
  `post-build` steps **fail the build on a non-zero exit code**. If a `post-build` step exits non-zero, the build is marked failed and no snapshot image is produced. Use this to gate snapshots on health checks — but make sure the commands are reliable so a flaky check doesn't block your builds.
</Warning>

<Info>
  `post-build` steps use the same [step types](#step-types) as `initialize` (shell `run` commands and GitHub Actions `uses`), and run from the home directory (`~`).
</Info>

## clone

For **repository-level blueprints**, the optional `clone` section overrides defaults used when Devin clones the repository into the snapshot. Every field is optional and falls back to a sensible default that preserves current behavior.

```yaml theme={null}
clone:
  path: my-project        # clone destination under ~/repos/ (default: repo short name)
  ref: develop            # branch or tag to check out (default: repo's default branch)
  depth: 1                # 0 = full history, N = --depth N (default: 0)
  tags: false             # false passes --no-tags (default: true)
  submodules: recursive   # true / false / "recursive" (default: true)
  lfs: false              # false sets GIT_LFS_SKIP_SMUDGE=1 during clone (default: true)
```

| Field | Type | Default | Description |
| - | - | - | - |
| `path` | string | repo short name | Override the clone destination directory under `~/repos/`. Must be unique across repos in the same snapshot. |
| `ref` | string | repo's default branch | Branch or tag to check out after cloning. Commit SHAs are not supported here. |
| `depth` | int | `0` | Clone depth. `0` clones the full history; any positive value passes `--depth N` for a shallow clone. |
| `tags` | bool | `true` | When `false`, passes `--no-tags` to skip fetching git tags. |
| `submodules` | bool or `"recursive"` | `true` | `true` or `"recursive"` passes `--recurse-submodules`. `false` skips submodules entirely. |
| `lfs` | bool | `true` | When `false`, sets `GIT_LFS_SKIP_SMUDGE=1` to skip Git LFS object downloads during clone. |

<Info>
  `clone` only applies to **repository-level** blueprints — it controls how that specific repository is cloned into the snapshot. It has no effect in organization-level or enterprise-level blueprints.
</Info>

## Step types

Each step in `initialize`, `maintenance`, or `post-build` uses one of two types: shell commands (`run`) or GitHub Actions (`uses`). `maintenance` steps support `run` only; see [GitHub Actions](#github-actions-uses).

### Shorthand and validation rules

* A section provided as a bare string becomes a single `run` step.
* A list entry provided as a bare string becomes a `run` step.
* A step must define `run` or `uses`, but never both.
* `uses` steps can't be used in `maintenance`. The build fails with `'uses' steps are not supported in maintenance sections`.
* `with` is valid only on `uses` steps.
* All `with` values are converted to strings; quote numeric values when the action expects a string.

### YAML document rules

Each `---` document must be a YAML mapping. A top-level sequence is rejected with `each YAML document must be a mapping, not a sequence; use '---' to separate multiple blocks`.

### Shell commands (`run`)

Execute arbitrary shell commands in bash, or in Windows PowerShell on Windows when the block sets [`shell: powershell`](#shell):

```yaml theme={null}
- name: "Install dependencies"
  run: |
    npm install
    pip install -r requirements.txt
```

| Field | Type | Description |
| - | - | - |
| `name` | string (optional) | Human-readable label for the step |
| `run` | string | Shell command(s) to execute |
| `env` | map (optional) | Extra environment variables for this step |

**Execution details:**

* Commands run in bash (Git Bash on Windows). If any command in a multi-line script fails, the entire step stops immediately. On Windows, set the top-level [`shell`](#shell) field to `powershell` to run commands in Windows PowerShell instead.
* Org-level blueprints execute in the home directory (`~`).
* Repo-level blueprints execute in the cloned repository root.
* Each step has a timeout of 3 hours.
* Secrets are automatically available as environment variables.

### GitHub Actions (`uses`)

Run GitHub Actions directly in your blueprint's `initialize` (or `post-build`) section:

```yaml theme={null}
- name: "Install Python"
  uses: github.com/actions/setup-python@v5
  with:
    python-version: "3.12"
```

| Field | Type | Description |
| - | - | - |
| `name` | string (optional) | Human-readable label for the step |
| `uses` | string | GitHub Action reference |
| `with` | map (optional) | Input parameters for the action |
| `env` | map (optional) | Extra environment variables for this step |

**Action reference format:**

```
github.com/<owner>/<repo>@<ref>
github.com/<owner>/<repo>/<subpath>@<ref>
```

The `github.com/` prefix and `@<ref>` suffix are both required. The ref is typically a version tag like `v5`.

**Commonly used actions:**

| Action | Purpose | Example `with` |
| - | - | - |
| `github.com/actions/setup-python@v5` | Install Python | `python-version: "3.12"` |
| `github.com/actions/setup-node@v4` | Install Node.js | `node-version: "20"` |
| `github.com/actions/setup-go@v5` | Install Go | `go-version: "1.22"` |
| `github.com/actions/setup-java@v4` | Install Java/JDK | `java-version: "21"`, `distribution: "temurin"` |
| `github.com/gradle/actions/setup-gradle@v4` | Install Gradle | (none) |
| `github.com/ruby/setup-ruby@v1` | Install Ruby | `ruby-version: "3.3"` |

<Info>
  Node.js actions (`node16`, `node20`, `node24`) and composite actions are supported. Docker actions are supported on Linux builds only, not on [Windows](/onboard-devin/environment/windows-support) builds. `post` cleanup steps are skipped. See [GitHub Actions limitations](/onboard-devin/environment/github-actions#limitations).
</Info>

<Warning>
  `uses` steps are not supported in `maintenance`. Actions can only run during `initialize` (and `post-build`); a `uses` step in `maintenance` fails the build.
</Warning>

**How `with` values work:**

Values passed via `with` are provided to the action as inputs, following the same conventions as GitHub Actions workflows. All values are converted to strings.

```yaml theme={null}
with:
  python-version: "3.12"
  check-latest: true
  cache: "pip"
```

**How actions propagate changes:**

Actions can modify the environment for subsequent steps. For example, `setup-python` adds the Python binary to `PATH`, which remains available for all later steps and in `maintenance`.

### run vs uses: which to use

| Use `run` when... | Use `uses` when... |
| - | - |
| Installing system packages (`apt-get`) | Setting up language runtimes (Python, Node, Go, Java, Ruby) |
| Running project-specific scripts | An official GitHub Action exists for what you need |
| Configuring files or environment | You want automatic version management and caching |
| The command is simple and self-contained | You'd use the same Action in a GitHub Actions workflow |

In practice, most configurations use `uses` for language runtimes and `run` for everything else.

## Environment variables and secrets

### Step-level environment variables

Any step can define extra environment variables with the `env` field:

```yaml theme={null}
- run: pip install -r requirements.txt
  env:
    PIP_INDEX_URL: "https://pypi.example.com/simple/"
    PIP_BREAK_SYSTEM_PACKAGES: "1"
```

These are scoped to the step and don't persist to subsequent steps.

### Cross-step environment variables (`$ENVRC`)

To propagate environment variables across steps, write them to the `$ENVRC` file:

```yaml theme={null}
- name: "Set shared variables"
  run: |
    echo "DATABASE_URL=postgresql://localhost:5432/myapp" >> $ENVRC
    echo "APP_ENV=development" >> $ENVRC
```

Variables written to `$ENVRC` are automatically exported and available to all
subsequent steps and the Devin session produced by the current build. This works
similarly to `$GITHUB_ENV` in GitHub Actions.

This also applies to `PATH`. If you install a tool to a non-standard directory
(anything outside `/usr/bin` or `/usr/local/bin`), append it to `$ENVRC` so
subsequent steps and repo-level blueprints can find the binary:

```yaml theme={null}
- name: "Install latest direnv"
  run: |
    curl -sfL https://direnv.net/install.sh | bash
    echo 'export PATH="$HOME/.local/bin:$PATH"' >> $ENVRC
```

A plain `export PATH=...` inside a `run:` block only affects that step's shell.
Each step starts a new shell process, so `PATH` changes that are not written to
`$ENVRC` are lost.

<Info>
  `uses:` actions (e.g. `actions/setup-node`) automatically propagate their `PATH`
  additions to `$ENVRC` — you only need to do this manually for `run:` steps.
</Info>

`$ENVRC` is reset at the start of every build, including differential builds.
Values written during one build are not available to the next build. In
particular, an inherited workspace runs only `maintenance`, so it cannot rely on
`PATH` or other variables that `initialize` wrote to `$ENVRC` in the parent
build. Configure any environment required by `maintenance` within
`maintenance` itself.

<script src="/anchor-scroll-fix.js" />

### Secrets

Secrets configured in the Devin UI (via the **Secrets** tab in each blueprint editor) are automatically injected as environment variables. You don't declare them in your blueprint. Just reference them by name (e.g., `$MY_SECRET`).

Secrets are injected before every step runs during builds. They are scrubbed from the snapshot image itself, so credentials are never baked into saved machine images. Outside of blueprint commands, secrets are not exported to every shell; Devin binds them to the specific commands that need them.

* **Organization secrets**: Available as environment variables in every step across all blueprints in the org. Set these in the **Secrets** tab of the org-wide blueprint editor.
* **Enterprise secrets**: Merged with org secrets (org secrets take precedence on name collisions). Available across all orgs in the enterprise.
* **Repository secrets**: Available as environment variables in that repo's blueprint steps and commands. Configure these in the **Secrets** tab of the repository's blueprint editor.

<Info>
  **Build-only secrets**: Enterprise secrets can be marked **Build only** when you add them in the enterprise blueprint editor's **Secrets** tab. This option is not available for org or repository secrets. A build-only secret is available only to enterprise and org blueprint steps during snapshot builds. It is removed before repositories are cloned, so repo blueprint steps and `post-build` steps cannot read it, and it is never injected into Devin sessions. Use it for credentials needed only during enterprise or org setup (e.g., downloading private artifacts in the enterprise blueprint's `initialize`).
</Info>

<Warning>
  `maintenance` runs during builds. At session start, `maintenance` commands are surfaced to the agent (not auto-executed), so the agent may re-run them if needed. If a `maintenance` step writes secrets into config files (e.g., `~/.m2/settings.xml`, `~/.npmrc`), those files will be baked into the snapshot. Place credential-writing steps in `maintenance` (not `initialize`) so they are refreshed during periodic builds, but be aware the written files persist in the image. For maximum security, use environment variables or `$ENVRC` instead of writing credentials to disk.
</Warning>

### File attachments

You can upload files (like `settings.xml` or other configuration files) through the blueprint editor. Uploaded files are written to `~/.files/` and an environment variable is set pointing to each file's path:

```
$FILE_SETTINGS_XML    -> /home/ubuntu/.files/settings.xml
$FILE_NPMRC           -> /home/ubuntu/.files/npmrc
```

The variable name is derived from the file name: uppercase, with non-alphanumeric characters replaced by underscores (leading and trailing underscores are removed), prefixed with `FILE_`.

File names must be plain file names: they cannot start with a dot or contain path separators, whitespace, or control characters. To use a dotfile such as `.npmrc`, upload it under a name without the leading dot (for example, `npmrc`) and copy it into place in a blueprint step.

Use file attachments in your blueprint steps:

```yaml theme={null}
maintenance:
  - name: "Configure Maven"
    run: |
      mkdir -p ~/.m2
      cp "$FILE_SETTINGS_XML" ~/.m2/settings.xml
  - name: "Configure npm"
    run: cp "$FILE_NPMRC" ~/.npmrc
```

## Git-backed blueprints

You can store blueprints as `.devin/blueprint.yaml` files directly in your repository, then sync them via the API or the UI. See [Git-backed blueprints](/onboard-devin/environment/git-backed-blueprints) for setup instructions and details.

## Complete example

<Info>
  For how blueprints compose across tiers (enterprise → org → repo), build statuses, repository states, and what triggers a rebuild, see [Builds and sessions](/onboard-devin/environment/blueprints#builds-and-sessions) on the Declarative configuration page.
</Info>

### Org-wide blueprint

Shared tooling that every repo in the org needs. This runs first (after any enterprise blueprint), in the home directory.

```yaml theme={null}
initialize:
  - name: "Install Node.js 20"
    uses: github.com/actions/setup-node@v4
    with:
      node-version: "20"

  - name: "Install Python 3.12 and uv"
    run: |
      curl -LsSf https://astral.sh/uv/install.sh | sh

  - name: "Install shared tools"
    run: |
      npm install -g pnpm turbo
      apt-get update && apt-get install -y jq ripgrep

  - name: "Configure private registry"
    run: |
      echo "//npm.corp.example.com/:_authToken=$NPM_REGISTRY_TOKEN" >> ~/.npmrc
```

### Repo-level blueprint

Project-specific setup for a Node.js + Python monorepo. This runs after the org-wide blueprint, in the repository directory.

```yaml theme={null}
initialize:
  - name: "Install Playwright browsers"
    run: npx playwright install --with-deps chromium

  - name: "Set up project environment variables"
    run: |
      echo "DATABASE_URL=postgresql://localhost:5432/myapp_dev" >> $ENVRC
      echo "REDIS_URL=redis://localhost:6379" >> $ENVRC
      echo "APP_ENV=development" >> $ENVRC

maintenance:
  - name: "Install frontend dependencies"
    run: |
      cd frontend
      pnpm install

  - name: "Install backend dependencies"
    run: |
      cd backend
      uv sync

  - name: "Run database migrations"
    run: |
      cd backend
      uv run alembic upgrade head
    env:
      DATABASE_URL: "postgresql://localhost:5432/myapp_dev"

knowledge:
  - name: lint
    contents: |
      Frontend:
      cd frontend && pnpm lint

      Backend:
      cd backend && uv run ruff check .

      Auto-fix:
      cd frontend && pnpm lint --fix
      cd backend && uv run ruff check --fix .

  - name: test
    contents: |
      Frontend unit tests:
      cd frontend && pnpm test

      Backend unit tests:
      cd backend && uv run pytest

      E2E tests (requires dev server running):
      cd frontend && pnpm test:e2e

  - name: build
    contents: |
      Frontend:
      cd frontend && pnpm build

      Backend:
      cd backend && uv run python -m build

  - name: dev-server
    contents: |
      Start the full development stack:
      cd backend && uv run uvicorn main:app --reload &
      cd frontend && pnpm dev

      Frontend: http://localhost:3000
      Backend API: http://localhost:8000
      API docs: http://localhost:8000/docs

  - name: database
    contents: |
      Run migrations:
      cd backend && uv run alembic upgrade head

      Create a new migration:
      cd backend && uv run alembic revision --autogenerate -m "description"

      Reset the database:
      cd backend && uv run alembic downgrade base && uv run alembic upgrade head
```


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