### Install Notion Workers CLI Source: https://developers.notion.com/workers/get-started/quickstart Install the command-line interface for Notion Workers. This is the first step to managing your workers. ```bash curl -fsSL https://ntn.dev | bash ``` -------------------------------- ### Initialize New Worker Project Source: https://developers.notion.com/workers/get-started/quickstart Scaffold a new worker project using the installed CLI. You will be prompted to choose a folder name for your project. ```bash ntn workers new ``` -------------------------------- ### Using the Notion API within a tool Source: https://developers.notion.com/workers/guides/tools Example of a tool that uses the `context.notion` object to interact with the Notion API. ```APIDOC ## worker.tool("getPageTitle", { ... }) ### Description Defines a tool named `getPageTitle` that reads the title of a Notion page using the provided `pageId`. ### Schema ```typescript schema: j.object({ pageId: j.string().describe("The Notion page ID.") }) ``` ### Hints ```typescript hints: { readOnlyHint: true } ``` ### Execute Function ```typescript execute: async ({ pageId }, { notion }) => { const page = await notion.pages.retrieve({ page_id: pageId }); return page; } ``` ``` -------------------------------- ### Deploy Worker to Notion Source: https://developers.notion.com/workers/get-started/quickstart Deploy your worker project to your Notion workspace. This command will guide you through the authentication process. ```bash ntn workers deploy ``` -------------------------------- ### Start OAuth Flow for GitHub Source: https://developers.notion.com/workers/guides/oauth Initiate the OAuth authorization flow for the 'githubAuth' capability using the `ntn` CLI. This will open a browser window for user authorization and securely store the resulting token. ```bash ntn workers oauth start githubAuth ``` -------------------------------- ### Defining a tool with structured output Source: https://developers.notion.com/workers/guides/tools Example of defining a tool that returns a structured JSON object. The `outputSchema` is used for validation. ```APIDOC ## worker.tool("lookupCustomer", { ... }) ### Description Defines a tool named `lookupCustomer` that searches for customer information based on an email. ### Execute Function ```typescript execute: async ({ email }) => { const customer = await findCustomerByEmail(email); if (!customer) { return { found: false }; } return { found: true, customer: { name: customer.name, plan: customer.plan, accountUrl: customer.accountUrl, }, }; } ``` ``` -------------------------------- ### Replace Sync Mode Example Source: https://developers.notion.com/workers/guides/syncs Configure a sync to use 'replace' mode, suitable for smaller datasets or APIs without change tracking. The execute function fetches pages of data and returns upserts. ```typescript worker.sync("teamsSync", { database: teams, mode: "replace", execute: async (state) => { const page = state?.page ?? 1; const { items, hasMore } = await fetchPage(page, 100); return { changes: items.map((item) => ({ type: "upsert" as const, key: item.id, properties: { Name: Builder.title(item.name), ID: Builder.richText(item.id), }, })), hasMore, nextState: hasMore ? { page: page + 1 } : undefined, }; }, }); ``` -------------------------------- ### Sync GitHub Issues using OAuth Token Source: https://developers.notion.com/workers/guides/oauth This example shows how to sync GitHub issues by acquiring an OAuth access token via `githubAuth.accessToken()`. The token is used to authenticate the fetch request for issues. ```typescript import * as Builder from "@notionhq/workers/builder"; worker.sync("githubIssuesSync", { database: issues, execute: async (state) => { const token = await githubAuth.accessToken(); const response = await fetch("https://api.github.com/issues", { headers: { Authorization: `Bearer ${token}` }, }); const items = await response.json(); return { changes: items.map((issue) => ({ type: "upsert" as const, key: String(issue.id), properties: { Title: Builder.title(issue.title), "Issue ID": Builder.richText(String(issue.id)), }, })), hasMore: false, }; }, }); ``` -------------------------------- ### Incremental Sync Mode Example Source: https://developers.notion.com/workers/guides/syncs Implement an 'incremental' sync mode for large datasets or APIs with change tracking. The execute function fetches changes (upserts and deletes) since the last run. ```typescript worker.sync("eventsSync", { database: events, mode: "incremental", execute: async (state) => { const { upserts, deletes, nextCursor } = await fetchChanges(state?.cursor); return { changes: [ ...upserts.map((item) => ({ type: "upsert" as const, key: item.id, properties: { Name: Builder.title(item.name), ID: Builder.richText(item.id), }, })), ...deletes.map((id) => ({ type: "delete" as const, key: id, })), ], hasMore: Boolean(nextCursor), nextState: nextCursor ? { cursor: nextCursor } : undefined, }; }, }); ``` -------------------------------- ### Defining a tool with output schema validation Source: https://developers.notion.com/workers/guides/tools Example of defining a tool with an `outputSchema` to validate the returned data structure. ```APIDOC ## worker.tool("searchTickets", { ... }) ### Description Defines a tool named `searchTickets` that searches for tickets based on a query and returns a structured list of results. ### Output Schema ```typescript outputSchema: j.object({ results: j.array( j.object({ id: j.string().describe("The ticket ID."), title: j.string().describe("The ticket title."), url: j.string().describe("A URL for the ticket.") }) ) }) ``` ### Execute Function ```typescript execute: async ({ query }) => { const tickets = await searchTickets(query); return { results: tickets.map(ticket => ({ id: ticket.id, title: ticket.title, url: ticket.url, })) }; } ``` ``` -------------------------------- ### Get GitHub Repositories using OAuth Token Source: https://developers.notion.com/workers/guides/oauth This snippet demonstrates how to fetch GitHub repositories by obtaining an OAuth access token from the `githubAuth` capability. The runtime automatically handles token refreshes. ```typescript import { j } from "@notionhq/workers/schema-builder"; worker.tool("getGitHubRepos", { title: "Get GitHub repos", description: "Fetch the user's GitHub repositories", schema: j.object({}), execute: async () => { const token = await githubAuth.accessToken(); const response = await fetch("https://api.github.com/user/repos", { headers: { Authorization: `Bearer ${token}` }, }); return response.json(); }, }); ``` -------------------------------- ### Trigger a Backfill Sync Source: https://developers.notion.com/workers/guides/syncs To initiate a backfill sync, first reset its state using the `ntn workers sync state reset` command, then trigger the sync to start running with `ntn workers sync trigger`. ```bash ntn workers sync state reset ticketsBackfill ntn workers sync trigger ticketsBackfill ``` -------------------------------- ### Get Sync State via CLI Source: https://developers.notion.com/workers/guides/syncs Command to retrieve and inspect the current state of a sync using its key. This is useful for diagnosing issues or understanding the sync's progress before deciding to reset its state. ```bash ntn workers sync state get ``` -------------------------------- ### Paginate large datasets in a sync Source: https://developers.notion.com/workers/guides/syncs Implement pagination by returning `hasMore: true` and a `nextState` in the `execute` function. The runtime will call `execute` again with the provided state until `hasMore: false` is returned. Start with batch sizes of around 100 records. ```typescript worker.sync("paginatedSync", { database: records, execute: async (state) => { const { items, nextCursor } = await fetchPage(state?.cursor); return { changes: items.map((item) => ({ type: "upsert" as const, key: item.id, properties: { Name: Builder.title(item.name), ID: Builder.richText(item.id), }, })), hasMore: Boolean(nextCursor), nextState: nextCursor ? { cursor: nextCursor } : undefined, }; }, }); ``` -------------------------------- ### Reset Sync State via CLI Source: https://developers.notion.com/workers/guides/syncs Command to reset the state of a specific sync using its key. This clears the stored `nextState`, forcing the sync to start from the beginning on its next run. ```bash ntn workers sync state reset ``` -------------------------------- ### Define Tool for Escalating Issues Source: https://developers.notion.com/workers/guides/tools Register a tool for creating support tickets. The description guides the agent on when to use this tool, specifying it should be used when a user asks to escalate an issue. ```typescript worker.tool("createSupportTicket", { title: "Create Support Ticket", description: "Create a support ticket when the user asks to escalate an issue to the support team.", // ... }); ``` -------------------------------- ### Execute Sample Tool Source: https://developers.notion.com/workers/get-started/quickstart Run the included sample tool 'sayHello' with provided input data. This demonstrates how to execute tools within your worker. ```bash ntn workers exec sayHello -d '{"name": "World"}' ``` -------------------------------- ### Deploy and List Webhooks via CLI Source: https://developers.notion.com/workers/guides/webhooks Use the Notion CLI to deploy your worker and list the generated webhook URLs. The --json and --plain flags provide output in different formats. ```bash ntn workers deploy ntn workers webhooks list ``` ```bash ntn workers webhooks list --json ``` ```bash ntn workers webhooks list --plain ``` -------------------------------- ### Marking a tool as read-only Source: https://developers.notion.com/workers/guides/tools Example of marking a tool with `readOnlyHint: true` to indicate it only reads data and has no side effects. ```APIDOC ## worker.tool("previewAccountDeletion", { ... }) ### Description Defines a tool named `previewAccountDeletion` that inspects what would be affected by an account deletion without making any changes. ### Hints ```typescript hints: { readOnlyHint: true } ``` ``` -------------------------------- ### Set a sync schedule Source: https://developers.notion.com/workers/guides/syncs Configure how often Notion triggers your sync using the `schedule` option. The minimum schedule is "5m" and the maximum is "7d". ```typescript worker.sync("frequentSync", { database: myDb, schedule: "5m", // ... }); ``` -------------------------------- ### .describe() Source: https://developers.notion.com/workers/reference/schema Sets the JSON Schema `description` field and returns a new builder. ```APIDOC schema.describe(text: string): SchemaBuilder j.string().describe("Email address for the assignee.") ``` -------------------------------- ### Builder.dateRange() Source: https://developers.notion.com/workers/reference/schema Creates a date range value from two 'YYYY-MM-DD' date strings. Does not validate if the start date is before the end date. ```APIDOC ## Builder.dateRange(startDate: string, endDate: string): TextValue ### Description 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`. ### Parameters #### Path Parameters - **startDate** (string) - Required - The start date string in 'YYYY-MM-DD' format. - **endDate** (string) - Required - The end date string in 'YYYY-MM-DD' format. ### Request Example ```typescript Builder.dateRange("2026-05-11", "2026-05-15") ``` ### Response #### Success Response (TextValue) - Returns a TextValue representing the date range, formatted as a date mention token. ### Response Example ```typescript [ [ "\u2023", [ [ "d", { type: "daterange", start_date: "2026-05-11", end_date: "2026-05-15", } ] ] ] ] ``` ``` -------------------------------- ### Create Date Schema Source: https://developers.notion.com/workers/reference/schema Use `j.date()` to create a string schema with `format: "date"`. Chain `.describe()` to add a description. ```typescript j.date().describe("Due date in YYYY-MM-DD format.") ``` -------------------------------- ### Get Worker Run Logs Source: https://developers.notion.com/workers/guides/webhooks Retrieves the logs for a specific worker run, identified by its run ID. Essential for debugging webhook handler errors. ```bash ntn workers runs logs ``` -------------------------------- ### Builder.dateTimeRange() Source: https://developers.notion.com/workers/reference/schema Creates a datetime range value from two ISO 8601 strings. Optionally includes a time zone. Does not validate if the start datetime is before the end datetime. ```APIDOC ## Builder.dateTimeRange( startDateTime: string, endDateTime: string, timeZone?: string, ): TextValue ### Description 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`. ### Parameters #### Path Parameters - **startDateTime** (string) - Required - The start ISO 8601 datetime string (e.g., 'YYYY-MM-DDTHH:mm:ssZ'). - **endDateTime** (string) - Required - The end ISO 8601 datetime string (e.g., 'YYYY-MM-DDTHH:mm:ssZ'). - **timeZone** (string) - Optional - The time zone for the datetime range. ### Request Example ```typescript Builder.dateTimeRange( "2026-05-11T09:30:00Z", "2026-05-11T10:30:00Z", "America/Los_Angeles", ) ``` ### Response #### Success Response (TextValue) - Returns a TextValue representing the datetime range, formatted as a date mention token with time zone information if provided. ### Response Example ```typescript [ [ "\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", } ] ] ] ] ``` ``` -------------------------------- ### Schema.select() Source: https://developers.notion.com/workers/reference/schema Creates a select property definition for a database with a predefined list of options. Each option can have a name and an optional color. ```APIDOC ## Schema.select() ### Description Creates a select property definition with predefined options. ### Method ```typescript Schema.select(options: SelectOption[]): PropertyConfiguration ``` ### Example ```typescript Status: Schema.select([ { name: "Open" }, { name: "Done", color: "green" }, ]) ``` ### Returns ```typescript { type: "select", options: [ { name: "Open" }, { name: "Done", color: "green" }, ] } ``` ``` -------------------------------- ### j.string() Source: https://developers.notion.com/workers/reference/schema Creates a string schema. ```APIDOC j.string(): SchemaBuilder j.string().describe("Search query.") ``` -------------------------------- ### Get Notion Worker Redirect URL Source: https://developers.notion.com/workers/guides/oauth Retrieve the redirect URL for your Notion worker using the `ntn` CLI. This URL is required when configuring your OAuth app with the third-party provider. ```bash ntn workers oauth show-redirect-url ``` -------------------------------- ### Test a Tool Locally with Custom .env File Source: https://developers.notion.com/workers/guides/tools Specify a custom dotenv file for local tool execution using the `--dotenv` flag. ```bash ntn workers exec lookupCustomer --local --dotenv .env.local -d '{"email":"ada@example.com"}' ``` -------------------------------- ### Run a Deployed Tool Source: https://developers.notion.com/workers/guides/tools Execute a deployed tool from the CLI using `ntn workers exec`. ```bash ntn workers exec lookupCustomer -d '{"email":"ada@example.com"}' ``` -------------------------------- ### Schedule hourly sync task Source: https://developers.notion.com/workers/reference/sdk Define a scheduled sync task named 'hourlySync' that runs every hour. The execute function is a placeholder that returns no changes, indicating a basic setup. ```typescript worker.sync("hourlySync", { database: tasks, schedule: "1h", execute: async () => ({ changes: [], hasMore: false, }), }); ``` -------------------------------- ### Create Email Schema Source: https://developers.notion.com/workers/reference/schema Use `j.email()` to create a string schema with `format: "email"`. Chain `.describe()` to add a description. ```typescript j.email().describe("Email address for the assignee.") ``` -------------------------------- ### Initialize Notion Worker Source: https://developers.notion.com/workers/guides/tools Import the Worker class and schema builder, then initialize a new Worker instance. This is the base for registering tools. ```typescript import { Worker } from "@notionhq/workers"; import { j } from "@notionhq/workers/schema-builder"; const worker = new Worker(); export default worker; ``` -------------------------------- ### Create Time Schema Source: https://developers.notion.com/workers/reference/schema Use `j.time()` to create a string schema with `format: "time"`. Chain `.describe()` to add a description. ```typescript j.time().describe("Start time.") ``` -------------------------------- ### Register a Tool with Input Schema Source: https://developers.notion.com/workers/guides/tools Register a tool named 'lookupCustomer' with a defined input schema for an email address. The 'execute' function handles the logic for finding a customer. ```typescript worker.tool("lookupCustomer", { title: "Lookup Customer", description: "Find a customer by email address.", schema: j.object({ email: j.email().describe("The customer's email address."), }), hints: { readOnlyHint: true }, execute: async ({ email }) => { const customer = await findCustomerByEmail(email); if (!customer) { return { found: false, message: `No customer found for ${email}.`, }; } return { found: true, name: customer.name, plan: customer.plan, accountUrl: customer.accountUrl, }; }, }); ``` -------------------------------- ### Use a secret in worker code for an API call Source: https://developers.notion.com/workers/guides/secrets This example demonstrates how to securely use an API key stored as a secret within a worker's tool definition. It includes error handling if the secret is not configured. ```typescript worker.tool("getWeather", { title: "Get Weather", description: "Fetch the current weather for a city", schema: { type: "object", properties: { city: { type: "string" }, }, required: ["city"], additionalProperties: false, }, execute: async ({ city }) => { const apiKey = process.env.OPENWEATHER_API_KEY; if (!apiKey) { throw new Error("OPENWEATHER_API_KEY is not configured"); } const response = await fetch( `https://api.openweathermap.org/data/2.5/weather?q=${encodeURIComponent( city, )}&appid=${apiKey}`, ); return response.json(); }, }); ``` -------------------------------- ### Manage Syncs via CLI Source: https://developers.notion.com/workers/guides/syncs Command-line interface commands for managing Workers syncs, including viewing status, triggering previews or immediate runs, resetting state, and enabling/disabling syncs. ```bash # Live-updating status dashboard ntn workers sync status # Preview output without writing to the database ntn workers sync trigger --preview # Trigger a real sync immediately ntn workers sync trigger # Reset sync state (restart from scratch) ntn workers sync state reset # Pause a sync ntn workers capabilities disable # Resume a sync ntn workers capabilities enable ``` -------------------------------- ### Test a Tool Locally Without .env File Source: https://developers.notion.com/workers/guides/tools Execute a tool locally without loading any `.env` file by using the `--no-dotenv` flag. ```bash ntn workers exec lookupCustomer --local --no-dotenv -d '{"email":"ada@example.com"}' ``` -------------------------------- ### Rate-Limit Outbound API Requests Source: https://developers.notion.com/workers/guides/syncs Implement a pacer to control the rate of outbound requests to an external API, ensuring compliance with rate limits. The `api.wait()` call pauses execution until a request slot is available, allowing a maximum of 10 requests per second in this example. ```typescript const api = worker.pacer("api", { allowedRequests: 10, intervalMs: 1000 }); worker.sync("customersSync", { database: customers, execute: async (state) => { await api.wait(); const data = await fetchCustomers(state?.cursor); // ... }, }); ``` -------------------------------- ### Test a Tool Locally with Default .env Source: https://developers.notion.com/workers/guides/tools Execute a tool locally using `ntn workers exec --local`. This command loads environment variables from the `.env` file by default. ```bash ntn workers exec lookupCustomer --local -d '{"email":"ada@example.com"}' ``` -------------------------------- ### Builder.notionIcon() Source: https://developers.notion.com/workers/reference/schema Creates an icon using Notion's native icon set. Optionally accepts a color, defaulting to 'gray'. ```APIDOC ## Builder.notionIcon() ### Description Creates an icon using Notion's native icon set. If `color` is omitted, it defaults to `"gray"`. ### Parameters #### Path Parameters - **icon** (NoticonName) - Required - The name of the Notion icon. - **color** (NoticonColor) - Optional - The color of the icon. Defaults to "gray". ### Request Example ```typescript Builder.notionIcon("checkmark", "green") ``` ### Response #### Success Response (Icon) - Returns an Icon object with type 'notion', the specified icon, and color. #### Response Example ```typescript { type: "notion", icon: "checkmark", color: "green" } ``` ``` -------------------------------- ### Configure Tool Hints Source: https://developers.notion.com/workers/reference/sdk Set tool hints to describe tool behavior. `readOnlyHint: true` marks a tool as safe for auto-execution. ```typescript hints: { readOnlyHint: true, } ``` -------------------------------- ### Initialize Worker Instance Source: https://developers.notion.com/workers/reference/sdk The Worker class is the entry point for every worker project. It exposes methods to add databases, pacers, and capabilities to the worker manifest. ```typescript import { Worker } from "@notionhq/workers"; const worker = new Worker(); export default worker; ``` -------------------------------- ### Create Datetime Schema Source: https://developers.notion.com/workers/reference/schema Use `j.datetime()` to create a string schema with `format: "date-time"`. Chain `.describe()` to add a description. ```typescript j.datetime().describe("ISO 8601 timestamp for the event.") ``` -------------------------------- ### Schema.file() Source: https://developers.notion.com/workers/reference/schema Creates a file property definition for a database. This property is used to attach files. ```APIDOC ## Schema.file() ### Description Creates a file property definition. ### Method ```typescript Schema.file(): PropertyConfiguration ``` ### Example ```typescript Attachment: Schema.file() ``` ### Returns ```typescript { type: "file" } ``` ``` -------------------------------- ### Builder.url() Source: https://developers.notion.com/workers/reference/schema Creates a URL value. ```APIDOC ## Builder.url() ### Description Creates a URL value. ### Parameters #### Path Parameters - **url** (string) - Required - The URL string. ### Request Example ```typescript Builder.url("https://example.com") ``` ### Response #### Success Response - **TextValue** (array) - A nested array representing the URL value, e.g., `[["https://example.com"]]`. ``` -------------------------------- ### Register Delta and Backfill Syncs Source: https://developers.notion.com/workers/guides/syncs Register both a delta sync for near-real-time updates and a backfill sync for full dataset sweeps against the same database. The delta sync uses 'incremental' mode with a '5m' schedule, while the backfill sync uses 'replace' mode with a 'manual' schedule. ```typescript worker.sync("ticketsDelta", { database: tickets, mode: "incremental", schedule: "5m", execute: async (state) => { await apiPacer.wait(); const { items, nextCursor } = await fetchTicketChanges(state?.cursor); return { changes: items.map((t) => ({ type: "upsert" as const, key: t.id, properties: { Summary: Builder.title(t.summary), "Ticket ID": Builder.richText(t.id), }, })), hasMore: Boolean(nextCursor), nextState: nextCursor ? { cursor: nextCursor } : undefined, }; }, }); // Backfill: full dataset sweep, run manually worker.sync("ticketsBackfill", { database: tickets, mode: "replace", schedule: "manual", execute: async (state) => { const page = state?.page ?? 1; await apiPacer.wait(); const { items, hasMore } = await fetchAllTickets(page); return { changes: items.map((t) => ({ type: "upsert" as const, key: t.id, properties: { Summary: Builder.title(t.summary), "Ticket ID": Builder.richText(t.id), }, })), hasMore, nextState: hasMore ? { page: page + 1 } : undefined, }; }, }); ``` -------------------------------- ### Create Notion Page from Webhook Event Source: https://developers.notion.com/workers/guides/webhooks Creates a new page in a Notion database when a webhook event is received. Requires the database ID and Notion API token to be configured as environment variables. ```typescript worker.webhook("createPageFromWebhook", { title: "Create Page From Webhook", description: "Creates a page when an external event is received", execute: async (events, { notion }) => { const databaseId = process.env.MY_WEBHOOK_DATABASE_ID; if (!databaseId) { throw new Error("MY_WEBHOOK_DATABASE_ID is not configured"); } for (const event of events) { const externalId = typeof event.body.id === "string" ? event.body.id : event.deliveryId; await notion.pages.create({ parent: { database_id: databaseId }, properties: { Name: { title: [ { text: { content: `Webhook event ${externalId}`, }, }, ], }, }, }); } }, }); ``` -------------------------------- ### Create File Property Source: https://developers.notion.com/workers/reference/schema Use `Schema.file()` to define a file property. ```typescript Schema.file(): PropertyConfiguration ``` ```typescript Attachment: Schema.file() ``` ```typescript { type: "file" } ``` -------------------------------- ### Builder.place() Source: https://developers.notion.com/workers/reference/schema Creates a place value. The value must include numeric lat and lon properties; otherwise, the function throws an error. ```APIDOC ## Builder.place() ### Description Creates a place value. The value must include numeric `lat` and `lon`; otherwise the function throws. ### Parameters #### Request Body - **value** (PlaceValue) - Required - The place value object, must contain `lat` and `lon`. - **lat** (number) - Required - Latitude coordinate. - **lon** (number) - Required - Longitude coordinate. - **name** (string) - Optional - The name of the place. - **address** (string) - Optional - The address of the place. ### Request Example ```typescript Builder.place({ lat: 37.776, lon: -122.417, name: "San Francisco", address: "San Francisco, CA", }) ``` ### Response #### Success Response (PlaceValue) - Returns the provided place value. #### Response Example ```typescript { lat: 37.776, lon: -122.417, name: "San Francisco", address: "San Francisco, CA", } ``` ``` -------------------------------- ### Initialize a Notion Worker Source: https://developers.notion.com/workers/get-started/overview This code initializes a new Worker instance and exports it. Capabilities like tools, syncs, and webhooks are then registered on this worker instance. ```typescript import { Worker } from "@notionhq/workers"; const worker = new Worker(); export default worker; // Register capabilities on the worker worker.tool("sayHello", { /* ... */ }); worker.sync("customersSync", { /* ... */ }); worker.webhook("onGithubPush", { /* ... */ }); ``` -------------------------------- ### Create Hostname Schema Source: https://developers.notion.com/workers/reference/schema Use `j.hostname()` to create a string schema with the format "hostname". ```typescript j.hostname(): SchemaBuilder ``` ```typescript j.hostname().describe("Host name to query.") ``` -------------------------------- ### j.hostname() Source: https://developers.notion.com/workers/reference/schema Creates a string schema with `format: "hostname"`. Use this to validate or define string values that represent hostnames. ```APIDOC ## j.hostname() ### Description Creates a string schema with `format: "hostname"`. ### Method ```typescript j.hostname(): SchemaBuilder ``` ### Example ```typescript j.hostname().describe("Host name to query.") ``` ``` -------------------------------- ### Create Duration Schema Source: https://developers.notion.com/workers/reference/schema Use `j.duration()` to create a string schema with `format: "duration"`. Chain `.describe()` to add a description. ```typescript j.duration().describe("Elapsed time as an ISO 8601 duration.") ``` -------------------------------- ### Builder.link() Source: https://developers.notion.com/workers/reference/schema Creates a text value with a link annotation, combining display text and a URL. ```APIDOC ## Builder.link(displayText: string, url: string): TextValue ### Description Creates a text value with a link annotation. ### Parameters #### Path Parameters - **displayText** (string) - Required - The text to display for the link. - **url** (string) - Required - The URL the link points to. ### Request Example ```typescript Builder.link("Issue", "https://example.com/issues/123") ``` ### Response #### Success Response (TextValue) - Returns a TextValue representing the link. ### Response Example ```typescript [["Issue", [["a", "https://example.com/issues/123"]]]] ``` ``` -------------------------------- ### Builder.email() Source: https://developers.notion.com/workers/reference/schema Creates an email value. ```APIDOC ## Builder.email() ### Description Creates an email value. ### Parameters #### Path Parameters - **email** (string) - Required - The email address string. ### Request Example ```typescript Builder.email("person@example.com") ``` ### Response #### Success Response - **TextValue** (array) - A nested array representing the email value, e.g., `[["person@example.com"]]`. ``` -------------------------------- ### worker.database() Source: https://developers.notion.com/workers/reference/sdk Declares a managed Notion database for sync output, specifying its schema and primary key. ```APIDOC ## worker.database() ### Description Declares a managed Notion database for sync output. ### Usage ```typescript 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" }]), }, }, }); ``` ### Parameters - `name` (string): The name of the database. - `options` (object): - `type` (string): Database declaration type. Currently only `"managed"` is supported. - `initialTitle` (string): Title used when Notion first creates the database. Changing this later does not rename an existing database. - `primaryKeyProperty` (string): Property used to match sync changes to Notion pages. Must be present in `schema.properties`. - `schema` (object): Database property schema. See [Schema and builders](/workers/reference/schema). ``` -------------------------------- ### Configure Google OAuth Source: https://developers.notion.com/workers/guides/oauth Set up Google OAuth for your worker, specifying authorization and token endpoints, scopes, client ID, and client secret. Includes authorization parameters for offline access and consent. ```typescript const googleAuth = worker.oauth("googleAuth", { name: "google-oauth", authorizationEndpoint: "https://accounts.google.com/o/oauth2/v2/auth", tokenEndpoint: "https://oauth2.googleapis.com/token", scope: "https://www.googleapis.com/auth/calendar.readonly", clientId: process.env.GOOGLE_CLIENT_ID ?? "", clientSecret: process.env.GOOGLE_CLIENT_SECRET ?? "", authorizationParams: { access_type: "offline", prompt: "consent", }, }); ``` -------------------------------- ### Builder.file() Source: https://developers.notion.com/workers/reference/schema Creates a file URL value. If fileName is omitted, the URL is used as the display text. ```APIDOC ## Builder.file(fileUrl: string, fileName?: string): TextValue ### Description Creates a file URL value. If `fileName` is omitted, the URL is also used as the display text. ### Parameters #### Path Parameters - **fileUrl** (string) - Required - The URL of the file. - **fileName** (string) - Optional - The display name for the file. ### Request Example ```typescript Builder.file("https://example.com/invoice.pdf", "Invoice") ``` ### Response #### Success Response (TextValue) - Returns a TextValue representing the file, including its display name and URL. ### Response Example ```typescript [["Invoice", [["a", "https://example.com/invoice.pdf"]]]] ``` ``` -------------------------------- ### Builder.text() Source: https://developers.notion.com/workers/reference/schema Creates a text value. ```APIDOC ## Builder.text() ### Description Creates a text value. ### Parameters #### Path Parameters - **content** (string) - Required - The text content. ### Request Example ```typescript Builder.text("Imported from upstream.") ``` ### Response #### Success Response - **TextValue** (array) - A nested array representing the text value, e.g., `[["Imported from upstream."]]`. ``` -------------------------------- ### Schema.date() Source: https://developers.notion.com/workers/reference/schema Creates a date property definition for a database. An optional `dateFormat` can be provided to specify the date format. ```APIDOC ## Schema.date() ### Description Creates a date property definition. If `dateFormat` is provided, it is emitted as `date_format`. ### Method ```typescript Schema.date(dateFormat?: DateFormat): PropertyConfiguration ``` ### Example ```typescript Due: Schema.date("YYYY/MM/DD") ``` ### Returns ```typescript { type: "date", date_format: "YYYY/MM/DD" } ``` ``` -------------------------------- ### Builder.imageIcon() Source: https://developers.notion.com/workers/reference/schema Creates an image icon from an external URL. Accepts a URL string. ```APIDOC ## Builder.imageIcon() ### Description Creates an image icon from an external URL. ### Parameters #### Path Parameters - **url** (string) - Required - The URL of the image. ### Request Example ```typescript Builder.imageIcon("https://example.com/icon.png") ``` ### Response #### Success Response (Icon) - Returns an Icon object with type 'image' and the specified URL. #### Response Example ```typescript { type: "image", url: "https://example.com/icon.png" } ``` ``` -------------------------------- ### Builder.select() Source: https://developers.notion.com/workers/reference/schema Creates a select value from a single option name. ```APIDOC ## Builder.select(value: string): TextValue ### Description Creates a select value from a single option name. ### Parameters #### Path Parameters - **value** (string) - Required - The name of the select option. ### Request Example ```typescript Builder.select("Open") ``` ### Response #### Success Response (TextValue) - Returns a TextValue representing the selected option. ### Response Example ```typescript [["Open"]] ``` ``` -------------------------------- ### Schema.place() Source: https://developers.notion.com/workers/reference/schema Creates a place property definition for geographic locations. ```APIDOC ## Schema.place() ### Description Creates a place property definition for geographic locations. ### Parameters This function does not accept any parameters. ### Request Example ```typescript Schema.place() ``` ### Response #### Success Response - **type** (string) - The type of the property, always "place". ``` -------------------------------- ### j.time() Source: https://developers.notion.com/workers/reference/schema Creates a string schema with `format: "time"`. ```APIDOC j.time(): SchemaBuilder j.time().describe("Start time.") ``` -------------------------------- ### Worker Methods Source: https://developers.notion.com/workers/reference/sdk The Worker class is the entry point for worker projects, exposing methods to add databases, pacers, and capabilities to the worker manifest. ```APIDOC ## Worker Methods ### Description The `Worker` class is the entry point for every worker project. The class exposes methods that add databases, pacers, and capabilities to the worker manifest. ### Methods - `worker.database()`: Declares a managed Notion database for sync output. - `worker.pacer()`: Declares a rate limit budget for calls to an external API. - `worker.sync()`: Syncs upstream records into a managed Notion database. - `worker.tool()`: Defines a callable tool with JSON Schema input and output. - `worker.webhook()`: Defines an HTTP webhook handler. - `worker.oauth()`: Defines OAuth configuration for external service authentication. ``` -------------------------------- ### Create a Notion page Source: https://developers.notion.com/workers/guides/api-client Create a new Notion page within a specified parent (e.g., a database) using `notion.pages.create`. Define the page's properties, such as 'Name' and 'Status'. ```typescript await notion.pages.create({ parent: { database_id: "..." }, properties: { Name: { title: [{ text: { content: "New item" } }], }, Status: { select: { name: "Open" }, }, }, }); ``` -------------------------------- ### j.date() Source: https://developers.notion.com/workers/reference/schema Creates a string schema with `format: "date"`. ```APIDOC j.date(): SchemaBuilder j.date().describe("Due date in YYYY-MM-DD format.") ``` -------------------------------- ### Builder.title() Source: https://developers.notion.com/workers/reference/schema Creates a title value. ```APIDOC ## Builder.title() ### Description Creates a title value. ### Parameters #### Path Parameters - **content** (string) - Required - The text content for the title value. ### Request Example ```typescript Builder.title("Write docs") ``` ### Response #### Success Response - **TextValue** (array) - A nested array representing the title value, e.g., `[["Write docs"]]`. ``` -------------------------------- ### Schema.multiSelect() Source: https://developers.notion.com/workers/reference/schema Creates a multi-select property definition with predefined options. ```APIDOC ## Schema.multiSelect() ### Description Creates a multi-select property definition with predefined options. ### Parameters #### Path Parameters - **options** (SelectOption[]) - Required - An array of objects, where each object defines a selectable option with a `name` and `color`. ### Request Example ```typescript Schema.multiSelect([ { name: "Bug", color: "red" }, { name: "Feature", color: "blue" }, ]) ``` ### Response #### Success Response - **type** (string) - The type of the property, always "multi_select". - **options** (SelectOption[]) - The array of predefined options for the multi-select property. ``` -------------------------------- ### Return Structured Output from a Tool Source: https://developers.notion.com/workers/guides/tools Define a tool that returns a structured JSON object. This is useful when the agent needs to inspect or reuse the results. ```typescript worker.tool("lookupCustomer", { // ... execute: async ({ email }) => { const customer = await findCustomerByEmail(email); if (!customer) { return { found: false }; } return { found: true, customer: { name: customer.name, plan: customer.plan, accountUrl: customer.accountUrl, }, }; }, }); ``` -------------------------------- ### j.anyOf() Source: https://developers.notion.com/workers/reference/schema Creates an `anyOf` schema from a variadic list of schema builders. This allows a value to match any of the provided schemas. ```APIDOC ## j.anyOf() ### Description Creates an `anyOf` schema from the provided schema builders. ### Method ```typescript j.anyOf[]>(...schemas: S): SchemaBuilder> ``` ### Example ```typescript j.anyOf(j.string(), j.number()).describe("String or numeric identifier.") ``` ``` -------------------------------- ### Create IPv6 Schema Source: https://developers.notion.com/workers/reference/schema Use `j.ipv6()` to create a string schema with the format "ipv6". ```typescript j.ipv6(): SchemaBuilder ``` ```typescript j.ipv6().describe("IPv6 address to allow.") ``` -------------------------------- ### Create Integer Schema Source: https://developers.notion.com/workers/reference/schema Use `j.integer()` to define a JSON schema for an integer. Chain `.describe()` to add a description. ```typescript j.integer().describe("Whole number of retries.") ``` -------------------------------- ### Create IPv4 Schema Source: https://developers.notion.com/workers/reference/schema Use `j.ipv4()` to create a string schema with the format "ipv4". ```typescript j.ipv4(): SchemaBuilder ``` ```typescript j.ipv4().describe("IPv4 address to allow.") ``` -------------------------------- ### Builder.multiSelect() Source: https://developers.notion.com/workers/reference/schema Creates a multi-select value from multiple option names, joined by commas. Returns an empty value if no options are provided. ```APIDOC ## Builder.multiSelect(...values: string[]): TextValue ### Description Creates a multi-select value from option names. Values are joined with commas. If no values are provided, returns an empty value. ### Parameters #### Path Parameters - **values** (string[]) - Required - An array of strings representing the selected options. ### Request Example ```typescript Builder.multiSelect("Bug", "Customer") ``` ### Response #### Success Response (TextValue) - Returns a TextValue representing the selected options, joined by commas. ### Response Example ```typescript [["Bug,Customer"]] ``` ``` -------------------------------- ### Define and Sync Related Databases Source: https://developers.notion.com/workers/guides/syncs Set up two managed databases, 'projects' and 'tasks', with a relation between them. The 'tasks' database includes a relation property to 'projects', configured for two-way linking. Syncs are defined for both databases to manage data flow. ```typescript 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", }), }, }, }); worker.sync("projectsSync", { database: projects, execute: async () => { /* ... */ }, }); worker.sync("tasksSync", { database: tasks, execute: async () => { const items = await fetchTasks(); return { changes: items.map((task) => ({ type: "upsert" as const, key: task.id, properties: { Name: Builder.title(task.name), "Task ID": Builder.richText(task.id), Project: [Builder.relation(task.projectId)], }, })), hasMore: false, }; }, }); ``` -------------------------------- ### Builder.dateTime() Source: https://developers.notion.com/workers/reference/schema Creates a datetime value from an ISO 8601 string. Optionally includes a time zone. ```APIDOC ## Builder.dateTime(isoString: string, timeZone?: string): TextValue ### Description 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`. ### Parameters #### Path Parameters - **isoString** (string) - Required - The ISO 8601 datetime string (e.g., 'YYYY-MM-DDTHH:mm:ssZ'). - **timeZone** (string) - Optional - The time zone for the datetime value. ### Request Example ```typescript Builder.dateTime("2026-05-11T09:30:00Z", "America/Los_Angeles") ``` ### Response #### Success Response (TextValue) - Returns a TextValue representing the datetime, formatted as a date mention token with time zone information if provided. ### Response Example ```typescript [ [ "\u2023", [ [ "d", { type: "datetime", start_date: "2026-05-11", start_time: "09:30", time_zone: "America/Los_Angeles", } ] ] ] ] ``` ``` -------------------------------- ### Register a sync capability with worker.sync() Source: https://developers.notion.com/workers/reference/sdk Register a sync capability using `worker.sync()` to write changes into a database. The `execute` function fetches upstream data and returns sync changes, receiving the previous state as its first argument. Ensure to call `issueTrackerApi.wait()` before fetching data if a pacer is configured. ```typescript worker.sync("tasksSync", { database: tasks, schedule: "30m", execute: async (state) => { const page = state?.page ?? 1; await issueTrackerApi.wait(); const { items, hasMore } = await fetchTasks(page); return { changes: items.map((item) => ({ type: "upsert", key: item.id, properties: { Name: Builder.title(item.name), "Task ID": Builder.richText(item.id), Status: Builder.select(item.status), }, })), hasMore, nextState: hasMore ? { page: page + 1 } : undefined, }; }, }); ``` -------------------------------- ### Define a Managed Database for Syncs Source: https://developers.notion.com/workers/guides/syncs Declare a database with a 'managed' type, initial title, primary key property, and schema. This database will be created and managed by Notion for your sync. ```typescript import { Worker } from "@notionhq/workers"; import * as Builder from "@notionhq/workers/builder"; import * as Schema from "@notionhq/workers/schema"; const worker = new Worker(); export default worker; const issues = worker.database("issues", { // only "managed" type is supported for now type: "managed", // the initial title of the database initialTitle: "Issues", // the property that uniquely identifies each row primaryKeyProperty: "Issue ID", // the schema defines the structure of the database schema: { // define each database property and its type properties: { Name: Schema.title(), "Issue ID": Schema.richText(), Status: Schema.richText(), }, }, }); worker.sync("issuesSync", { // ... }); ``` -------------------------------- ### Create Image Icon with Builder.imageIcon() Source: https://developers.notion.com/workers/reference/schema Use Builder.imageIcon() to create an icon from an external image URL. Provide the URL as a string argument. ```typescript Builder.imageIcon("https://example.com/icon.png") ``` -------------------------------- ### Create a file URL value Source: https://developers.notion.com/workers/reference/schema Use Builder.file() to create a file URL value. If `fileName` is omitted, the URL is used as the display text. ```typescript Builder.file("https://example.com/invoice.pdf", "Invoice") ``` -------------------------------- ### j.ref() Source: https://developers.notion.com/workers/reference/schema Creates a reference schema that points to another schema definition using a JSON pointer path. ```APIDOC ## j.ref() ### Description Creates a reference schema with `$ref` set to `path`. ### Method ```typescript j.ref(path: string): SchemaBuilder ``` ### Example ```typescript j.ref("#/$defs/user") ``` ``` -------------------------------- ### View Sync Execution Logs Source: https://developers.notion.com/workers/guides/syncs View execution logs for a specific sync run by providing the run ID. This is useful for debugging. ```bash ntn workers runs logs ```