+250 skills, dinamita para tu productividad 🧨Explorar →

Notion as Code, tu workspace en TypeScript

Imagina que pudieras describir tu workspace de Notion entero en un archivo de TypeScript. Los teamspaces, las páginas, la jerarquía, el contenido. Y que, al desplegarlo, Notion se encargara de dejar tu workspace tal y como lo describiste.

Eso es Notion as Code.

No va de escribir código dentro de Notion. Va de tratar tu workspace igual que tratas tu infraestructura: lo describes en código, lo despliegas y, cuando algo cambia, editas el código y vuelves a desplegar. Notion reconcilia la diferencia por ti. Si te suena a Terraform o Pulumi, vas bien encaminado.

Es un producto en fase alpha, todavía con aristas y cambios rompedores por delante, pero el concepto es tan potente que merece que lo entiendas ya.

Lo que cubre este artículo:

  • Qué es Notion as Code y por qué es declarativo, no imperativo
  • Cómo funcionan los resource IDs y por qué son la clave de todo
  • Un script real de ejemplo, línea a línea
  • Las tres formas de usarlo: SDK, API directa y agentes de código
  • El flujo asíncrono de la API (/v1/infra_as_code y el polling de tareas)
  • Los límites actuales de la alpha que debes conocer antes de tocarlo

🚧 Antes de nada: Notion recomienda probar esto en un workspace nuevo, no en el principal. Está en desarrollo y puede haber cambios que rompan tu configuración. Y necesitas que te acepten en la alpha rellenando su formulario de acceso.

¿Qué es Notion as Code?

Notion as Code te permite construir y actualizar Notion de forma programática y en bloque. En lugar de lanzar peticiones individuales a la API pública para cada cambio, describes el estado final que quieres y Notion se encarga de actualizar tu workspace para que coincida.

Léelo otra vez, porque ahí está toda la miga: describes el estado final. No das instrucciones paso a paso (“crea esta página, luego esta otra, luego muévela aquí”). Declaras cómo quieres que quede el resultado y el sistema calcula qué tiene que hacer para llegar ahí.

Son dos piezas:

  • Un SDK de TypeScript para que tú (o tu agente de código) describáis qué queréis en el workspace.
  • Un endpoint de API pública para desplegar esa descripción a tu workspace.

Esta distinción entre declarativo e imperativo es la misma que separa a Terraform de un script de bash lleno de comandos. Y es exactamente lo que hace que Notion as Code sea interesante: no gestionas el “cómo”, solo el “qué”.

Enfoque Qué escribes Quién decide los pasos
API pública clásica Una petición por cada cambio Tú, a mano, en orden
Notion as Code El estado final que deseas Notion reconcilia por ti
Curso gratis · paso a paso

Describir lo que quieres antes de tocar código: eso es SDD

La misma idea que Notion as Code aplicada a tu agente: en este curso montas un ciclo completo de Spec Driven Development con OpenSpec sobre un proyecto real, describes, aplicas y archivas, antes de coger tú el volante.

Entra en el curso gratis →

¿Qué son los resource IDs y por qué son la clave?

Aquí está el truco que hace que todo el sistema funcione. Fíjate en este script de ejemplo, sacado de la documentación oficial:

function createProjectHubSimple() {
  // Definimos un teamspace
  const teamspace = notion.teamspace({
    resourceId: "main-ts",
    parent: { type: "resourceId", resourceId: "my-space" },
    name: "Main",
    accessLevel: "default",
  })

  // Añadimos una pagina de primer nivel con contenido en Markdown
  const hub = teamspace.addPage({
    resourceId: "hub-page",
    icon: { type: "emoji", emoji: "🗂️" },
    properties: { title: notion.text("Project Hub") },
    content: [
      "# Team",
      "",
      '<page url="{{getting-started}}">Getting Started</page>',
      "",
      "# Policies",
    ].join("\n"),
  })

  // Añadimos una pagina anidada dentro de la anterior
  notion.page({
    resourceId: "getting-started",
    parent: { type: "resourceId", resourceId: hub.resourceId },
    icon: { type: "emoji", emoji: "📘" },
    properties: { title: notion.text("Getting Started") },
    content: [
      "# Welcome",
      "This is the Getting Started page for the project.",
      "- Sign in",
      "- Read the onboarding docs",
    ].join("\n"),
  })
}

¿Notas algo raro? No hay IDs de Notion por ningún lado. En su lugar, cada recurso tiene un resourceId: un identificador único que tú te inventas (main-ts, hub-page, getting-started).

Esto es fundamental. Cuando escribes el script, esas páginas todavía no existen, así que no puedes referenciarlas por su ID real. Usas tus propios identificadores lógicos y dejas que Notion resuelva las relaciones entre ellos (mira cómo getting-started referencia a hub.resourceId como su padre).

Después del primer despliegue, Notion te devuelve el mapeo entre tus resource IDs y los registros reales que ha creado:

{
  "my-space": { "id": "123", "table": "space" },
  "hub-page": { "id": "456", "table": "block" },
  "getting-started": { "id": "789", "table": "block" }
}

Ese mapeo se guarda en un fichero de estado de sesión (con la fecha en el nombre, tipo 2026-07-13...). Es la pieza que le pasas al script en la siguiente ejecución: con él en la mano, puedes editar tu script y volver a desplegar para modificar los registros reales en Notion en lugar de crear otros nuevos. Y repetir el ciclo tantas veces como quieras. Editas, despliegas, editas, despliegas.

🔑 El punto clave: los resource IDs desacoplan tu script del workspace concreto. Tú describes la estructura; Notion gestiona los IDs reales, y el fichero de estado de sesión hace de puente entre ambos.

Notion as Code es otra señal de hacia dónde va nuestro trabajo: describir en código lo que antes hacíamos a mano. Cada domingo, +6.700 developers compartimos lo que vamos aprendiendo de esta ola de IA. Gratis, desde 2018.

Suscríbete gratis →

¿Puedo reutilizar el mismo script en varios workspaces?

Sí, y esta es una de las ventajas que menos se ven a primera vista. Como el script no está acoplado a un workspace concreto, puedes tener varios mapeos de resource IDs a registros reales.

¿Qué significa en la práctica? Que el mismo script te sirve para desplegar en muchos workspaces distintos. Escribes una vez la plantilla de “proyecto nuevo” y la aplicas a cliente A, cliente B y cliente C, cada uno con su propio mapeo.

Y como al final es código, tienes a tu disposición todo lo que el código te da: variables y bucles para reutilizar patrones comunes. ¿Necesitas montar 10 equipos con la misma estructura y solo cambiar algunos nombres? Un bucle y listo:

const equipos = ["Diseño", "Backend", "Producto", "Marketing"]

// Generamos un teamspace identico para cada equipo cambiando solo el nombre
for (const nombre of equipos) {
  notion.teamspace({
    resourceId: `ts-${nombre.toLowerCase()}`,
    parent: { type: "resourceId", resourceId: "my-space" },
    name: nombre,
    accessLevel: "default",
  })
}

Esto es, exactamente, lo que hace potente a la filosofía “as Code” en cualquier ámbito: dejas de repetir configuración a mano y la generas con lógica. Lo mismo que llevas años haciendo con tu infraestructura, ahora con tu documentación y tus espacios de trabajo.

Construye agentes con criterio

Del agente que escribe tu Notion al que orquestas tú

Aquí dejas que un agente escriba los scripts; en esta masterclass montas agentes de IA con arquitectura de verdad, seis niveles que van de un LLM con tools a un sistema multiagéntico, para que no se te descontrolen en producción.

Ver la masterclass →

Masterclass en directo · 6 niveles de arquitectura · Acceso con Web Reactiva Premium

¿Cómo empiezo a usar Notion as Code?

Hay tres caminos, según cuánto quieras ensuciarte las manos. Vamos del más cómodo al más crudo.

Camino 1: el SDK de JavaScript (recomendado)

Para la alpha, este es el camino más suave, porque el SDK te esconde buena parte de la complejidad. Son tres pasos:

  1. Clona el repo notion-sdk-js.
  2. Cámbiate a la rama EXPERIMENTAL__notion-as-code.
  3. Abre el README de esa rama (tú o tu agente de código) y arranca desde ahí.
# Clona el SDK oficial de Notion
git clone https://github.com/makenotion/notion-sdk-js.git
cd notion-sdk-js

# Cambia a la rama experimental de Notion as Code
git checkout EXPERIMENTAL__notion-as-code

El README de esa rama es tu punto de entrada. Ten en cuenta que, al ser una rama experimental, la documentación vive ahí y no en la web principal de Notion.

Camino 2: los agentes de código

Aquí es donde esto se pone interesante de verdad. Como Notion as Code no es más que TypeScript describiendo una estructura, un agente de código puede escribir esos scripts por ti en lenguaje natural. Es, de hecho, el uso que Notion enseña en su propia demo. Te cuento el flujo tal cual, porque es más simple de lo que parece.

1. Le pides el workspace a tu agente. Abres tu agente favorito (en la demo usan OpenCode, pero sirve cualquiera) y le sueltas algo tan vago como esto:

“Usa Notion as Code para montarme un workspace para gestionar mi tienda de caramelos. Crea un teamspace por departamento y haz que quede bonito, con muchos iconos. Mi space ID es b96f072e-…”.

Fíjate en dos detalles: le das poquísima dirección (y aun así te construye playbooks, un registro diario de turnos como base de datos, un recetario…) y le pasas tu space ID para que sepa dónde desplegar y pueda decirte cómo ejecutar el script cuando termine.

💡 ¿De dónde sacas el space ID? En tu workspace, entra en Ajustes y lo tienes abajo del todo como workspace ID, listo para copiar.

2. Ejecutas lo que te dice. El agente escribe el script y te da un par de comandos. Tras exportar tu token, compilas y lanzas:

# Exporta tu token de Notion (una sola vez)
export NOTION_API_TOKEN="secret_tu_token"

# Compila el script que ha escrito el agente...
npm run build
# ...y ejecuta el comando que te indica el propio agente

Vuelves a Notion y ahí está todo: teamspaces por departamento, páginas y bases de datos, poblados a partir de cuatro frases.

3. Iteras sin miedo. ¿No te convence algo? Se lo dices al agente y le pasas el fichero de estado de sesión de la ejecución anterior. Por ejemplo: “los iconos de las páginas de primer nivel deberían ir del color del icono del equipo; actualiza el script y dime cómo re-ejecutar”. El agente edita el script y tú vuelves a lanzar el mismo npm run build y el mismo comando. Como esta vez va con el estado de sesión, actualiza los registros en lugar de crear otros nuevos.

Puede que se deje algo (en la demo actualizó las páginas pero no las bases de datos a la primera). No pasa nada: se lo señalas y re-ejecutas el mismo comando. Ese es todo el bucle.

Y el resultado final es lo que engancha: un script determinista, versionable en git, que levanta tu workspace entero —teams, bases de datos y páginas— y que puedes guardar junto a su fichero de estado por cada workspace. ¿Gestionas varios clientes con la misma estructura? Un script, varios ficheros de estado.

Es el mismo patrón de trabajo que vimos al hablar de cómo diseñar un workflow de desarrollo con IA: el humano decide el qué, el agente produce el cómo, y el sistema declarativo garantiza que el resultado sea reproducible. Y si trabajas con agentes que se apoyan en conocimiento experto empaquetado, esto te sonará al enfoque de las WordPress Agent Skills: darle a la IA las herramientas y el contexto adecuados para que genere código correcto en lugar de inventárselo.

Camino 3: la API pública directa

Si no quieres pasar por el SDK, puedes hablar directamente con el endpoint. Es más trabajo, pero tienes control total. Vamos con ello, que tiene su enjundia.

¿Cómo funciona la API de Notion as Code por dentro?

El nuevo endpoint /v1/infra_as_code estará disponible una vez te acepten en la alpha. Se comporta parecido al resto de endpoints de la API pública, pero con dos diferencias importantes que debes tener claras.

Primera diferencia: usa personal access tokens. A diferencia de la API pública clásica, que usa tokens de bot de integración, Notion as Code requiere personal access tokens. No los mezcles.

Segunda diferencia: es una API asíncrona. No obtienes el resultado en la misma llamada. El flujo tiene dos tiempos:

  1. Haces un POST /v1/infra_as_code que te devuelve un taskId.
  2. Consultas GET /v1/async_tasks/{taskId} en bucle hasta que la tarea termine.

Así se ve el patrón, simplificado:

// 1. Enviamos la descripcion del workspace y recibimos un taskId
const res = await fetch("https://api.notion.com/v1/infra_as_code", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${PERSONAL_ACCESS_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ intents }), // la version serializada de tu script
})
const { id: taskId } = await res.json()

// 2. Consultamos el estado hasta que termine
let task
do {
  await esperar(2000) // pequena pausa entre consultas
  const poll = await fetch(`https://api.notion.com/v1/async_tasks/${taskId}`, {
    headers: { Authorization: `Bearer ${PERSONAL_ACCESS_TOKEN}` },
  })
  task = await poll.json()
} while (task.status === "running")

El POST acepta tres campos que conviene conocer:

Campo Tipo Para qué sirve
intents Array<Intent> La representación serializada de tu script
existingResources Record<string, RecordPointer> Registros de ejecuciones previas: si los pasas, se actualizan en vez de crearse nuevos
existingProperties Record<string, string> Igual que el anterior, pero para propiedades

Esos existingResources y existingProperties son la mecánica de la reconciliación. Es como le dices al sistema “estos registros ya existen, no me los dupliques, actualízalos”. Son justo los mapeos que te devolvió el despliegue anterior.

Y cuando consultas la tarea, la respuesta te trae el estado (running, succeeded o failed) junto con los conteos de registros creados y los nuevos mapeos de resource IDs a registros reales. Ese es el output que guardas para el siguiente despliegue.

💡 Si vas por la API directa, lo más pesado es serializar tu script a intents a mano. Por eso Notion recomienda el SDK: te construye esa representación por ti. A menos que tengas una razón de peso, usa el SDK.

¿Qué límites tiene la alpha ahora mismo?

Toca la parte honesta, porque esto está en pañales y conviene que sepas dónde están las paredes antes de darte contra ellas:

  • Solo crea o actualiza dentro de un espacio existente. Todavía no puedes crear un espacio nuevo con esta herramienta.
  • No todas las entidades de Notion están soportadas. Los primitivos de alto nivel (páginas, teamspaces…) funcionan, pero hay cosas que aún no. El archivo de definición de tipos del SDK es la fuente de la verdad sobre qué está disponible.
  • El rate limit es bajo: 5 peticiones por minuto. A diferencia de otros endpoints, aquí una sola petición puede crear o actualizar muchas entidades, así que Notion ha bajado el límite de momento.

Ninguno de estos límites es definitivo. Es una alpha y la lista de primitivos soportados va a crecer. Pero si montas algo hoy contando con crear espacios desde cero o con lanzar cientos de peticiones por minuto, te vas a estrellar.

Meterse en un alpha antes que nadie tiene su gracia, pero cuesta seguirle el ritmo a todo. En la newsletter seleccionamos 12 recursos cada semana sobre herramientas y adopción de IA para que no se te escape lo importante. Ya somos +6.700.

Quiero esa dinamita 🧨

¿Merece la pena meterse ahora?

Voy a mojarme.

Si buscas una herramienta estable para producción, espera. Es alpha, hay cambios rompedores anunciados y ni siquiera puedes tocarla hasta que te acepten. No montes nada crítico sobre esto todavía.

Pero si te dedicas a gestionar workspaces de Notion a escala —agencias, consultoras, equipos que clonan la misma estructura una y otra vez— este es el tipo de tecnología que cambia cómo trabajas. Pasar de clicar durante horas a describir una plantilla y desplegarla en múltiples workspaces es un salto que ya vimos en el mundo de la infraestructura, y sabemos cómo acaba: nadie que lo prueba quiere volver atrás.

Y hay una segunda razón, más de fondo, para prestarle atención. Un workspace descrito en código es un workspace que un agente de IA puede construir. Notion no ha diseñado esto de forma declarativa por casualidad: lo ha hecho porque el futuro de la gestión de estas herramientas pasa por que se lo pidas a una IA en lenguaje natural y ella genere el código. Reducir la fricción en tareas repetitivas es, como comentamos al hablar de qué es la Developer Experience, una de las mejores inversiones que puedes hacer.

Mi consejo: crea un workspace de pruebas, apúntate a la alpha y dedícale una tarde a montar una plantilla sencilla. No para usarlo en serio hoy, sino para entender un patrón que vas a ver cada vez más.

TL;DR

  • 🚀 Notion as Code es un SDK de TypeScript + una API declarativa para construir y actualizar tu workspace en bloque, describiendo el estado final.
  • 🧩 Usas resource IDs (identificadores que tú inventas) en vez de IDs reales; tras el primer deploy recibes el mapeo a los registros de Notion.
  • ↺ Editas el script y vuelves a desplegar para actualizar los mismos registros. Es idempotente y reutilizable entre workspaces con bucles y variables.
  • 🔌 La API (POST /v1/infra_as_code) es asíncrona: devuelve un taskId que consultas en GET /v1/async_tasks/{taskId}. Requiere personal access tokens.
  • 🚧 Está en alpha: solo dentro de espacios existentes, no todas las entidades soportadas y límite de 5 peticiones por minuto.

Preguntas frecuentes

¿Qué es Notion as Code?

Es una forma de construir y actualizar tu workspace de Notion de manera programática y en bloque. En vez de lanzar peticiones individuales a la API para cada cambio, describes el estado final que quieres en un script de TypeScript y Notion actualiza tu workspace para que coincida.

¿En qué se diferencia de escribir código dentro de Notion?

En todo. Escribir código dentro de Notion es pegar snippets en bloques para que se vean con formato. Notion as Code es lo contrario: describes la estructura de tu workspace desde fuera, en código, y la despliegas mediante un SDK o la API pública.

¿Es declarativo o imperativo?

Es declarativo. No indicas los pasos uno a uno, sino el resultado final que deseas, y Notion calcula qué operaciones hacen falta para llegar ahí. Es la misma filosofía que herramientas de Infrastructure as Code como Terraform o Pulumi.

¿Qué son los resource IDs en Notion as Code?

Son identificadores únicos que tú te inventas para cada recurso de tu script (una página, un teamspace). Como los registros aún no existen cuando escribes el código, usas estos IDs lógicos. Tras el primer despliegue, Notion te devuelve el mapeo entre tus resource IDs y los registros reales que ha creado.

¿Puedo actualizar un workspace ya creado con el mismo script?

Sí. Guardas el mapeo de resource IDs que te devolvió el despliegue anterior y lo pasas de nuevo (en los campos existingResources y existingProperties). Así Notion actualiza los mismos registros en lugar de crear duplicados. Editas el script, vuelves a desplegar y repites.

¿Cómo empiezo a usar Notion as Code?

El camino más suave es el SDK de JavaScript: clona el repo notion-sdk-js, cámbiate a la rama EXPERIMENTAL__notion-as-code y sigue el README de esa rama. También puedes usar la API pública directamente o dejar que un agente de código escriba los scripts por ti.

¿Qué token necesito para la API?

Necesitas un personal access token. A diferencia de la API pública clásica de Notion, que usa tokens de bot de integración, el endpoint de Notion as Code requiere tokens de acceso personal.

¿La API es síncrona o asíncrona?

Es asíncrona. Haces un POST /v1/infra_as_code que te devuelve un taskId, y después consultas GET /v1/async_tasks/{taskId} en bucle hasta que el estado sea succeeded o failed. El resultado incluye los mapeos de recursos creados o actualizados.

¿Puede un agente de IA generar estos scripts?

Sí, y es el uso que Notion enseña en su demo. Le describes el workspace en lenguaje natural a tu agente de código (Claude Code, OpenCode, el que uses) y le pasas tu space ID; él escribe el script y te indica cómo ejecutarlo (npm run build más un comando). Para cambios, le pasas el fichero de estado de sesión, edita el script y re-ejecutas el mismo comando para actualizar.

¿Qué limitaciones tiene ahora mismo?

Al estar en alpha, solo puede crear o actualizar dentro de un espacio existente (no crear espacios nuevos), no soporta todas las entidades de Notion todavía, y tiene un límite de 5 peticiones por minuto. Notion recomienda probarlo en un workspace de pruebas, no en el principal.

Fuentes

🧨 Última oprtunidad para recibir la dinamita que mereces sobre programación con IA el próximo domingo: Suscríbete gratis a Web Reactiva en https://webreactiva.com/newsletter

Imagen de Daniel Primo
Claude, IA de Anthropic

Escrito con la ayuda de la IA generativa de Claude, fuentes fidedignas y con un human in the loop:
Dani Primo.

CEO en pantuflas de Web Reactiva. Programador y formador en tecnologías que cambian el mundo y a las personas. Activo en linkedin, en substack y canal @webreactiva en telegram

12 recursos para developers cada domingo en tu bandeja de entrada

Además de una skill práctica bien explicada, trucos para mejorar tu futuro profesional y una pizquita de humor útil para el resto de la semana. Gratis.