We are in official beta.

Email & Web

Send emails, parse EML files, and capture web pages

5 endpoints in this category. All require X-API-Key header.


Send Email

POST /api/SendEmail 1 token

Send an HTML email from DocButterfly's sender.

Requires GRAPH_TENANT_ID, GRAPH_CLIENT_ID, GRAPH_CLIENT_SECRET, GRAPH_SENDER_EMAIL. Sending limits (#1516): accounts on a free or trial plan are in SANDBOX MODE and may only mail their own account address and any address confirmed through a verification link — so you can test the endpoint end to end before you buy — and are capped at 5 recipients per message and 20 recipients per UTC day. Paid plans send to any recipient, capped at 50 per message and 500 (Starter) / 2,500 (Small Business) / 10,000 (Enterprise) recipients per UTC day. to, cc and bcc all count, and are all restricted. Recipients must be bare addresses: a display name ("Name" <a@b>) is refused on every plan, as is replyTo carrying one. A recipient on a reserved domain (.test, .example, .invalid, .localhost, or example.com, example.net, example.org and their subdomains) is never mailed and comes back under "suppressed" with reason reserved_tld or reserved_domain (#1881, #3004). Attachment limits (#1995), counted in decoded file bytes and checked before the message is sent: free and trial plans may attach 5 files per message, 1.0 MB each, 2.0 MB in total; paid plans may attach 10 files per message, 2.5 MB each, 2.5 MB in total. Microsoft Graph refuses any message whose whole request exceeds 4 MB, so no plan and no setting goes above 2.5 MB of attachments. Every attachment is typed from its own first bytes: a file declared as an image whose contents are not an image is refused, and the detected type is what travels on the message. Refusals are 403 RECIPIENT_NOT_ALLOWED_SANDBOX / RECIPIENT_LIMIT_EXCEEDED / RECIPIENT_DISPLAY_NAME_NOT_ALLOWED, 413 TOO_MANY_ATTACHMENTS / ATTACHMENT_TOO_LARGE / ATTACHMENTS_TOO_LARGE, 415 ATTACHMENT_TYPE_MISMATCH and 429 SEND_EMAIL_DAILY_LIMIT — branch on code, never on the message — and a refused call is not billed. Keeping a copy (#1522): we keep no copy of what you send unless your account is one we enable on request and you set saveToSentItems to true; the copy, with its recipients and attachments, is then kept in the mailbox we send from until you ask us to remove it. For every other account saveToSentItems is ignored and the email is still sent. Every successful response carries saveToSentItems: {requested, applied}, plus reason "not enabled for this account" when a copy was asked for and not kept.
Parameters
NameTypeRequiredDescription
to array required Recipient(s)
subject string required Subject line
body string required HTML body
cc array optional CC recipients
bcc array optional BCC recipients
attachments array optional Array of {name, contentType, content}
importance string optional normal, high, low
saveToSentItems boolean optional Keep a copy of the message in the mailbox we send from. Only for accounts we enable on request; ignored for every other account (default: false)
Request Example
JSON
{"to": ["recipient@example.com"], "subject": "Test from DocFlow", "body": "<h1>Hello</h1><p>Sent via DocFlow API.</p>"}
Response Example
JSON
{"success": true, "message": "Email sent successfully", "recipients": {"to": ["recipient@example.com"], "cc": [], "bcc": []}, "suppressed": [], "subject": "Test from DocFlow", "attachmentCount": 0, "saveToSentItems": {"requested": false, "applied": false}, "timing": {"total": 812}}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/SendEmail" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"to": ["recipient@example.com"], "subject": "Test from DocFlow", "body": "<h1>Hello</h1><p>Sent via DocFlow API.</p>"}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""to"": [""recipient@example.com""], ""subject"": ""Test from DocFlow"", ""body"": ""<h1>Hello</h1><p>Sent via DocFlow API.</p>""}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/SendEmail", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/SendEmail"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"to": ["recipient@example.com"], "subject": "Test from DocFlow", "body": "<h1>Hello</h1><p>Sent via DocFlow API.</p>"}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/SendEmail
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "to": [
│        "recipient@example.com"
│      ],
│      "subject": "Test from DocFlow",
│      "body": "\u003Ch1\u003EHello\u003C/h1\u003E\u003Cp\u003ESent via DocFlow API.\u003C/p\u003E"
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/SendEmail"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Parse Email

POST /api/ParseEmail 1 token

Parse an email's metadata: EML/MIME or Outlook .msg.

An Outlook .msg answers with the same fields. headers holds the message's Internet headers when it was received (a message saved from Sent Items or Drafts has none). attachmentCount counts every attachment, including one that is only a link to a file stored somewhere else. A message saved with only a rich-text body returns its plain text and an empty htmlBody. A damaged .msg, or an Office file that is not an Outlook message, is 400 UNREADABLE_EMAIL.
Parameters
NameTypeRequiredDescription
email string required Base64 EML/MIME message or Outlook .msg file
Request Example
JSON
{"email": "<base64-eml>"}
Response Example
JSON
{"success": true, "from": {"name": "Dana Reed", "address": "sender@test.com"}, "to": [{"name": "", "address": "recipient@test.com"}], "cc": [], "bcc": [], "subject": "Test", "date": "2026-09-05T14:02:11.000Z", "messageId": "<a1b2c3@test.com>", "inReplyTo": "", "references": [], "textBody": "Hello, the invoice is attached.", "htmlBody": "", "headers": {"subject": "Test", "date": "2026-09-05T14:02:11.000Z", "message-id": "<a1b2c3@test.com>", "mime-version": "1.0", "content-type": {"value": "multipart/mixed", "params": {"boundary": "BOUND1"}}}, "attachmentCount": 1, "hasAttachments": true, "timing": {"total": 38, "parse": 16}}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/ParseEmail" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"email": "<base64-eml>"}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""email"": ""<base64-eml>""}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/ParseEmail", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/ParseEmail"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"email": "<base64-eml>"}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/ParseEmail
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "email": "\u003Cbase64-eml\u003E"
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/ParseEmail"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Extract Email Attachments

POST /api/ExtractEmailAttachments 1 token

Extract the attachments from an email: EML/MIME or Outlook .msg.

From an Outlook .msg, an attached email comes back as its own .msg file. An Outlook attachment that carries no file (a link to a file stored somewhere else, or an embedded object) is not in attachments: it is listed under notExtracted with its filename and reason (linked, embedded-object, no-data, or too-complex for an attached email that could not be extracted). A damaged .msg, or an Office file that is not an Outlook message, is 400 UNREADABLE_EMAIL.
Parameters
NameTypeRequiredDescription
email string required Base64 EML/MIME message or Outlook .msg file
Request Example
JSON
{"email": "<base64-eml>"}
Response Example
JSON
{"success": true, "attachments": [{"filename": "report.pdf", "contentType": "application/pdf", "size": 12345, "content": "JVBERi0xLjcK...", "contentId": "", "related": false}], "count": 1, "totalSize": 12345, "timing": {"total": 22, "parse": 22}}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/ExtractEmailAttachments" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"email": "<base64-eml>"}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""email"": ""<base64-eml>""}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/ExtractEmailAttachments", content);
response.EnsureSuccessStatusCode();

var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
import requests
import json

url = "https://api.docbutterfly.com/api/ExtractEmailAttachments"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"email": "<base64-eml>"}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

data = response.json()
print(json.dumps(data, indent=2))
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/ExtractEmailAttachments
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "email": "\u003Cbase64-eml\u003E"
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/ExtractEmailAttachments"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed
Try in Testbed

Convert Email to PDF

POST /api/ConvertEmailToPdf 2 tokens

Turn an email (EML/MIME or Outlook .msg) into one PDF: a From, To, Date and Subject header, the message, a page listing its attachments, then its PDF attachments.

Uses Chromium for rendering, so it may take 3-10s on a cold start. Only PDF attachments are added, after the message and in the order the email lists them. Every attachment is listed on the attachments page with its name, type and size and what happened to it, and attachments[].status in the response says the same: merged, inline (an image the message shows), not-pdf, unreadable (a PDF that could not be opened, such as a password-protected one), too-many-pages (the attached PDFs may add at most 2,000 pages), linked, embedded-object, no-data or too-complex. Script and active content in the message are removed before it is printed, and only https links stay clickable (other links keep their text). Images the message links to on the web (https only) are not fetched unless options.loadRemoteImages is true, the way mail clients block them: fetching one tells the sender the message was opened. An Outlook message saved with only a rich-text body prints its plain text. A message too large to print (more than 1,000 pages, or past the time or memory one print may use) is refused with 413 PDF_RENDER_TOO_LARGE. A damaged .msg, or an Office file that is not an Outlook message, is 400 UNREADABLE_EMAIL.
Parameters
NameTypeRequiredDescription
email string required Base64 EML/MIME message or Outlook .msg file
includeAttachments boolean optional List every attachment on a page of its own and add the PDF attachments after the message (default: true)
options.loadRemoteImages boolean optional Fetch the https images the message links to on the web. Off, only the images inside the email show (default: false)
options.pageSize string optional Named paper size — see the paper-size table on the API reference overview. Case- and punctuation-insensitive; aliases such as "US Letter" are accepted. Via raw JSON a custom size object is also accepted: {"width": n, "height": n, "units": "pt|px|in|mm|cm"} (units default pt; 1-14400pt / 200in per side). An unknown size, unit, or orientation returns 400 — nothing silently falls back (default: Letter) (one of: Letter, Legal, Tabloid, Ledger, Executive, Statement, Folio, A0, A1, A2, A3, A4, A5, A6, B4, B5)
options.orientation string optional Page orientation. "landscape" puts the long edge horizontal. Omit to keep the size's own orientation (portrait for every named size except Ledger) (one of: portrait, landscape)
options.margin object optional Page margins {top, right, bottom, left}
Request Example
JSON
{"email": "<base64-eml-or-msg>"}
Response Example
PDF
{"success": true, "pdf": "JVBERi0xLjcK...", "contentType": "application/pdf", "size": 48211, "pageCount": 4, "pageSize": {"name": "Letter", "width": 612, "height": 792, "orientation": "portrait"}, "format": "msg", "subject": "Signed lease", "attachments": [{"filename": "lease.pdf", "contentType": "application/pdf", "size": 40960, "status": "merged"}, {"filename": "photo.jpg", "contentType": "image/jpeg", "size": 120344, "status": "not-pdf"}], "timing": {"total": 2310, "parse": 12, "attachments": 40, "launch": 1502, "render": 310, "pdf": 420}}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/ConvertEmailToPdf" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"email": "<base64-eml-or-msg>"}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""email"": ""<base64-eml-or-msg>""}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/ConvertEmailToPdf", content);
response.EnsureSuccessStatusCode();

// The response contains a base64-encoded file in the JSON body
var result = await response.Content.ReadAsStringAsync();
using var doc = System.Text.Json.JsonDocument.Parse(result);
var base64 = doc.RootElement.GetProperty("pdf").GetString();
var bytes = Convert.FromBase64String(base64!);
await File.WriteAllBytesAsync("output.pdf", bytes);
import requests
import json
import base64

url = "https://api.docbutterfly.com/api/ConvertEmailToPdf"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"email": "<base64-eml-or-msg>"}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

# Decode the base64 PDF and save to file
data = response.json()
pdf_bytes = base64.b64decode(data["pdf"])
with open("output.pdf", "wb") as f:
    f.write(pdf_bytes)
print("Saved to output.pdf")
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/ConvertEmailToPdf
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "email": "\u003Cbase64-eml-or-msg\u003E"
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/ConvertEmailToPdf"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed

To save the output file:
7. Add a "Parse JSON" action on the HTTP response body
8. Use base64ToBinary(body('Parse_JSON')?['pdf']) to convert
9. Pass the result to a "Create file" action (SharePoint, OneDrive, etc.)
Try in Testbed

Capture Web Page

POST /api/CaptureWebPage 2 tokens

Capture a URL as PDF or screenshot.

Parameters
NameTypeRequiredDescription
url string required URL to capture
output string optional pdf or screenshot (default: pdf)
options.captureMode string optional screen (full visual fidelity), print (traditional), fast (minimal wait) (default: screen)
options.pageSize string optional Named paper size — see the paper-size table on the API reference overview. Case- and punctuation-insensitive; aliases such as "US Letter" are accepted. Via raw JSON a custom size object is also accepted: {"width": n, "height": n, "units": "pt|px|in|mm|cm"} (units default pt; 1-14400pt / 200in per side). An unknown size, unit, or orientation returns 400 — nothing silently falls back. PDF output only; legacy key options.format is still accepted (default: Letter) (one of: Letter, Legal, Tabloid, Ledger, Executive, Statement, Folio, A0, A1, A2, A3, A4, A5, A6, B4, B5)
options.orientation string optional Page orientation. "landscape" puts the long edge horizontal. Omit to keep the size's own orientation (portrait for every named size except Ledger) (one of: portrait, landscape)
options.fullPage boolean optional Full page capture
options.viewport object optional {width, height} in pixels
options.timeout number optional Navigation timeout in ms (max 60000) (default: 30000)
returnBase64 boolean optional Return base64 (default: true)
Request Example
JSON
{"url": "https://example.com", "output": "pdf", "options": {"pageSize": "Letter"}, "returnBase64": true}
Response Example
PDF
{"success": true, "data": "JVBERi0xLjcK...", "contentType": "application/pdf", "url": "https://example.com", "outputType": "pdf", "pageSize": {"name": "Letter", "width": 612, "height": 792, "orientation": "portrait"}, "timing": {"total": 2143, "launch": 1502, "navigation": 480}}
Code Examples
curl -X POST "https://api.docbutterfly.com/api/CaptureWebPage" \
  -H "X-API-Key: df_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "output": "pdf", "options": {"pageSize": "Letter"}, "returnBase64": true}'
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "df_your_api_key_here");

var json = @"{""url"": ""https://example.com"", ""output"": ""pdf"", ""options"": {""pageSize"": ""Letter""}, ""returnBase64"": true}";
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync("https://api.docbutterfly.com/api/CaptureWebPage", content);
response.EnsureSuccessStatusCode();

// The response contains a base64-encoded file in the JSON body
var result = await response.Content.ReadAsStringAsync();
using var doc = System.Text.Json.JsonDocument.Parse(result);
var base64 = doc.RootElement.GetProperty("pdf").GetString();
var bytes = Convert.FromBase64String(base64!);
await File.WriteAllBytesAsync("output.pdf", bytes);
import requests
import json
import base64

url = "https://api.docbutterfly.com/api/CaptureWebPage"
headers = {
    "X-API-Key": "df_your_api_key_here",
    "Content-Type": "application/json"
}
payload = json.loads('{"url": "https://example.com", "output": "pdf", "options": {"pageSize": "Letter"}, "returnBase64": true}')

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

# Decode the base64 PDF and save to file
data = response.json()
pdf_bytes = base64.b64decode(data["pdf"])
with open("output.pdf", "wb") as f:
    f.write(pdf_bytes)
print("Saved to output.pdf")
┌─────────────────────────────────────────────┐
│  Power Automate - HTTP Action               │
├─────────────────────────────────────────────┤
│                                             │
│  Method:  POST                              │
│  URI:     https://api.docbutterfly.com/api/CaptureWebPage
│                                             │
│  Headers:                                   │
│    X-API-Key:    df_your_api_key_here       │
│    Content-Type: application/json           │
│                                             │
│  Body:                                      │
│    {
│      "url": "https://example.com",
│      "output": "pdf",
│      "options": {
│        "pageSize": "Letter"
│      },
│      "returnBase64": true
│    }
│                                             │
└─────────────────────────────────────────────┘

Steps:
1. Add an HTTP action to your flow
2. Set Method to "POST"
3. Set URI to "https://api.docbutterfly.com/api/CaptureWebPage"
4. Add the headers shown above
5. Paste the Body JSON into the Body field
6. Replace placeholder values with dynamic content as needed

To save the output file:
7. Add a "Parse JSON" action on the HTTP response body
8. Use base64ToBinary(body('Parse_JSON')?['pdf']) to convert
9. Pass the result to a "Create file" action (SharePoint, OneDrive, etc.)
Try in Testbed