MisarMisar Docs
MisarMailMisar.BlogMisarReachMisarPostMisar.DevMisarSEOMisar PlatformMisar SSO
API Reference

Attachments

Upload email attachments to Supabase Storage and reference them in outbound emails

Upload files to MisarMail's attachment storage and get back signed URLs to reference in your emails. Files are stored in a per-user Supabase Storage bucket and served via time-limited signed URLs.

Requires an active MisarMail session (dashboard only). Base URL: https://api.misar.io/mail.

Upload attachments

POST/mail/attachments/upload

Submit one or more files as a multipart/form-data upload using the repeated field name files. Up to 5 files per request, 10 MB each. Uploads are checked against your account's storage quota before writing.

Request body (multipart/form-data)

filesfile[]bodyrequired

One or more files (field name repeated). Max 5 files, 10 MB each. Allowed MIME types: application/pdf, image/png, image/jpeg, image/gif, image/webp, text/plain, text/csv, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document (.docx), application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet (.xlsx), application/zip.

Response fields

successboolean

true when every file uploaded successfully.

urlsstring[]

Signed URLs (one per uploaded file, in order), each valid for 1 hour.

curl -X POST https://api.misar.io/mail/attachments/upload \
  -F "files=@/path/to/invoice-june-2025.pdf" \
  -F "files=@/path/to/terms.pdf"
{
  "success": true,
  "urls": [
    "https://supabase-mail.misar.io/storage/v1/object/sign/email-attachments/<user_id>/invoice-june-2025.pdf?token=eyJ...",
    "https://supabase-mail.misar.io/storage/v1/object/sign/email-attachments/<user_id>/terms.pdf?token=eyJ..."
  ]
}

Limits

ConstraintValue
Max files per request5
Max file size10 MB each
URL validity1 hour
Storage bucketemail-attachments (scoped per user)

Signed URLs expire after 1 hour. Upload attachments as close as possible to send time — if you need to reference a file in a later send, re-upload it to obtain a fresh signed URL.

Using the URL in an email

After uploading, reference a returned URL in your email HTML as a download link or inline image.

As a download link

<a href="{{attachment_url}}">Download your invoice (PDF)</a>

As an inline image

<img src="{{attachment_url}}" alt="Product diagram" width="600" />

For brand logos and reused images, use a CDN-hosted URL directly in your template HTML instead of uploading to attachment storage each time.

Example

curl -X POST https://api.misar.io/mail/attachments/upload \
  -F "files=@/path/to/invoice-june-2025.pdf"
async function uploadAttachments(files: File[]) {
  const formData = new FormData();
  for (const file of files) formData.append("files", file);

  const res = await fetch("/api/attachments/upload", {
    method: "POST",
    credentials: "include",
    body: formData,
    // Do NOT set Content-Type — the browser sets it with the boundary automatically
  });

  if (!res.ok) {
    const err = await res.json();
    throw new Error(err.error ?? "Upload failed");
  }

  return res.json() as Promise<{ success: boolean; urls: string[] }>;
}

Status codes

  • 200 — OK. All files uploaded; urls returned.
  • 400 — Bad request. No files provided, Maximum 5 files allowed, File "<name>" exceeds 10MB limit, or File type "<type>" is not allowed for "<name>".
  • 401 — Unauthorized. No active session.
  • 413 — Payload Too Large. The upload would exceed your account's storage quota.
  • 500 — Server error. Failed to upload "<name>" or Failed to get URL for "<name>" — retry.