# Save a settings section draft

`PUT /v1/admin/site/settings/{section}`

URL: https://docs.spacerun.co/docs/platform/reference/site-settings/saveSiteSettingsDraft

- **Operation ID:** `saveSiteSettingsDraft`
- **Tags:** Site settings
- **Base URL:** `http://localhost:8787`

Replaces the section's draft; nothing goes live until it is published. Audited by the database function. The route accepts any of the write permissions, but the database then checks the permission required by the specific section; holding only a non-matching one yields 403 `forbidden`.

**Workflow:** [Integration guide](https://docs.spacerun.co/docs/platform/guides/site-publishing).

**Authentication:** staff Bearer JWT with permission `site.write` or `billing.write` or `settings.write`.

## Authentication

- **Auth:** staff Bearer JWT (`Authorization: Bearer <access_token>`) with the permissions below.
- **Required permissions:** `site.write`, `billing.write`, `settings.write`

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `section` | path | `string` | yes | One of: `"general"`, `"branding"`, `"seo"`, `"auth_ui"`, `"billing"`, `"credits"`, `"limits"`, `"support"`, `"legal"`, `"maintenance"` |

## Request body

Required: yes.

Content type: `application/json`

Schema: `object`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `draft` | `object` | yes | - |

## Responses

### 204

Draft saved.

- Header `x-request-id`: Request identifier; quote it when reporting an error.
No response body.

## Errors

### 400

Request validation failed.

- Header `x-request-id`: Request identifier; quote it when reporting an error.
Content type: `application/json`

Schema: `object (ValidationErrorBody)`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `success` | `boolean` | yes | One of: `false` |
| `error` | `object` | yes | - |
| `error.name` | `string` | yes | One of: `"ZodError"` |
| `error.issues` | `object[]` | yes | - |
| `error.issues[].code` | `string` | yes | - |
| `error.issues[].path` | `(string \| number)[]` | yes | - |
| `error.issues[].message` | `string` | yes | - |

**Request validation**

```json
{
  "success": false,
  "error": {
    "name": "ZodError",
    "issues": [
      {
        "code": "custom",
        "path": [
          "field"
        ],
        "message": "Invalid value"
      }
    ]
  }
}
```

### 401

Missing, malformed, expired or wrong-audience Bearer token (`missing_token`, `invalid_token`, `invalid_audience`).

- Header `x-request-id`: Request identifier; quote it when reporting an error.
Content type: `application/json`

Schema: `object (ErrorBody)`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | `string` | yes | Stable machine-readable error code, e.g. `forbidden`, `not_found`. |
| `details` | `any` | no | Optional structured context. For 403 it is `{ perm }`. |

**Error response**

```json
{
  "error": "missing_token"
}
```

### 403

`forbidden`: lacks the section-specific write permission.

- Header `x-request-id`: Request identifier; quote it when reporting an error.
Content type: `application/json`

Schema: `object (ErrorBody)`, fields as described above.

**Error response**

```json
{
  "error": "forbidden",
  "details": {
    "perm": "site.write | billing.write | settings.write"
  }
}
```

### 404

`not_found`: unknown section.

- Header `x-request-id`: Request identifier; quote it when reporting an error.
Content type: `application/json`

Schema: `object (ErrorBody)`, fields as described above.

**Error response**

```json
{
  "error": "not_found"
}
```

### 500

Unexpected server error (`internal`). No details are returned.

- Header `x-request-id`: Request identifier; quote it when reporting an error.
Content type: `application/json`

Schema: `object (ErrorBody)`, fields as described above.

**Error response**

```json
{
  "error": "internal"
}
```

## Examples

### curl

```bash
curl -X PUT 'http://localhost:8787/v1/admin/site/settings/general' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Content-Type: application/json' \
  --data '{"draft":{}}'
```

### TypeScript

```ts
const accessToken = process.env.ACCESS_TOKEN; // user JWT from your sign-in flow

const response = await fetch("http://localhost:8787/v1/admin/site/settings/general", {
  method: "PUT",
  headers: {
    "Authorization": `Bearer ${accessToken}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "draft": {}
  }),
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
const data = response.status === 204 || response.status === 205
  ? undefined
  : response.headers.get("content-type")?.includes("json")
    ? await response.json()
    : await response.text();
```
