Ir a la documentación
CLI

Scripts

Salida JSON, flujos, códigos de salida, variables de entorno y ejecución sin supervisión o en CI.

Salida JSON

Con --json, stdout contiene solo JSON, con sangría de dos espacios, mientras las notas y el progreso se quedan en stderr, y nada pregunta. Una lista muestra { items, hasMore, nextCursor }, un objeto de la API se muestra tal como lo devolvió la API, y un comando escrito a mano muestra el objeto que describe su ayuda.

Terminal
openemail whoami --json | jq -r .workspaceIdopenemail emails list --status failed --json | jq -r ".items[].id"

Un error va a stderr como una sola línea de JSON, y el código de salida es el que obtendría una persona:

stderr
{"error":{"type":"permission_error","code":"insufficient_scope","message":"This API key does not have the domains:write scope.","hint":"The credential is missing a scope this call needs. Use a key that has it, or sign in again with openemail login.","next":null,"status":403,"requestId":"req_7Hc2kQ","param":null,"docUrl":"https://openemail.uk/docs/api/errors#insufficient_scope","exitCode":4}}
CampoQué contiene
typeEl tipo de error de la API, o cli_error, network_error o internal_error para un fallo dentro de la CLI
codeUn código estable como insufficient_scope, not_signed_in o unknown_flag
messageQué salió mal, en una frase
hint, nextQué probar, y el comando que ejecutar después, o null
status, requestId, param, docUrlDe la API cuando el error vino de ella, si no null
exitCodeEl código de salida con el que termina el proceso

Flujos

Parte de la salida es un flujo de objetos JSON, uno por línea, para que un pipeline procese cada elemento en cuanto llega:

  • Una lista de recursos con --all cuando stdout no es un terminal, o con --ndjson. --max <n> se detiene tras esa cantidad de elementos.
  • openemail temp watch --json, una línea por mensaje nuevo.
  • openemail mcp serve, un mensaje JSON-RPC por línea en cada dirección.
Terminal
openemail contacts list --all > contacts.ndjsonopenemail emails list --status failed --all --max 500 | jq -r .id

Códigos de salida

CódigoSignificado
0Hecho
1Un fallo inesperado, un error del servidor o un envío que falló
2Un error de uso: un argumento incorrecto, un comando o una opción desconocidos, un valor o una confirmación que no se pudo pedir, o un origen o una ruta a los que la CLI no enviará una credencial
3Sin sesión iniciada, o el inicio de sesión se rechazó, caducó o se cerró mientras se ejecutaba el comando
4No permitido: falta un scope o un permiso, un código de verificación que no se pudo pedir o está en pausa, o una clave de API donde hace falta un inicio de sesión con el navegador
5No encontrado
6Un conflicto con el estado actual
7La entrada no era válida
8Límite de peticiones, o la asignación de IA está agotada
9La red falló o se agotó el tiempo
10Cancelado: rechazaste una confirmación o una solicitud
130, 143Detenido con Ctrl+C, o por SIGTERM

Variables de entorno

VariableQué hace
OPENEMAIL_API_KEYUna clave de API que usar en lugar de cualquier perfil guardado
OPENEMAIL_PROFILEEl perfil guardado que usar
OPENEMAIL_BASE_URLEl origen de la API para OPENEMAIL_API_KEY, --api-key y los comandos que no envían ninguna credencial. Un inicio de sesión guardado solo va a la API en la que inició sesión
OPENEMAIL_APP_URLEl origen de la app web, para el inicio de sesión, open y los enlaces a la documentación
OPENEMAIL_CONFIG_DIRDónde se guardan los perfiles y los tokens de bandeja, ~/.openemail si no se define
OPENEMAIL_NO_UPDATE_CHECKNo buscar nunca en npm una versión más nueva. OPENEMAIL_DISABLE_UPDATE_NOTICE hace lo mismo
NO_COLOR, FORCE_COLOR=0Sin color
CINo preguntar nunca, no abrir nunca un navegador, no buscar nunca actualizaciones. La mayoría de los servicios de CI se reconocen sin ella
VISUAL, EDITOREl editor que send y reply abren para un cuerpo

Ejecuciones sin supervisión

La CLI solo pregunta cuando stdin y stdout son ambos terminales, y no se aplica ninguno de --json, --no-input o CI. Si no:

  • Un valor obligatorio que falta se detiene con el código de salida 2 y nombra la opción que hay que pasar.
  • Un comando destructivo se detiene con Refusing to run unattended. Pass --yes to confirm. y el código de salida 2, salvo que pases --yes.
  • Un cambio que necesita un código de verificación se detiene con el código de salida 4, porque nadie puede escribirlo. Usa una clave de API, o ejecuta primero openemail verify.

En CI

Dale al trabajo una clave de API con solo los scopes que necesita, guárdala en un secreto y deja que OPENEMAIL_API_KEY la lleve. No se guarda nada, nada pregunta y no se ejecuta ninguna comprobación de actualizaciones.

.github/workflows/deploy.yml
- name: Tell the team  env:    OPENEMAIL_API_KEY: ${{ secrets.OPENEMAIL_API_KEY }}  run: |    npx -y @openemail/[email protected] send \      --from [email protected] \      --to [email protected] \      --subject "Deployed ${{ github.sha }}" \      --text "Build ${{ github.run_number }} is live." \      --idempotency-key "deploy-${{ github.run_id }}"
Esperar un correo de registro
ADDRESS=$(npx -y @openemail/[email protected] temp new --ttl 15)./signup-test.sh "$ADDRESS"npx -y @openemail/[email protected] temp watch --first --json | jq -r .snippetnpx -y @openemail/[email protected] temp delete --yes
Fallar ante envíos fallidos
failed=$(openemail emails list --status failed --json | jq ".items | length")test "$failed" -eq 0

Pasa --idempotency-key en un envío que un pipeline pueda reintentar, y derívala de lo que hizo necesario el envío, como un id de ejecución. Repetir el paso devuelve entonces el primer envío en lugar de enviar dos veces.

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.