Documentation Index
Fetch the complete documentation index at: https://developers.notion.com/llms.txt
Use this file to discover all available pages before exploring further.
The Workers SDK includes three schema-related exports:
import { j } from "@notionhq/workers/schema-builder";
import * as Schema from "@notionhq/workers/schema";
import * as Builder from "@notionhq/workers/builder";
| Import | Description |
|---|
j | JSON Schema builder for tool input and output schemas. |
Schema | Database property schema helpers for syncs. |
Builder | Database property value helpers for sync changes. |
Schema builder
The j export from @notionhq/workers/schema-builder builds JSON Schemas
for tool input and output. Use it instead
of hand-writing JSON Schema so tool contracts stay compatible across a wide
range of closed and open-source models. Builder methods return a
SchemaBuilder<T>.
interface SchemaBuilder<T> {
describe(text: string): SchemaBuilder<T>;
nullable(): SchemaBuilder<T | null>;
}
j.object()
j.object<P extends Record<string, SchemaBuilder<unknown>>>(
properties: P,
): SchemaBuilder<{ [K in keyof P]: Infer<P[K]> }>
Creates an object schema. All provided properties are included in required, and additionalProperties is set to false.
j.object({
query: j.string(),
limit: j.number().nullable(),
})
j.string()
j.string(): SchemaBuilder<string>
Creates a string schema.
j.string().describe("Search query.")
j.number()
j.number(): SchemaBuilder<number>
Creates a number schema.
j.number().describe("Maximum number of results.")
j.array()
j.array<T>(
items: SchemaBuilder<T>,
options?: { minItems?: 0 | 1 },
): SchemaBuilder<T[]>
Creates an array schema.
j.array(j.string())
j.array(j.string(), { minItems: 1 })
.describe()
schema.describe(text: string): SchemaBuilder<T>
Sets the JSON Schema description field and returns a new builder.
j.string().describe("Email address for the assignee.")
.nullable()
schema.nullable(): SchemaBuilder<T | null>
Wraps the schema in anyOf with { type: "null" } and returns a new builder. In object schemas, the property is still required, but its value may be null.
j.object({
dueDate: j.string().nullable().describe("ISO date, or null when unset."),
})
j.integer()
j.integer(): SchemaBuilder<number>
Creates an integer schema.
j.integer().describe("Whole number of retries.")
j.boolean()
j.boolean(): SchemaBuilder<boolean>
Creates a boolean schema.
j.boolean().describe("Whether archived records should be included.")
j.enum()
j.enum<T extends string>(...values: readonly T[]): SchemaBuilder<T>
j.enum<T extends number>(...values: readonly T[]): SchemaBuilder<T>
Creates an enum schema from string or number literal values.
j.enum("low", "medium", "high").describe("Priority level.")
j.datetime()
j.datetime(): SchemaBuilder<string>
Creates a string schema with format: "date-time".
j.datetime().describe("ISO 8601 timestamp for the event.")
j.date()
j.date(): SchemaBuilder<string>
Creates a string schema with format: "date".
j.date().describe("Due date in YYYY-MM-DD format.")
j.time()
j.time(): SchemaBuilder<string>
Creates a string schema with format: "time".
j.time().describe("Start time.")
j.duration()
j.duration(): SchemaBuilder<string>
Creates a string schema with format: "duration".
j.duration().describe("Elapsed time as an ISO 8601 duration.")
j.email()
j.email(): SchemaBuilder<string>
Creates a string schema with format: "email".
j.email().describe("Email address for the assignee.")
j.hostname()
j.hostname(): SchemaBuilder<string>
Creates a string schema with format: "hostname".
j.hostname().describe("Host name to query.")
j.ipv4()
j.ipv4(): SchemaBuilder<string>
Creates a string schema with format: "ipv4".
j.ipv4().describe("IPv4 address to allow.")
j.ipv6()
j.ipv6(): SchemaBuilder<string>
Creates a string schema with format: "ipv6".
j.ipv6().describe("IPv6 address to allow.")
j.uuid()
j.uuid(): SchemaBuilder<string>
Creates a string schema with format: "uuid".
j.uuid().describe("External record ID.")
j.anyOf()
j.anyOf<S extends SchemaBuilder<unknown>[]>(
...schemas: S
): SchemaBuilder<Infer<S[number]>>
Creates an anyOf schema from the provided schema builders.
j.anyOf(j.string(), j.number()).describe("String or numeric identifier.")
j.ref()
j.ref(path: string): SchemaBuilder<unknown>
Creates a reference schema with $ref set to path.
Database schema helpers
Use Schema helpers to define the properties of managed databases declared with worker.database().
import * as Schema from "@notionhq/workers/schema";
const tasks = worker.database("tasks", {
type: "managed",
initialTitle: "Tasks",
primaryKeyProperty: "Task ID",
schema: {
properties: {
Name: Schema.title(),
"Task ID": Schema.richText(),
Status: Schema.select([
{ name: "Open" },
{ name: "Done", color: "green" },
]),
},
},
});
Schema.title()
Schema.title(): PropertyConfiguration
Creates a title property definition. This field becomes the title for all pages in the database. A database must have exactly one title property.
Returns:
Schema.richText()
Schema.richText(): PropertyConfiguration
Creates a rich text property definition.
"Task ID": Schema.richText()
Returns:
Schema.url()
Schema.url(): PropertyConfiguration
Creates a URL property definition.
Returns:
Schema.email()
Schema.email(): PropertyConfiguration
Creates an email property definition.
Returns:
Schema.phoneNumber()
Schema.phoneNumber(): PropertyConfiguration
Creates a phone number property definition.
Phone: Schema.phoneNumber()
Returns:
Schema.checkbox()
Schema.checkbox(): PropertyConfiguration
Creates a checkbox property definition.
Returns:
Schema.file()
Schema.file(): PropertyConfiguration
Creates a file property definition.
Attachment: Schema.file()
Returns:
Schema.number()
Schema.number(format?: NumberFormat): PropertyConfiguration
Creates a number property definition. If format is provided, it is included in the returned configuration.
Amount: Schema.number("dollar")
Returns:
{ type: "number", format: "dollar" }
Schema.date()
Schema.date(dateFormat?: DateFormat): PropertyConfiguration
Creates a date property definition. If dateFormat is provided, it is emitted as date_format.
Due: Schema.date("YYYY/MM/DD")
Returns:
{ type: "date", date_format: "YYYY/MM/DD" }
Schema.select()
Schema.select(options: SelectOption[]): PropertyConfiguration
Creates a select property definition with predefined options.
Status: Schema.select([
{ name: "Open" },
{ name: "Done", color: "green" },
])
Returns:
{
type: "select",
options: [
{ name: "Open" },
{ name: "Done", color: "green" },
],
}
Schema.multiSelect()
Schema.multiSelect(options: SelectOption[]): PropertyConfiguration
Creates a multi-select property definition with predefined options.
Tags: Schema.multiSelect([
{ name: "Bug", color: "red" },
{ name: "Feature", color: "blue" },
])
Returns:
{
type: "multi_select",
options: [
{ name: "Bug", color: "red" },
{ name: "Feature", color: "blue" },
],
}
Schema.status()
Schema.status(config: { groups: StatusGroup[] }): PropertyConfiguration
Creates a status property definition with status groups.
State: Schema.status({
groups: [
{
name: "To-do",
options: [{ name: "Not started" }],
},
{
name: "In progress",
options: [{ name: "In progress", color: "blue" }],
},
{
name: "Complete",
options: [{ name: "Done", color: "green" }],
},
],
})
Returns:
{
type: "status",
groups: [
{ name: "To-do", options: [{ name: "Not started" }] },
{ name: "In progress", options: [{ name: "In progress", color: "blue" }] },
{ name: "Complete", options: [{ name: "Done", color: "green" }] },
],
}
Schema.people()
Schema.people(): PropertyConfiguration
Creates a people property definition.
Assignees: Schema.people()
Returns:
Schema.place()
Schema.place(): PropertyConfiguration
Creates a place property definition for geographic locations.
Returns:
Schema.relation()
Schema.relation(
relatedDatabaseKey: string,
config?: { twoWay: false } | { twoWay: true; relatedPropertyName: string },
): PropertyConfiguration
Creates a relation property definition that references another database declared in the same worker. relatedDatabaseKey must match the key passed to worker.database() for the related database. If config is omitted, the relation is one-way.
const projects = worker.database("projects", {
type: "managed",
initialTitle: "Projects",
primaryKeyProperty: "Project ID",
schema: {
properties: {
Name: Schema.title(),
"Project ID": Schema.richText(),
},
},
});
const tasks = worker.database("tasks", {
type: "managed",
initialTitle: "Tasks",
primaryKeyProperty: "Task ID",
schema: {
properties: {
Name: Schema.title(),
"Task ID": Schema.richText(),
Project: Schema.relation("projects", {
twoWay: true,
relatedPropertyName: "Tasks",
}),
},
},
});
Returns:
{
type: "relation",
relatedDatabaseKey: "projects",
config: {
twoWay: true,
relatedPropertyName: "Tasks",
},
}
Property value builders
Use Builder helpers to construct property values returned by sync changes. These properties must match the types defined in the database schema.
return {
changes: [
{
type: "upsert",
key: task.id,
properties: {
Name: Builder.title(task.name),
"Task ID": Builder.richText(task.id),
Status: Builder.select(task.status),
},
},
],
hasMore: false,
};
Builder.richText()
Builder.richText(content: string): TextValue
Creates a plain rich text value. Builder.richText() does not accept formatting
options; it returns a single text token with no annotations.
Builder.richText("task-123")
Returns:
Builder.url()
Builder.url(url: string): TextValue
Creates a URL value.
Builder.url("https://example.com")
Returns:
[["https://example.com"]]
Builder.title()
Builder.title(content: string): TextValue
Creates a title value.
Builder.title("Write docs")
Returns:
Builder.text()
Builder.text(content: string): TextValue
Creates a text value.
Builder.text("Imported from upstream.")
Returns:
[["Imported from upstream."]]
Builder.email()
Builder.email(email: string): TextValue
Creates an email value.
Builder.email("person@example.com")
Returns:
Builder.phoneNumber()
Builder.phoneNumber(phone: string): TextValue
Creates a phone number value.
Builder.phoneNumber("+14155550123")
Returns:
Builder.checkbox()
Builder.checkbox(checked: boolean): TextValue
Creates a checkbox value. true returns Yes; false returns No.
Returns:
Builder.file()
Builder.file(fileUrl: string, fileName?: string): TextValue
Creates a file URL value. If fileName is omitted, the URL is also used as the display text.
Builder.file("https://example.com/invoice.pdf", "Invoice")
Returns:
[["Invoice", [["a", "https://example.com/invoice.pdf"]]]]
Builder.number()
Builder.number(value: number): TextValue
Creates a number value by converting value to a string. If value is NaN, returns an empty value.
Returns:
Builder.date()
Builder.date(dateString: string): TextValue
Creates a date value from a YYYY-MM-DD date string. Throws if the input does
not match that format or cannot be parsed by JavaScript Date.
Builder.date("2026-05-11")
Returns a date mention token:
[["\u2023", [["d", { type: "date", start_date: "2026-05-11" }]]]]
Builder.dateTime()
Builder.dateTime(isoString: string, timeZone?: string): TextValue
Creates a datetime value from an ISO 8601 datetime string that starts with
YYYY-MM-DDTHH:mm. The builder stores the first 10 characters as start_date
and characters 11 through 16 as start_time. If timeZone is provided, it is
included as time_zone.
Builder.dateTime("2026-05-11T09:30:00Z", "America/Los_Angeles")
Returns a date mention token:
[
[
"\u2023",
[
[
"d",
{
type: "datetime",
start_date: "2026-05-11",
start_time: "09:30",
time_zone: "America/Los_Angeles",
},
],
],
],
]
Builder.dateRange()
Builder.dateRange(startDate: string, endDate: string): TextValue
Creates a date range value from two YYYY-MM-DD date strings. Throws if either
input does not match that format or cannot be parsed by JavaScript Date. The
builder does not validate that startDate is before endDate.
Builder.dateRange("2026-05-11", "2026-05-15")
Returns a date mention token:
[
[
"\u2023",
[
[
"d",
{
type: "daterange",
start_date: "2026-05-11",
end_date: "2026-05-15",
},
],
],
],
]
Builder.dateTimeRange()
Builder.dateTimeRange(
startDateTime: string,
endDateTime: string,
timeZone?: string,
): TextValue
Creates a datetime range value from two ISO 8601 datetime strings that start
with YYYY-MM-DDTHH:mm. If timeZone is provided, it is included as
time_zone. The builder does not validate that startDateTime is before
endDateTime.
Builder.dateTimeRange(
"2026-05-11T09:30:00Z",
"2026-05-11T10:30:00Z",
"America/Los_Angeles",
)
Returns a date mention token:
[
[
"\u2023",
[
[
"d",
{
type: "datetimerange",
start_date: "2026-05-11",
start_time: "09:30",
end_date: "2026-05-11",
end_time: "10:30",
time_zone: "America/Los_Angeles",
},
],
],
],
]
Builder.link()
Builder.link(displayText: string, url: string): TextValue
Creates a text value with a link annotation.
Builder.link("Issue", "https://example.com/issues/123")
Returns:
[["Issue", [["a", "https://example.com/issues/123"]]]]
Builder.select()
Builder.select(value: string): TextValue
Creates a select value from a single option name.
Returns:
Builder.multiSelect()
Builder.multiSelect(...values: string[]): TextValue
Creates a multi-select value from option names. Values are joined with commas. If no values are provided, returns an empty value.
Builder.multiSelect("Bug", "Customer")
Returns:
Builder.status()
Builder.status(value: string): TextValue
Creates a status value from a status option name.
Returns:
Builder.people()
Builder.people(...emails: string[]): PeopleValue
Creates a people value from email addresses.
Builder.people("a@example.com", "b@example.com")
Returns:
[{ email: "a@example.com" }, { email: "b@example.com" }]
Builder.place()
Builder.place(value: PlaceValue): PlaceValue
Creates a place value. The value must include numeric lat and lon; otherwise the function throws.
Builder.place({
lat: 37.776,
lon: -122.417,
name: "San Francisco",
address: "San Francisco, CA",
})
Returns the provided place value.
Builder.relation()
Builder.relation(primaryKey: string): RelationReference
Creates a relation reference from the primary key of a related record. Relation property values use arrays of relation references.
Single relation:
Project: [Builder.relation("project-123")]
Multiple relations:
Projects: [
Builder.relation("project-123"),
Builder.relation("project-456"),
]
Returns:
[
{ type: "primaryKey", value: "project-123" },
{ type: "primaryKey", value: "project-456" },
]
Builder.emojiIcon()
Builder.emojiIcon(emoji: string): Icon
Creates an emoji icon.
Returns:
{ type: "emoji", value: "✅" }
Builder.notionIcon()
Builder.notionIcon(
icon: NoticonName,
color: NoticonColor = "gray",
): Icon
Creates an icon using Notion’s native icon set. If color is omitted, it defaults to "gray".
Builder.notionIcon("checkmark", "green")
Returns:
{ type: "notion", icon: "checkmark", color: "green" }
Builder.imageIcon()
Builder.imageIcon(url: string): Icon
Creates an image icon from an external URL.
Builder.imageIcon("https://example.com/icon.png")
Returns:
{ type: "image", url: "https://example.com/icon.png" }