Ir a la documentación
CLI

Hilos, borradores y etiquetas

Cada comando de los espacios de nombres threads, drafts y labels, y cómo encajan bajo inbox, read, archive y los demás comandos de correo.

Descripción general

Los comandos de correo, como inbox, read, archive y label add, están escritos para personas: aceptan varios ids de hilo a la vez, dan formato a lo que muestran y mantienen ocultos los ids de las etiquetas. Cada uno ejecuta comandos de esta página, que son los métodos del SDK para hilos, borradores y etiquetas, un comando por método, así que threads.listAttachments es openemail threads list-attachments.

Usa estos cuando necesites lo que los comandos de correo dejan fuera: un hilo exactamente como lo devuelve la API, los archivos de un mensaje, los borradores, y crear, renombrar, cambiar de color o eliminar etiquetas.

  • openemail thread y openemail draft funcionan igual que los nombres en plural. openemail labels no tiene forma singular: openemail label es el comando de correo que pone etiquetas a los hilos.
  • Los verbos aceptan los alias habituales: ls para list, show y view para get, new y add para create, edit para update, y rm, del y remove para delete.
  • Cada opción está en openemail <namespace> <verb> --help, como openemail threads list --help.

Hilos

Las conversaciones del buzón. Un id de hilo como CAHk7pQ2x9LmZ4 sale de threads list, openemail inbox u openemail search.

ComandoQué hace
openemail threads listListar una página de hilos de una carpeta, del más reciente al más antiguo. Cada fila es solo un id. --folder, --query, --label-ids, --sort, --date-from, --date-to y --from-contacts la filtran y la ordenan
openemail threads get <id>Leer un hilo con todos sus mensajes, del más antiguo al más reciente, con sus etiquetas y su estado de no leído
openemail threads update <id>Marcar un hilo como leído con --read o como no leído con --no-read, y poner o quitar etiquetas con --add-label-ids y --remove-label-ids, hasta 50 de cada
openemail threads trash <id>Mover un hilo a la Papelera, fuera de la bandeja de entrada, el spam, los pospuestos y el archivo en un solo paso. Pide que confirmes
openemail threads snooze <id> <wake-at>Ocultar un hilo hasta un instante futuro, como 2026-10-01T09:00:00Z. Posponerlo de nuevo sustituye la hora de reactivación
openemail threads unsnooze <id>Devolver ahora un hilo pospuesto a la bandeja de entrada y borrar su hora de reactivación
openemail threads list-attachments <id> <message-id>Listar los adjuntos de un mensaje, cada uno con sus bytes en línea como base64 en content
  • --folder es inbox por defecto y se compara como un id de etiqueta, así que funcionan sent, archive, spam, trash, draft, snoozed, starred y unread, bin se lee como trash, y también funciona un id de etiqueta de usuario como USER_RECEIPTS. Una carpeta que no coincide con nada devuelve una página vacía, no un error.
  • --query acepta la sintaxis de búsqueda de la app, e in:anywhere busca en todas las carpetas. --label-ids filtra aún más, ya que un hilo debe llevar la carpeta y cada id que pases. --date-from y --date-to leen el mensaje más reciente de cada hilo, y ambos extremos se incluyen.
  • threads get incluye entre los mensajes las respuestas en borrador sin enviar, marcadas con isDraft: true, y también abre un id de borrador.
  • threads update necesita --read, --no-read o una etiqueta que añadir o quitar. Las eliminaciones se aplican antes que las adiciones. Un id de etiqueta que no corresponde a ninguna etiqueta se rechaza con label_not_found y no cambia nada en el hilo, así que crea primero la etiqueta. TRASH, SNOOZED y DRAFT se rechazan con label_not_directly_settable: usa threads trash y threads snooze.
  • threads trash no elimina nada, y el hilo sigue pudiéndose leer con threads get, pero ningún comando saca un hilo de la Papelera. Mover a la Papelera un hilo pospuesto cancela también su reactivación.
  • threads snooze envía <wake-at> tal cual, así que dale un instante ISO 8601 futuro con Z o un desfase, porque una hora sin ninguno se lee en la zona horaria del servidor. Un retraso como 3h se rechaza por no válido. openemail snooze --until 3h acepta un retraso. Los hilos se reactivan en un barrido cada hora, con hasta una hora de retraso, y siempre en la bandeja de entrada.
  • threads list-attachments devuelve cada archivo entero en una sola respuesta. Toma el id del mensaje de los messages de threads get. content es una cadena vacía cuando no se encuentran los bytes guardados, así que comprueba su longitud antes de decodificarlo.

Borradores

Mensajes sin enviar guardados en el buzón. Un id de borrador empieza por draft-.

ComandoQué hace
openemail drafts listListar una página de borradores, del guardado más recientemente al más antiguo. Cada fila es solo un id, y --query busca entre ellos
openemail drafts get <id>Leer los destinatarios, el asunto, el cuerpo y el remitente de un borrador, el hilo al que responde y los nombres de sus adjuntos
openemail drafts createGuardar un borrador nuevo a partir de --to, --cc, --bcc, --subject, --html, --text, --from y --thread-id, todos opcionales
openemail drafts update <id>Cambiar campos de un borrador guardado. Un campo que omitas conserva su valor
openemail drafts delete <id>Eliminar un borrador para siempre. No va a la Papelera. Pide que confirmes
  • drafts list --query busca en el asunto, el remitente y el principio del cuerpo, y nunca sale de los borradores. older_than:30d y los demás operadores de fecha leen cuándo se guardó el borrador por última vez, y to:, cc: y bcc: no coinciden con nada en un borrador.
  • Un borrador se guarda como un hilo con la etiqueta DRAFT, así que threads get abre uno y openemail inbox draft los lista. drafts get, update y delete rechazan un id de hilo normal con un 404.
  • Un openemail drafts create sin nada más guarda un borrador en blanco. Solo se comprueban las longitudes: un asunto de hasta 998 caracteres, y --html y --text de hasta 1,000,000 cada uno, y se conserva --html cuando se definen los dos. No hay opción para adjuntos.
  • drafts update sustituye cada campo que envías. Una lista sustituye entera a la guardada, así que --to con una sola dirección quita las demás, y una actualización vacía la lista de adjuntos del borrador.
  • --thread-id registra el hilo al que responde un borrador, pero el borrador se sigue guardando como un hilo propio.
  • Volver a ejecutar drafts create guarda un segundo borrador, porque no acepta clave de idempotencia. Un nombre visible con una coma se divide en dos destinatarios rotos, así que no pongas la coma.
  • openemail send --draft <id> --to <address> envía un borrador. El cuerpo sale del borrador, y también el asunto salvo que pases --subject, mientras que los destinatarios son los que nombras. No se puede combinar con un cuerpo, --template ni --translate.

Etiquetas

Las etiquetas que puede llevar un hilo. Un id de etiqueta de usuario es USER_ seguido del nombre con el que se creó, en mayúsculas, con cada tramo de espacios convertido en _, así que Big Clients es USER_BIG_CLIENTS.

ComandoQué hace
openemail labels listListar las etiquetas de usuario del espacio de trabajo, ordenadas por nombre, cada una con su color, threadCount, createdAt y updatedAt
openemail labels list-colorsListar la paleta que ofrece la app, catorce colores sólidos y siete degradados. value es lo que hay que pasar como color
openemail labels get <id>Leer una etiqueta de usuario, con su id comparado distinguiendo mayúsculas y minúsculas
openemail labels create --name <value>Crear una etiqueta de usuario. --color-background-color le da un color
openemail labels update <id>Renombrar una etiqueta o cambiarle el color. El id se mantiene, y también los hilos que la llevan
openemail labels delete <id>Eliminar una etiqueta y quitarla de todos los hilos que la llevaban. Pide que confirmes
  • Un id nunca cambia, ni siquiera tras renombrar, así que guarda ids en lugar de nombres.
  • Las etiquetas del sistema como INBOX, STARRED y UNREAD no se listan y no se pueden cambiar ni eliminar, aunque threads update las acepta. labels get sobre una de ellas da 404.
  • Un espacio de trabajo tiene hasta 50 etiquetas de usuario. Un nombre que ya tiene otra etiqueta, comparado sin distinguir mayúsculas, se rechaza con label_name_taken.
  • Un color es un valor hexadecimal como #3B82F6 o un token de degradado como gradient:sunset. --label-color acepta el color entero como JSON, y --label-color null lo borra.
  • Una etiqueta pertenece al espacio de trabajo, así que renombrarla, cambiarle el color o eliminarla la cambia para todos sus miembros.
  • labels delete no se puede deshacer. Volver a crear una etiqueta con el mismo nombre da el mismo id, pero los hilos no la recuperan. Su threadCount en labels get dice cuántas conversaciones la perderán.

Cómo los usan los comandos de correo

Comando de correoQué ejecuta
inbox [folder]threads list para una página, y luego threads get en cada hilo, de seis en seis
search <query...>threads list --query, y luego threads get en cada hilo
read <thread-id>threads get, y luego threads update --read salvo que pases --no-mark-read
reply <thread-id>threads get para los destinatarios, el asunto y la dirección de envío, y luego emails send en el hilo
archive <thread-id...>threads update --add-label-ids ARCHIVE --remove-label-ids INBOX
unarchive <thread-id...>threads update --add-label-ids INBOX --remove-label-ids ARCHIVE
star, unstar <thread-id...>threads update añadiendo o quitando STARRED
mark read, unread <thread-id...>threads update --read, o --no-read
trash <thread-id...>threads trash
snooze <thread-id...> --until <when>threads snooze, convirtiendo antes en un instante un retraso como 3h
unsnooze <thread-id...>threads unsnooze
label add, remove <thread-id...>threads update --add-label-ids, o --remove-label-ids
send --draft <id>emails send --draft-id
  • Un comando de correo acepta varios ids de hilo e informa sobre cada uno, y con --json muestra { results, succeeded, failed }. Un comando de esta página acepta un solo id y muestra lo que devuelve la API.
  • openemail inbox lee cada hilo que lista para mostrar quién escribió el último y el asunto. threads list hace una solicitud por página y muestra solo ids, que es todo lo que necesita un pipeline.
  • openemail read convierte un mensaje HTML en texto y marca el hilo como leído. threads get muestra el hilo tal como lo devuelve la API y no cambia nada.

Ejemplos

Marca un hilo como leído, archívalo y etiquétalo en una sola solicitud, donde mark read, archive y label add harían tres:

Una sola actualización
openemail threads update CAHk7pQ2x9LmZ4 --read --add-label-ids ARCHIVE,USER_RECEIPTS --remove-label-ids INBOX --json

Crea una etiqueta y archiva debajo de ella cada hilo que coincida. Redirigido, --all muestra un objeto JSON por línea:

Etiquetar una búsqueda
openemail labels create --name Receipts --color-background-color gradient:meadowopenemail threads list --query "in:anywhere subject:receipt newer_than:1y" --all | jq -r .id | xargs openemail label add --label USER_RECEIPTS

Guarda un archivo de un mensaje. Los ids de los mensajes están en los messages de threads get:

Guardar un adjunto
openemail threads get CAHk7pQ2x9LmZ4 --json | jq -r ".messages[].id"openemail threads list-attachments CAHk7pQ2x9LmZ4 message_4c1b257a --json | jq -r '.[] | select(.filename == "invoice.pdf") | .content' | base64 --decode > invoice.pdf

Escribe un borrador, cámbialo, vuelve a leerlo y luego envíalo:

Borrador y luego envío
DRAFT=$(openemail drafts create --to [email protected] --subject "Engine notes for Thursday" --html "<p>Agenda below.</p>" --json | jq -r .id)openemail drafts update "$DRAFT" --to [email protected],[email protected]openemail drafts get "$DRAFT"openemail send --draft "$DRAFT" --from [email protected] --to [email protected],[email protected]

Limpia los borradores que nadie ha guardado en 30 días. La simulación muestra cada DELETE sin enviarlo, y --yes responde a la confirmación:

Borradores antiguos
openemail drafts list --query older_than:30d --all | jq -r .id > stale.txtxargs -n 1 openemail drafts delete --dry-run < stale.txtxargs -n 1 openemail drafts delete --yes < stale.txt

Elige un degradado de la paleta, previsualiza el cambio, hazlo y, más tarde, vuelve a quitar el color:

Cambiar el color de una etiqueta
openemail labels list-colors --json | jq -r '.[] | select(.kind == "gradient") | .value'openemail labels update USER_RECEIPTS --name "Receipts 2026" --color-background-color gradient:aurora --dry-runopenemail labels update USER_RECEIPTS --name "Receipts 2026" --color-background-color gradient:auroraopenemail labels update USER_RECEIPTS --label-color null

Scopes y códigos de verificación

ScopeComandos
threads:readthreads list, get y list-attachments
threads:writethreads update, trash, snooze y unsnooze
drafts:readdrafts list y get
drafts:writedrafts create, update y delete
labels:readlabels list, list-colors y get
labels:writelabels create, update y delete

Un scope que falta se detiene con el código de salida 4. Ninguno de estos comandos pide un código de verificación, ni con un inicio de sesión con el navegador ni con una clave de API.

Un inicio de sesión o una clave limitados a algunas direcciones solo ven los hilos entregados a ellas, y cualquier otro hilo da 404, como si no existiera. Las etiquetas pertenecen al espacio de trabajo, así que se siguen viendo todas, pero threadCount cuenta solo las conversaciones que se pueden ver.

Páginas, confirmaciones y simulaciones

  • threads list, drafts list y labels list leen una página, de 25 salvo que --limit indique otra cosa, hasta 100. --cursor sigue desde el cursor que mostró una página. Un cursor de hilos mantiene el orden en que se entregó, así que envía con él los mismos filtros.
  • --all lee todas las páginas y --max <n> se detiene tras esa cantidad. Redirigido o con --ndjson muestra un objeto JSON por línea, y con --json un único documento { items, hasMore, nextCursor }.
  • hasMore puede ser true en lo que resulta ser la última página, y la siguiente llamada no devuelve entonces ningún elemento. Un hilo que recibe correo nuevo mientras paginas se adelanta al cursor y las páginas posteriores no lo devuelven, y lo mismo pasa con un borrador guardado mientras paginas.
  • threads trash, drafts delete y labels delete piden que confirmes. Sin supervisión, con --json, --no-input o sin terminal, se detienen con el código de salida 2 y no cambian nada salvo que pases --yes.
  • --dry-run muestra la solicitud que enviaría un comando, con la credencial ocultada, y sale con el código 0 sin enviarla ni pedir confirmación. Con --json muestra { dryRun, request }.

Cuerpos JSON y borrar un campo

--data recibe el cuerpo entero como JSON, en línea, desde un archivo con @path o desde stdin con -, y una opción que pases además reemplaza su clave.

Un valor de opción vacío es un error de uso, así que un campo que se borra con un valor vacío pasa por --data. --label-color null borra el color de una etiqueta.

Terminal
openemail drafts update draft-5f0c2a9e-8b1d-4e7a-a3c6-2d9f41b7e0c8 --data '{"from":""}'openemail drafts update draft-5f0c2a9e-8b1d-4e7a-a3c6-2d9f41b7e0c8 --data '{"threadId":""}'openemail drafts update draft-5f0c2a9e-8b1d-4e7a-a3c6-2d9f41b7e0c8 --data '{"to":[]}'openemail drafts create --data @draft.json --subject "Overrides the file"

El primero guarda el borrador sin remitente, el segundo lo separa del hilo al que respondía y el tercero borra sus destinatarios.

Todas las opciones

Terminal
openemail threads --helpopenemail threads list --helpopenemail drafts create --help --json

openemail <namespace> <verb> --help muestra cada argumento y opción con su tipo, los scopes que necesita la llamada, su método y ruta, lo que devuelve y las notas de la referencia de la API. Añade --json para obtener la misma ayuda como datos.

Tu bandeja de entrada,
en tus propios términos.

Infraestructura de correo para empresas, IA, agentes y correo personal. Creada para escalar, con privacidad y control. Todo lo que el correo debería haber tenido desde el primer día.

OpenEmail

Infraestructura de correo para empresas, IA, agentes y correo personal. Creada para escalar, con privacidad y control. Todo lo que el correo debería haber tenido desde el primer día.

© 2026 OpenEmail. Todos los derechos reservados.