Notion: Copy full page content between databases — still no reliable solution?

:bullseye: What is your goal?

Automatically copy the full content of a Notion page from a database A to a corresponding page in database B, in a reliable way without manually rebuilding each block type.

:thinking: What is the problem & what have you tried?

Hi everyone,

I’m trying to copy full Notion page content from a page in database A to another page in database B (archive use case), and I’m running into structural issues when updating the content.

I’ve tested several approaches:

  • OK => List Page Content (which I actually like — the 1 bundle per block approach is quite clean)

  • OK => Custom API calls (/blocks/{id}/children)

  • KO => Append block children

  • KO => Update page content

Listing blocks is not the problem — I can retrieve page content reliably with different methods.
The issue is really on the update(patch) side.

When sending blocks back to Notion, I get validation errors, including errors on block types I’m not even sending, for example:

[400] body failed validation. Fix one:
body.embed should be defined
body.bookmark should be defined
body.image should be defined
body.video should be defined
...

Even though my payload only contains standard types like paragraph, heading_2, to_do, etc.

From older threads, it seems this might be due to Notion validating against all possible block schemas:

So my questions:

  1. Is this behavior (errors on unrelated block types) expected / known?
  2. Has anything improved recently (Make or Notion side) to simplify full page content transfer since older topics i have been through?
  3. Is there now a better approach than rebuilding blocks per type or iterating block-by-block (which becomes costly)?

Thanks in advance for any insights!

:clipboard: Error messages or input/output bundles

[400] body failed validation. Fix one: body.embed should be defined, instead was undefined. body.bookmark should be defined, instead was undefined. body.image should be defined, instead was undefined. body.video should be defined, instead was undefined. body.pdf should be defined, instead was undefined. body.file should be defined, instead was undefined. body.audio should be defined, instead was undefined. body.code should be defined, instead was undefined. body.equation should be defined, instead was undefined. body.divider should be defined, instead was undefined

(Goes on and on with all possible types )

Notion does not support these specific blocks. It only supports text blocks such as headers, paragraphs, and bullets, etc. I’ve never had it work with embeds and videos, but I’m sure they fall into the same category as database views, which are unsupported.

Yes, for text blocks, you’ll have to iterate over one block at a time and put it back together.

Personally, if you’re just moving from one database to another, Notion AI is a far superior option for this.

As far as getting errors for blocks that you’re not even sending, I don’t know. There’s definitely going to need to be more information on why that could be possible.

Thank you for your response Frank.
I join my legacy workflow which worked until a month ago

Would you have more information about how I can elaborate this workaround with notion AI ?

Hello everyone,
Found a workaround for the moment. Make is not involved unfortunately.
Workaround would be to use Notion AI indeed, by creating an Notion agent in your workspace.
Example prompt :

_______________________________________

:open_book: Overview

You are an archiving agent. When a project page is moved to the Archived status in the Test - Project Board database, you create a full copy of that page in the Test - Projects Backups database, then link the new page to the original one.

The goal of this test is to verify that both the properties AND the page content are faithfully copied.

:bullseye: Trigger

You are triggered when a page in the Test - Project Board has its Status property updated. Act only if the new status is Archived. Otherwise, do nothing.

:hammer_and_wrench: Procedure

  1. Load the source page using loadPage to retrieve all its properties and its full markdown content.

  2. Create a new page in the Test - Projects Backups database using createPage:

    • Parent: the data source of Test - Projects Backups.

    • Icon: reuse the icon from the source page.

    • Properties: copy the following values if they exist:

      • Project Name

      • Description

      • Client, Service Agreement, Scope of Work, Project Type

      • Project Manager, Team Members

      • Revenue, Budget, Cost, Profit Margin, Customer Satisfaction Score

      • Project Start Date (date)

      • External Reference ID

    • Status on the copy: Archived project

    • Archived Date: today’s date (Europe/Paris timezone).

    • Source Project: relation to the source page (URL of the source page in Test - Project Board).

    • Content: copy the markdown content from the source page as is, without modifying anything and without adding any comments.

  3. Confirm briefly in the thread with the archived project name and the link to the created backup page.

:white_check_mark: Important Rules

  • Copy the content exactly as is: blocks, tables, callouts, code, to-dos, quotes, formulas, etc.

  • Do not modify the source page (no deletion, no editing).

  • If a source property is empty, leave it empty in the copy.

  • If a backup page already exists for the same Source Project, do not create another one: report the duplicate instead.

:compass: Databases involved

  • Source: Test - Project Board

  • Destination: Test - Projects Backups

_______________________________________

Hope it can help, makes the coffee for me, have a good one.
Max