For the complete documentation index, see llms.txt. This page is also available as Markdown.

Apply a batch of content changes to a change request

Applies an ordered array of content changes (up to 50) to the change request atomically, creating a single new revision. Changes are applied sequentially; if any single change is invalid the entire batch is rejected and no revision is created. Use this to create, update, rename, move, or delete pages within a change request before merging to live. This is the primary way to programmatically author content in a change request. Renaming a page — update_page can change a page's title and/or its slug (the path segment used to build its URL within its current parent). Both fields are independent: to rename only the title without changing the URL, set title and omit slug; to change the URL without changing the title, set slug and omit title. Moving a page — update_page can also change a page's parent and/or its position among siblings with into/at. Set into to the new parent's page ID, or null to move the page to the root of the tree; omit into to leave the parent unchanged. Set at to place the page at a specific zero-based index among its new siblings; omit it to leave the position unchanged (when the parent isn't changing) or append at the end (when it is). A page cannot be moved under itself or one of its own descendants. insert_page's into/at remain the way to place a new page at creation time. To put an image or attachment in a page, upload it with an insert_files change. Give the file a ref and a page inserted in the same batch can reference it as ![Alt](./<ref>) or [File](./<ref>), which resolves to the file's ID at apply time regardless of operation order. Uploaded files are also listed as insertedFiles when compat=false, and a file already in the change request can be referenced directly as /files/<fileId>. Inline data: URIs in markdown are not ingested and large image blocks are dropped, so upload the bytes with insert_files instead. Publishing an OpenAPI spec — an OpenAPI spec belongs to the organization (see createOpenAPISpec) and appears in a space only through a page that renders it. Insert that page with an insert_computed_page change: { "operation": "insert_computed_page", "title": "API reference", "computed": { "type": "builtin:openapi", "props": { "models": true }, "dependencies": { "spec": { "ref": { "kind": "openapi", "spec": "<spec slug>" } } } } }. GitBook replaces that page, at its position, with the API reference: one page per tag (or per operation with "grouping": "by-operation" in props), plus a models page when models is true, regenerated whenever the spec changes. Use into to nest the reference under an existing page. Do not recreate a spec with insert_page: openapi-operation blocks in a document only render the operations they name. When page content is provided as markdown, links to other pages are resolved against the change request's current page tree. You can link a page by:

  • Page ID — /pages/<pageId> (also /pages/<pageId>#anchor).

  • Page slug path — /pages/<slug> for a top-level page, or /pages/<parent-slug>/<slug> for a nested page (e.g. /pages/guides/getting-started).

  • Markdown file path — the path the page would have in Git: /pages/<slug>.md for a page, or /pages/<slug>/README.md for a page that has child pages. The space's root page is /pages/README.md.

  • Relative markdown link — resolved against the page being edited, e.g. ./sibling.md, ../other.md, or ../README.md (the parent page). Folder-style links without an extension (e.g. ./section) resolve to that folder's page.

External URLs (https://…) are kept as-is. A link that does not match any page in the change request is left as plain text rather than causing the request to fail. GitBook normalizes submitted content, so the stored page may differ from what was sent. To help callers reconcile local state with the stored result, the response can list each created and modified page with its resolved ID and a urls.location to fetch the page's persisted content. For change requests with frequent concurrent edits, consider expectedRevision to protect against overwriting changes made since your read. If the branch has changed since the supplied revision, the batch is rejected with HTTP 409 and none of the submitted changes are applied. Response shape (compat) — this endpoint is changing what it returns:

  • compat=true (current default) returns the updated change request, matching the endpoint's original behavior.

  • compat=false returns the updated change request and the list of affected pages (see the response schema).

The default is true for now to preserve backwards compatibility, but will switch to false in a future release, at which point the affected-page list is always included. You should pass compat=false if you want the new behavior today and avoid unexpected errors when the default flips in the future.

Available in MCP
post
Authorizations
AuthorizationstringRequired
Bearer authentication header of the form Bearer <token>.
Path parameters
spaceIdstringRequired

A unique entity identifier

Pattern: ^[a-zA-Z0-9_-]+$
changeRequestIdstringRequired

A unique entity identifier

Pattern: ^[a-zA-Z0-9_-]+$
Query parameters
compatbooleanOptional

When true, the updated change request is returned. When false, the updated change request and the list of affected pages are returned.

Default: true
Body
expectedRevisionstring · min: 1Optional

The saved branch revision on which these changes are based, available in getChangeRequestById's revision field. If the branch has changed, including pending realtime edits, the batch is rejected with 409 and none of the submitted changes are applied. This field is optional and most changes can omit it.

Responses
200

The change request has been updated

application/json

The change request when compat=true (default), or the change request plus the list of affected pages when compat=false.

or
post/spaces/{spaceId}/change-requests/{changeRequestId}/content
POST /v1/spaces/{spaceId}/change-requests/{changeRequestId}/content HTTP/1.1
Host: api.gitbook.com
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 200

{
  "expectedRevision": "text",
  "changes": [
    {
      "operation": "update_page",
      "page": "page_id",
      "document": {
        "markdown": "# Hello World\n\nThis is a markdown document linking to [another page](/pages/page_id).\n"
      }
    }
  ]
}
{
  "object": "change-request",
  "id": "text",
  "number": 1,
  "status": "draft",
  "subject": "text",
  "description": {
    "object": "document",
    "data": {},
    "nodes": [
      {
        "object": "block",
        "type": "paragraph",
        "data": {},
        "nodes": [
          {
            "object": "text",
            "leaves": [
              {
                "object": "leaf",
                "text": "Hello world",
                "marks": []
              }
            ]
          }
        ]
      }
    ]
  },
  "createdBy": {
    "object": "user",
    "id": "text",
    "displayName": "text",
    "email": "text",
    "photoURL": "text",
    "urls": {
      "location": "https://example.com"
    }
  },
  "createdAt": "2026-01-01T00:00:00.000Z",
  "updatedAt": "2026-01-01T00:00:00.000Z",
  "mergedBy": {
    "object": "user",
    "id": "text",
    "displayName": "text",
    "email": "text",
    "photoURL": "text",
    "urls": {
      "location": "https://example.com"
    }
  },
  "mergedAt": "2026-01-01T00:00:00.000Z",
  "space": "text",
  "revision": "text",
  "revisionInitial": "text",
  "revisionMergedAncestor": "text",
  "revisionMerged": "text",
  "comments": 1,
  "changeCounts": {
    "pages": {
      "added": 1,
      "modified": 1,
      "deleted": 1
    },
    "library": {
      "added": 1,
      "modified": 1,
      "deleted": 1
    },
    "blocks": {
      "added": 1,
      "modified": 1,
      "deleted": 1
    },
    "blocksOmittedReason": "too-many-pages"
  },
  "siteTopic": {
    "site": "text",
    "topic": "text"
  },
  "siteFindings": [
    {
      "site": "text",
      "finding": "text"
    }
  ],
  "styleguide": {
    "site": "text",
    "run": "text",
    "changedPages": 1,
    "checkedAt": "2026-01-01T00:00:00.000Z"
  },
  "outdated": true,
  "imports": [
    {
      "object": "import-run",
      "id": "text",
      "startedAt": "2026-01-01T00:00:00.000Z",
      "completedAt": "2026-01-01T00:00:00.000Z",
      "createdAt": "2026-01-01T00:00:00.000Z",
      "updatedAt": "2026-01-01T00:00:00.000Z",
      "status": "pending",
      "reason": "text",
      "source": {
        "type": "website",
        "url": "https://example.com"
      },
      "target": {
        "space": "text",
        "changeRequest": "text",
        "page": "text"
      },
      "site": "text",
      "createdBy": "text",
      "urls": {
        "location": "https://example.com"
      },
      "pages": [
        {
          "id": "text",
          "sourceURL": "text",
          "type": "page",
          "status": "complete"
        }
      ]
    }
  ],
  "links": [
    {
      "id": "text",
      "ref": {
        "kind": "url",
        "url": "text"
      },
      "title": "text",
      "isSyncing": true,
      "expanded": {
        "kind": "external-ticket",
        "provider": "jira",
        "state": "connected",
        "key": "text",
        "url": "https://example.com",
        "status": {
          "id": "text",
          "name": "text"
        },
        "summary": "text"
      }
    }
  ],
  "urls": {
    "app": "https://example.com",
    "location": "https://example.com"
  }
}

Last updated

Was this helpful?

Powered by GitBook