Desarrolladores
API de pizarras, presentaciones, búsqueda y almacenamiento
Esta página cubre el resto de la API REST: las pizarras y sus elementos, las presentaciones del Estudio y sus diapositivas, la búsqueda en todo un espacio de trabajo y Mi unidad, donde puedes listar, descargar, subir y borrar archivos. Como en toda la API, cada petición actúa en tu nombre y solo llega a lo que puedes ver en la app.
Antes de empezar
- URL base:
https://app.tylode.com/api/v1 - Manda tu token en la cabecera
Authorization: Bearer tylode_pat_xxx. Los tokens de acceso personal necesitan el plan Pro. Consulta Autenticación. - Obtén el ID del espacio con
GET /api/v1/workspaceso en la app, en Ajustes → Workspace → Datos del espacio → ID del espacio → Copiar. - Los errores que puede dar cualquier endpoint (
401,403,429) se explican en Errores y convenciones. - Los ejemplos en JavaScript usan la función
tylode()de la API de páginas.
Endpoints
| Método | Ruta | Qué hace | Permiso (scope) |
|---|---|---|---|
| GET | /api/v1/whiteboards | Lista las pizarras de un espacio | whiteboards:read |
| POST | /api/v1/whiteboards | Crea una pizarra | whiteboards:write |
| GET | /api/v1/whiteboards/:id/elements | Lista los elementos de una pizarra | whiteboards:read |
| POST | /api/v1/whiteboards/:id/elements | Añade un elemento | whiteboards:write |
| PATCH | /api/v1/whiteboards/:id/elements/:elementId | Mueve o cambia un elemento | whiteboards:write |
| DELETE | /api/v1/whiteboards/:id/elements/:elementId | Borra un elemento | whiteboards:delete |
| DELETE | /api/v1/whiteboards/:id | Mueve una pizarra a la papelera | whiteboards:delete |
| GET | /api/v1/presentations | Lista tus presentaciones | presentations:read |
| POST | /api/v1/presentations | Crea una presentación | presentations:write |
| GET | /api/v1/presentations/:id/slides | Lista las diapositivas de una presentación | presentations:read |
| POST | /api/v1/presentations/:id/slides | Añade una diapositiva en blanco | presentations:write |
| GET | /api/v1/presentations/:id/slides/:slideId/elements | Lista los elementos de una diapositiva | presentations:read |
| POST | /api/v1/presentations/:id/slides/:slideId/elements | Añade un texto o una forma a una diapositiva | presentations:write |
| PATCH | /api/v1/presentations/:id/slides/:slideId/elements/:elementId | Mueve o cambia un elemento de una diapositiva | presentations:write |
| DELETE | /api/v1/presentations/:id/slides/:slideId/elements/:elementId | Borra un elemento de una diapositiva | presentations:delete |
| DELETE | /api/v1/presentations/:id/slides/:slideId | Borra una diapositiva | presentations:delete |
| DELETE | /api/v1/presentations/:id | Mueve una presentación a la papelera | presentations:delete |
| GET | /api/v1/search | Busca en un espacio | search:read |
| GET | /api/v1/storage | Lista una carpeta de Mi unidad | storage:read |
| GET | /api/v1/storage/:id | Devuelve un archivo con un enlace de descarga | storage:read |
| POST | /api/v1/storage | Sube un archivo a Mi unidad | storage:write |
| DELETE | /api/v1/storage/:id | Mueve un archivo de Mi unidad a la papelera | storage:delete |
Los permisos solo cuentan para las aplicaciones OAuth.
Pizarras
Las pizarras pertenecen a un espacio de trabajo. En Pizarras tienes cómo funcionan en la app.
Listar pizarras
GET /api/v1/whiteboards
Devuelve las pizarras de un espacio, de la más antigua a la más reciente, con id, workspace_id, name y created_by. Las que están en la papelera no aparecen.
Permiso (scope): whiteboards:read
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
workspace_id | query | string | Sí | El espacio que quieres listar. |
curl "https://app.tylode.com/api/v1/whiteboards?workspace_id=WORKSPACE_ID" \
-H "Authorization: Bearer tylode_pat_xxx"Respuesta 200
{
"data": [
{
"id": "b2e5a8d1-4c7f-4a0b-9e3d-6f9c2b5e8a14",
"workspace_id": "7c1e2a4b-3f5d-4e8a-9b21-6d0f5c8e1a37",
"name": "Retro Q3",
"created_by": "2f7c9e41-8b3a-4d6e-a1f5-0c8e3b7d9a52"
}
]
}Errores
| Estado | Cuándo |
|---|---|
400 | Falta workspace_id. |
Crear una pizarra
POST /api/v1/whiteboards
Crea una pizarra vacía.
Permiso (scope): whiteboards:write
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
workspace_id | body | string | Sí | Espacio donde se crea. |
name | body | string | No | Nombre. Por defecto, Whiteboard. |
curl -X POST https://app.tylode.com/api/v1/whiteboards \
-H "Authorization: Bearer tylode_pat_xxx" \
-H "Content-Type: application/json" \
-d '{ "workspace_id": "WORKSPACE_ID", "name": "Brainstorm: pricing page" }'Respuesta 201
{
"data": {
"id": "c3f6b9e2-5d8a-4b1c-a4e7-0a3d6c9f2b25",
"workspace_id": "7c1e2a4b-3f5d-4e8a-9b21-6d0f5c8e1a37",
"name": "Brainstorm: pricing page",
"created_by": "2f7c9e41-8b3a-4d6e-a1f5-0c8e3b7d9a52"
}
}Errores
| Estado | Cuándo |
|---|---|
400 | Falta workspace_id o no se ha podido crear la pizarra (por ejemplo, porque no puedes crear contenido en ese espacio). |
Listar elementos
GET /api/v1/whiteboards/:id/elements
Devuelve todos los elementos de una pizarra, del fondo al frente (por z_index).
Permiso (scope): whiteboards:read
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
id | path | string | Sí | ID de la pizarra. |
Cada elemento trae id, whiteboard_id, type, x, y, width, height, content, style y z_index. La lista incluye todos los tipos que haya en la pizarra: sticky, text, rectangle, ellipse y también connector, embed y media, que puedes leer pero no crear por la API. No indica qué elementos une cada conector.
curl https://app.tylode.com/api/v1/whiteboards/WHITEBOARD_ID/elements \
-H "Authorization: Bearer tylode_pat_xxx"Respuesta 200
{
"data": [
{
"id": "d4a7c0f3-6e9b-4c2d-b5f8-1b4e7d0a3c36",
"whiteboard_id": "b2e5a8d1-4c7f-4a0b-9e3d-6f9c2b5e8a14",
"type": "sticky",
"x": 120,
"y": 80,
"width": 180,
"height": 120,
"content": "Too many clicks to invite someone",
"style": { "color": "#fecaca" },
"z_index": 3
}
]
}Si la pizarra no existe o no puedes verla, recibes una lista vacía.
Añadir un elemento
POST /api/v1/whiteboards/:id/elements
Añade una nota adhesiva, un texto o una forma a una pizarra.
Permiso (scope): whiteboards:write
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
id | path | string | Sí | ID de la pizarra. |
type | body | string | Sí | sticky, text, rectangle o ellipse. |
x | body | number | No | Posición horizontal de la esquina superior izquierda del elemento en el lienzo. Por defecto, 0. |
y | body | number | No | Posición vertical de la esquina superior izquierda. Por defecto, 0. |
width | body | number | No | Ancho. Por defecto, 200. |
height | body | number | No | Alto. Por defecto, 200. |
content | body | string | No | Texto que se muestra dentro. Por defecto, vacío. |
style | body | object | No | Aspecto. Por defecto, {}. |
Las coordenadas van en unidades del lienzo (píxeles con el zoom al 100 %). (0, 0) es el origen del lienzo y la y crece hacia abajo, así que para poner notas en fila, deja la misma y y suma a x el ancho más un hueco.
La clave de style que usa la pizarra para estos tipos es color, un color CSS como "#bbf7d0":
| Tipo | Qué hace style.color | Sin él |
|---|---|---|
sticky | Color de la nota. La paleta de la app es #fde68a, #bbf7d0, #bfdbfe, #fbcfe8, #fecaca y #ddd6fe. | Amarillo (#fde68a). |
rectangle, ellipse | Color de relleno. | Un relleno claro y semitransparente con borde. |
text | Nada. | — |
Los elementos nuevos se crean con z_index 0, así que si se solapan con otros pueden quedar por detrás.
curl -X POST https://app.tylode.com/api/v1/whiteboards/WHITEBOARD_ID/elements \
-H "Authorization: Bearer tylode_pat_xxx" \
-H "Content-Type: application/json" \
-d '{
"type": "sticky",
"x": 320,
"y": 80,
"width": 180,
"height": 120,
"content": "Add a template gallery",
"style": { "color": "#bbf7d0" }
}'// Una nota adhesiva por idea, en fila
const ideas = ["Shorter signup", "Import from Trello", "Dark mode for boards"];
for (const [i, idea] of ideas.entries()) {
await tylode(`/whiteboards/${WHITEBOARD_ID}/elements`, {
method: "POST",
body: { type: "sticky", x: i * 200, y: 0, width: 180, height: 120, content: idea },
});
}Respuesta 201
{
"data": {
"id": "e5b8d1a4-7f0c-4d3e-a6b9-2c5f8e1b4d47",
"whiteboard_id": "b2e5a8d1-4c7f-4a0b-9e3d-6f9c2b5e8a14",
"type": "sticky",
"x": 320,
"y": 80,
"width": 180,
"height": 120,
"content": "Add a template gallery",
"style": { "color": "#bbf7d0" },
"z_index": 0
}
}Errores
| Estado | Cuándo |
|---|---|
400 | Falta type o no es uno de los cuatro tipos permitidos. |
400 | No se ha podido crear el elemento (por ejemplo, la pizarra no existe o no puedes editarla). |
Cambiar un elemento
PATCH /api/v1/whiteboards/:id/elements/:elementId
Mueve un elemento o le cambia el tamaño, el texto o el estilo. Solo cambia lo que mandas; el resto del elemento se queda como está.
Permiso (scope): whiteboards:write
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
id | path | string | Sí | ID de la pizarra. |
elementId | path | string | Sí | ID del elemento, de Listar elementos. |
x | body | number | No | Posición horizontal nueva de la esquina superior izquierda. |
y | body | number | No | Posición vertical nueva. |
width | body | number | No | Ancho nuevo, mayor que 0. |
height | body | number | No | Alto nuevo, mayor que 0. |
content | body | string | No | Texto nuevo. Solo en notas, textos y formas: en el resto (imágenes, vídeos, conectores, incrustados…) recibes 400 con code: "content_not_editable", aunque sí puedes moverlos y cambiar su tamaño. |
style | body | object | No | Las claves de estilo que cambian. Se juntan con el estilo que ya tenía. |
Manda al menos uno de los campos del cuerpo. Los números van en unidades del lienzo y no pueden pasar de 100 000 (en positivo o en negativo).
style admite estas claves: color, fill, stroke, fontSize, fontFamily, bold, italic, underline, textAlign, lineHeight, letterSpacing y opacity. Cada una lleva un texto (de hasta 100 caracteres), un número o un booleano; las demás claves se ignoran. Solo cambian las claves que mandas: { "style": { "color": "#fecaca" } } cambia el color y deja el resto del estilo como estaba.
curl -X PATCH https://app.tylode.com/api/v1/whiteboards/WHITEBOARD_ID/elements/ELEMENT_ID \
-H "Authorization: Bearer tylode_pat_xxx" \
-H "Content-Type: application/json" \
-d '{
"x": 520,
"content": "Add a template gallery (v2)",
"style": { "color": "#fecaca" }
}'Respuesta 200
{
"data": {
"id": "e5b8d1a4-7f0c-4d3e-a6b9-2c5f8e1b4d47",
"whiteboard_id": "b2e5a8d1-4c7f-4a0b-9e3d-6f9c2b5e8a14",
"type": "sticky",
"x": 520,
"y": 80,
"width": 180,
"height": 120,
"content": "Add a template gallery (v2)",
"style": { "color": "#fecaca" },
"z_index": 0
}
}Errores
| Estado | Cuándo |
|---|---|
400 | El ID de la pizarra o del elemento no es válido. |
400 | No has mandado nada que cambiar. |
400 | x, y, width o height no son números válidos (width y height tienen que ser mayores que 0), o content no es texto. |
400 | style no es un objeto. |
404 | El elemento no existe, no es de esa pizarra o no puedes cambiarlo. |
Borrar un elemento
DELETE /api/v1/whiteboards/:id/elements/:elementId
Borra un elemento de una pizarra. Los elementos no tienen papelera: no se puede recuperar.
Permiso (scope): whiteboards:delete
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
id | path | string | Sí | ID de la pizarra. |
elementId | path | string | Sí | ID del elemento. |
curl -X DELETE https://app.tylode.com/api/v1/whiteboards/WHITEBOARD_ID/elements/ELEMENT_ID \
-H "Authorization: Bearer tylode_pat_xxx"Respuesta 200
{ "data": { "id": "e5b8d1a4-7f0c-4d3e-a6b9-2c5f8e1b4d47", "papelera": false } }Errores
| Estado | Cuándo |
|---|---|
400 | El ID de la pizarra o del elemento no es válido. |
404 | El elemento no existe, no es de esa pizarra o no puedes borrarlo. |
Mover una pizarra a la papelera
DELETE /api/v1/whiteboards/:id
Manda una pizarra a la papelera, igual que al eliminarla en la app. Se puede recuperar desde la papelera, y mientras está ahí no sale en Listar pizarras.
Permiso (scope): whiteboards:delete
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
id | path | string | Sí | ID de la pizarra. |
curl -X DELETE https://app.tylode.com/api/v1/whiteboards/WHITEBOARD_ID \
-H "Authorization: Bearer tylode_pat_xxx"Respuesta 200
{ "data": { "id": "b2e5a8d1-4c7f-4a0b-9e3d-6f9c2b5e8a14", "papelera": true } }Errores
| Estado | Cuándo |
|---|---|
400 | El ID no es válido. |
403 | Puedes ver la pizarra, pero tu rol no te deja mandarla a la papelera. |
404 | La pizarra no existe, ya está en la papelera o no puedes verla. |
Lo que tienen en común todos los DELETE está en Borrar: papelera o para siempre.
Presentaciones
Las presentaciones son documentos del Estudio. Son personales: te pertenecen a ti, no a un espacio de trabajo, y viven en Mi unidad. La lista incluye las tuyas y las que han compartido contigo. Mira Estudio.
Estos endpoints no necesitan workspace_id; si lo mandas, se ignora.
Listar presentaciones
GET /api/v1/presentations
Devuelve tus documentos del Estudio y los que han compartido contigo, del más antiguo al más reciente. Los que están en la papelera no aparecen.
Permiso (scope): presentations:read
Cada elemento trae id, owner_id, folder_id (la carpeta de Mi unidad en la que está, o null), name, created_by, canvas_width y canvas_height. Aquí llegan todos los formatos del Estudio (presentaciones, documentos, publicaciones para redes, impresión); el tamaño del lienzo en píxeles los distingue, por ejemplo 960 × 540 en una presentación 16:9.
curl https://app.tylode.com/api/v1/presentations \
-H "Authorization: Bearer tylode_pat_xxx"Respuesta 200
{
"data": [
{
"id": "f6c9e2b5-8a1d-4e4f-b7c0-3d6a9f2c5e58",
"owner_id": "2f7c9e41-8b3a-4d6e-a1f5-0c8e3b7d9a52",
"folder_id": null,
"name": "Q3 results",
"created_by": "2f7c9e41-8b3a-4d6e-a1f5-0c8e3b7d9a52",
"canvas_width": 960,
"canvas_height": 540
}
]
}Crear una presentación
POST /api/v1/presentations
Crea una presentación con una diapositiva en blanco, igual que al crearla en el Estudio. El lienzo es de 960 × 540 (16:9).
Permiso (scope): presentations:write
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
name | body | string | No | Nombre. Por defecto, Presentación. |
folder_id | body | string | No | Carpeta de Mi unidad en la que se guarda. Los IDs de carpeta salen de Listar una carpeta. Por defecto, la raíz. |
curl -X POST https://app.tylode.com/api/v1/presentations \
-H "Authorization: Bearer tylode_pat_xxx" \
-H "Content-Type: application/json" \
-d '{ "name": "Kick-off deck" }'Respuesta 201
{
"data": {
"id": "a7d0f3c6-9b2e-4f5a-a8d1-4e7b0a3d6f69",
"owner_id": "2f7c9e41-8b3a-4d6e-a1f5-0c8e3b7d9a52",
"folder_id": null,
"name": "Kick-off deck",
"created_by": "2f7c9e41-8b3a-4d6e-a1f5-0c8e3b7d9a52",
"canvas_width": 960,
"canvas_height": 540
}
}Errores
| Estado | Cuándo |
|---|---|
400 | No se ha podido crear la presentación (por ejemplo, el folder_id no existe). |
Listar diapositivas
GET /api/v1/presentations/:id/slides
Devuelve las diapositivas de una presentación en orden, con id, presentation_id, position (0 es la primera) y background. El contenido de cada diapositiva está en Listar los elementos de una diapositiva.
Permiso (scope): presentations:read
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
id | path | string | Sí | ID de la presentación. |
curl https://app.tylode.com/api/v1/presentations/PRESENTATION_ID/slides \
-H "Authorization: Bearer tylode_pat_xxx"Respuesta 200
{
"data": [
{
"id": "b8e1a4d7-0c3f-4a6b-9e2d-5f8c1b4e7a70",
"presentation_id": "a7d0f3c6-9b2e-4f5a-a8d1-4e7b0a3d6f69",
"position": 0,
"background": { "color": "#ffffff" }
}
]
}Si no puedes ver la presentación, recibes una lista vacía.
Añadir una diapositiva
POST /api/v1/presentations/:id/slides
Añade una diapositiva en blanco al final de una presentación. No lleva cuerpo.
Permiso (scope): presentations:write
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
id | path | string | Sí | ID de la presentación. |
curl -X POST https://app.tylode.com/api/v1/presentations/PRESENTATION_ID/slides \
-H "Authorization: Bearer tylode_pat_xxx"Respuesta 201
{
"data": {
"id": "c9f2b5e8-1d4a-4b7c-a0e3-6a9d2c5f8b81",
"presentation_id": "a7d0f3c6-9b2e-4f5a-a8d1-4e7b0a3d6f69",
"position": 1,
"background": { "color": "#ffffff" }
}
}Errores
| Estado | Cuándo |
|---|---|
400 | No se ha podido añadir la diapositiva (por ejemplo, la presentación no existe o no puedes editarla). |
Listar los elementos de una diapositiva
GET /api/v1/presentations/:id/slides/:slideId/elements
Devuelve los elementos de una diapositiva, del fondo al frente (por z_index), con id, slide_id, type, x, y, width, height, content, style y z_index. Incluye todos los tipos que haya (textos, formas, imágenes…), aunque por la API solo puedes añadir textos, rectángulos y elipses.
Permiso (scope): presentations:read
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
id | path | string | Sí | ID de la presentación. |
slideId | path | string | Sí | ID de la diapositiva, de Listar diapositivas. |
Las coordenadas van en píxeles del lienzo de la presentación (canvas_width × canvas_height, 960 × 540 en las que crea la API), con (0, 0) en la esquina superior izquierda y la y creciendo hacia abajo.
curl https://app.tylode.com/api/v1/presentations/PRESENTATION_ID/slides/SLIDE_ID/elements \
-H "Authorization: Bearer tylode_pat_xxx"Respuesta 200
{
"data": [
{
"id": "d0a3c6f9-2e5b-4c8d-b1e4-7f0a3d6c9b92",
"slide_id": "b8e1a4d7-0c3f-4a6b-9e2d-5f8c1b4e7a70",
"type": "text",
"x": 80,
"y": 60,
"width": 800,
"height": 80,
"content": "Q3 results",
"style": { "fontSize": 48, "bold": true },
"z_index": 0
}
]
}Errores
| Estado | Cuándo |
|---|---|
400 | El ID de la presentación o de la diapositiva no es válido. |
404 | La diapositiva no existe, no es de esa presentación o no puedes verla. |
Añadir un elemento a una diapositiva
POST /api/v1/presentations/:id/slides/:slideId/elements
Añade un texto, un rectángulo o una elipse a una diapositiva, delante de todo lo que ya hay.
Permiso (scope): presentations:write
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
id | path | string | Sí | ID de la presentación. |
slideId | path | string | Sí | ID de la diapositiva. |
type | body | string | No | text, rectangle o ellipse. Por defecto, text. |
x | body | number | No | Posición horizontal de la esquina superior izquierda. Por defecto, 80. |
y | body | number | No | Posición vertical de la esquina superior izquierda. Por defecto, 80. |
width | body | number | No | Ancho. Por defecto, 600 en los textos y 300 en las formas. |
height | body | number | No | Alto. Por defecto, 80 en los textos y 200 en las formas. |
content | body | string | No | Texto que se muestra. Por defecto, vacío. |
style | body | object | No | Aspecto, con las mismas claves que en Cambiar un elemento. Los textos llevan fontSize 32 si no mandas otro. |
curl -X POST https://app.tylode.com/api/v1/presentations/PRESENTATION_ID/slides/SLIDE_ID/elements \
-H "Authorization: Bearer tylode_pat_xxx" \
-H "Content-Type: application/json" \
-d '{
"type": "text",
"content": "Q3 results",
"x": 80,
"y": 60,
"width": 800,
"height": 80,
"style": { "fontSize": 48, "bold": true }
}'// Un título y, debajo, una caja de color
const path = `/presentations/${PRESENTATION_ID}/slides/${SLIDE_ID}/elements`;
await tylode(path, {
method: "POST",
body: { content: "Q3 results", x: 80, y: 60, width: 800, height: 80, style: { fontSize: 48, bold: true } },
});
await tylode(path, {
method: "POST",
body: { type: "rectangle", x: 80, y: 180, width: 800, height: 280, style: { fill: "#e0f2fe" } },
});Respuesta 201
{
"data": {
"id": "d0a3c6f9-2e5b-4c8d-b1e4-7f0a3d6c9b92",
"slide_id": "b8e1a4d7-0c3f-4a6b-9e2d-5f8c1b4e7a70",
"type": "text",
"x": 80,
"y": 60,
"width": 800,
"height": 80,
"content": "Q3 results",
"style": { "fontSize": 48, "bold": true },
"z_index": 0
}
}Errores
| Estado | Cuándo |
|---|---|
400 | El ID de la presentación o de la diapositiva no es válido. |
400 | type no es text, rectangle ni ellipse. |
400 | x, y, width o height no son números válidos, o content no es texto. |
400 | style no es un objeto. |
400 | No se ha podido añadir el elemento (por ejemplo, porque no puedes editar la presentación). |
404 | La diapositiva no existe, no es de esa presentación o no puedes verla. |
Cambiar un elemento de una diapositiva
PATCH /api/v1/presentations/:id/slides/:slideId/elements/:elementId
Funciona igual que Cambiar un elemento de una pizarra: mueve un elemento o le cambia el tamaño, el texto o el estilo, y solo cambia lo que mandas. El estilo se junta con el que ya tenía.
Permiso (scope): presentations:write
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
id | path | string | Sí | ID de la presentación. |
slideId | path | string | Sí | ID de la diapositiva. |
elementId | path | string | Sí | ID del elemento, de Listar los elementos de una diapositiva. |
x, y | body | number | No | Posición nueva. |
width, height | body | number | No | Tamaño nuevo, mayor que 0. |
content | body | string | No | Texto nuevo. Solo en notas, textos y formas: en el resto (imágenes, vídeos, conectores, incrustados…) recibes 400 con code: "content_not_editable", aunque sí puedes moverlos y cambiar su tamaño. |
style | body | object | No | Las claves de estilo que cambian. |
curl -X PATCH https://app.tylode.com/api/v1/presentations/PRESENTATION_ID/slides/SLIDE_ID/elements/ELEMENT_ID \
-H "Authorization: Bearer tylode_pat_xxx" \
-H "Content-Type: application/json" \
-d '{ "content": "Q3 results: +18 %", "style": { "color": "#0f766e" } }'Respuesta 200
El elemento tal como queda, con los mismos campos que al añadirlo.
Errores
| Estado | Cuándo |
|---|---|
400 | Algún ID no es válido. |
400 | No has mandado nada que cambiar, un valor no es válido o style no es un objeto. |
404 | La diapositiva o el elemento no existen, no son de esa presentación o no puedes cambiarlos. |
Borrar un elemento de una diapositiva
DELETE /api/v1/presentations/:id/slides/:slideId/elements/:elementId
Borra un texto, una forma o una imagen de una diapositiva. No se puede recuperar.
Permiso (scope): presentations:delete
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
id | path | string | Sí | ID de la presentación. |
slideId | path | string | Sí | ID de la diapositiva. |
elementId | path | string | Sí | ID del elemento. |
curl -X DELETE https://app.tylode.com/api/v1/presentations/PRESENTATION_ID/slides/SLIDE_ID/elements/ELEMENT_ID \
-H "Authorization: Bearer tylode_pat_xxx"Respuesta 200
{ "data": { "id": "d0a3c6f9-2e5b-4c8d-b1e4-7f0a3d6c9b92", "papelera": false } }Errores
| Estado | Cuándo |
|---|---|
400 | Algún ID no es válido. |
404 | La diapositiva o el elemento no existen, no son de esa presentación o no puedes borrarlos. |
Borrar una diapositiva
DELETE /api/v1/presentations/:id/slides/:slideId
Borra una diapositiva con todos sus elementos. Las diapositivas no tienen papelera: no se puede recuperar.
Permiso (scope): presentations:delete
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
id | path | string | Sí | ID de la presentación. |
slideId | path | string | Sí | ID de la diapositiva. |
curl -X DELETE https://app.tylode.com/api/v1/presentations/PRESENTATION_ID/slides/SLIDE_ID \
-H "Authorization: Bearer tylode_pat_xxx"Respuesta 200
{ "data": { "id": "c9f2b5e8-1d4a-4b7c-a0e3-6a9d2c5f8b81", "papelera": false } }Errores
| Estado | Cuándo |
|---|---|
400 | El ID de la presentación o de la diapositiva no es válido. |
404 | La diapositiva no existe, no es de esa presentación o no puedes borrarla. |
Mover una presentación a la papelera
DELETE /api/v1/presentations/:id
Manda una presentación a la papelera de Mi unidad, igual que al eliminarla en el Estudio. Se puede recuperar, y mientras está en la papelera no sale en Listar presentaciones.
Permiso (scope): presentations:delete
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
id | path | string | Sí | ID de la presentación. |
curl -X DELETE https://app.tylode.com/api/v1/presentations/PRESENTATION_ID \
-H "Authorization: Bearer tylode_pat_xxx"Respuesta 200
{ "data": { "id": "a7d0f3c6-9b2e-4f5a-a8d1-4e7b0a3d6f69", "papelera": true } }Errores
| Estado | Cuándo |
|---|---|
400 | El ID no es válido. |
404 | La presentación no existe, ya está en la papelera o no puedes borrarla. |
Lo que tienen en común todos los DELETE está en Borrar: papelera o para siempre.
Búsqueda
Una sola llamada busca en páginas, tableros, pizarras, presentaciones, correo y mensajes de chat, ordenado por relevancia. Es el mejor punto de partida para "encuentra la página que habla de X" en una integración o un agente de IA. En Búsqueda tienes cómo se busca en la app.
Buscar en un espacio
GET /api/v1/search
Permiso (scope): search:read
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
workspace_id | query | string | Sí | El espacio en el que buscar. |
q | query | string | Sí | Lo que buscas. No puede ir en blanco. |
limit | query | number | No | Máximo de resultados, de 1 a 50. Por defecto, 20. Los valores fuera de rango se ajustan al límite más cercano. |
Cada resultado trae kind, id, title, snippet, parent_id y rank. Qué se busca y cómo se ordena depende del tipo:
kind | Aparece cuando | title | snippet | rank |
|---|---|---|---|---|
page | El texto de la página coincide con q en una búsqueda de texto completo, o el título contiene q. Se saltan las páginas de la papelera. | Título de la página | Los primeros 140 caracteres del texto de la página | 1 o más; más alto cuanto mejor coincide el texto |
board | El nombre contiene q. | Nombre del tablero | null | 0,9 |
whiteboard | El nombre contiene q. | Nombre de la pizarra | null | 0,9 |
presentation | El nombre contiene q. Tus presentaciones aparecen busques en el espacio que busques. | Nombre de la presentación | null | 0,9 |
mail | El asunto de un hilo en el que participas contiene q. | Asunto | null | 0,8 |
message | El texto del mensaje coincide con q en una búsqueda de texto completo, en una conversación en la que estás. | Nombre de la conversación (Chat en los mensajes directos) | Los primeros 140 caracteres del mensaje | Relevancia del texto, normalmente muy por debajo de 1 |
- "Contiene" no distingue mayúsculas de minúsculas.
- La búsqueda de texto completo busca palabras enteras y aplica las reglas del español, así que los plurales y las formas verbales encuentran su raíz. Puedes usar
"frases entre comillas",ORentre palabras y-palabrapara excluir una. - En los resultados
message,parent_ides el ID de la conversación; en el resto esnull. - Los resultados se ordenan por
rank(de mayor a menor) y después por título, así que las páginas siempre salen antes que el resto.
curl -G https://app.tylode.com/api/v1/search \
-H "Authorization: Bearer tylode_pat_xxx" \
--data-urlencode "workspace_id=WORKSPACE_ID" \
--data-urlencode "q=presupuesto" \
--data-urlencode "limit=5"const params = new URLSearchParams({ workspace_id: WORKSPACE_ID, q: "presupuesto", limit: "5" });
const results = await tylode(`/search?${params}`);
const firstPage = results.find((r) => r.kind === "page");Respuesta 200
{
"data": [
{
"kind": "page",
"id": "0e3a6d9c-2f5b-4c8e-b1a4-7d0f3b6e9c92",
"title": "Presupuesto 2027",
"snippet": "Resumen del presupuesto por equipos. Marketing sube un 12 % respecto a 2026 por la campaña de lanzamiento…",
"parent_id": null,
"rank": 1.0759909
},
{
"kind": "board",
"id": "1f4b7e0a-3c6d-4d9f-a2b5-8e1c4f7a0d03",
"title": "Presupuesto: aprobaciones",
"snippet": null,
"parent_id": null,
"rank": 0.9
},
{
"kind": "message",
"id": "2a5c8f1b-4d7e-4e0a-b3c6-9f2d5a8b1e14",
"title": "Finance",
"snippet": "He subido el presupuesto revisado, echadle un ojo antes del jueves",
"parent_id": "3c8a1e6f-9d2b-4f5a-a7e4-1b6c9d3f0e25",
"rank": 0.0607927
}
]
}Errores
| Estado | Cuándo |
|---|---|
400 | Falta workspace_id o q. |
Las bases de datos, los eventos del calendario, las tarjetas y los archivos de Mi unidad no aparecen en los resultados.
Almacenamiento (Mi unidad)
Mi unidad es tu almacenamiento personal de archivos. La API puede listar carpetas y archivos, descargar un archivo, subir archivos nuevos y mandarlos a la papelera. No hay endpoint para renombrar ni mover archivos; eso se hace en la app. Mira Mi unidad.
Mi unidad es tuya, no de un espacio de trabajo, así que para leerla no hace falta workspace_id (si lo mandas, se ignora). Para subir sí: mira Subir un archivo. Los archivos de la papelera no aparecen.
Listar una carpeta
GET /api/v1/storage
Devuelve las carpetas y los archivos que hay directamente dentro de una carpeta de tu unidad, cada grupo ordenado por position.
Permiso (scope): storage:read
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
folder_id | query | string | No | Carpeta que quieres listar. Sin él, la raíz de Mi unidad. |
La respuesta trae dos listas: folders (id, parent_folder_id, name, position) y files (id, folder_id, attachment_id, position, filename, mime_type, size_bytes). Para recorrer toda la unidad, vuelve a llamar con el id de cada carpeta.
curl "https://app.tylode.com/api/v1/storage?folder_id=FOLDER_ID" \
-H "Authorization: Bearer tylode_pat_xxx"Respuesta 200
{
"data": {
"folders": [
{
"id": "3b6d9f2c-5e8a-4a1b-b4d7-0a3e6c9f2b25",
"parent_folder_id": "4c7e0a3d-6f9b-4b2c-a5e8-1b4f7d0a3c36",
"name": "Invoices",
"position": 0
}
],
"files": [
{
"id": "5d8f1b4e-7a0c-4c3d-b6f9-2c5a8e1b4d47",
"folder_id": "4c7e0a3d-6f9b-4b2c-a5e8-1b4f7d0a3c36",
"attachment_id": "6e9a2c5f-8b1d-4d4e-a7a0-3d6b9f2c5e58",
"position": 0,
"filename": "contract-northwind.pdf",
"mime_type": "application/pdf",
"size_bytes": 248193
}
]
}
}Si la carpeta no existe o no es tuya, recibes dos listas vacías.
Obtener un archivo
GET /api/v1/storage/:id
Devuelve los datos de un archivo y un download_url temporal.
Permiso (scope): storage:read
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
id | path | string | Sí | ID del archivo (el id del listado de la carpeta, no el attachment_id). |
El download_url es un enlace firmado que vale 10 minutos (expires_in_seconds es 600). Descárgalo con un GET normal, sin la cabecera Authorization. Cualquiera que tenga el enlace puede descargar el archivo hasta que caduque, así que no lo compartas ni lo guardes en logs; pide uno nuevo cuando lo necesites.
# 1. Pide los datos del archivo y un enlace nuevo
curl https://app.tylode.com/api/v1/storage/FILE_ID \
-H "Authorization: Bearer tylode_pat_xxx"
# 2. Descárgalo (usa el download_url del paso 1)
curl -L -o contract-northwind.pdf "DOWNLOAD_URL"import { writeFile } from "node:fs/promises";
const file = await tylode(`/storage/${FILE_ID}`);
const res = await fetch(file.download_url); // sin cabecera Authorization
await writeFile(file.filename, Buffer.from(await res.arrayBuffer()));Respuesta 200
{
"data": {
"id": "5d8f1b4e-7a0c-4c3d-b6f9-2c5a8e1b4d47",
"folder_id": "4c7e0a3d-6f9b-4b2c-a5e8-1b4f7d0a3c36",
"attachment_id": "6e9a2c5f-8b1d-4d4e-a7a0-3d6b9f2c5e58",
"filename": "contract-northwind.pdf",
"mime_type": "application/pdf",
"size_bytes": 248193,
"download_url": "https://…/contract-northwind.pdf?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
"expires_in_seconds": 600
}
}Errores
| Estado | Cuándo |
|---|---|
404 | El archivo no existe, no es tuyo, está en la papelera o no tiene contenido guardado. |
Subir un archivo
POST /api/v1/storage
Sube un archivo a Mi unidad, en la raíz o en una carpeta. Funciona como subirlo desde la app: se admiten los mismos tipos de archivo y cuenta para el almacenamiento de tu plan.
Permiso (scope): storage:write
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
workspace_id | body | string | Sí | El espacio desde el que subes. Mi unidad es tuya, pero el archivo se guarda como adjunto de ese espacio, así que necesitas poder subir archivos en él. |
filename | body | string | Sí | Nombre del archivo, con su extensión. Hasta 255 caracteres; las barras (/ y \) se cambian por _ y se quitan los caracteres de control e invisibles (como los que invierten la dirección del texto). |
content_base64 | body | string | Sí | El contenido del archivo, en base64. |
mime_type | body | string | No | Tipo del archivo, como application/pdf o image/png. Solo cuenta si la extensión no es conocida: para las conocidas (.pdf, .png, .docx…), el tipo sale de la extensión. Por defecto, application/octet-stream. |
folder_id | body | string | No | Carpeta de Mi unidad en la que se guarda, de Listar una carpeta. Por defecto, la raíz. |
Límites:
- Hasta 3 MB por archivo a través de la API. Para archivos más grandes, súbelos desde la app.
- Los mismos tipos de archivo que en la app. No se pueden subir páginas HTML, SVG, JavaScript ni ejecutables.
- El almacenamiento de tu plan. Si el archivo no cabe, la subida se rechaza con un mensaje que lo explica. Mira Límites.
curl -X POST https://app.tylode.com/api/v1/storage \
-H "Authorization: Bearer tylode_pat_xxx" \
-H "Content-Type: application/json" \
-d "{
\"workspace_id\": \"WORKSPACE_ID\",
\"filename\": \"invoice-2026-09.pdf\",
\"mime_type\": \"application/pdf\",
\"content_base64\": \"$(base64 < invoice-2026-09.pdf | tr -d '\n')\"
}"import { readFile } from "node:fs/promises";
const content = await readFile("invoice-2026-09.pdf");
const file = await tylode("/storage", {
method: "POST",
body: {
workspace_id: WORKSPACE_ID,
filename: "invoice-2026-09.pdf",
mime_type: "application/pdf",
content_base64: content.toString("base64"),
},
});
console.log(file.id);Respuesta 201
El archivo nuevo, con los mismos campos que en Listar una carpeta. Con su id puedes pedir el enlace de descarga en Obtener un archivo.
{
"data": {
"id": "7f0b3d6a-9c2e-4f5a-b8d1-4e7a0c3f6b69",
"folder_id": "4c7e0a3d-6f9b-4b2c-a5e8-1b4f7d0a3c36",
"attachment_id": "8a1c4e7b-0d3f-4a6c-9b2e-5f8d1a4c7e70",
"position": 0,
"filename": "invoice-2026-09.pdf",
"mime_type": "application/pdf",
"size_bytes": 182344
}
}Errores
| Estado | Cuándo |
|---|---|
400 | Falta workspace_id, filename o content_base64, o folder_id no es un ID válido. |
400 | content_base64 no es base64 válido. |
400 | Ese tipo de archivo no se puede subir. Los ejecutables, los scripts, el HTML y el SVG se rechazan por su extensión, aunque declares otro tipo. |
400 | No se ha podido subir: no puedes subir archivos en ese espacio o el archivo no cabe en el almacenamiento de tu plan. |
404 | La carpeta no existe, no es tuya o está en la papelera. |
413 | El archivo pasa de 3 MB. |
Mover un archivo a la papelera
DELETE /api/v1/storage/:id
Manda un archivo a la papelera de Mi unidad, igual que al borrarlo en la app. Se puede recuperar desde ahí, y mientras está en la papelera no sale en Listar una carpeta.
Permiso (scope): storage:delete
| Parámetro | Dónde | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
id | path | string | Sí | ID del archivo (el id del listado de la carpeta, no el attachment_id). |
curl -X DELETE https://app.tylode.com/api/v1/storage/FILE_ID \
-H "Authorization: Bearer tylode_pat_xxx"Respuesta 200
{ "data": { "id": "5d8f1b4e-7a0c-4c3d-b6f9-2c5a8e1b4d47", "papelera": true } }Errores
| Estado | Cuándo |
|---|---|
400 | El ID no es válido. |
404 | El archivo no existe, no es tuyo o ya está en la papelera. |
Lo que tienen en común todos los DELETE está en Borrar: papelera o para siempre.
Relacionado
- Pizarras, Estudio y Mi unidad en la app
- API de páginas, para abrir una página que hayas encontrado con la búsqueda
- API de chats, correo y notificaciones
- MCP:
search_workspace,list_drive,get_drive_file,upload_drive_filey las herramientas de pizarras y presentaciones usan estos mismos endpoints