---
title: "List a website's publish log"
description: "Every publish of the site, newest first: the version, what was live before, which call ran (promote or rollback), its status, when, and who pressed, with the platform's own row for version one carrying nobody."
api_method: GET
api_path: "/v1/workspaces/{workspaceId}/sites/{siteId}/publishes"
canonical_url: https://wiblo.app/docs/developers/api/sites/list-site-publishes
last_updated: 2026-09-28T10:47:20+02:00
md_url: https://wiblo.app/docs/developers/api/sites/list-site-publishes.md
---

# List a website's publish log

`GET /v1/workspaces/{workspaceId}/sites/{siteId}/publishes`

Every publish of the site, newest first: the version, what was live before, which call ran (`promote` or `rollback`), its status, when, and who pressed, with the platform's own row for version one carrying nobody. The source of `wiblo sites publishes` and the timeline on the site page. A row still `publishing` is checked against Vercel on this read and settled when the address has moved. Every active member may call it, and a run's workspace key is an expected bearer. Per-user rate-limited at 60/60s.

## Path parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `workspaceId` | `string` | Yes |  |
| `siteId` | `string` | Yes |  |

## Request

**curl**

```bash
curl https://api.wiblo.app/v1/workspaces/{workspaceId}/sites/{siteId}/publishes \
  -H "Authorization: Bearer $WIBLO_TOKEN"
```

**TypeScript**

```ts
import { createSdk, listSitePublishes } from "@workspace/sdk"

const sdk = createSdk({ baseUrl: "https://api.wiblo.app" })

const { data, error } = await listSitePublishes({
  client: sdk,
  path: { workspaceId: "...", siteId: "..." },
})
```

## Responses

**`200`** — The site's publish log, newest first. Returns `SitePublishListResponse`.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `publishes` | `array<SitePublishSummary>` | Yes |  |

**`401`** — No valid session, `wbl_*` bearer, or run token was present. Returns `ApiErrorEnvelope`.

**`404`** — Workspace not visible to the caller (`WORKSPACE_NOT_FOUND`), or no site with that id in it (`SITE_NOT_FOUND`). Returns `ApiErrorEnvelope`.

**`422`** — Path param failed UUID validation (`INVALID_PARAMS`). Returns `ApiErrorEnvelope`.

**`429`** — Rate limit exceeded. The body's `error.code` is `RATE_LIMITED` and `error.details.retry_after` is the same number of seconds as the `Retry-After` header. Returns `ApiErrorEnvelope`.

### The SitePublishSummary object

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | `string` | Yes |  |
| `site_id` | `string` | Yes |  |
| `version_id` | `string` | Yes |  |
| `version_number` | `integer \| null` | Yes | The number of the version published. Null only if the version lost its number, which a ready version never does. |
| `previous_version_id` | `string \| null` | Yes | What the live URL served before. Null on version one. |
| `previous_version_number` | `integer \| null` | Yes |  |
| `method` | `"promote" \| "rollback"` | Yes |  |
| `status` | `"publishing" \| "published" \| "failed"` | Yes |  |
| `source` | `"create" \| "person" \| "run" \| "key"` | Yes |  |
| `published_by` | `object \| null` | Yes | The member who pressed, or whose agent pressed. Null for version one, which the platform published at creation, and for another machine key. Also null when that person is no longer an active member of the workspace: their member row is archived, or no member row is linked to them. |
| `published_by.member_id` | `string` | Yes |  |
| `published_by.name` | `string` | Yes |  |
| `published_by_run_id` | `string \| null` | Yes | The agent run whose key pressed, when `source` is `run`. |
| `created_at` | `string` | Yes |  |
| `settled_at` | `string \| null` | Yes |  |
