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 threadyopenemail draftfuncionan igual que los nombres en plural.openemail labelsno tiene forma singular:openemail labeles el comando de correo que pone etiquetas a los hilos.- Los verbos aceptan los alias habituales:
lsparalist,showyviewparaget,newyaddparacreate,editparaupdate, yrm,delyremoveparadelete. - Cada opción está en
openemail <namespace> <verb> --help, comoopenemail threads list --help.
Hilos
Las conversaciones del buzón. Un id de hilo como CAHk7pQ2x9LmZ4 sale de threads list, openemail inbox u openemail search.
| Comando | Qué hace |
|---|---|
| openemail threads list | Listar 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 |
--folderesinboxpor defecto y se compara como un id de etiqueta, así que funcionansent,archive,spam,trash,draft,snoozed,starredyunread,binse lee comotrash, y también funciona un id de etiqueta de usuario comoUSER_RECEIPTS. Una carpeta que no coincide con nada devuelve una página vacía, no un error.--queryacepta la sintaxis de búsqueda de la app, ein:anywherebusca en todas las carpetas.--label-idsfiltra aún más, ya que un hilo debe llevar la carpeta y cada id que pases.--date-fromy--date-toleen el mensaje más reciente de cada hilo, y ambos extremos se incluyen.threads getincluye entre los mensajes las respuestas en borrador sin enviar, marcadas conisDraft: true, y también abre un id de borrador.threads updatenecesita--read,--no-reado 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 conlabel_not_foundy no cambia nada en el hilo, así que crea primero la etiqueta.TRASH,SNOOZEDyDRAFTse rechazan conlabel_not_directly_settable: usathreads trashythreads snooze.threads trashno elimina nada, y el hilo sigue pudiéndose leer conthreads 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 snoozeenvía<wake-at>tal cual, así que dale un instante ISO 8601 futuro conZo un desfase, porque una hora sin ninguno se lee en la zona horaria del servidor. Un retraso como3hse rechaza por no válido.openemail snooze --until 3hacepta 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-attachmentsdevuelve cada archivo entero en una sola respuesta. Toma el id del mensaje de losmessagesdethreads get.contentes 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-.
| Comando | Qué hace |
|---|---|
| openemail drafts list | Listar 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 create | Guardar 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 --querybusca en el asunto, el remitente y el principio del cuerpo, y nunca sale de los borradores.older_than:30dy los demás operadores de fecha leen cuándo se guardó el borrador por última vez, yto:,cc:ybcc:no coinciden con nada en un borrador.- Un borrador se guarda como un hilo con la etiqueta
DRAFT, así quethreads getabre uno yopenemail inbox draftlos lista.drafts get,updateydeleterechazan un id de hilo normal con un 404. - Un
openemail drafts createsin nada más guarda un borrador en blanco. Solo se comprueban las longitudes: un asunto de hasta 998 caracteres, y--htmly--textde hasta 1,000,000 cada uno, y se conserva--htmlcuando se definen los dos. No hay opción para adjuntos. drafts updatesustituye cada campo que envías. Una lista sustituye entera a la guardada, así que--tocon una sola dirección quita las demás, y una actualización vacía la lista de adjuntos del borrador.--thread-idregistra el hilo al que responde un borrador, pero el borrador se sigue guardando como un hilo propio.- Volver a ejecutar
drafts createguarda 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,--templateni--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.
| Comando | Qué hace |
|---|---|
| openemail labels list | Listar las etiquetas de usuario del espacio de trabajo, ordenadas por nombre, cada una con su color, threadCount, createdAt y updatedAt |
| openemail labels list-colors | Listar 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,STARREDyUNREADno se listan y no se pueden cambiar ni eliminar, aunquethreads updatelas acepta.labels getsobre 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
#3B82F6o un token de degradado comogradient:sunset.--label-coloracepta el color entero como JSON, y--label-color nulllo borra. - Una etiqueta pertenece al espacio de trabajo, así que renombrarla, cambiarle el color o eliminarla la cambia para todos sus miembros.
labels deleteno se puede deshacer. Volver a crear una etiqueta con el mismo nombre da el mismo id, pero los hilos no la recuperan. SuthreadCountenlabels getdice cuántas conversaciones la perderán.
Cómo los usan los comandos de correo
| Comando de correo | Qué 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
--jsonmuestra{ results, succeeded, failed }. Un comando de esta página acepta un solo id y muestra lo que devuelve la API. openemail inboxlee cada hilo que lista para mostrar quién escribió el último y el asunto.threads listhace una solicitud por página y muestra solo ids, que es todo lo que necesita un pipeline.openemail readconvierte un mensaje HTML en texto y marca el hilo como leído.threads getmuestra 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:
openemail threads update CAHk7pQ2x9LmZ4 --read --add-label-ids ARCHIVE,USER_RECEIPTS --remove-label-ids INBOX --jsonCrea una etiqueta y archiva debajo de ella cada hilo que coincida. Redirigido, --all muestra un objeto JSON por línea:
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_RECEIPTSGuarda un archivo de un mensaje. Los ids de los mensajes están en los messages de threads get:
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.pdfEscribe un borrador, cámbialo, vuelve a leerlo y luego envíalo:
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:
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.txtElige un degradado de la paleta, previsualiza el cambio, hazlo y, más tarde, vuelve a quitar el color:
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 nullScopes y códigos de verificación
| Scope | Comandos |
|---|---|
| threads:read | threads list, get y list-attachments |
| threads:write | threads update, trash, snooze y unsnooze |
| drafts:read | drafts list y get |
| drafts:write | drafts create, update y delete |
| labels:read | labels list, list-colors y get |
| labels:write | labels 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 listylabels listleen una página, de 25 salvo que--limitindique otra cosa, hasta 100.--cursorsigue 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.--alllee todas las páginas y--max <n>se detiene tras esa cantidad. Redirigido o con--ndjsonmuestra un objeto JSON por línea, y con--jsonun único documento{ items, hasMore, nextCursor }.hasMorepuede 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 deleteylabels deletepiden que confirmes. Sin supervisión, con--json,--no-inputo sin terminal, se detienen con el código de salida2y no cambian nada salvo que pases--yes.--dry-runmuestra la solicitud que enviaría un comando, con la credencial ocultada, y sale con el código0sin enviarla ni pedir confirmación. Con--jsonmuestra{ 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.
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
openemail threads --helpopenemail threads list --helpopenemail drafts create --help --jsonopenemail <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.