Desarrolladores
Recetas
Ejemplos listos para usar que combinan la API de Tylode con herramientas que ya usas. Cada uno está completo: cópialo, pon tus IDs y tu token, y ejecútalo.
Lo que necesitas para cualquier receta
Un token de acceso personal. Créalo en Ajustes → API y webhooks → API y plugins → Crear token y cópialo en el momento; solo se muestra una vez. Los tokens necesitan el plan Pro. Consulta Autenticación.
El ID de tu espacio de trabajo. Cópialo en Ajustes → Workspace → Datos del espacio → ID del espacio → Copiar, o pídeselo a la API:
bashcurl https://app.tylode.com/api/v1/workspaces \ -H "Authorization: Bearer tylode_pat_xxx"Usa el
iddel espacio que quieras.
Guarda el token en secreto: puede hacer todo lo que tú puedes hacer en la app. Déjalo en variables de entorno o en los secretos de tu plataforma, nunca en código que publiques ni en una página web. Entre todas tus peticiones puedes hacer hasta 60 llamadas por minuto (mira Errores y convenciones).
Apuntar un gasto con Atajos de Apple
Apunta un gasto desde el iPhone en unos segundos: el atajo te pide el importe, el concepto y la categoría, y añade una fila a la tabla Movimientos de tu página de Finanzas. Usa la API de bases de datos, que acepta nombres de columna y etiquetas de opción, así que no tienes que pelearte con IDs.
Antes de montarlo
Si todavía no la tienes, crea la página Finanzas desde la galería de plantillas (mira Plantillas). Crea una tabla llamada Movimientos con las columnas Fecha, Concepto, Tipo, Categoría e Importe. Si les has cambiado el nombre, usa los tuyos más abajo.
Busca el ID de la tabla. Desde un ordenador:
bashcurl "https://app.tylode.com/api/v1/databases?workspace_id=WORKSPACE_ID" \ -H "Authorization: Bearer tylode_pat_xxx"Copia el
idde la entrada cuyonameesMovimientos. ¿No tienes un ordenador a mano? Haz un atajo de usar y tirar con Obtener contenido de la URL apuntando a esa misma URL, añade el encabezadoAuthorizationconBearer tylode_pat_xxx, pon detrás Vista rápida, ejecútalo y copia el ID del resultado.
Monta el atajo
En la app Atajos, crea un atajo nuevo llamado "Apuntar gasto" y añade estas acciones en orden:
Solicitar entrada: tipo de entrada Número, pregunta "Importe".
Solicitar entrada: tipo de entrada Texto, pregunta "Concepto".
Lista: añade los elementos
Casa,Comida,Transporte,Ocio,SaludyOtros.Seleccionar de la lista: selecciona de la Lista del paso anterior, pregunta "Categoría".
Formatear fecha: fecha Fecha actual, formato Personalizado, cadena de formato
yyyy-MM-dd.Obtener contenido de la URL:
URL:
https://app.tylode.com/api/v1/databases/DATABASE_ID/rowsMétodo: POST
Encabezados:
Authorization→Bearer tylode_pat_xxx, yContent-Type→application/jsonCuerpo de la solicitud: JSON. Añade un campo
propertiesde tipo Diccionario y, dentro, estos campos de tipo Texto:Clave Valor Fechala variable Fecha formateada Conceptola Entrada proporcionada del paso 2 TipoGastoCategoríael Elemento seleccionado Importela Entrada proporcionada del paso 1
Obtener valor del diccionario: obtén el valor de la clave
erroren Contenido de la URL.Si el Valor del diccionario tiene algún valor: Mostrar alerta con el Valor del diccionario. De lo contrario: Mostrar notificación "Gasto apuntado".
El paso 6 envía exactamente esta petición:
{
"properties": {
"Fecha": "2026-09-23",
"Concepto": "Coffee with Marta",
"Tipo": "Gasto",
"Categoría": "Comida",
"Importe": "2,40"
}
}Mandar el importe como texto no es problema: la API acepta la coma decimal, así que 2,40 se guarda como el número 2,4. Si algo no cuadra, por ejemplo una categoría que no existe, la alerta del paso 8 muestra un error con las opciones válidas, así que puedes arreglar el atajo desde el propio móvil.
Añade el atajo a la pantalla de inicio o lánzalo con Siri ("Apuntar gasto"). Para apuntar ingresos, duplícalo y cambia Tipo por Ingreso.
Mandar la agenda del día a Slack
Cada mañana de lunes a viernes, publica en un canal de Slack los eventos de hoy y las tarjetas que vencen hoy. Usa la API de calendario, la API de tableros y un webhook entrante de Slack (créalo en Slack para el canal que quieras y copia su URL).
El script
Guárdalo como agenda-slack.mjs. Necesita Node.js 18 o posterior y no tiene dependencias.
// agenda-slack.mjs
// Variables de entorno: TYLODE_TOKEN, TYLODE_WORKSPACE_ID, SLACK_WEBHOOK_URL, TZ (p. ej. Europe/Madrid)
const BASE = "https://app.tylode.com/api/v1";
const { TYLODE_TOKEN, TYLODE_WORKSPACE_ID, SLACK_WEBHOOK_URL } = process.env;
async function tylode(path) {
const res = await fetch(BASE + path, { headers: { Authorization: `Bearer ${TYLODE_TOKEN}` } });
const json = await res.json();
if (!res.ok) throw new Error(`${res.status} ${path}: ${json.error}`);
return json.data;
}
// Hoy, en la zona horaria definida en TZ
const start = new Date();
start.setHours(0, 0, 0, 0);
const end = new Date(start);
end.setDate(end.getDate() + 1);
const today = start.toLocaleDateString("sv-SE"); // YYYY-MM-DD
// 1. Los eventos de hoy (los recurrentes llegan ya desplegados)
const params = new URLSearchParams({
workspace_id: TYLODE_WORKSPACE_ID,
from: start.toISOString(),
to: end.toISOString(),
});
const events = (await tylode(`/calendar/events?${params}`)).filter((e) => new Date(e.start_at) < end);
// 2. Las tarjetas que vencen hoy, en todos los tableros
const boards = await tylode(`/boards?workspace_id=${TYLODE_WORKSPACE_ID}`);
const due = [];
for (const board of boards) {
const cards = await tylode(`/boards/${board.id}/cards`);
for (const card of cards) if (card.due_date === today) due.push({ ...card, board: board.name });
}
// 3. Monta el mensaje
const hhmm = (iso) => new Date(iso).toLocaleTimeString("en-GB", { hour: "2-digit", minute: "2-digit" });
const lines = [`*Agenda for ${start.toLocaleDateString("en-GB", { weekday: "long", day: "numeric", month: "long" })}*`];
if (events.length === 0) lines.push("No events today.");
for (const e of events) {
const when = e.all_day ? "All day" : e.end_at ? `${hhmm(e.start_at)}–${hhmm(e.end_at)}` : hhmm(e.start_at);
lines.push(`• ${when} ${e.title}`);
}
lines.push("", `*Cards due today (${due.length})*`);
for (const c of due) lines.push(`• ${c.title} _(${c.board})_`);
if (due.length === 0) lines.push("Nothing due.");
// 4. Publica en Slack
const slack = await fetch(SLACK_WEBHOOK_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ text: lines.join("\n") }),
});
if (!slack.ok) throw new Error(`Slack answered ${slack.status}`);
console.log(`Posted ${events.length} events and ${due.length} cards.`);Los textos del mensaje están en inglés; cámbialos por los tuyos (y "en-GB" por "es-ES" para las fechas en español). El script hace 2 peticiones más una por tablero, así que se queda muy por debajo del límite de 60 por minuto salvo que tengas decenas de tableros. En Slack el mensaje se ve así:
Agenda for Monday 28 September
• 09:30–10:15 Dentist
• 10:00–10:30 Team sync
Cards due today (1)
• Fix the signup email (Product)Ejecútalo con GitHub Actions
Pon el script en un repositorio, añade tres secretos del repositorio (Settings → Secrets and variables → Actions): TYLODE_TOKEN, TYLODE_WORKSPACE_ID y SLACK_WEBHOOK_URL, y añade este flujo como .github/workflows/agenda.yml:
name: Daily agenda
on:
schedule:
# 06:00 UTC, de lunes a viernes. GitHub siempre programa en UTC.
- cron: "0 6 * * 1-5"
workflow_dispatch: # permite lanzarlo a mano desde la pestaña Actions
jobs:
agenda:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: node agenda-slack.mjs
env:
TZ: Europe/Madrid
TYLODE_TOKEN: ${{ secrets.TYLODE_TOKEN }}
TYLODE_WORKSPACE_ID: ${{ secrets.TYLODE_WORKSPACE_ID }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}TZ decide qué es "hoy" para el script; la línea cron decide cuándo se ejecuta, en UTC. Las ejecuciones programadas pueden arrancar con unos minutos de retraso.
O ejecútalo con cron
En cualquier máquina que esté siempre encendida, guarda las variables en un archivo .env junto al script:
# .env
TZ=Europe/Madrid
TYLODE_TOKEN=tylode_pat_xxx
TYLODE_WORKSPACE_ID=WORKSPACE_ID
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/XXX/YYY/ZZZDespués añade una línea con crontab -e. Esta se ejecuta a las 08:00 en la zona horaria de la máquina, de lunes a viernes:
0 8 * * 1-5 cd "$HOME/tylode-agenda" && set -a && . ./.env && set +a && node agenda-slack.mjs >> agenda.log 2>&1Convertir formularios en tarjetas de un tablero
El formulario de contacto de tu web crea una tarjeta en un tablero Leads por cada envío. El navegador nunca ve tu token: el formulario envía los datos a una pequeña función serverless, y solo esa función habla con Tylode. Usa Crear una tarjeta.
1. Busca el ID del tablero
curl "https://app.tylode.com/api/v1/boards?workspace_id=WORKSPACE_ID" \
-H "Authorization: Bearer tylode_pat_xxx"Copia el id de tu tablero Leads. Las tarjetas van a la primera lista del tablero. Si prefieres otra lista, coge su list_id de una tarjeta que ya esté en ella (GET /boards/BOARD_ID/cards) y añádelo a la petición del paso 3.
2. El formulario
<!-- contact.html -->
<form action="/api/lead" method="post">
<label>Name <input name="name" required></label>
<label>Email <input name="email" type="email" required></label>
<label>Message <textarea name="message" rows="4"></textarea></label>
<!-- Trampa para spam: las personas no la ven, los bots la rellenan -->
<input name="website" tabindex="-1" autocomplete="off" style="position:absolute; left:-9999px" aria-hidden="true">
<button type="submit">Send</button>
</form>3. La función
Esta versión es para Vercel: guárdala como api/lead.js en un proyecto cuyo package.json tenga "type": "module", y define las variables de entorno TYLODE_TOKEN y TYLODE_LEADS_BOARD_ID. Usa Request y Response estándar de la web, así que en otras plataformas (Netlify, Cloudflare Workers…) solo cambia la forma de exportar la función.
// api/lead.js
export async function POST(request) {
const form = await request.formData();
// Los bots rellenan el campo oculto: fingimos que ha ido bien y no hacemos nada
if (form.get("website")) return Response.redirect(new URL("/thanks.html", request.url), 303);
const name = String(form.get("name") ?? "").trim().slice(0, 200);
const email = String(form.get("email") ?? "").trim().slice(0, 200);
const message = String(form.get("message") ?? "").trim().slice(0, 5000);
if (!name || !email) return new Response("Name and email are required.", { status: 400 });
const res = await fetch(
`https://app.tylode.com/api/v1/boards/${process.env.TYLODE_LEADS_BOARD_ID}/cards`,
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.TYLODE_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
title: `${name} <${email}>`,
description: message,
// list_id: "LIST_ID", // opcional: una lista concreta
}),
},
);
if (!res.ok) {
console.error("Tylode answered", res.status, await res.text());
return new Response("We couldn't send your message. Please try again later.", { status: 502 });
}
return Response.redirect(new URL("/thanks.html", request.url), 303);
}Las tarjetas se crean a nombre del dueño del token, y cada una dispara el webhook card.created, así que también puedes recibir un mensaje en Slack por cada lead nuevo. Si tu formulario tiene mucho tráfico, recuerda el límite de 60 peticiones por minuto por usuario.
Hacer copia de seguridad de tus páginas
Este script guarda en tu ordenador, como archivos JSON, todas las páginas que puedes ver en todos los espacios a los que perteneces. Usa GET /workspaces y la API de páginas.
// backup-pages.mjs (Node.js 18+; variable de entorno: TYLODE_TOKEN)
import { mkdir, writeFile } from "node:fs/promises";
const BASE = "https://app.tylode.com/api/v1";
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function tylode(path) {
const res = await fetch(BASE + path, {
headers: { Authorization: `Bearer ${process.env.TYLODE_TOKEN}` },
});
const json = await res.json();
if (!res.ok) throw new Error(`${res.status} ${path}: ${json.error}`);
await sleep(1100); // para no pasar de 60 peticiones por minuto
return json.data;
}
const stamp = new Date().toISOString().slice(0, 10);
const workspaces = await tylode("/workspaces");
for (const ws of workspaces) {
const dir = `backup-${stamp}/${ws.slug}`;
await mkdir(dir, { recursive: true });
// El listado trae los títulos y el árbol (parent_page_id), pero no el contenido
const pages = await tylode(`/pages?workspace_id=${ws.id}`);
await writeFile(`${dir}/_index.json`, JSON.stringify(pages, null, 2));
// Una petición por página para traer su contenido
for (const summary of pages) {
const page = await tylode(`/pages/${summary.id}`);
await writeFile(`${dir}/${page.id}.json`, JSON.stringify(page, null, 2));
console.log(`${ws.name} / ${page.title}`);
}
}TYLODE_TOKEN=tylode_pat_xxx node backup-pages.mjsObtienes una carpeta por espacio con un _index.json (el título, el icono y la página padre de cada página, para reconstruir el árbol) y un archivo por página con todo su JSON de bloques. A una petición por segundo, 300 páginas tardan unos cinco minutos.
Unas cuantas notas, para que no haya sorpresas:
- Es una copia en JSON, no en Markdown. El contenido de las páginas es JSON de bloques (mira Formato del contenido de una página). Pasarlo a Markdown implica escribir tu propio conversor para los tipos de bloque que uses. Si solo necesitas unas pocas páginas en Markdown, usa Exportar .md en la app (mira Exportar).
- Para restaurar una página, crea una nueva con
POST /pagesy manda elcontentguardado conPATCH /pages/:id. Los IDs de los bloques se pueden reutilizar tal cual. - Lo que no incluye: las filas de las bases de datos (añádelas con
GET /databases/:id/rowsde la API de bases de datos), los archivos adjuntos, los comentarios y el historial de las páginas.
Publicar eventos de webhooks en Discord o Slack
Para recibir un mensaje en un canal cada vez que pasa algo en Tylode (se crea una página, se mueve una tarjeta, entra alguien nuevo), no hace falta consultar la API una y otra vez: crea un webhook en Ajustes → API y webhooks → Webhooks. Cada envío incluye un campo text con una frase ya redactada, que es justo lo que esperan los webhooks entrantes de Slack, así que puedes pegar como destino la URL de un webhook de Slack. Discord espera el texto en un campo llamado content, así que apunta el webhook de Tylode a una pequeña función tuya que verifique la firma y reenvíe text a tu webhook de Discord como content.
En Webhooks tienes todo lo necesario para los dos casos: la lista de eventos, la carga y la verificación de la firma en Node.js y Python.
Preguntar a Claude por tu espacio con MCP
Conecta Claude (o cualquier cliente MCP) a Tylode y pregunta con tus palabras: "¿Qué tengo en el calendario esta semana?", "Busca la página de precios y resúmemela", "Crea una tarjeta en el tablero Product para arreglar el email de registro". Claude usa la misma API que estas recetas, con tu token y tus permisos.
Con Claude Code, basta un comando:
claude mcp add --transport http tylode https://app.tylode.com/api/mcp --header "Authorization: Bearer tylode_pat_xxx"La configuración para Claude Desktop, Cursor y otros clientes, y la lista completa de herramientas, está en MCP.