
本文详解 notion api 创建页面时因属性类型误用导致 400 错误的根本原因,重点纠正 `title`、`rich_text`、`url` 等字段的嵌套结构误区,并提供可直接运行的修复代码与关键注意事项。
在使用 Notion API 创建数据库页面(notion.pages.create)时,一个高频踩坑点是:错误地将所有属性值统一用数组形式(如 Name: [{ text: { content: "..." } }])传入,而忽略了不同属性类型对顶层键名和数据结构的严格要求。你遇到的 body.properties.Link.id should be defined 这类报错看似指向缺失字段,实则是 API 因结构不匹配提前校验失败——它根本没解析到 Link 的实际值,而是发现该属性对象不符合任何已知类型模式,于是回退到内部字段校验逻辑并抛出误导性提示。
核心规则如下:
- ✅ 标题(Title)属性:必须使用 title 作为顶层键,其值为 text 对象数组(即使只有一项);
- ✅ 富文本(Rich Text)属性(如 Notes、Year):必须使用 rich_text 作为顶层键,值同为 text 对象数组;
- ✅ URL 属性(如 Link):直接使用 url 作为顶层键,值为字符串(注意:需含协议,如 https://,否则 Notion 可能拒绝);
- ❌ 禁止混用:不可将 title 或 rich_text 写成数组(如 Name: [...]),也不可将 url 包裹进 text 结构中。
以下是修正后的完整可运行示例(已适配最新 Notion API v1):
const { Client } = require('@notionhq/client');
const notion = new Client({
auth: process.env.NOTION_TOKEN,
});
async function main() {
try {
const response = await notion.pages.create({
parent: {
type: 'database_id',
database_id: process.env.DB_ID,
},
properties: {
Name: {
title: [
{
text: {
content: 'Test name',
},
},
],
},
Link: {
url: 'https://www.google.com', // ✅ 必须带 https:// 协议
},
Notes: {
rich_text: [
{
text: {
content: 'sample notes',
},
},
],
},
Year: {
rich_text: [
{
text: {
content: '2020',
},
},
],
},
},
});
console.log('✅ Page created successfully:', response.url);
} catch (error) {
console.error('❌ Failed to create page:', error.message);
// 建议打印完整 error.body 用于调试
if (error.body) console.error('Response body:', error.body);
}
}
main();? 关键注意事项:
- 协议强制要求:url 字段值必须包含 http:// 或 https://,www.google.com 会被拒绝,应写为 https://www.google.com;
- 数据库权限检查:确保集成(Integration)已在目标数据库中被明确添加为“可编辑”成员(Notion UI → Database → ··· → Add connections);
- 属性名称大小写敏感:Name、Link 等必须与数据库中实际 Property 名称完全一致(包括空格和大小写);
- Relation / Checkbox 等复杂类型:需按官方文档对应结构书写(如 relation: { database_id: "...", ... }),切勿尝试用 text 数组模拟;
- 调试技巧:启用 console.error(error.body) 可获取更精准的验证错误位置,比仅看 error.message 更有效。
遵循上述结构规范后,90% 以上的 400 Bad Request 页面创建失败问题即可解决。记住:Notion API 的属性不是“自由格式”,而是强契约式 Schema —— 每个 property type 都有唯一合法的顶层键名与嵌套结构,这是避免误导性报错的关键。










