# PageCycle API reference

Every PageCycle tool as an HTTPS route, acting as the person who signed in, with their Confluence permissions. A site or org admin turns App REST APIs on for PageCycle in Connected apps first. The authorization URL needs sns=db702242-b6fc-4a44-bcea-e6ad97e8db84.7b249cc1-1e34-4a73-850f-d51fafab4b8c, or the token carries none of PageCycle's scopes. Answers may gain fields: ignore the ones you do not know. To turn the API on and make a first call, start with the [REST API guide](https://atlassian.braingrid.ai/docs/pagecycle/rest-api).

Download the [OpenAPI file](https://atlassian.braingrid.ai/pagecycle-api.openapi.json) (OpenAPI 3.1.0) to generate a client or load the routes into an API tool.

## Base URL

```text
https://api.atlassian.com/svc/confluence/YOUR_CLOUD_ID/apps/db702242-b6fc-4a44-bcea-e6ad97e8db84_7b249cc1-1e34-4a73-850f-d51fafab4b8c
```

Your site's cloud id is on its `/_edge/tenant_info` page. Every request sends `Authorization: Bearer <token>` from an OAuth 2.0 integration. Every answer from PageCycle is JSON with the same four fields: `ok`, `answer` (what happened, in words), `code` (`null` on success) and `data`.

## Status codes

| HTTP | When |
|---|---|
| 200 | Done. `answer` says it in words, `data` as JSON. |
| 202 | Working: a long change goes on; continue it with POST /operations/{id}. |
| 400 | The request is malformed, or names something the tool cannot read (code bad_input). |
| 401 | No person is signed in behind the token (code unknown_actor). |
| 403 | The person may not do this: no permission, not a space admin, someone else's preview, or they have not allowed PageCycle access yet. |
| 404 | Not found, or the person cannot view it. Nothing in the answer names it. |
| 409 | Does not fit the space as it is now: PageCycle is off in the space, the workflow does not allow it, the page needs the person's go-ahead first (data.confirmNeeded), or the preview expired or the settings changed (a fresh preview is in data). |
| 425 | Too early: a confirmation waits 8 seconds after its preview (data.confirmableAt). |
| 429 | Too many unconfirmed previews in two minutes. |
| 500 | PageCycle could not finish; the answer says so in words. |
| 503 | The PageCycle license is inactive: moves, review dates and long changes are paused; reads and settings still answer. |

Some calls never reach PageCycle: Atlassian answers a missing token, a missing scope or an API that is off itself, in its own format. See [Refusals from Atlassian](https://atlassian.braingrid.ai/docs/pagecycle/rest-api#refusals-from-atlassian).

## Pages

One page at a time: read its status and History, move it to another status, or set its next review. Every call acts as the person who signed in, so it reaches only the pages that person can open, and a move follows the same rules as Move to in Confluence.

| Route | What it does |
|---|---|
| [`GET /pages/{page}/status`](#get-pages-page-status) | A page's workflow status, since when and who moved it there, the version approved, its next review and the moves the person can make. |
| [`POST /pages/{page}/moves`](#post-pages-page-moves) | Moves a page to another status in its space's workflow, as the person, under the same rules as Move to in Confluence. |
| [`GET /pages/{page}/history`](#get-pages-page-history) | Every move on a page with who, when and why, newest first, and whether it changed since sign-off. |
| [`PUT /pages/{page}/reviewDate`](#put-pages-page-reviewdate) | Sets or clears a signed-off page's next review, as the person (they need edit permission). |

### GET /pages/{page}/status

A page's workflow status, since when and who moved it there, the version approved, its next review and the moves the person can make.

**Scopes:** `read:pagecycle:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `getPagecyclePageStatus`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `page` | string | Yes | The Confluence page id. Pattern `^[0-9]{1,20}$`. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `page` | object | Yes |  |
| `status` | object or null | Yes |  |
| `since` | string or null | Yes | Date-time. |
| `movedBy` | string or null | Yes | Who moved the page into its status; null for an automation, an import or Confluence itself. |
| `approvedVersion` | integer or null | Yes | The page version the move into this status was made on. |
| `reviewBy` | string or null | Yes | The next review, YYYY-MM-DD. Date. |
| `confluenceStatusRemoved` | boolean | Yes | Confluence shows no status where PageCycle knew one (a Confluence approval may be running): a move needs confirm. |
| `flagged` | boolean | Yes | The last status change broke the workflow; an allowed move clears it. |
| `canEdit` | boolean | Yes |  |
| `movesPaused` | boolean | Yes | The person could move the page, but the PageCycle license is inactive. |
| `moves` | list of object | Yes | The moves the person can make now. |

**Example answer**

```json
{
  "ok": true,
  "answer": "Approved by Jordan Lee, Sep 30 · version 4 · next review Mar 30\nYou can move it to Archived (Archive).",
  "code": null,
  "data": {
    "page": {
      "id": "8013",
      "title": "Export to CSV spec",
      "version": 4,
      "spaceId": "7001"
    },
    "status": {
      "id": "approved",
      "name": "Approved",
      "category": "final"
    },
    "since": "2026-09-30T10:00:00.000Z",
    "movedBy": "Jordan Lee",
    "approvedVersion": 4,
    "reviewBy": "2027-03-30",
    "confluenceStatusRemoved": false,
    "flagged": false,
    "canEdit": true,
    "movesPaused": false,
    "moves": [
      {
        "to": {
          "id": "archived",
          "name": "Archived"
        },
        "label": "Archive",
        "commentRequired": false
      }
    ]
  }
}
```

### POST /pages/{page}/moves

Moves a page to another status in its space's workflow, as the person, under the same rules as Move to in Confluence. Recorded in the page's History.

**Scopes:** `write:pagecycle-page:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `movePagecyclePage`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `page` | string | Yes | The Confluence page id. Pattern `^[0-9]{1,20}$`. |

**Body fields**

| Name | Type | Required | Description |
|---|---|---|---|
| `to` | string | Yes | The status to move to, by name or id. Up to 255 characters. |
| `comment` | string or null | No | Up to 2000 characters. |
| `reviewDate` | string or null | No | For a move into a signed-off status: YYYY-MM-DD or "in 6 months". Up to 40 characters. |
| `confirm` | boolean | No | Only after the person agreed: go ahead on a page whose Confluence status was removed. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `page` | object | Yes |  |
| `status` | object | Yes |  |
| `reviewBy` | string or null | Yes | Date. |
| `endedApproval` | boolean | Yes | The page had no Confluence status (an approval may have been running); this move ended it. |

**Example answer**

```json
{
  "ok": true,
  "answer": "In review · recorded in History",
  "code": null,
  "data": {
    "page": {
      "id": "8013",
      "title": "Export to CSV spec"
    },
    "status": {
      "id": "in-review",
      "name": "In review",
      "category": "review"
    },
    "reviewBy": null,
    "endedApproval": false
  }
}
```

### GET /pages/{page}/history

Every move on a page with who, when and why, newest first, and whether it changed since sign-off.

**Scopes:** `read:pagecycle:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `getPagecyclePageHistory`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `page` | string | Yes | The Confluence page id. Pattern `^[0-9]{1,20}$`. |
| `limit` | string | No | At most this many rows (1 to 50). Pattern `^[0-9]{1,3}$`. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `page` | object | Yes |  |
| `status` | object or null | Yes |  |
| `signedOffVersion` | integer or null | Yes |  |
| `editedSinceSignOff` | boolean or null | Yes | For a signed-off page: whether it was edited after the version signed off. |
| `entries` | list of object | Yes | Newest first. |
| `truncated` | boolean | Yes | More History exists than this call returned. |

**Example answer**

```json
{
  "ok": true,
  "answer": "Needs re-review since Oct 1 · version 9 · next review Mar 2\nOct 1 · Priya Nair edited the page, so PageCycle moved it from Approved to Needs re-review (\"Edited after approval\")\nSep 2 · Jordan Lee moved it from In review to Approved: \"Checked against the release plan\"",
  "code": null,
  "data": {
    "page": {
      "id": "8023",
      "title": "Search filters spec",
      "version": 9
    },
    "status": {
      "id": "needs-re-review",
      "name": "Needs re-review",
      "category": "attention"
    },
    "signedOffVersion": null,
    "editedSinceSignOff": null,
    "entries": [
      {
        "at": "2026-10-01T10:00:00.000Z",
        "kind": "automation",
        "outcome": "accepted",
        "from": {
          "id": "approved",
          "name": "Approved"
        },
        "to": {
          "id": "needs-re-review",
          "name": "Needs re-review"
        },
        "by": null,
        "comment": null,
        "reason": null,
        "sentence": "Priya Nair edited the page, so PageCycle moved it from Approved to Needs re-review (\"Edited after approval\")"
      },
      {
        "at": "2026-09-02T10:00:00.000Z",
        "kind": "formal",
        "outcome": "accepted",
        "from": {
          "id": "in-review",
          "name": "In review"
        },
        "to": {
          "id": "approved",
          "name": "Approved"
        },
        "by": "Jordan Lee",
        "comment": "Checked against the release plan",
        "reason": null,
        "sentence": "Jordan Lee moved it from In review to Approved: \"Checked against the release plan\""
      }
    ],
    "truncated": false
  }
}
```

### PUT /pages/{page}/reviewDate

Sets or clears a signed-off page's next review, as the person (they need edit permission). Recorded in the page's History.

**Scopes:** `write:pagecycle-page:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `setPagecycleReviewDate`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `page` | string | Yes | The Confluence page id. Pattern `^[0-9]{1,20}$`. |

**Body fields**

| Name | Type | Required | Description |
|---|---|---|---|
| `date` | string or null | Yes | YYYY-MM-DD or "in 6 months"; null clears it. Up to 40 characters. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `page` | object | Yes |  |
| `reviewBy` | string or null | Yes | Date. |

**Example answer**

```json
{
  "ok": true,
  "answer": "Next review Apr 2 · recorded in History",
  "code": null,
  "data": {
    "page": {
      "id": "8014",
      "title": "SSO for Enterprise PRD"
    },
    "reviewBy": "2027-04-02"
  }
}
```

## Spaces

A whole space at a glance: which spaces use PageCycle, how many pages sit in each status, which pages need attention, the space's History, its workflow and its automations. These routes only read, and they count only the pages the person can view.

| Route | What it does |
|---|---|
| [`GET /spaces`](#get-spaces) | Every space that uses PageCycle and where the person can view a tracked page, with its counts. |
| [`GET /spaces/{space}/summary`](#get-spaces-space-summary) | How many pages are in each status in a space, and the pages that need attention. |
| [`GET /spaces/{space}/pages`](#get-spaces-space-pages) | Pages in a space by status, overdue for review, or stuck in their status for some days, at most 50 at a time. |
| [`GET /spaces/{space}/history`](#get-spaces-space-history) | A space's History, newest first, filtered by person, status or dates, for pages the person can view. |
| [`GET /spaces/{space}/workflow`](#get-spaces-space-workflow) | A space's statuses and moves: who may make each move, which need a comment, and where pages start. |
| [`GET /spaces/{space}/automations`](#get-spaces-space-automations) | A space's automations in plain words, and for space admins whether they run well. |

### GET /spaces

Every space that uses PageCycle and where the person can view a tracked page, with its counts.

**Scopes:** `read:pagecycle:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `listPagecycleSpaces`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `limit` | string | No | At most this many rows (1 to 50). Pattern `^[0-9]{1,3}$`. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `spaces` | list of object | Yes |  |
| `total` | integer | Yes |  |
| `truncated` | boolean | Yes |  |
| `pagesTruncated` | boolean | Yes | Counted only the first tracked pages. |

**Example answer**

```json
{
  "ok": true,
  "answer": "1 space uses PageCycle\nProduct (PROD) · 28 pages · 4 need attention · 2 past the review date",
  "code": null,
  "data": {
    "spaces": [
      {
        "id": "7001",
        "key": "PROD",
        "name": "Product",
        "pages": 28,
        "needsAttention": 4,
        "overdue": 2
      }
    ],
    "total": 1,
    "truncated": false,
    "pagesTruncated": false
  }
}
```

### GET /spaces/{space}/summary

How many pages are in each status in a space, and the pages that need attention. Counts only pages the person can view.

**Scopes:** `read:pagecycle:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `getPagecycleSpaceSummary`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | string | Yes | The Confluence space key. Pattern `^[A-Za-z0-9~_-]{1,255}$`. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | object | Yes |  |
| `total` | integer | Yes |  |
| `withoutStatus` | integer | Yes |  |
| `statuses` | list of object | Yes |  |
| `needsAttention` | list of object | Yes | At most 10; needsAttentionTotal counts them all. |
| `needsAttentionTotal` | integer | Yes |  |
| `truncated` | boolean | Yes |  |

**Example answer**

```json
{
  "ok": true,
  "answer": "28 pages · 10 approved and current · 6 in review · 2 need re-review · 2 review due · 6 drafts · 2 archived\nNeeds re-review: Search filters spec · edited Oct 1\nNeeds re-review: API rate limits spec · edited Sep 30\nReview due: Data retention requirements · 17 days overdue\nReview due: Integrations roadmap · 4 days overdue",
  "code": null,
  "data": {
    "space": {
      "id": "7001",
      "key": "PROD",
      "name": "Product"
    },
    "total": 28,
    "withoutStatus": 0,
    "statuses": [
      {
        "id": "approved",
        "name": "Approved",
        "category": "final",
        "count": 10,
        "overdue": 0
      },
      {
        "id": "in-review",
        "name": "In review",
        "category": "review",
        "count": 6,
        "overdue": 0
      },
      {
        "id": "needs-re-review",
        "name": "Needs re-review",
        "category": "attention",
        "count": 2,
        "overdue": 0
      }
    ],
    "needsAttention": [
      {
        "page": {
          "id": "8023",
          "title": "Search filters spec"
        },
        "status": {
          "id": "needs-re-review",
          "name": "Needs re-review"
        },
        "detail": "edited Oct 1"
      },
      {
        "page": {
          "id": "8024",
          "title": "API rate limits spec"
        },
        "status": {
          "id": "needs-re-review",
          "name": "Needs re-review"
        },
        "detail": "edited Sep 30"
      },
      {
        "page": {
          "id": "8025",
          "title": "Data retention requirements"
        },
        "status": {
          "id": "review-due",
          "name": "Review due"
        },
        "detail": "17 days overdue"
      }
    ],
    "needsAttentionTotal": 4,
    "truncated": false
  }
}
```

Lists are cut to 3 items here; the OpenAPI file has the whole answer.

### GET /spaces/{space}/pages

Pages in a space by status, overdue for review, or stuck in their status for some days, at most 50 at a time.

**Scopes:** `read:pagecycle:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `listPagecyclePages`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | string | Yes | The Confluence space key. Pattern `^[A-Za-z0-9~_-]{1,255}$`. |
| `status` | string | No | One status name, or several separated by commas. Up to 500 characters. |
| `overdue` | `"true"`, `"false"` | No |  |
| `stuckDays` | string | No | Pattern `^[0-9]{1,4}$`. |
| `limit` | string | No | At most this many rows (1 to 50). Pattern `^[0-9]{1,3}$`. |
| `after` | string | No | The next value of the previous answer. Pattern `^[0-9]{1,20}$`. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | object | Yes |  |
| `pages` | list of object | Yes |  |
| `total` | integer | Yes | Every page that matches. |
| `next` | string or null | Yes | Pass it as after for the next rows; null on the last. |
| `truncated` | boolean | Yes |  |

**Example answer**

```json
{
  "ok": true,
  "answer": "Checkout redesign spec · Mobile onboarding PRD · Q1 roadmap · 3 more\nCheckout redesign spec · in review 8 days · owner Maya Chen\nMobile onboarding PRD · in review 3 days · owner Priya Nair\n4 more: call again with after: \"8008\".",
  "code": null,
  "data": {
    "space": {
      "id": "7001",
      "key": "PROD",
      "name": "Product"
    },
    "pages": [
      {
        "id": "8007",
        "title": "Checkout redesign spec",
        "status": {
          "id": "in-review",
          "name": "In review",
          "category": "review"
        },
        "daysInStatus": 8,
        "owner": "Maya Chen",
        "version": 6,
        "signedOffVersion": null,
        "reviewBy": null
      },
      {
        "id": "8008",
        "title": "Mobile onboarding PRD",
        "status": {
          "id": "in-review",
          "name": "In review",
          "category": "review"
        },
        "daysInStatus": 3,
        "owner": "Priya Nair",
        "version": 4,
        "signedOffVersion": null,
        "reviewBy": null
      }
    ],
    "total": 6,
    "next": "8008",
    "truncated": false
  }
}
```

### GET /spaces/{space}/history

A space's History, newest first, filtered by person, status or dates, for pages the person can view.

**Scopes:** `read:pagecycle:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `getPagecycleSpaceHistory`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | string | Yes | The Confluence space key. Pattern `^[A-Za-z0-9~_-]{1,255}$`. |
| `person` | string | No | Up to 200 characters. |
| `status` | string | No | Up to 255 characters. |
| `from` | string | No | Pattern `^[0-9]{4}-[0-9]{2}-[0-9]{2}$`, date. |
| `to` | string | No | Pattern `^[0-9]{4}-[0-9]{2}-[0-9]{2}$`, date. |
| `limit` | string | No | At most this many rows (1 to 50). Pattern `^[0-9]{1,3}$`. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | object | Yes |  |
| `entries` | list of object | Yes | Newest first. |
| `total` | integer | Yes |  |
| `truncated` | boolean | Yes |  |
| `windowFull` | boolean | Yes | The search read only the newest 500 changes: older matches may exist (narrow with to). |

**Example answer**

```json
{
  "ok": true,
  "answer": "30 changes in Product\nOct 1 · Priya Nair moved \"Offline mode spec\" to Draft\nOct 1 · Sam Park moved \"Saved views PRD\" to In review\nShowing the newest 2 (ask for up to 50, or narrow by person, status or dates).",
  "code": null,
  "data": {
    "space": {
      "id": "7001",
      "key": "PROD",
      "name": "Product"
    },
    "entries": [
      {
        "page": {
          "id": "8001",
          "title": "Offline mode spec"
        },
        "at": "2026-10-01T10:00:00.000Z",
        "kind": "formal",
        "outcome": "accepted",
        "from": null,
        "to": {
          "id": "draft",
          "name": "Draft"
        },
        "by": "Priya Nair",
        "comment": null,
        "reason": null,
        "sentence": "Priya Nair moved \"Offline mode spec\" to Draft"
      },
      {
        "page": {
          "id": "8011",
          "title": "Saved views PRD"
        },
        "at": "2026-10-01T10:00:00.000Z",
        "kind": "formal",
        "outcome": "accepted",
        "from": null,
        "to": {
          "id": "in-review",
          "name": "In review"
        },
        "by": "Sam Park",
        "comment": null,
        "reason": null,
        "sentence": "Sam Park moved \"Saved views PRD\" to In review"
      }
    ],
    "total": 30,
    "truncated": true,
    "windowFull": false
  }
}
```

### GET /spaces/{space}/workflow

A space's statuses and moves: who may make each move, which need a comment, and where pages start.

**Scopes:** `read:pagecycle:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `getPagecycleWorkflow`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | string | Yes | The Confluence space key. Pattern `^[A-Za-z0-9~_-]{1,255}$`. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | object | Yes |  |
| `enabled` | boolean | Yes |  |
| `statuses` | list of object | Yes |  |
| `moves` | list of object | Yes |  |
| `startStatus` | object or null | Yes |  |
| `newPageStatus` | object or null | Yes |  |

**Example answer**

```json
{
  "ok": true,
  "answer": "Product: 6 statuses, 11 moves\nStatuses: Draft (draft, purple), In review (in review, blue), Approved (signed off, green), Needs re-review (needs attention, yellow), Review due (needs attention, red), Archived (archived, grey)\nMove \"Submit for review\": Draft → In review · anyone who can edit\nMove \"Request changes\": In review → Draft · anyone who can edit\nMove \"Approve\": In review → Approved · pagecycle-approvers · comment required\nMove \"Edited after approval\": Approved → Needs re-review · automations only\nMove \"Resubmit\": Needs re-review → In review · anyone who can edit\nMove \"Re-approve\": Needs re-review → Approved · pagecycle-approvers · comment required\nMove \"Review date reached\": Approved → Review due · automations only\nMove \"Start review\": Review due → In review · anyone who can edit\nMove \"Confirm still valid\": Review due → Approved · pagecycle-approvers · comment required\nMove \"Archive\": Approved → Archived · anyone who can edit\nMove \"Reopen\": Archived → Draft · anyone who can edit\nPages start in Draft. New pages get no status.",
  "code": null,
  "data": {
    "space": {
      "id": "7001",
      "key": "PROD",
      "name": "Product"
    },
    "enabled": true,
    "statuses": [
      {
        "id": "draft",
        "name": "Draft",
        "category": "draft",
        "color": "purple"
      },
      {
        "id": "in-review",
        "name": "In review",
        "category": "review",
        "color": "blue"
      },
      {
        "id": "approved",
        "name": "Approved",
        "category": "final",
        "color": "green"
      }
    ],
    "moves": [
      {
        "id": "submit",
        "label": "Submit for review",
        "from": {
          "id": "draft",
          "name": "Draft"
        },
        "to": {
          "id": "in-review",
          "name": "In review"
        },
        "groups": [],
        "commentRequired": false,
        "automationOnly": false
      },
      {
        "id": "request-changes",
        "label": "Request changes",
        "from": {
          "id": "in-review",
          "name": "In review"
        },
        "to": {
          "id": "draft",
          "name": "Draft"
        },
        "groups": [],
        "commentRequired": false,
        "automationOnly": false
      },
      {
        "id": "approve",
        "label": "Approve",
        "from": {
          "id": "in-review",
          "name": "In review"
        },
        "to": {
          "id": "approved",
          "name": "Approved"
        },
        "groups": [
          "pagecycle-approvers"
        ],
        "commentRequired": true,
        "automationOnly": false
      }
    ],
    "startStatus": {
      "id": "draft",
      "name": "Draft"
    },
    "newPageStatus": null
  }
}
```

Lists are cut to 3 items here; the OpenAPI file has the whole answer.

### GET /spaces/{space}/automations

A space's automations in plain words, and for space admins whether they run well.

**Scopes:** `read:pagecycle:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `getPagecycleAutomations`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | string | Yes | The Confluence space key. Pattern `^[A-Za-z0-9~_-]{1,255}$`. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | object | Yes |  |
| `automations` | list of object | Yes |  |
| `health` | object or null | Yes | Space admins only. |

**Example answer**

```json
{
  "ok": true,
  "answer": "Product: 2 automations\n1. Edited after approval: When a page is edited, if kind is signed off: move to Needs re-review\n2. Review date reached: When the review date passes, if kind is signed off: move to Review due; comment \"The review date for this page has passed. Please check it is still accurate, then move it to Approved again or start a review.\"\nHealth: PageCycle's status checks are running late; 0 problems in this space in the last 24 hours.",
  "code": null,
  "data": {
    "space": {
      "id": "7001",
      "key": "PROD",
      "name": "Product"
    },
    "automations": [
      {
        "id": "edited-after-approval",
        "position": 1,
        "name": "Edited after approval",
        "enabled": true,
        "sentence": "When a page is edited, if kind is signed off: move to Needs re-review"
      },
      {
        "id": "review-due",
        "position": 2,
        "name": "Review date reached",
        "enabled": true,
        "sentence": "When the review date passes, if kind is signed off: move to Review due; comment \"The review date for this page has passed. Please check it is still accurate, then move it to Approved again or start a review.\""
      }
    ],
    "health": {
      "checksLate": true,
      "problems24h": 0,
      "recent": []
    }
  }
}
```

## Workflow changes

Change a space's workflow: statuses, moves, defaults, automations and settings, or turn PageCycle on or off. Space admins only. Each call returns a preview and changes nothing until you confirm it with `POST /confirmations/{id}`, the same preview and confirm Rovo uses.

| Route | What it does |
|---|---|
| [`POST /spaces/{space}/automations`](#post-spaces-space-automations) | Previews a new automation written in words: when, if, then. |
| [`POST /spaces/{space}/statuses`](#post-spaces-space-statuses) | Previews a new status after an existing one, with the moves in and out of it copied from that status. |
| [`PATCH /spaces/{space}/statuses/{status}`](#patch-spaces-space-statuses-status) | Previews renaming, recoloring or changing the kind of a status, and updating every page that has it. |
| [`DELETE /spaces/{space}/statuses/{status}`](#delete-spaces-space-statuses-status) | Previews removing a status, moving its pages to another one first. |
| [`POST /spaces/{space}/moves`](#post-spaces-space-moves) | Previews a new move between two statuses, optionally limited to groups or needing a comment. |
| [`PATCH /spaces/{space}/moves/{move}`](#patch-spaces-space-moves-move) | Previews renaming a move, changing who may make it, or whether it needs a comment. |
| [`DELETE /spaces/{space}/moves/{move}`](#delete-spaces-space-moves-move) | Previews removing a move. |
| [`PUT /spaces/{space}/workflowDefaults`](#put-spaces-space-workflowdefaults) | Previews where pages start and which status new pages get. |
| [`PATCH /spaces/{space}/automations/{automation}`](#patch-spaces-space-automations-automation) | Previews changing an automation, turning it on or off, or moving it in the list. |
| [`DELETE /spaces/{space}/automations/{automation}`](#delete-spaces-space-automations-automation) | Previews removing an automation. |
| [`PUT /spaces/{space}/settings`](#put-spaces-space-settings) | Previews what happens when someone breaks the workflow in Confluence, and how long History is kept. |
| [`POST /spaces/{space}/pagecycle`](#post-spaces-space-pagecycle) | Previews turning PageCycle on in a space: the default workflow, and the space's Confluence statuses matched to it. |
| [`DELETE /spaces/{space}/pagecycle`](#delete-spaces-space-pagecycle) | Previews turning PageCycle off in a space. |

### POST /spaces/{space}/automations

Previews a new automation written in words: when, if, then.

**Scopes:** `manage:pagecycle-space:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `addPagecycleAutomation`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | string | Yes | The Confluence space key. Pattern `^[A-Za-z0-9~_-]{1,255}$`. |

**Body fields**

| Name | Type | Required | Description |
|---|---|---|---|
| `when` | string | Yes | "a page is edited", "moved to \<status\>", "moved to any status" or "the review date passes". Up to 500 characters. |
| `if` | string | No | Conditions separated by ";": "status is A or B", "kind is signed off", "mover in group G", "label L". Up to 1000 characters. |
| `then` | string | Yes | Actions separated by ";": "move to S", "review in N days", "add label L", comment "text". Up to 1000 characters. |
| `name` | string | No | The automation's name (default "When \<when\>"). Up to 255 characters. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `preview` | string | Yes | What would change, in words. Show it to the person. A preview over 60,000 bytes is refused, never cut. Up to 60000 characters. |
| `note` | string or null | Yes | Pages the change would leave alone, when there are any. |
| `confirmation` | string | Yes | The confirmation or operation id a preview or a progress answer gave. Pattern `^op_[A-Za-z0-9]{1,40}$`. |
| `expiresAt` | string | Yes | After this, confirming answers 409 with a fresh preview. Date-time. |
| `confirmableAt` | string | Yes | Confirming before this answers 425. Date-time. |

**Example answer**

```json
{
  "ok": true,
  "answer": "Preview: adds the automation \"When moved to Approved\" in Product: When moved to Approved: review in 180 days\nNothing changes yet. Show this preview to the person. Once they agree, send POST /confirmations/op_id2, at least 8 seconds from now and within 15 minutes.",
  "code": null,
  "data": {
    "preview": "adds the automation \"When moved to Approved\" in Product: When moved to Approved: review in 180 days",
    "note": null,
    "confirmation": "op_id2",
    "expiresAt": "2026-10-02T12:15:00.000Z",
    "confirmableAt": "2026-10-02T12:00:08.000Z"
  }
}
```

### POST /spaces/{space}/statuses

Previews a new status after an existing one, with the moves in and out of it copied from that status.

**Scopes:** `manage:pagecycle-space:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `addPagecycleStatus`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | string | Yes | The Confluence space key. Pattern `^[A-Za-z0-9~_-]{1,255}$`. |

**Body fields**

| Name | Type | Required | Description |
|---|---|---|---|
| `name` | string | Yes | The new status's name. Up to 255 characters. |
| `after` | string | Yes | The status it comes after: pages reach it and leave it the way they leave that one. Up to 255 characters. |
| `kind` | string | No | draft, in review, signed off, needs attention or archived (default: the kind of the status it comes after). Up to 40 characters. |
| `color` | string | No | purple, blue, green, yellow, red or grey (default: the kind's color). Up to 40 characters. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `preview` | string | Yes | What would change, in words. Show it to the person. A preview over 60,000 bytes is refused, never cut. Up to 60000 characters. |
| `note` | string or null | Yes | Pages the change would leave alone, when there are any. |
| `confirmation` | string | Yes | The confirmation or operation id a preview or a progress answer gave. Pattern `^op_[A-Za-z0-9]{1,40}$`. |
| `expiresAt` | string | Yes | After this, confirming answers 409 with a fresh preview. Date-time. |
| `confirmableAt` | string | Yes | Confirming before this answers 425. Date-time. |

**Example answer**

```json
{
  "ok": true,
  "answer": "Preview: adds the status On hold (draft, purple) after Draft in Product · moves added: \"Send to On hold\" (Draft → On hold, anyone who can edit); \"Submit for review\" (On hold → In review, anyone who can edit) · no pages move\nNothing changes yet. Show this preview to the person. Once they agree, send POST /confirmations/op_id1, at least 8 seconds from now and within 15 minutes.",
  "code": null,
  "data": {
    "preview": "adds the status On hold (draft, purple) after Draft in Product · moves added: \"Send to On hold\" (Draft → On hold, anyone who can edit); \"Submit for review\" (On hold → In review, anyone who can edit) · no pages move",
    "note": null,
    "confirmation": "op_id1",
    "expiresAt": "2026-10-02T12:15:00.000Z",
    "confirmableAt": "2026-10-02T12:00:08.000Z"
  }
}
```

### PATCH /spaces/{space}/statuses/{status}

Previews renaming, recoloring or changing the kind of a status, and updating every page that has it.

**Scopes:** `manage:pagecycle-space:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `updatePagecycleStatus`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | string | Yes | The Confluence space key. Pattern `^[A-Za-z0-9~_-]{1,255}$`. |
| `status` | string | Yes | Its name, or its id (always works). Up to 255 characters. |

**Body fields**

| Name | Type | Required | Description |
|---|---|---|---|
| `name` | string | No | A new name. Up to 255 characters. |
| `color` | string | No | purple, blue, green, yellow, red or grey (default: the kind's color). Up to 40 characters. |
| `kind` | string | No | draft, in review, signed off, needs attention or archived (default: the kind of the status it comes after). Up to 40 characters. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `preview` | string | Yes | What would change, in words. Show it to the person. A preview over 60,000 bytes is refused, never cut. Up to 60000 characters. |
| `note` | string or null | Yes | Pages the change would leave alone, when there are any. |
| `confirmation` | string | Yes | The confirmation or operation id a preview or a progress answer gave. Pattern `^op_[A-Za-z0-9]{1,40}$`. |
| `expiresAt` | string | Yes | After this, confirming answers 409 with a fresh preview. Date-time. |
| `confirmableAt` | string | Yes | Confirming before this answers 425. Date-time. |

**Example answer**

```json
{
  "ok": true,
  "answer": "Preview: renames Parked to On hold in Product · 0 pages hold it; their Confluence status and the label under the page title are rewritten under your name · a page whose Confluence status was removed is left as it is\nNothing changes yet. Show this preview to the person. Once they agree, send POST /confirmations/op_id1, at least 8 seconds from now and within 15 minutes.",
  "code": null,
  "data": {
    "preview": "renames Parked to On hold in Product · 0 pages hold it; their Confluence status and the label under the page title are rewritten under your name · a page whose Confluence status was removed is left as it is",
    "note": null,
    "confirmation": "op_id1",
    "expiresAt": "2026-10-02T12:15:00.000Z",
    "confirmableAt": "2026-10-02T12:00:08.000Z"
  }
}
```

### DELETE /spaces/{space}/statuses/{status}

Previews removing a status, moving its pages to another one first.

**Scopes:** `manage:pagecycle-space:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `removePagecycleStatus`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | string | Yes | The Confluence space key. Pattern `^[A-Za-z0-9~_-]{1,255}$`. |
| `status` | string | Yes | Its name, or its id (always works). Up to 255 characters. |
| `moveTo` | string | No | Where its pages go. Up to 255 characters. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `preview` | string | Yes | What would change, in words. Show it to the person. A preview over 60,000 bytes is refused, never cut. Up to 60000 characters. |
| `note` | string or null | Yes | Pages the change would leave alone, when there are any. |
| `confirmation` | string | Yes | The confirmation or operation id a preview or a progress answer gave. Pattern `^op_[A-Za-z0-9]{1,40}$`. |
| `expiresAt` | string | Yes | After this, confirming answers 409 with a fresh preview. Date-time. |
| `confirmableAt` | string | Yes | Confirming before this answers 425. Date-time. |

**Example answer**

```json
{
  "ok": true,
  "answer": "Preview: removes the status Parked from Product · first moves its 0 pages to Draft under your name (a page whose Confluence status was removed moves in PageCycle only) · moves into and out of Parked go too\nNothing changes yet. Show this preview to the person. Once they agree, send POST /confirmations/op_id1, at least 8 seconds from now and within 15 minutes.",
  "code": null,
  "data": {
    "preview": "removes the status Parked from Product · first moves its 0 pages to Draft under your name (a page whose Confluence status was removed moves in PageCycle only) · moves into and out of Parked go too",
    "note": null,
    "confirmation": "op_id1",
    "expiresAt": "2026-10-02T12:15:00.000Z",
    "confirmableAt": "2026-10-02T12:00:08.000Z"
  }
}
```

### POST /spaces/{space}/moves

Previews a new move between two statuses, optionally limited to groups or needing a comment.

**Scopes:** `manage:pagecycle-space:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `addPagecycleMove`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | string | Yes | The Confluence space key. Pattern `^[A-Za-z0-9~_-]{1,255}$`. |

**Body fields**

| Name | Type | Required | Description |
|---|---|---|---|
| `from` | string | Yes | The status the move starts from. Up to 255 characters. |
| `to` | string | Yes | The status it moves to. Up to 255 characters. |
| `label` | string | No | Up to 255 characters. |
| `groups` | string | No | Group names, separated by commas. Up to 2000 characters. |
| `commentRequired` | boolean | No |  |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `preview` | string | Yes | What would change, in words. Show it to the person. A preview over 60,000 bytes is refused, never cut. Up to 60000 characters. |
| `note` | string or null | Yes | Pages the change would leave alone, when there are any. |
| `confirmation` | string | Yes | The confirmation or operation id a preview or a progress answer gave. Pattern `^op_[A-Za-z0-9]{1,40}$`. |
| `expiresAt` | string | Yes | After this, confirming answers 409 with a fresh preview. Date-time. |
| `confirmableAt` | string | Yes | Confirming before this answers 425. Date-time. |

**Example answer**

```json
{
  "ok": true,
  "answer": "Preview: adds the move \"Shelve\" (Draft → Archived, anyone who can edit) in Product\nNothing changes yet. Show this preview to the person. Once they agree, send POST /confirmations/op_id1, at least 8 seconds from now and within 15 minutes.",
  "code": null,
  "data": {
    "preview": "adds the move \"Shelve\" (Draft → Archived, anyone who can edit) in Product",
    "note": null,
    "confirmation": "op_id1",
    "expiresAt": "2026-10-02T12:15:00.000Z",
    "confirmableAt": "2026-10-02T12:00:08.000Z"
  }
}
```

### PATCH /spaces/{space}/moves/{move}

Previews renaming a move, changing who may make it, or whether it needs a comment. Name it by its label or "From → To".

**Scopes:** `manage:pagecycle-space:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `updatePagecycleMove`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | string | Yes | The Confluence space key. Pattern `^[A-Za-z0-9~_-]{1,255}$`. |
| `move` | string | Yes | Its name, or its id (always works). Up to 255 characters. |

**Body fields**

| Name | Type | Required | Description |
|---|---|---|---|
| `label` | string | No | Up to 255 characters. |
| `groups` | string | No | Up to 2000 characters. |
| `commentRequired` | boolean | No |  |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `preview` | string | Yes | What would change, in words. Show it to the person. A preview over 60,000 bytes is refused, never cut. Up to 60000 characters. |
| `note` | string or null | Yes | Pages the change would leave alone, when there are any. |
| `confirmation` | string | Yes | The confirmation or operation id a preview or a progress answer gave. Pattern `^op_[A-Za-z0-9]{1,40}$`. |
| `expiresAt` | string | Yes | After this, confirming answers 409 with a fresh preview. Date-time. |
| `confirmableAt` | string | Yes | Confirming before this answers 425. Date-time. |

**Example answer**

```json
{
  "ok": true,
  "answer": "Preview: changes the move \"Shelve old\" (In review → Archived, anyone who can edit) to \"Retire\" (In review → Archived, anyone who can edit) in Product\nNothing changes yet. Show this preview to the person. Once they agree, send POST /confirmations/op_id1, at least 8 seconds from now and within 15 minutes.",
  "code": null,
  "data": {
    "preview": "changes the move \"Shelve old\" (In review → Archived, anyone who can edit) to \"Retire\" (In review → Archived, anyone who can edit) in Product",
    "note": null,
    "confirmation": "op_id1",
    "expiresAt": "2026-10-02T12:15:00.000Z",
    "confirmableAt": "2026-10-02T12:00:08.000Z"
  }
}
```

### DELETE /spaces/{space}/moves/{move}

Previews removing a move.

**Scopes:** `manage:pagecycle-space:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `removePagecycleMove`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | string | Yes | The Confluence space key. Pattern `^[A-Za-z0-9~_-]{1,255}$`. |
| `move` | string | Yes | Its name, or its id (always works). Up to 255 characters. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `preview` | string | Yes | What would change, in words. Show it to the person. A preview over 60,000 bytes is refused, never cut. Up to 60000 characters. |
| `note` | string or null | Yes | Pages the change would leave alone, when there are any. |
| `confirmation` | string | Yes | The confirmation or operation id a preview or a progress answer gave. Pattern `^op_[A-Za-z0-9]{1,40}$`. |
| `expiresAt` | string | Yes | After this, confirming answers 409 with a fresh preview. Date-time. |
| `confirmableAt` | string | Yes | Confirming before this answers 425. Date-time. |

**Example answer**

```json
{
  "ok": true,
  "answer": "Preview: removes the move \"Shelve old\" (In review → Archived, anyone who can edit) from Product · pages keep their status\nNothing changes yet. Show this preview to the person. Once they agree, send POST /confirmations/op_id1, at least 8 seconds from now and within 15 minutes.",
  "code": null,
  "data": {
    "preview": "removes the move \"Shelve old\" (In review → Archived, anyone who can edit) from Product · pages keep their status",
    "note": null,
    "confirmation": "op_id1",
    "expiresAt": "2026-10-02T12:15:00.000Z",
    "confirmableAt": "2026-10-02T12:00:08.000Z"
  }
}
```

### PUT /spaces/{space}/workflowDefaults

Previews where pages start and which status new pages get.

**Scopes:** `manage:pagecycle-space:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `setPagecycleWorkflowDefaults`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | string | Yes | The Confluence space key. Pattern `^[A-Za-z0-9~_-]{1,255}$`. |

**Body fields**

| Name | Type | Required | Description |
|---|---|---|---|
| `startStatus` | string | No | Up to 255 characters. |
| `newPageStatus` | string | No | Up to 255 characters. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `preview` | string | Yes | What would change, in words. Show it to the person. A preview over 60,000 bytes is refused, never cut. Up to 60000 characters. |
| `note` | string or null | Yes | Pages the change would leave alone, when there are any. |
| `confirmation` | string | Yes | The confirmation or operation id a preview or a progress answer gave. Pattern `^op_[A-Za-z0-9]{1,40}$`. |
| `expiresAt` | string | Yes | After this, confirming answers 409 with a fresh preview. Date-time. |
| `confirmableAt` | string | Yes | Confirming before this answers 425. Date-time. |

**Example answer**

```json
{
  "ok": true,
  "answer": "Preview: new pages get In review in Product\nNothing changes yet. Show this preview to the person. Once they agree, send POST /confirmations/op_id1, at least 8 seconds from now and within 15 minutes.",
  "code": null,
  "data": {
    "preview": "new pages get In review in Product",
    "note": null,
    "confirmation": "op_id1",
    "expiresAt": "2026-10-02T12:15:00.000Z",
    "confirmableAt": "2026-10-02T12:00:08.000Z"
  }
}
```

### PATCH /spaces/{space}/automations/{automation}

Previews changing an automation, turning it on or off, or moving it in the list. Name it by its name or position.

**Scopes:** `manage:pagecycle-space:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `updatePagecycleAutomation`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | string | Yes | The Confluence space key. Pattern `^[A-Za-z0-9~_-]{1,255}$`. |
| `automation` | string | Yes | Its name, or its id (always works). Up to 255 characters. |

**Body fields**

| Name | Type | Required | Description |
|---|---|---|---|
| `when` | string | No | "a page is edited", "moved to \<status\>", "moved to any status" or "the review date passes". Up to 500 characters. |
| `if` | string | No | Conditions separated by ";": "status is A or B", "kind is signed off", "mover in group G", "label L". Up to 1000 characters. |
| `then` | string | No | Actions separated by ";": "move to S", "review in N days", "add label L", comment "text". Up to 1000 characters. |
| `name` | string | No | Up to 255 characters. |
| `enabled` | boolean | No |  |
| `position` | integer | No | From 1, up to 50. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `preview` | string | Yes | What would change, in words. Show it to the person. A preview over 60,000 bytes is refused, never cut. Up to 60000 characters. |
| `note` | string or null | Yes | Pages the change would leave alone, when there are any. |
| `confirmation` | string | Yes | The confirmation or operation id a preview or a progress answer gave. Pattern `^op_[A-Za-z0-9]{1,40}$`. |
| `expiresAt` | string | Yes | After this, confirming answers 409 with a fresh preview. Date-time. |
| `confirmableAt` | string | Yes | Confirming before this answers 425. Date-time. |

**Example answer**

```json
{
  "ok": true,
  "answer": "Preview: changes the automation \"Edited after approval\" in Product to: When a page is edited, if kind is signed off: move to Needs re-review (off)\nNothing changes yet. Show this preview to the person. Once they agree, send POST /confirmations/op_id1, at least 8 seconds from now and within 15 minutes.",
  "code": null,
  "data": {
    "preview": "changes the automation \"Edited after approval\" in Product to: When a page is edited, if kind is signed off: move to Needs re-review (off)",
    "note": null,
    "confirmation": "op_id1",
    "expiresAt": "2026-10-02T12:15:00.000Z",
    "confirmableAt": "2026-10-02T12:00:08.000Z"
  }
}
```

### DELETE /spaces/{space}/automations/{automation}

Previews removing an automation.

**Scopes:** `manage:pagecycle-space:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `removePagecycleAutomation`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | string | Yes | The Confluence space key. Pattern `^[A-Za-z0-9~_-]{1,255}$`. |
| `automation` | string | Yes | Its name, or its id (always works). Up to 255 characters. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `preview` | string | Yes | What would change, in words. Show it to the person. A preview over 60,000 bytes is refused, never cut. Up to 60000 characters. |
| `note` | string or null | Yes | Pages the change would leave alone, when there are any. |
| `confirmation` | string | Yes | The confirmation or operation id a preview or a progress answer gave. Pattern `^op_[A-Za-z0-9]{1,40}$`. |
| `expiresAt` | string | Yes | After this, confirming answers 409 with a fresh preview. Date-time. |
| `confirmableAt` | string | Yes | Confirming before this answers 425. Date-time. |

**Example answer**

```json
{
  "ok": true,
  "answer": "Preview: removes the automation \"Edited after approval\" (When a page is edited, if kind is signed off: move to Needs re-review) from Product\nNothing changes yet. Show this preview to the person. Once they agree, send POST /confirmations/op_id1, at least 8 seconds from now and within 15 minutes.",
  "code": null,
  "data": {
    "preview": "removes the automation \"Edited after approval\" (When a page is edited, if kind is signed off: move to Needs re-review) from Product",
    "note": null,
    "confirmation": "op_id1",
    "expiresAt": "2026-10-02T12:15:00.000Z",
    "confirmableAt": "2026-10-02T12:00:08.000Z"
  }
}
```

### PUT /spaces/{space}/settings

Previews what happens when someone breaks the workflow in Confluence, and how long History is kept.

**Scopes:** `manage:pagecycle-space:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `updatePagecycleSpaceSettings`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | string | Yes | The Confluence space key. Pattern `^[A-Za-z0-9~_-]{1,255}$`. |

**Body fields**

| Name | Type | Required | Description |
|---|---|---|---|
| `onBreak` | string | No | "put back" or "flag". Up to 40 characters. |
| `keepHistory` | string | No | 30 days, 90 days, 1 year or 3 years. Up to 40 characters. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `preview` | string | Yes | What would change, in words. Show it to the person. A preview over 60,000 bytes is refused, never cut. Up to 60000 characters. |
| `note` | string or null | Yes | Pages the change would leave alone, when there are any. |
| `confirmation` | string | Yes | The confirmation or operation id a preview or a progress answer gave. Pattern `^op_[A-Za-z0-9]{1,40}$`. |
| `expiresAt` | string | Yes | After this, confirming answers 409 with a fresh preview. Date-time. |
| `confirmableAt` | string | Yes | Confirming before this answers 425. Date-time. |

**Example answer**

```json
{
  "ok": true,
  "answer": "Preview: a status change that breaks the workflow is flagged in Product\nNothing changes yet. Show this preview to the person. Once they agree, send POST /confirmations/op_id1, at least 8 seconds from now and within 15 minutes.",
  "code": null,
  "data": {
    "preview": "a status change that breaks the workflow is flagged in Product",
    "note": null,
    "confirmation": "op_id1",
    "expiresAt": "2026-10-02T12:15:00.000Z",
    "confirmableAt": "2026-10-02T12:00:08.000Z"
  }
}
```

### POST /spaces/{space}/pagecycle

Previews turning PageCycle on in a space: the default workflow, and the space's Confluence statuses matched to it.

**Scopes:** `manage:pagecycle-space:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `enablePagecycleSpace`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | string | Yes | The Confluence space key. Pattern `^[A-Za-z0-9~_-]{1,255}$`. |

**Body fields**

| Name | Type | Required | Description |
|---|---|---|---|
| `mapping` | string | No | How Confluence statuses map to PageCycle statuses, when the preview asks. Up to 2000 characters. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `preview` | string | Yes | What would change, in words. Show it to the person. A preview over 60,000 bytes is refused, never cut. Up to 60000 characters. |
| `note` | string or null | Yes | Pages the change would leave alone, when there are any. |
| `confirmation` | string | Yes | The confirmation or operation id a preview or a progress answer gave. Pattern `^op_[A-Za-z0-9]{1,40}$`. |
| `expiresAt` | string | Yes | After this, confirming answers 409 with a fresh preview. Date-time. |
| `confirmableAt` | string | Yes | Confirming before this answers 425. Date-time. |

**Example answer**

```json
{
  "ok": true,
  "answer": "Preview: turns PageCycle on in News · 0 pages scanned · 0 without a status stay without one · pages restricted from you aren't counted\nNothing changes yet. Show this preview to the person. Once they agree, send POST /confirmations/op_id1, at least 8 seconds from now and within 15 minutes.",
  "code": null,
  "data": {
    "preview": "turns PageCycle on in News · 0 pages scanned · 0 without a status stay without one · pages restricted from you aren't counted",
    "note": null,
    "confirmation": "op_id1",
    "expiresAt": "2026-10-02T12:15:00.000Z",
    "confirmableAt": "2026-10-02T12:00:08.000Z"
  }
}
```

### DELETE /spaces/{space}/pagecycle

Previews turning PageCycle off in a space. History and settings stay.

**Scopes:** `manage:pagecycle-space:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `disablePagecycleSpace`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `space` | string | Yes | The Confluence space key. Pattern `^[A-Za-z0-9~_-]{1,255}$`. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `preview` | string | Yes | What would change, in words. Show it to the person. A preview over 60,000 bytes is refused, never cut. Up to 60000 characters. |
| `note` | string or null | Yes | Pages the change would leave alone, when there are any. |
| `confirmation` | string | Yes | The confirmation or operation id a preview or a progress answer gave. Pattern `^op_[A-Za-z0-9]{1,40}$`. |
| `expiresAt` | string | Yes | After this, confirming answers 409 with a fresh preview. Date-time. |
| `confirmableAt` | string | Yes | Confirming before this answers 425. Date-time. |

**Example answer**

```json
{
  "ok": true,
  "answer": "Preview: turns PageCycle off in Product · History is kept · pages keep their Confluence status · moves are no longer checked\nNothing changes yet. Show this preview to the person. Once they agree, send POST /confirmations/op_id1, at least 8 seconds from now and within 15 minutes.",
  "code": null,
  "data": {
    "preview": "turns PageCycle off in Product · History is kept · pages keep their Confluence status · moves are no longer checked",
    "note": null,
    "confirmation": "op_id1",
    "expiresAt": "2026-10-02T12:15:00.000Z",
    "confirmableAt": "2026-10-02T12:00:08.000Z"
  }
}
```

## Confirmations and operations

Apply a preview, and follow a change that touches many pages. A confirmation applies exactly what was previewed, once, for the person who asked for it. A long change answers `202` with an operation id: call `POST /operations/{id}` until it answers `200`.

| Route | What it does |
|---|---|
| [`POST /confirmations/{id}`](#post-confirmations-id) | Applies a preview, for the person who asked for it, at least 8 seconds after it and within 15 minutes. |
| [`GET /operations/{id}`](#get-operations-id) | Where a change stands, read only: it never applies a batch. |
| [`POST /operations/{id}`](#post-operations-id) | Continues a long change by its next batch, for its previewer or another space admin, and says how far it got. |

### POST /confirmations/{id}

Applies a preview, for the person who asked for it, at least 8 seconds after it and within 15 minutes. Repeating it answers the saved result.

**Scopes:** `manage:pagecycle-space:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `confirmPagecycleChange`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `id` | string | Yes | The confirmation or operation id a preview or a progress answer gave. Pattern `^op_[A-Za-z0-9]{1,40}$`. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `operation` | string | Yes | The confirmation or operation id a preview or a progress answer gave. Pattern `^op_[A-Za-z0-9]{1,40}$`. |
| `status` | `"previewed"`, `"applying"`, `"running"`, `"done"`, `"failed"`, `"expired"`, `"superseded"` | Yes |  |
| `progress` | string or null | No | How far a long change got. |
| `preview` | string | No |  |
| `expiresAt` | string | No | Date-time. |

**Example answer**

```json
{
  "ok": true,
  "answer": "Done: the move \"Shelve\" is in Product's workflow.",
  "code": null,
  "data": {
    "operation": "op_id1",
    "status": "done"
  }
}
```

### GET /operations/{id}

Where a change stands, read only: it never applies a batch. For a space admin of its space; a preview nobody confirmed only for its previewer.

**Scopes:** `read:pagecycle:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `getPagecycleOperationStatus`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `id` | string | Yes | The confirmation or operation id a preview or a progress answer gave. Pattern `^op_[A-Za-z0-9]{1,40}$`. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `operation` | string | Yes | The confirmation or operation id a preview or a progress answer gave. Pattern `^op_[A-Za-z0-9]{1,40}$`. |
| `status` | `"previewed"`, `"applying"`, `"running"`, `"done"`, `"failed"`, `"expired"`, `"superseded"` | Yes |  |
| `kind` | string | Yes | The tool that previewed it. |
| `preview` | string | Yes |  |
| `progress` | string or null | Yes |  |
| `expiresAt` | string | Yes | Date-time. |
| `finishedAt` | string or null | Yes | Date-time. |

**Example answer**

```json
{
  "ok": true,
  "answer": "Previewed, not applied: adds the move \"Shelve\" (Draft → Archived, anyone who can edit) in Product",
  "code": null,
  "data": {
    "operation": "op_id1",
    "status": "previewed",
    "kind": "addPagecycleMove",
    "preview": "adds the move \"Shelve\" (Draft → Archived, anyone who can edit) in Product",
    "progress": null,
    "expiresAt": "2026-10-02T12:15:00.000Z",
    "finishedAt": null
  }
}
```

### POST /operations/{id}

Continues a long change by its next batch, for its previewer or another space admin, and says how far it got.

**Scopes:** `manage:pagecycle-space:custom`, `read:forge-app:confluence`

**Rovo and MCP tool:** `getPagecycleOperation`

**Parameters**

| Name | Type | Required | Description |
|---|---|---|---|
| `id` | string | Yes | The confirmation or operation id a preview or a progress answer gave. Pattern `^op_[A-Za-z0-9]{1,40}$`. |

**Answer fields** (in `data`)

| Name | Type | Required | Description |
|---|---|---|---|
| `operation` | string | Yes | The confirmation or operation id a preview or a progress answer gave. Pattern `^op_[A-Za-z0-9]{1,40}$`. |
| `status` | `"previewed"`, `"applying"`, `"running"`, `"done"`, `"failed"`, `"expired"`, `"superseded"` | Yes |  |
| `progress` | string or null | No | How far a long change got. |
| `preview` | string | No |  |
| `expiresAt` | string | No | Date-time. |

**Example answer**

```json
{
  "ok": true,
  "answer": "Done: the move \"Shelve\" is in Product's workflow.",
  "code": null,
  "data": {
    "operation": "op_id1",
    "status": "done"
  }
}
```
