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

# Preview Environments: Test Changes on Live Branches

> Create a live, isolated copy of any service for any Git branch, each with its own URL, so reviewers can test changes before they merge.

A preview environment is a full, isolated copy of a web server, worker, or static website running from a specific Git branch. Each preview gets its own URL derived from the branch name and your project's hostname suffix, so you can share a live link with teammates, run automated tests, or do thorough QA — all without touching your production deployment. Previews use the same ECS infrastructure as your production services, so what you test is exactly what you ship.

## How Previews Work

When you create a preview, Springwinter registers a new ECS task definition scoped to the target branch. It then builds and deploys the branch code exactly as it would for a production deployment, using a separate task and a unique URL. For example, if your production web server lives at `api.acme.springwinter.app` and you create a preview for the branch `feat/new-checkout`, the preview URL might be `api--feat-new-checkout.acme.springwinter.app`.

The preview task runs independently of production — you can redeploy, update environment variables, or tear it down without any impact on the live service.

<Note>
  Previews are not created automatically on every push. You create them explicitly through the dashboard or API. Once a preview exists, auto-deploy is active: every subsequent push to that branch redeploys the preview automatically.
</Note>

## Creating a Preview

Send a `POST` request to the previews endpoint for the resource, including the branch name in the request body:

<Tabs>
  <Tab title="Web Server">
    ```http theme={null}
    POST /api/projects/{project_id}/web_servers/{id}/previews
    Content-Type: application/json

    {
      "branch": "feat/new-checkout"
    }
    ```
  </Tab>

  <Tab title="Worker">
    ```http theme={null}
    POST /api/projects/{project_id}/workers/{id}/previews
    Content-Type: application/json

    {
      "branch": "feat/new-checkout"
    }
    ```
  </Tab>

  <Tab title="Static Website">
    ```http theme={null}
    POST /api/projects/{project_id}/static_websites/{id}/previews
    Content-Type: application/json

    {
      "branch": "feat/new-checkout"
    }
    ```
  </Tab>
</Tabs>

Springwinter responds with the preview object, including the unique URL and the preview ID you'll use for subsequent operations.

## Managing Previews

Once a preview is running, you can inspect or remove it using the following endpoints. The same pattern applies to workers and static websites — replace `web_servers` with `workers` or `static_websites` as needed.

**Retrieve a preview:**

```http theme={null}
GET /api/projects/{project_id}/web_servers/{id}/previews/{preview_id}
```

**Delete a preview:**

```http theme={null}
DELETE /api/projects/{project_id}/web_servers/{id}/previews/{preview_id}
```

Deleting a preview tears down the ECS task and removes the associated URL immediately. The branch and its code in GitHub are not affected.

## Preview Observability

Each preview has its own logs, metrics, and environment endpoint so you can debug it just like a production service.

<CardGroup cols={3}>
  <Card title="Logs" icon="file-lines">
    Stream CloudWatch logs for the preview task.

    `GET /api/projects/{project_id}/web_servers/{id}/previews/{preview_id}/logs`
  </Card>

  <Card title="Metrics" icon="chart-line">
    View CPU, memory, request, and error metrics scoped to the preview.

    `GET /api/projects/{project_id}/web_servers/{id}/previews/{preview_id}/metrics`
  </Card>

  <Card title="Environment" icon="sliders">
    Read or update the environment variables for this specific preview.

    `GET /api/projects/{project_id}/web_servers/{id}/previews/{preview_id}/environment`
  </Card>
</CardGroup>

To override environment variables for a preview — for example, to point it at a staging database instead of the production one — send a `PUT` request to the preview's environment endpoint:

```http theme={null}
PUT /api/projects/{project_id}/web_servers/{id}/previews/{preview_id}/environment
Content-Type: application/json

[
  { "name": "DATABASE_URL", "value": "postgres://user:pass@staging-host:5432/mydb" },
  { "name": "APP_ENV", "value": "staging" }
]
```

See [Environment Variables](/concepts/environment-variables) for full details on how the `PUT` endpoint works and the replace-all semantics you need to be aware of.

## Best Practices

<Tip>
  Use previews for pull request review. Create a preview when you open a PR and share the URL in the PR description. Reviewers can click through the live app rather than running it locally, and the preview tears down cleanly when the PR is merged or closed.
</Tip>

<Accordion title="Recommended workflow for QA">
  1. Open a pull request on GitHub for your feature branch.
  2. Create a preview via the Springwinter dashboard or API, pointing at the PR branch.
  3. Share the preview URL with your QA team or include it in the PR description.
  4. Push additional commits to the branch — the preview auto-redeploys on each push.
  5. When the PR is approved and merged, delete the preview to stop incurring AWS costs.
</Accordion>

<Note>
  Preview environments consume AWS resources in your account and contribute to your monthly cost. Delete previews you are no longer actively using to avoid unnecessary charges. Springwinter displays per-preview cost estimates on the resource detail page.
</Note>
