---
title: "Paginated list of sites owned by the authenticated user"
method: GET
path: "/sites"
tags: ["Sites"]
---

# Paginated list of sites owned by the authenticated user

`GET /sites`

## Request

- Base URL: `https://api.nippy.host`
- URL: `https://api.nippy.host/sites`
- Auth: `bearer` (a scheme the document does not define)

Returns the dashboard list with per-site stats and a summary block. Sites in the transient `pending` upload state are excluded.

## Query parameters

- `status` 'live' | 'inactive'
- `page` number
- `pageSize` number

## Response `200`

List of sites with stats

- APIListSitesResponse
  - `data` APISiteWithStats[], required
    - `id` string, required
    - `subdomain` string, required: Subdomain on the platform apex
    - `status` 'awaiting_verification' | 'live' | 'inactive' | 'suspended', required: Lifecycle status. Sites mid-upload (`pending`) are excluded.
    - `suspendedReason` 'billing' | 'abuse' | 'duplicate' | 'expired', nullable: Why a `suspended` site is offline: `billing` — the account holds more live sites than its plan allows, and it comes back when there is room (an upgrade, or a deleted site); `abuse` — taken down by staff; `duplicate` — held while a duplicate-account case is open; `expired` — a Free site its owner did not keep online, which comes back with one click until `deletesAt`. Null for every other status.
    - `renewalDueAt` string, date-time, nullable: Free-site renewal (ADR 0064): when this live site next needs its owner to keep it online. Null when the site never expires — a paid plan, a site published before the renewal rule, or a site that is not live.
    - `offlineAt` string, date-time, nullable: When this live Free site goes offline unless its owner keeps it online: seven days after the renewal email, and never less than 24 hours after the "goes offline tomorrow" reminder. Null when the site never expires.
    - `deletesAt` string, date-time, nullable: When an `expired` site and its files are deleted: 30 days after it went offline, never less than seven days after the deletion warning or 24 hours after the "will be deleted tomorrow" notice. Null for every other site.
    - `publicUrl` string, required: Public URL where the site is reachable
    - `createdAt` string, date-time, required
    - `updatedAt` string, date-time, required
    - `fileCount` number, nullable: Number of files in the most recent finalized version
    - `totalBytes` number, nullable: Sum of file sizes in the most recent finalized version
    - `lastPublishedAt` string, date-time, nullable: Timestamp of the most recent finalized upload (i.e. last successful publish)
    - `versionCount` number, required: Number of times this site has been published (finalized batches)
    - `recentPageviews` number, required: Sample-corrected pageviews recorded for this site over the trailing 30 days. Zero when the site has no traffic or analytics are disabled.
    - `recentBytesServed` number, required: Total bytes served for this site over the trailing 30 days (HTML, assets and downloads). Recorded regardless of the analytics toggle.
    - `recentViewsSeries` number[], required: Sample-corrected daily pageviews over the trailing 30 days, oldest first — exactly 30 UTC-day buckets, zero-filled. Powers the sites-list sparkline. All zeros when the site has no traffic or analytics are off.
    - `downloadsPolicy` 'auto' | 'on' | 'off', required: Owner preference controlling whether the auto-generated directory listing offers ZIP / per-file downloads. `auto` falls back to a heuristic (sites with a root index.html get downloads off).
    - `passwordProtected` boolean, required: Whether the site is currently password-protected. The hash itself is never returned.
    - `searchIndexable` boolean, required: When false, the worker advertises the site as non-indexable: synthesised /robots.txt, `X-Robots-Tag: noindex, nofollow`, and a `<meta robots>` tag injected into HTML responses. Defaults to true.
    - `analyticsEnabled` boolean, required: When true, the worker injects the analytics script and records pageview/engagement beacons for the site. Defaults to true.
    - `formCaptureEnabled` boolean, required: Whether Nippy saves replies sent through forms on this site. On by default; the per-form controls live under the site's forms endpoint.
    - `metaTitle` string, nullable: Owner-supplied `<title>` override. Null means no override — the source HTML's title is used.
    - `metaDescription` string, nullable: Owner-supplied `<meta name="description">` override. Null means no override — the source HTML's description is used.
  - `pagination` APIListSitesPagination, required
    - `page` number, required: 1-based page number returned
    - `pageSize` number, required
    - `total` number, required: Total sites the authed user owns (excluding pending)
    - `totalPages` number, required: `ceil(total / pageSize)`
  - `summary` APIListSitesSummary, required
    - `totalSites` number, required: Total sites owned (excluding pending)
    - `totalBytes` number, required: Sum of bytes across the most recent version of every site
    - `totalViews` number, required: Sum of sample-corrected pageviews across all of the user’s sites over the trailing 30 days
    - `totalBytesServed` number, required: Sum of bytes served across all of the user’s sites over the trailing 30 days
    - `byStatus` object, required: Per-status counts for the user's sites

## Other responses

- `401`: Not authenticated

---

[API](https://skmtc.dev/nippy/apis/nippy-backend-api.md) · [All operations](https://skmtc.dev/nippy/apis/nippy-backend-api/llms.txt) · [OpenAPI document](https://skmtc.dev/nippy/apis/nippy-backend-api/revisions/7ab23f040a55?raw)
