Datos: colecciones e ítems
Guarda datos estructurados en colecciones, créalos, búscalos por texto y contrólalos.
Una colección es una tabla de datos estructurados del workspace; sus registros son ítems. Es el almacén que tu Met puede leer como fuente de datos y que tú operas por API para guardar, buscar y actualizar información. Trabaja server-side con tu key:
const met = new Met(key, { workspaceId });
Colecciones
const col = await met.collections.create({ name: 'Preferencias' });
await met.collections.list(); // Collection[]
await met.collections.retrieve(col.id);
await met.collections.update(col.id, { name: 'Preferencias del cliente' });
await met.collections.delete(col.id);
create acepta name y un folder_id? opcional (scopes collections:read/collections:write). El id de una colección es numérico.
Ocultar una colección al Met sin borrarla: ponla en
expose_to_agent: false(defaulttrue). El Met deja de verla como fuente de datos, pero tú la sigues operando por API. Reexponla conupdate(col.id, { expose_to_agent: true }). Más contexto en Mets y herramientas.
Ítems
El primer argumento de casi todo es el collectionId numérico:
const item = await met.items.create(col.id, { nombre: 'Ana', canal: 'preferido' });
await met.items.list(col.id); // una página { data, has_more }
for await (const it of met.items.iterate(col.id)) { /* todas las páginas */ }
await met.items.retrieve(item.id);
await met.items.update(col.id, item.id, { canal: 'whatsapp' });
await met.items.patchField(col.id, item.id, 'canal', 'email'); // un solo campo
await met.items.setStatus(item.id, 'archivado');
await met.items.delete(item.id);
Los datos del ítem viven en item.data. Si un campo es una fórmula ("=…"), su resultado resuelto aparece en item.computed[campo] — data conserva la fórmula cruda; escribe siempre sobre data. Para un ítem sin colección (a nivel workspace) usa met.items.createOrphan(body).
Búsqueda
met.items.search(query) devuelve un Item[] con las coincidencias en todo el workspace:
const encontrados = await met.items.search('descuento anual');
Es búsqueda léxica por texto: coincide por las palabras que aparecen en los campos del ítem. No es semántica ni vectorial — no hay embeddings ni ranking por significado, así que busca por los términos literales que esperas encontrar. Para acotar por otro campo, filtra el resultado en tu código:
const soloDeAna = (await met.items.search('preferencia'))
.filter((it) => it.data?.contact_id === 42);
Ejemplo: memoria por cliente
Una colección de preferencias, un ítem por contacto, y recuperación por búsqueda + filtro:
const prefs = await met.collections.create({ name: 'preferencias' });
await met.items.create(prefs.id, {
contact_id: 42,
nota: 'Prefiere que le escriban por la mañana, tono cercano.',
});
// Más tarde: recuperar lo que sabemos de ese contacto
const memoria = (await met.items.search('prefiere'))
.filter((it) => it.data?.contact_id === 42);
Como search es léxica, guarda en el texto del ítem las palabras por las que luego querrás encontrarlo.
Carpetas
Cuando el workspace pasa de unas diez colecciones, el panel las agrupa en carpetas. Es organización de la vista, no del dato: mover una colección de carpeta no cambia sus ítems ni rompe ninguna referencia.
const carpetas = await met.folders.list();
const arbol = await met.folders.hierarchy();
list() devuelve las carpetas planas; hierarchy() las devuelve anidadas, que es lo que quieres para pintar un árbol sin reconstruir la relación padre-hijo a mano.
const f = await met.folders.create({ name: 'Operación' });
await met.folders.move(f.id, null); // null = raíz
await met.folders.reorder([f.id, otra.id]);
move acepta null como padre para sacar una carpeta a la raíz. El orden es explícito y persistente: reorder recibe los ids en el orden que quieres, y reorderCollectionsInFolder hace lo mismo con las colecciones de una carpeta. No hay orden alfabético automático — si no reordenas, quedan como se crearon.
Slugs: URLs legibles en vez de ids
Un ítem y una colección tienen id numérico, y además pueden tener un slug. Sirve para que tu integración no tenga que guardar ids nuestros:
await met.slugs.updateCollectionSlug(collection.id, 'facturas');
await met.slugs.updateItemSlug(item.id, 'inv-001');
const col = await met.slugs.resolveCollectionBySlug('facturas');
const inv = await met.slugs.resolveItemBySlug(col.id, 'inv-001');
El slug de un ítem es único dentro de su colección, no en todo el workspace: por eso resolveItemBySlug pide las dos cosas. El de una colección sí es único en el workspace.
Hay dos formas más de llegar a algo, y la diferencia importa:
// Por ruta legible: carpeta/colección
const r = await met.slugs.resolvePath('operacion/facturas');
// Por código corto del ítem (el que muestra el panel)
const x = await met.slugs.resolveByCode('AB/12');
resolvePath es para construir URLs que un humano lee y edita. resolveByCode es para el camino inverso: alguien te dicta el código que ve en pantalla y lo tienes que encontrar. El código lo genera Meteor y no cambia; el slug lo pones tú y puede cambiar, así que no lo uses como identificador estable en tu base — para eso está el id, o el código.