---
title: "Update page content"
method: PATCH
path: "/api/v1/pages/{slug}"
tags: ["pages"]
---

# Update page content

`PATCH /api/v1/pages/{slug}`

## Request

- Base URL: `https://app.qrtap.kg`
- URL: `https://app.qrtap.kg/api/v1/pages/{slug}`
- Auth: HTTP bearer

Replaces the page content with a new published version. The body replaces the content wholesale — GET the page first if you only mean to change one field. The slug and `public_url` never change, so printed QR codes stay valid. A slug that belongs to another organization answers 404, never 403.

## Path parameters

- `slug` string, required

## Request body

- PageWriteRequest
  - `content` PageContent, required: Content of a public page. Sanitised server-side on every write by the same authority the workspace builder uses: unknown keys are dropped, phone numbers normalised to +digits, WhatsApp/Instagram rewritten to canonical links, and only http/https URLs survive. `name` is required, and at least one contact (`phone`, `whatsapp`, `instagram` or `bookingUrl`) must be present — otherwise the write is refused with 422 `invalid_content`.
    - `kind` 'profile': Always "profile" (set server-side).
    - `segment` string: Page kind: master | vrach | psiholog | otzyvy | … Use `otzyvy` for a review-funnel page.
    - `theme` 'emerald' | 'ocean' | 'plum' | 'terracotta' | 'graphite': Accent colour preset.
    - `name` string, required: Business or person name — the page heading.
    - `specialty` string
    - `bio` string
    - `phone` string: Any format on input; stored as +digits (9..15 digits).
    - `whatsapp` string: Number on input; stored as https://wa.me/<digits>.
    - `instagram` string: @handle or profile URL; stored as https://instagram.com/<handle>.
    - `twogis` string, uri
    - `bookingUrl` string, uri
    - `hours` string
    - `address` string
    - `licenseNumber` string
    - `services` ProfileService[]
      - `name` string, required: Service name.
      - `price` string: Price as free text, e.g. "1500 сом".
    - `reviewLinks` object: Review-platform links (segment `otzyvy`). http/https only.
      - `twogis` string, uri
      - `google` string, uri
      - `yandex` string, uri
      - `flamp` string, uri
    - `socialLinks` object: Social icon row. http/https only; @handles are normalised.
      - `tiktok` string
      - `telegram` string
      - `website` string, uri
      - `youtube` string, uri

## Response `200`

Updated page (version incremented).

- Page: Page including its current content.
  - `id` string, uuid, required
  - `slug` string, required: Public slug; stable for the life of the page.
  - `title` string: Page heading (mirrors content.name).
  - `segment` string
  - `theme` 'emerald' | 'ocean' | 'plum' | 'terracotta' | 'graphite'
  - `status` 'draft' | 'published' | 'archived', required
  - `published` boolean, required: Convenience mirror of status === "published".
  - `version` integer, required: Current content version (increments on every write).
  - `public_url` string, uri, required: Where the page is served: https://app.qrtap.kg/a/{slug}.
  - `created_at` string, date-time
  - `updated_at` string, date-time: When the current version was published.
  - `content` PageContent, required: Content of a public page. Sanitised server-side on every write by the same authority the workspace builder uses: unknown keys are dropped, phone numbers normalised to +digits, WhatsApp/Instagram rewritten to canonical links, and only http/https URLs survive. `name` is required, and at least one contact (`phone`, `whatsapp`, `instagram` or `bookingUrl`) must be present — otherwise the write is refused with 422 `invalid_content`.
    - `kind` 'profile': Always "profile" (set server-side).
    - `segment` string: Page kind: master | vrach | psiholog | otzyvy | … Use `otzyvy` for a review-funnel page.
    - `theme` 'emerald' | 'ocean' | 'plum' | 'terracotta' | 'graphite': Accent colour preset.
    - `name` string, required: Business or person name — the page heading.
    - `specialty` string
    - `bio` string
    - `phone` string: Any format on input; stored as +digits (9..15 digits).
    - `whatsapp` string: Number on input; stored as https://wa.me/<digits>.
    - `instagram` string: @handle or profile URL; stored as https://instagram.com/<handle>.
    - `twogis` string, uri
    - `bookingUrl` string, uri
    - `hours` string
    - `address` string
    - `licenseNumber` string
    - `services` ProfileService[]
      - `name` string, required: Service name.
      - `price` string: Price as free text, e.g. "1500 сом".
    - `reviewLinks` object: Review-platform links (segment `otzyvy`). http/https only.
      - `twogis` string, uri
      - `google` string, uri
      - `yandex` string, uri
      - `flamp` string, uri
    - `socialLinks` object: Social icon row. http/https only; @handles are normalised.
      - `tiktok` string
      - `telegram` string
      - `website` string, uri
      - `youtube` string, uri

## Other responses

- `400`: The slug path segment is malformed (lowercase a-z, 0-9 and dashes, 3..64 chars), or the body is not `{"content": {…}}`.
- `401`: Missing, invalid or revoked API key.
- `404`: No such object in your organization.
- `422`: The page content was refused by the server-side sanitizer (see `detail`).
- `429`: Limit exceeded — the request had no effect. `error` is `rate_limited` with `scope: "minute"` (a burst brake: wait `retry_after` seconds and continue) or `quota_exceeded` with `scope: "day"` (the workspace's daily quota, counted in UTC; it returns at `reset_at`, the next UTC midnight, and only a higher plan raises it before then).

---

[API](https://skmtc.dev/qrtap/apis/qrtap-rest-api.md) · [All operations](https://skmtc.dev/qrtap/apis/qrtap-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/qrtap/apis/qrtap-rest-api/revisions/8af17ac525bd?raw)
