> ## 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.

# Projects API: Create and Manage Projects

> Manage Springwinter projects via REST. Create, update, delete projects and provision HTTPS certificates through the API.

Projects are the top-level organizational unit in Springwinter. Every resource — web servers, workers, static websites, caches, databases, and storage buckets — belongs to a single project. The endpoints below let you create and manage projects programmatically, including provisioning and removing HTTPS certificates on the project's shared load balancer. All requests require a valid `Authorization: Bearer <token>` header or an active cookie session with a CSRF token.

***

## List Projects

```http theme={null}
GET /api/projects
```

Returns all projects that belong to your organization. Use this endpoint to build dashboards, validate project names, or look up project IDs for subsequent resource calls.

### Response

<ResponseField name="id" type="string">
  Unique identifier for the project.
</ResponseField>

<ResponseField name="name" type="string">
  Human-readable project name.
</ResponseField>

<ResponseField name="hostname_suffix" type="string">
  The suffix appended to every service hostname inside this project (e.g. `storefront` produces `api.storefront.springwinter.app`).
</ResponseField>

```json theme={null}
[
  {
    "id": "proj_01h8xkr2m4fgz3nvq7p0c5w9",
    "name": "Storefront",
    "hostname_suffix": "storefront"
  },
  {
    "id": "proj_02j9ylr3n5ghb4ovr8q1d6x0",
    "name": "Analytics Platform",
    "hostname_suffix": "analytics"
  }
]
```

***

## Create a Project

```http theme={null}
POST /api/projects
```

Creates a new project. The `hostname_suffix` must be globally unique across all Springwinter customers — Springwinter uses it to build public DNS records for every service in the project.

### Body Parameters

<ParamField body="name" type="string" required>
  Display name for the project. Shown in the dashboard and API responses.
</ParamField>

<ParamField body="hostname_suffix" type="string" required>
  URL-safe slug used as the subdomain suffix for all services in this project. Must be lowercase, alphanumeric, and may include hyphens. Must be globally unique.
</ParamField>

```json theme={null}
{
  "name": "Storefront",
  "hostname_suffix": "storefront"
}
```

### Response — `201 Created`

Returns the newly created project object.

```json theme={null}
{
  "id": "proj_01h8xkr2m4fgz3nvq7p0c5w9",
  "name": "Storefront",
  "hostname_suffix": "storefront"
}
```

***

## Get a Project

```http theme={null}
GET /api/projects/{id}
```

Returns a single project by its ID.

### Path Parameters

<ParamField path="id" type="string" required>
  The unique ID of the project to retrieve.
</ParamField>

### Response

```json theme={null}
{
  "id": "proj_01h8xkr2m4fgz3nvq7p0c5w9",
  "name": "Storefront",
  "hostname_suffix": "storefront"
}
```

***

## Update a Project

```http theme={null}
PATCH /api/projects/{id}
```

Updates mutable attributes on a project. You can change the `name` or `hostname_suffix`. Changing the suffix immediately updates all service hostnames within the project, so coordinate any DNS or environment variable changes before calling this endpoint in production.

### Path Parameters

<ParamField path="id" type="string" required>
  The unique ID of the project to update.
</ParamField>

### Body Parameters

<ParamField body="name" type="string">
  Updated display name for the project.
</ParamField>

<ParamField body="hostname_suffix" type="string">
  New hostname suffix to apply to all services in this project. Must be globally unique and URL-safe.
</ParamField>

```json theme={null}
{
  "hostname_suffix": "shop"
}
```

### Response

Returns the updated project object.

```json theme={null}
{
  "id": "proj_01h8xkr2m4fgz3nvq7p0c5w9",
  "name": "Storefront",
  "hostname_suffix": "shop"
}
```

***

## Delete a Project

```http theme={null}
DELETE /api/projects/{id}
```

Permanently deletes a project. This operation is irreversible.

### Path Parameters

<ParamField path="id" type="string" required>
  The unique ID of the project to delete.
</ParamField>

<Warning>
  You can only delete a project that contains no resources. Remove all web servers, workers, static websites, caches, databases, and storage buckets before calling this endpoint. Springwinter returns `409 Conflict` if the project still has attached resources.
</Warning>

### Response — `204 No Content`

An empty body on success.

***

## Enable HTTPS (Provision Certificate)

```http theme={null}
POST /api/projects/{project_id}/certificate
```

Provisions an AWS ACM certificate for the project's load balancer and enables HTTPS on all web server endpoints in the project. Springwinter handles DNS validation automatically using the Route 53 hosted zone associated with your AWS account.

### Path Parameters

<ParamField path="project_id" type="string" required>
  The unique ID of the project for which to provision the certificate.
</ParamField>

<Note>
  Certificate provisioning is asynchronous. After this call returns, poll `GET /api/projects/{id}` and check the `certificate_status` field until it reaches `issued`. DNS validation typically completes within a few minutes.
</Note>

### Response — `202 Accepted`

```json theme={null}
{
  "certificate_status": "pending_validation",
  "certificate_arn": "arn:aws:acm:us-east-1:123456789012:certificate/abc12345-1234-1234-1234-abc123456789"
}
```

***

## Disable HTTPS (Remove Certificate)

```http theme={null}
DELETE /api/projects/{project_id}/certificate
```

Removes the ACM certificate from the project load balancer and reverts all web server endpoints to HTTP only.

### Path Parameters

<ParamField path="project_id" type="string" required>
  The unique ID of the project from which to remove the certificate.
</ParamField>

<Warning>
  Removing the certificate immediately drops HTTPS support for all services in the project. Any clients or integrations that enforce HTTPS will start failing. Ensure you have updated all dependent systems before calling this endpoint.
</Warning>

### Response — `204 No Content`

An empty body on success.

***

## Get Bedrock Configuration

```http theme={null}
GET /api/projects/{project_id}/bedrock
```

Returns the Amazon Bedrock configuration attached to this project. Bedrock integration allows your services to call AWS foundation models using the project's IAM role, with no credentials to manage.

### Path Parameters

<ParamField path="project_id" type="string" required>
  The unique ID of the project whose Bedrock configuration you want to retrieve.
</ParamField>

### Response

```json theme={null}
{
  "enabled": true,
  "region": "us-east-1",
  "allowed_model_ids": [
    "anthropic.claude-3-5-sonnet-20241022-v2:0",
    "amazon.titan-text-express-v1"
  ]
}
```

***

## Update Bedrock Configuration

```http theme={null}
PUT /api/projects/{project_id}/bedrock
```

Creates or replaces the Bedrock configuration for this project. After this call, all services in the project can invoke the specified foundation models using their injected AWS credentials.

### Path Parameters

<ParamField path="project_id" type="string" required>
  The unique ID of the project to configure.
</ParamField>

### Body Parameters

<ParamField body="enabled" type="boolean" required>
  Set to `true` to enable Bedrock access for all services in the project, or `false` to disable it.
</ParamField>

<ParamField body="region" type="string" required>
  AWS region in which to call Bedrock (e.g. `us-east-1`). Must match a region where your desired models are available.
</ParamField>

<ParamField body="allowed_model_ids" type="array" required>
  List of Bedrock model IDs your services are permitted to invoke. Springwinter scopes the IAM policy to exactly these models.
</ParamField>

```json theme={null}
{
  "enabled": true,
  "region": "us-east-1",
  "allowed_model_ids": [
    "anthropic.claude-3-5-sonnet-20241022-v2:0",
    "amazon.titan-text-express-v1"
  ]
}
```

### Response — `200 OK`

Returns the updated Bedrock configuration object.

```json theme={null}
{
  "enabled": true,
  "region": "us-east-1",
  "allowed_model_ids": [
    "anthropic.claude-3-5-sonnet-20241022-v2:0",
    "amazon.titan-text-express-v1"
  ]
}
```
