> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spojit.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Attachment

> Fetch the bytes of an email attachment on demand, ready to send on or embed.

The **Attachment** node fetches the actual file bytes of an email attachment when the workflow reaches it. A [Mailhook trigger](/workflow-editor/nodes/mailhook) gives downstream nodes only attachment **metadata** (id, filename, content type), so the trigger input stays small. The Attachment node downloads the bytes for the attachments you actually need, then hands them to the next node as base64 content.

<Note>
  The Attachment node only works in a workflow started by a **Mailhook trigger**. It reads the triggering email from `{{ input }}`, so the designer will refuse to save a workflow that has an Attachment node without a Mailhook trigger.
</Note>

***

## When to use it

* "When an invoice arrives by email, pull the PDF and file it in the knowledge base."
* "Forward every image attachment on to a colleague."
* "Grab the one spreadsheet on the email and run it through a transform."

You only pay the download cost for attachments a workflow consumes, so it is fine to receive large emails and fetch nothing.

***

## Configuration

| Field                             | Description                                                                                           | Templated |
| --------------------------------- | ----------------------------------------------------------------------------------------------------- | --------- |
| **Label**                         | Display name on the canvas                                                                            | No        |
| **Mode**                          | `Single` returns the first matching attachment as an object; `Multiple` returns every match as a list | No        |
| **Content type**                  | Filter by MIME type. Comma-separated, wildcards allowed, e.g. `application/pdf, image/*`              | No        |
| **Filename pattern**              | Filter by filename glob, e.g. `*.pdf` or `invoice-*.csv`                                              | No        |
| **Attachment ID**                 | Select one exact attachment by id. When set, the other filters are ignored                            | Yes       |
| **Min / Max size**                | Filter by declared size in bytes                                                                      | No        |
| **Fail if no attachment matches** | Off by default: the step produces no output and the run continues. On: the step fails                 | No        |
| **Email ID** (Advanced)           | Defaults to the triggering email. Leave blank                                                         | Yes       |

### Filters

All filters are optional and combined with AND. Leave them all empty and choose **Multiple** to fetch every attachment on the email. The content-type filter accepts a comma-separated list and matches if any pattern matches, so `application/pdf, image/png` matches either, and `image/*` matches any image.

***

## Output

In **Single** mode the output is one object:

```json theme={null}
{
  "filename": "INV-2041.pdf",
  "contentType": "application/pdf",
  "size": 48213,
  "content": "JVBERi0xLjQK..."
}
```

`content` is the file bytes, base64-encoded. In **Multiple** mode the output is a list:

```json theme={null}
{
  "attachments": [
    { "filename": "INV-2041.pdf", "contentType": "application/pdf", "size": 48213, "content": "JVBERi0xLjQK..." }
  ],
  "count": 1,
  "totalBytes": 48213
}
```

If nothing matches, **Single** mode outputs nothing (use a [Condition node](/workflow-editor/nodes/condition) to branch on it) and **Multiple** mode outputs `count: 0`, unless **Fail if no attachment matches** is on.

***

## Using the bytes downstream

The output is shaped to drop straight into the nodes that consume files. With an output variable of `attachment`:

* **[Send Email](/workflow-editor/nodes/send-email)** attachment: set filename to `{{ attachment.filename }}` and content to `{{ attachment.content }}`.
* **[Knowledge](/workflow-editor/nodes/knowledge)** document input: set the input to `{{ attachment.content }}`.

In **Multiple** mode, put a [Loop node](/workflow-editor/nodes/loop) over `{{ attachment.attachments }}` and reference each item's `content` and `filename`. See [Passing Data Between Nodes](/workflow-editor/passing-data).

***

## Limits

* **Per attachment:** each file is capped (10 MB by default). A larger file fails with a clear error. Base64 inflates the size roughly 1.33 times.
* **Per run:** the total downloaded across all Attachment nodes in one run is capped (25 MB by default). Exceeding it fails the run.
* **Retention:** received emails are retained for 30 days. Re-running an older execution can fail to download because the attachment link has expired.
