---
title: "Change a site's url, timezone or week start"
method: PATCH
path: "/sites/{id}"
tags: ["Sites"]
---

# Change a site's url, timezone or week start

`PATCH /sites/{id}`

## Request

- Base URL: `https://statable.com/api/v1`
- URL: `https://statable.com/api/v1/sites/{id}`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/statable/apis/statable-stats-api/docs/sites/:id/patch.ts> (a function with typed inputs; its response is checked against the schema)

Owner or admin only — a member gets 403 `not_site_owner`. Omitted fields are left alone. Unlike the read surface there is no tracking-active gate: a lapsed account must still be able to fix and clean up its sites. Another account's id answers 404 `unknown_site`, exactly as a nonexistent one.

## Request body

- UpdateSiteRequest: Omitted fields are left unchanged.
  - `url` string: Must start with http:// or https://.
  - `timezone` string
  - `week_start` integer: 0 = Sunday … 6 = Saturday.

## Response `200`

The updated site.

- SiteDetail
  - `site_id` integer, required
  - `name` string, required: The site url as stored.
  - `hash` string, required: Same token as in SiteSummary.hash.
  - `timezone` string, required
  - `week_start` integer, required
  - `hobby` boolean, required
  - `script_url` string, required
  - `snippet` string, required: The ready-to-paste script tag.

## Other responses

- `400`: `invalid_request` — bad url, timezone or week_start, a url with no host, or, on a hobby site, a host that no longer qualifies for the hobby plan. `domain_not_allowed` — the new url sits in a zone we do not serve. A url change is held to the same rules as a new site.
- `401`: Missing/malformed/invalid/revoked bearer token (`unauthorized`), or a key past its expiry (`key_expired`; the message names the expiry time).
- `403`: `insufficient_scope`, `key_not_scoped`, or `not_site_owner`.
- `404`: `write_disabled` or `unknown_site`.
- `409`: `site_exists` — the account already uses that url.
- `429`: Hourly account (default 2000/h) or per-key (default 600/h) limit hit (`rate_limited`). Retry after the `Retry-After` seconds. The X-RateLimit-* headers report the window that tripped (account on an account limit).
- `500`: Unexpected server error (`internal`). Report it with the `request_id` from the body or the X-Request-ID header: it is what lets the exact log entry be found, and without it a 500 can only be matched by guessing at a time window.

---

[API](https://skmtc.dev/statable/apis/statable-stats-api.md) - [All operations](https://skmtc.dev/statable/apis/statable-stats-api/llms.txt) - [OpenAPI document](https://skmtc.dev/statable/apis/statable-stats-api/revisions/352b6d47c186?raw)
