---
name: metabase_create_document
kind: function
lang: py
domain: infra
version: "1.1.0"
purity: impure
signature: "def metabase_create_document(client: MetabaseClient, name: str, document: dict, collection_id: int = 0, *, validate: bool = True) -> dict"
description: "Crea un document con contenido ProseMirror. Valida el arbol contra la whitelist de nodos ANTES de enviar (evita documentos que la API acepta pero el frontend renderiza vacíos). Usar prosemirror_card_embed() para embeber cards."
tags: [metabase, document, create, api, prosemirror, python]
uses_functions: [metabase_validate_document_payload_py_infra]
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [httpx, uuid]
params:
  - name: client
    desc: "instancia autenticada de MetabaseClient"
  - name: name
    desc: "titulo del document (1-254 caracteres, no blank)"
  - name: document
    desc: "arbol ProseMirror JSON: {type: 'doc', content: [...]}, o '' para arrancar vacio"
  - name: collection_id
    desc: "ID de coleccion destino (0 = root)"
  - name: validate
    desc: "si True (default), valida el ProseMirror antes de enviar. Lanza ValueError si hay nodos no soportados"
output: "dict: document recien creado con id, entity_id y metadata"
tested: false
tests: []
test_file_path: ""
file_path: "python/functions/metabase/documents.py"
---

## Ejemplo

```python
from metabase.documents import metabase_create_document, prosemirror_card_embed

doc = metabase_create_document(client, "Reporte Q1", {
    "type": "doc",
    "content": [
        {"type": "heading", "attrs": {"level": 1},
         "content": [{"type": "text", "text": "KPIs"}]},
        {"type": "paragraph",
         "content": [{"type": "text", "text": "Revenue por canal:"}]},
        prosemirror_card_embed(42, height=450),
    ]
})
```

## Nodos ProseMirror — whitelist

**Renderizan correctamente** (TipTap v0.59):
`doc, paragraph, text, heading, bulletList, orderedList, listItem, blockquote, codeBlock, horizontalRule, hardBreak, cardEmbed, flexContainer, smartLink, resizeNode, mention`

**La API acepta pero el frontend IGNORA** (resultado: documento vacío):
`callout, taskList, taskItem, details, table, tableRow, tableCell, image, iframe`

**Marks que renderizan:** `bold, italic, strike, code, link`
**Marks ignorados:** `underline, highlight, subscript, textStyle`

## cardEmbed — SIEMPRE envolver en resizeNode

Un `cardEmbed` desnudo renderiza pero queda con ~50px de alto. Metabase espera que vaya dentro de un `resizeNode`:

```python
# MAL — card diminuta
{"type": "cardEmbed", "attrs": {"id": 42}}

# BIEN — usar el helper
from metabase.documents import prosemirror_card_embed
prosemirror_card_embed(42, height=450)
# Genera: {"type": "resizeNode", "attrs": {"height": 450, "minHeight": 280},
#          "content": [{"type": "cardEmbed", "attrs": {"id": 42, ...}}]}
```

## Notas

- La validación (`validate=True`) llama internamente a `metabase_validate_document_payload`. Si detecta nodos no soportados, lanza `ValueError` ANTES de hacer el POST — evita documentos que se ven vacíos.
- Pasar `validate=False` solo si se está experimentando con nodos nuevos.
- Para destacar texto, usar `blockquote` (NO `callout`).
- Cuando embebes un card via `cardEmbed`, Metabase crea una referencia al card — el card debe existir.
