Ir a la documentación
PHP

Archivos

`files->list`, `listAll`, `iterate`, `get`, `download`, `listLinks`, `listAllLinks`, `iterateLinks`, `createLink`, `revokeLink`, `revokeAllLinks`, `stats`, `upload`, `delete` y `deleteMany`.

Todos los métodos

files.php
use OpenEmail\Constants\FileKinds;use OpenEmail\Constants\FileSorts; $largest = $client->files->list(kind: FileKinds::PDF, sort: FileSorts::LARGEST, limit: 1); foreach ($largest as $file) {    foreach ($client->files->listAllLinks($file['id']) as $link) {        echo $link['url'], ' ', $link['downloads'], PHP_EOL;    }     file_put_contents(basename($file['filename']), $client->files->download($file['id']));} $stats = $client->files->stats();echo $stats['totals']['files'], ' ', $stats['uploaded']['bytes'], PHP_EOL;

Cada archivo que guarda el buzón, adjuntos enviados y recibidos y los archivos subidos a él: la página Archivos de la aplicación. download devuelve los bytes como cadena, que file_put_contents guarda sin cambios. Los enlaces son los enlaces de descarga con los que salió un archivo, con cuántas veces se descargó cada uno, y stats es la pestaña Analíticas.

list, listAll e iterate admiten q:, kind: y sort:, y también direction: (inbound, outbound o uploaded), address:, los archivos de una dirección comparada sin distinguir mayúsculas y minúsculas, y since: y until:, un DateTimeInterface o una cadena ISO 8601. since: incluye su momento y until: se detiene antes. Un DateTimeInterface se envía en UTC, y una cadena con una fecha sin hora, como 2026-09-01, se lee como medianoche UTC.

q: busca en el nombre del archivo y en su tipo. kind: es image, pdf, audio, video o text, y sort: es newest, el valor por defecto, oldest, largest o name. OpenEmail\Constants\FileKinds, FileSorts y FileDirections nombran las opciones. list devuelve una OpenEmail\Result\Page, y listAll devuelve todos los archivos en un solo array. iterate devuelve un Generator que entrega un archivo cada vez y solo obtiene la página siguiente cuando el bucle la necesita.

Leer necesita files:read, y subir, eliminar y publicar o revocar enlaces necesitan files:write, que incluye files:read. Una clave creada antes de que los archivos tuvieran ámbitos propios recibió los correspondientes. Una clave sin el ámbito se rechaza con un 403 insufficient_scope, lanzado como una PermissionException cuyo isScopeMissing() es true. Una clave limitada a direcciones o dominios concretos solo ve los archivos que llegaron a ellos, así que no ve los archivos subidos para todo el espacio de trabajo.

download guarda el archivo entero en memoria, así que descarga los archivos muy grandes de uno en uno. Pasa el nombre por basename() antes de escribirlo, como hace el ejemplo, porque viene de quien envió el archivo.

Subir y eliminar

upload.php
$report = "month,sent\n2026-09,1200\n";$upload = $client->files->upload($report, filename: 'report.csv', contentType: 'text/csv'); if ($upload['deletable']) {    $client->files->delete($upload['id']);} $logo = $client->files->upload(new \SplFileInfo('logo.svg'));echo $logo['filename'], ' ', $logo['mimeType'], PHP_EOL; $result = $client->files->deleteMany(['file_0c4e7a91d2b84f63a5e19b7d', 'file_6bb640f5b99e47deb758f1f5']); foreach ($result['kept'] as $kept) {    echo $kept['filename'], ' ', $kept['reason'], PHP_EOL;}

upload guarda los bytes tal cual, hasta 100 MB, con el nombre indicado en filename:, y devuelve el archivo. Un envío lo adjunta como ['fileId' => $upload['id']] en los attachments de emails->send. Pasa contentType:, o datos que lleven su propio tipo, y cualquier otra cosa se guarda como application/octet-stream. El tipo nunca se deduce de filename:, así que una cadena de bytes necesita contentType: para guardarse como otra cosa. Nunca se reintenta, porque un segundo intento guardaría una segunda copia.

Los datos son una cadena de bytes, un SplFileInfo, un stream de fopen(), o un stream o archivo subido PSR-7. Un SplFileInfo o un stream abierto sobre un archivo no necesitan ninguno de los dos argumentos: el nombre es el del propio archivo, y el tipo sale de su extensión cuando el paquete la conoce, como .pdf o .png. Un archivo subido en Laravel o Symfony, y un archivo subido PSR-7, traen el nombre y el tipo que envió el navegador. Una cadena no lleva nombre, así que una cadena sin filename: lanza una InvalidArgumentException antes de enviar nada.

Una subida puede durar 600 segundos, o el timeout del cliente si es mayor, y timeout: fija otro límite para una sola llamada. Un cliente construido con timeout: 0 espera lo que tarde la subida.

Solo se puede eliminar un archivo subido del que nada depende, y deletable y usage en cada archivo lo indican de antemano. delete rechaza cualquier otro archivo con un 409 file_in_use, lanzado como una ConflictException. deleteMany admite hasta 100 ids, elimina lo que puede e informa del resto en kept, cada uno con su motivo, y en missing. Ninguno de los dos se reintenta. Un 404 en un segundo delete tras una respuesta perdida significa que el primero funcionó, y un segundo deleteMany informa de esos archivos en missing.