You have a space that someone got right. A client onboarding space, a project template, a runbook set. You want another one just like it. Twenty-one years after someone first asked, Confluence Cloud still has no button for that: CONFCLOUD-3191, "Easily create a copy of an entire space", was opened in May 2005, has 882 votes, and is Gathering Interest.
Copying a page tree is not copying a space
The native Copy page tree action is good and it is not the same thing. It copies pages beneath a parent, with their attachments, into a destination you have already created. What it does not do is the part people actually ask for:
- The space itself. You create the space by hand first — key, name, home page — and the copy drops into it.
- The links. This is the one that breaks silently, and it is the whole subject of this post.
- Restrictions. Page restrictions do not come along, which is usually right and occasionally exactly wrong.
The silent failure: links that still point home
A Confluence page body in storage format refers to another page in one of two ways. By space key and title:
<ac:link><ri:page ri:space-key="OLD" ri:content-title="Runbook" /></ac:link>
…or by page id, as a plain URL like /pages/123456/Runbook.
Copy the tree and both forms survive the copy intact — still pointing at the original space. Nothing errors. Every link still resolves, to the wrong page. Your new client's space has a navigation structure that quietly walks visitors back into the space you copied from, and you find out when one of them edits a page there.
The first form is fixable: rewrite ri:space-key and any
/spaces/OLD/ path to the new key as you copy each body. The second form is
genuinely harder, and worth being precise about, because this is the limit of any solution
including ours: a page id does not exist until that page has been created. A
link from page A to page B, written by id, cannot be rewritten while copying A if B has not been
copied yet. Honest handling means rewriting what can be rewritten, saying so about the rest, and
not claiming a clean copy.
What you can build yourself
The REST API gives you all the pieces. Create the space, then walk the tree:
POST /wiki/rest/api/space → create the target space
GET /wiki/api/v2/pages/{id}?body-format=storage → source body
GET /wiki/api/v2/pages/{id}/children → the frontier
POST /wiki/api/v2/pages → the copy, under its new parent
Two things will bite a script that does this. Scopes: the v2 endpoints accept
only granular scopes — read:page:confluence, write:page:confluence —
and a classic scope gets you 401 scope does not match, while some v1 endpoints you
still need for labels, attachments and restrictions take the classic ones. You will hold both
sets. Time: a few hundred pages exceeds any single request, so the walk has to
be a resumable job with its progress and its page-id map persisted, not a loop.
The app
Space Copy & Templates for Confluence is that job, done carefully. The target space is created as you, so you own it. Pages are copied breadth-first, 20 per invocation through the Forge async queue, re-enqueuing until the frontier is empty — a 4,000-page space finishes rather than timing out, and a page that fails is recorded and skipped rather than ending the run. Bodies get the link rewrite, labels and attachments come across, restrictions are opt-in. Any space can be saved as a template and stamped out again.
It is permission-safe by construction: only spaces you can read are offered, and every source page is confirmed readable by you before it is copied, so a copy can never widen access to anything.
The limits, stated before you install rather than after. Links by page id still point at the source, for the reason above. Blog posts, comments and page history are not copied — you get the current version of each page. Space permissions are not copied; the new space gets your defaults. And it copies pages, not Confluence's page-template objects: a "space template" here means a space used as a blueprint, which is what people building this usually mean, and is not what CONFCLOUD-7752 asks for.
Written by Abaho Katabarwa at Katabarwa Labs. We build small, single-purpose Atlassian and Azure tools that run entirely inside your own tenant. Questions: support@katabarwalabs.dev.