---
title: "List the files inside a sent zip or tar attachment"
method: GET
path: "/sent-emails/{id}/attachments/{attachment}/members"
tags: ["Sending"]
---

# List the files inside a sent zip or tar attachment

`GET /sent-emails/{id}/attachments/{attachment}/members`

## Request

- Base URL: `https://api.primitive.dev/v1`
- URL: `https://api.primitive.dev/v1/sent-emails/{id}/attachments/{attachment}/members`
- Auth: HTTP bearer

Lists the regular files inside a zip, tar or tar.gz attachment with each one's path, decoded size and SHA-256. The format is detected from the content. Unsafe paths refuse the whole archive, and resource limits bound the work (see the 413 and 422 responses). Authenticate with an organization API key, an authorized organization OAuth token, or an address-bound agent connection key. A connected agent reads only mail sent from its own address. Function credentials are not supported. Discarded content is unavailable.

## Response `200`

Files inside the archive

- object
  - `success` true, required
  - `data` ArchiveMembers, required
    - `part_index` integer, required: The attachment the listing is of.
    - `filename` string, nullable, required: That attachment's filename.
    - `format` 'zip' | 'tar' | 'tar.gz', required
    - `members` ArchiveMember[], required: Regular files in archive order.
      - `path` string, required: Member path inside the archive, relative, with "/" separators and no leading "./".
      - `size_bytes` integer, required: Decoded size in bytes.
      - `sha256` string, required: SHA-256 of the decoded bytes.

## Other responses

- `400`: Invalid request parameters
- `401`: Invalid or missing API key
- `403`: Authenticated caller lacks permission for the operation
- `404`: Missing or inaccessible message, or no such attachment.
- `409`: attachment_name_ambiguous: more than one attachment has this filename, or a digits-only path value matches no part_index but is the name of an attachment; error.details.part_indexes lists every match, so fetch by part_index or by ?filename=. Or attachment_changed: attachment metadata changed during the read.
- `410`: content_discarded
- `413`: archive_limit_exceeded, or attachment_limit_exceeded for the attachment itself. Limits: at most 1000 entries of any kind (files, directories and links all count); each file at most 31457280 bytes decoded; all files together (for tar.gz, the whole decoded tar stream) at most 33554432 bytes; a compression ratio above 100:1 is refused once decoded output passes 1048576 bytes; member paths at most 1024 UTF-8 bytes. Any limit exceeded is 413 archive_limit_exceeded.
- `422`: attachment_not_archive, archive_unsafe_path, archive_invalid or archive_unsupported. The format is detected from the content, not the filename: zip, tar, or tar inside gzip. An archive with an absolute, drive-letter, backslash, control-character, Unicode format or separator character (bidirectional controls included), empty, "." or ".." path segment is refused whole (422 archive_unsafe_path) rather than listed without the entry. Any symbolic or hard link is refused the same way (422 archive_unsafe_path), wherever it points. Paths that differ only by letter case or Unicode normalization count as duplicates. Duplicate paths, overlapping zip data, a zip local header whose name or method disagrees with the central directory, and truncated or corrupt structures are 422 archive_invalid; encryption, zip64, multi-volume archives, compression other than stored or deflate, sparse tar files, and device or other special files are 422 archive_unsupported. Directories are validated and counted but neither listed nor served.
- `429`: Rate limit exceeded. The `ratelimit-*` headers describe the limiter that rejected this request, with its own limit and window, not the API budget that successful responses report. A limiter that reports only a wait sends `Retry-After` alone.
- `502`: attachment_integrity_failed
- `503`: attachment_not_ready, attachment_storage_unavailable or archive_busy; see Retry-After. archive_busy: this server is already reading as many archives as it allows at once. Nothing is wrong with the archive; retry after Retry-After.

## Changes

> 32 revisions in range; 1 not diffed.

- **2026-10-21** `0360ea8d4f3d`: 143 warning
  - added the new `agent_changed` enum value to the `error/code` response property for the response status `400`
  - added the new `agent_changed` enum value to the `error/code` response property for the response status `401`
  - added the new `agent_changed` enum value to the `error/code` response property for the response status `403`
  - added the new `agent_changed` enum value to the `error/code` response property for the response status `404`
  - …139 more
- **2026-10-21** `5279a7bed7ac`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/primitive/apis/primitive-api/changes/sent-emails/:id/attachments/:attachment/members/get.md)

---

[API](https://skmtc.dev/primitive/apis/primitive-api.md) - [All operations](https://skmtc.dev/primitive/apis/primitive-api/llms.txt) - [OpenAPI document](https://skmtc.dev/primitive/apis/primitive-api/revisions/bce409c97acb?raw)
