Skip to content

Save a settings section draft โ€‹

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

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

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 โ€‹

NameInTypeRequiredDescription
sectionpathstringyesOne of: "general", "branding", "seo", "auth_ui", "billing", "credits", "limits", "support", "legal", "maintenance"

Request body โ€‹

Required: yes.

Content type: application/json

Schema: object

FieldTypeRequiredDescription
draftobjectyes-

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)

FieldTypeRequiredDescription
successbooleanyesOne of: false
errorobjectyes-
error.namestringyesOne of: "ZodError"
error.issuesobject[]yes-
error.issues[].codestringyes-
error.issues[].path(string | number)[]yes-
error.issues[].messagestringyes-

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)

FieldTypeRequiredDescription
errorstringyesStable machine-readable error code, e.g. forbidden, not_found.
detailsanynoOptional 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();

Try this endpoint

Requests go directly from your browser to the API. Send request executes this endpoint against the selected server.

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

Your token stays in this tab's memory and is sent only when you press Send request.

Parameters
Request body (required)

Built for developers. Ready for agents.