4

I'm able to create a new page using the Notion API, and as part of that page I want to create & include a database table. I'm able to create the page successfully, but when trying to create the database using the child_database block, I am getting a status 400 error. Sample code below. Any help appreciated.

let payload = {
    'parent': {'database_id': database_id_variable},
    'properties': {
        'Name': {
            'title': [
                {'text': {'content': 'My Grocery List Page'}}
            ]
        }
    },
    'children': [
        {
            'object': 'block',
            'type': 'child_database',
            'child_database': {
                'title': 'Grocery List',
                    'properties': {
                        'Grocery item': {
                            'type': 'title',
                            'title': [{ 'type': 'text', 'text': { 'content': 'Tomatoes' } }]
                        },
                    }
            }
        },
    ]
}

let response = await fetch('https://api.notion.com/v1/pages', {
    method: 'POST',
    body: JSON.stringify(payload),
    headers: {
        'Authorization' : 'Bearer secret_XXX',
        'Content-Type': 'application/json',
        'Notion-Version': '2021-08-16',
    },
});
console.log(await response.json());
}
Josh
  • 51
  • 4

3 Answers3

2

This is now possible by making 2 API calls, using the newer Notion API version 2022-06-28.

Steps:

  1. Create the page as a child of the database, and return the new page's ID.
  2. Create a new database as a child of the new page.

The 2 calls are, as far as I understand, required, since they cannot be combined in a single call (with a database as a block in the new page).

To create or update child_database type blocks, use the Create a database and the Update a database endpoints, specifying the ID of the parent page in the parent body param.

From https://developers.notion.com/reference/block#child-database

Create the page as a child of the database, and return the new page's ID

Using the Notion API, it's possible to create a new page in an existing database (of which you have the ID).

This can be done by making a POST request to the /pages endpoint with the following body:

{
  parent: { type: 'database_id', database_id: 'parent_database_id' },
  properties: {
    Name: { // Name of the database's title property
      title: [
        {
          text: { content: 'My Grocery List page' }
        }
      ]
    }
  }
}

This in turn returns an object which has, among others, the id property, which holds the ID of the newly created page.

Create a new database as a child of the new page

To create a new database in a page, make a POST request to the /databases endpoint with the following body:

{
  parent: { type: 'page_id', page_id: 'parent_page_id' },
  title: [
    {
      text: { content: 'Grocery List' }
    }
  ],
  is_inline: true, // This shows the database INLINE in the parent page
    properties: {
      'Grocery item': {
        title: {}
      }
    }
  }
};

Please note the is_inline property, set to true (as stated in another answer). When true, the database appears in the parent page as an inline block. When false or omitted, the database appears as a child page of the parent page.

Complete (documented) code sample

(runnable via Node.js after changing the values for the constants defined on top)

// Environment constants
const API_URL = 'https://api.notion.com/v1';
const API_SECRET = 'my_api_secret';
const PARENT_DATABASE_ID = 'my_parent_database_id';

/**
 * 
 * @param {string} path The API path.
 * @param {string} method The HTTP method (get, post, put, patch, delete)
 * @param {object} [body] The optional payload to send with the request.
 * 
 * @returns {Promise.<object>} A promise which resolves into the parsed API response.
 */
const doRequest = async (path, method, body = null) => {
  const opts = {
    method: method.toUpperCase(),
    headers: {
      'Authorization': `Bearer ${API_SECRET}`,
      'Content-Type': 'application/json',
      'Notion-Version': '2022-06-28' // Note the newer API version in use
    }
  };
  if (body) opts.body = JSON.stringify(body);

  const response = await fetch(`${API_URL}/${path}`, opts);
  return await response.json();
}

/**
 * Create a new Notion page in an existing Notion database.
 * 
 * @param {string} parentId The parent database's ID.
 * 
 * @returns {Promise.<String>} A promise which resolves into the ID of the newly created page.
 */
const createNewPageInDatabase = async (parentId) => {
  const payload = {
    parent: { type: 'database_id', database_id: parentId },
    properties: {
      Name: {
        title: [
          {
            text: { content: 'My Grocery List page' }
          }
        ]
      }
    }
  };

  const response = await doRequest('pages', 'post', payload);
  return response.id;
};

/**
 * Create a new Notion DB with a title prop 'Grocery item' in an existing Notion page.
 * 
 * @param {string} parentId The parent page's ID.
 * 
 * @returns {Promise.<String>} A promise which resolves into the ID of the newly created database.
 */
const createNewDatabaseInPage = async (parentId) => {
  const payload = {
    parent: { type: 'page_id', page_id: parentId },
    title: [
      {
        text: { content: 'Grocery List' }
      }
    ],
    is_inline: true, // This creates the database inline in the parent page
    properties: {
      'Grocery item': {
        title: {}
      }
    }
  };

  const response = await doRequest('databases', 'post', payload);
  return response.id;
}

/**
 * Run the program.
 */
const init = async () => {
  const newPageId = await createNewPageInDatabase(PARENT_DATABASE_ID);
  const newSubDatabaseId = await createNewDatabaseInPage(newPageId);

  console.log(`Created new DB ${newSubDatabaseId} in new page ${newPageId} in existing DB ${PARENT_DATABASE_ID}.`);
};

init();
Gerrit Bertier
  • 4,101
  • 2
  • 20
  • 36
  • 1
    Whoops. Bounty expired while I was on holiday (don't worry I lose the bounty either way). Let me just see if this works and if it does I'll look into "tipping" you the bounty. – Att Righ May 30 '23 at 17:59
  • @AttRigh No worries, please let me know if you can't get it working. – Gerrit Bertier May 31 '23 at 09:58
  • Yep - just a heads up that I am going to look at this (had something at the weekend that I really wanted to get done and then pretty tired last evening). I'll probably get to it one evening during the week. Otherwise I'll just give you the bounty on Sunday! – Att Righ Jun 06 '23 at 09:15
  • Hmm... I want to give you this bounty. But I couldn't find a tip button and it'll only let me create a new bounty of 400 points :( – Att Righ Jun 15 '23 at 09:53
0

While not a child database, I was able to resolve my issue by creating a simple table instead since Notion just announced the API would now support simple tables:

https://developers.notion.com/reference/block#table-blocks

Josh
  • 51
  • 4
0

I know it's been a while but I just stumbled upon this. As of today, there is the is_inline property for databases. With it, you can simply create a database via the databases endpoint (Create a database), specify it's parent and set the is_inline flag to true.

Simon
  • 126
  • 2