Ir a la documentación
Python

Listar y obtener

`emails.list`, `emails.list_all`, `emails.iterate`, `emails.get` y `emails.list_events`.

emails.list

list_emails.py
from openemail import openemail first = openemail.emails.list(status=['queued', 'scheduled'], from_='[email protected]', limit=50) if first['nextCursor']:    second = openemail.emails.list(        status=['queued', 'scheduled'],        from_='[email protected]',        limit=50,        cursor=first['nextCursor'],    )

Una página es {'items': [...], 'hasMore': ..., 'nextCursor': ...}. Devuelve nextCursor como cursor, con los mismos filtros, para obtener la página siguiente.

emails.iterate y emails.list_all

iterate_emails.py
import sys from openemail import openemail for email in openemail.emails.iterate(status='failed'):    print(email['id'], email['lastError'], file=sys.stderr) failures = openemail.emails.list_all(status='failed', from_='[email protected]')

Ambos siguen nextCursor por ti. iterate es un generador que obtiene una página solo cuando el bucle llega a ella, así que salir del bucle detiene las solicitudes, mientras que list_all recorre todas las páginas antes de devolver una única lista, así que dale un filtro que termine. En ambos casos es paginación por keyset, de modo que un mensaje que llegue a mitad de la iteración no puede hacer que se salte una fila, como ocurriría con un offset.

emails.get y emails.list_events

get_email.py
from openemail import openemail email = openemail.emails.get('msg_…')print(email['status'], email['recipients']) events = openemail.emails.list_all_events('msg_…')for event in events:    print(event['type'], event['createdAt'])

get es la única llamada que devuelve recipients, una fila por dirección. Una lista de cincuenta mensajes que llevan cada uno sus destinatarios es un informe de una página que nadie pidió.

Parámetros

statusEmailStatus | Sequence[EmailStatus]
Un estado o varios (`queued`, `scheduled`, `sending`, `sent`, `partial`, `bounced`, `cancelled`, `failed`), que coinciden con cualquiera de los indicados. El SDK envía una lista como un único valor separado por comas porque el servidor divide por comas; un valor fuera de ese conjunto es un 422 que nombra el desconocido.
broadcast_idstr
Solo las copias de un envío masivo, un id `brd_` de `broadcasts.send`. Cada persona a la que llega un envío masivo recibe un mensaje propio, así que esto lista a quién fue y qué pasó con cada copia. `broadcasts.list_recipients` lista a las mismas personas con sus aperturas, clics y bajas.
from_str
Coincidencia exacta con la dirección de envío tal como se registró, que es el `addr@host` escueto en minúsculas. La fila se escribe con cualquier nombre visible eliminado, así que una dirección con ángulos como `Acme <[email protected]>` no coincide con nada. Tu valor se pasa a minúsculas antes de comparar, y es una igualdad, no una coincidencia por prefijo ni por dominio. El guion bajo final está ahí porque `from` es una palabra reservada de Python.
limitint
Filas en esta página, de 1 a 100, con 25 por defecto. Un valor fuera de ese rango se rechaza con un 422 en lugar de recortarse.
cursorstr
Un id de mensaje (`msg_…`) desde el que paginar. Es keyset y no offset: las filas vuelven estrictamente más antiguas que el `createdAt` de ese mensaje, así que los envíos que lleguen a mitad de página no pueden desplazar una fila y hacer que te la saltes. Un id que no nombra ningún mensaje de este espacio de trabajo es un 400.
scheduled_fromdatetime | str
Solo los mensajes programados para este instante o después: un `datetime`, o un instante ISO-8601 con zona horaria. Un mensaje sin `scheduledAt` queda fuera, así que con `scheduled_to` y `status=['queued', 'scheduled']` esto enumera lo que espera para salir en un intervalo.
scheduled_todatetime | str
Solo los mensajes programados para este instante o antes. Un `scheduled_from` posterior a él es un 422 `invalid_parameter` en `scheduledTo`.

Respuesta: Page[EmailResource]

itemslist[EmailResource]
Una página de mensajes, de más nuevo a más antiguo por `createdAt`, extraída del sobre `data` de la API. Las filas de la lista nunca llevan el desglose `recipients` por dirección. Eso está en `get`.
hasMorebool
Si hay más filas que coinciden con el filtro más allá de esta página. Se responde obteniendo una fila más que `limit` en lugar de con una segunda consulta de recuento.
nextCursorstr | None
El id que hay que devolver como `cursor`, y null en la última página. `iterate` y `list_all` se detienen cuando esto es null o `hasMore` es false, ya que una página que afirme que hay más sin nombrar ningún cursor provocaría un bucle infinito.
items[].objectLiteral['email']
Siempre `'email'` en una fila de esta lista.
items[].idstr
El id propio de esta API, `msg_…`. Es lo que aceptan todos los demás endpoints de emails y lo que nombra un cursor.
items[].statusEmailStatus
En qué punto de su vida está el mensaje. `partial` es un estado propio y no una variante de failed: algunos destinatarios ya lo tienen y no se les puede quitar el envío, así que reintentar es un error. `bounced` significa que rebotó en todos los destinatarios después de salir, así que nadie lo tiene, y cada destinatario en `get` dice por qué.
items[].modeApiKeyMode
`live` o `test`, tomado de la clave que lo envió. Un envío de prueba se registra aquí y nunca se transmite.
items[].fromstr
La dirección bajo la que se autorizó el envío, almacenada escueta y en minúsculas, de modo que un nombre visible indicado en `from` sí sale por la red pero no se guarda aquí. Es una cadena simple y no un diccionario porque esta es la identidad que se autorizó: una dirección fuera del ámbito de envío de una clave, que no esté en un dominio que posee ni declarada en ella, se rechaza con un 403 y nunca se cambia en silencio por una que sí lo esté.
items[].subjectstr | None
El asunto tal como está almacenado. Null en un mensaje registrado sin ninguno.
items[].messageIdstr | None
El Message-ID de RFC 5322, no nuestro id. Null hasta que existe el MIME, y el servicio de envío lo reescribe a la salida, así que un rebote o DSN posterior lleva un id distinto y se correlaciona mediante `items[].id`.
items[].threadIdstr | None
El hilo al que pertenece este mensaje, cuando se indicó o se asignó uno. Null en caso contrario.
items[].transportEmailTransport | str | None
Cómo salieron los bytes. Null hasta el despacho, y con tipo abierto para que un transporte que este SDK aún no nombra no sea un cambio incompatible: los registros almacenados pueden seguir nombrando algunos que ya no se usan.
items[].attemptsint
Cuántos intentos de despacho ha tenido el mensaje, 0 antes del primero.
items[].lastErrorstr | None
El error de despacho más reciente, escrito para una persona. Null mientras no haya fallado nada.
items[].scheduledAtstr | None
Cuándo está previsto que salga el mensaje, como instante ISO-8601. Solo es null en un envío inmediato sin ventana de cancelación: una ventana es un retraso corto y nada más, así que `cancellableForSeconds` también rellena este campo, en una fila cuyo `status` es `queued` y no `scheduled`.
items[].cancellableUntilstr | None
El instante en que está previsto que salga el mensaje, con el mismo valor que `scheduledAt` en cualquier envío que se aplazara y null en uno que no. Es una marca de tiempo para mostrar, no la comprobación que hace el servidor: `cancel` ramifica según `status` y solo detiene un mensaje mientras siga en `queued` o `scheduled`.
items[].sentAtstr | None
Cuándo salió. Null hasta que el despacho se ha completado, razón por la cual el campo por el que hay que ramificar es `status` y no este.
items[].tagsdict[str, str]
Las etiquetas indicadas en el envío, devueltas tal cual y nunca interpretadas. Siempre un diccionario (`{}` si no se pusieron, nunca null), y solo devueltas: esta llamada filtra por `status`, `from_`, `broadcast_id`, `scheduled_from` y `scheduled_to`, así que una etiqueta es algo que se lee en un mensaje, no una forma de encontrarlo.
items[].broadcastIdstr | None
El envío masivo `brd_` del que este mensaje es una copia, o null para un mensaje enviado por sí solo.
items[].sourceEmailSource | str
Qué superficie solicitó el envío: `composer`, `api`, `mcp`, `ai`, `oauth` o `form`. `api` es este cliente con una clave de API, y `oauth` es este cliente con un token de acceso.
items[].createdAtstr
Cuándo se escribió el registro de envío, que es antes del despacho. Es el campo por el que ordena la lista y el campo con el que compara un cursor.
items[].trackingNotRequired[EmailTrackingSummary]
El resumen de interacción, presente solo en una fila cuyo mensaje tuvo seguimiento y ausente en caso contrario. Su ausencia es la respuesta a «¿se hizo seguimiento de esto?», mientras que `openCount: 0` se leería como «nadie lo abrió».
items[].tracking.opensbool
Si este mensaje salió con un píxel. Lo que se aplicó a este mensaje, no lo que dice ahora la configuración de la cuenta.
items[].tracking.clicksbool
Si se reescribieron los enlaces de este mensaje. False cuando el cuerpo no tenía enlaces que reescribir, ya que entonces no se cambió nada.
items[].tracking.openedbool
Si se registró alguna apertura contabilizada, derivado de `openCount > 0`.
items[].tracking.clickedbool
Si se registró algún clic contabilizado, derivado de `clickCount > 0`.
items[].tracking.openCountint
Aperturas que se cree causadas por una persona, sumadas sobre cada copia del mensaje. Los escáneres y los proxies de privacidad se registran pero se excluyen, y las peticiones repetidas en menos de treinta segundos se agrupan en una.
items[].tracking.clickCountint
Clics contabilizados, sumados sobre las copias. Se deduplican por enlace y no por mensaje, porque seguir dos enlaces con segundos de diferencia son dos actos y no una repetición.
items[].tracking.firstOpenAtstr | None
La primera apertura contabilizada entre las copias, y null mientras no haya ninguna. Las visitas de máquinas nunca la mueven.
items[].translationNotRequired[EmailTranslationResource]
Nunca está presente en una fila de lista: el registro de traducción vive en la solicitud almacenada, que una lista deliberadamente no obtiene. Su ausencia aquí no dice nada sobre si el mensaje se tradujo. Pregúntale a `get`.

Referencia