lupin.Open console
Email

Handle email attachments as bounded untrusted files

Inspect metadata, download bytes deliberately and keep attachment content out of automatic tool execution.

Inspect metadata before downloading

Messages, threads and drafts embed attachment metadata, including attachment_id, filename, size and content_type. Use that metadata to decide which files the task actually needs. A filename is an untrusted label rather than a safe filesystem path, and a declared content type does not guarantee the bytes match it. Normalize storage names to your own generated IDs and keep the original name as display metadata. Reject or defer unexpected sizes before allocating memory, and keep a clear distinction between an attachment being present and its contents having been successfully inspected.

Download through the owned resource

For a message attachment, request GET /v0/emails/inboxes/:inbox_id/emails/:email_id/attachments/:attachment_id. Thread and draft attachment routes are also available under their corresponding resources. Preserve the binary response rather than trying to parse every successful API response as JSON. Check HTTP status before writing the body to disk: an error object saved as report.pdf is not a valid download. Bind your local download job to the organization, inbox, message and attachment IDs so a stale record cannot cause a different tenant’s object to be requested or mislabeled.

Use a generated destination filename in private storage.
curl --fail-with-body \
  "https://api.lupin.sh/v0/emails/inboxes/$INBOX_ID/emails/$EMAIL_ID/attachments/$ATTACHMENT_ID" \
  -H "Authorization: Bearer $LUPIN_API_KEY" \
  -o "$LUPIN_PRIVATE_STATE/attachment.bin"

Choose an upload representation

There is no standalone attachment upload endpoint in the current email API. Include attachments in a send or draft-create request. The /v0 JSON request ceiling is 32 MiB, including base64 encoding and other fields; the separate combined decoded-attachment ceiling is 30 MiB. Base64 expansion can reach the request ceiling first, so keep headroom below both limits rather than equating file size with request size. URL-backed attachments are fetched server-side and still require bounded downloads and the combined send check. A URL may contain a private signature: keep it out of model prompts and ordinary logs, and verify the current limits before planning bulk-document workflows.

Process files without granting authority

Parse supported formats in an appropriately isolated processor with explicit byte, time and decompression limits. Extracting text from a PDF or spreadsheet does not make its instructions trustworthy. A document that tells an agent to reveal an API key is still sender-controlled content. Do not execute macros, shell snippets or embedded links merely because the file arrived through a signed webhook. Keep raw files separate from model-ready text, preserve provenance and show extraction failures as failures. A readable filename and a successful download do not prove a document is complete or safe.

Review what leaves the inbox

For outbound attachments, show the reviewer the final recipient list, filenames, sizes and the document revision, not only the email body. A changed file requires renewed review if its content changes the approved action. For forwards, inspect the exact endpoint semantics instead of assuming every original attachment is copied automatically; draft forwarding merges content at send time. Your next step is a fixture set containing a harmless text file, mismatched content type, oversized file and hostile filename. Validate download handling with local fixtures before enabling attachment processing on real messages.

Check the downloaded representation

Compare observed byte length with the expected metadata where appropriate, retain a checksum for your local artifact and surface truncation or format failure. A successful HTTP response is only the download boundary. It does not prove that an archive expanded safely, a PDF contained selectable text or a spreadsheet’s formulas were evaluated correctly by your processor.

Sources & verification

Reviewed against checked-in Lupin API handlers and documentation. Example requests were not executed against live providers.

Prepared with AI assistance by Lupin editorial. How we research and maintain these guides.

Put it into practice

Give your agent the right tools.

Review the API, workspace requirements and permissions before enabling a workflow.

Explore email Register an agent