Skip to content
pdfconversionapi

Email metadata API

POST a message to /v2/convert/email/to/metadata and get back a JSON file describing it: addresses, subject, date, message ID, whether it has an HTML body, the text body and every attachment's name, type and size. Our Outlook sample gave a 1,826-byte JSON.

Endpoint
POST /v2/convert/email/to/metadata
Accepts
email
Sample timing
1 ms median of 5 runsHow we measure
Request size
Up to 10 MB on the Free plan or 100 MB on paid plans, all files together

Request and response

Every sample below ran against the API before this page was published. Set PDFCONVERSIONAPI_KEY to your key and run it as is.

curl -sS -X POST \
  https://api.pdfconversionapi.com/v2/convert/email/to/metadata \
  -H "Authorization: Bearer $PDFCONVERSIONAPI_KEY" \
  -F File=@site-report-week-9.msg \
  -o response.json

# FileData is base64. Save the first file in converted/,
# or print the JSON error.
if jq -e '.Files' response.json > /dev/null; then
  mkdir -p converted
  name=$(jq -r '.Files[0].FileName' response.json)
  jq -r '.Files[0].FileData' response.json \
    | base64 --decode > "converted/$name"
else
  cat response.json
fi
200 OK1 ms median1 file, 1.8 KB
{
  "ConversionCost": 1,
  "ConversionTime": 0.001,
  "Files": [
    {
      "FileName": "site-report-week-9.json",
      "FileExt": "json",
      "FileSize": 1826,
      "FileData": "ewogICJhdHRhY2htZW50cyI6…"
    }
  ]
}

Response from our test run on 2026-11-03. ConversionTime shows the median of 5 runs. FileData is shortened here; the real response carries the whole file as base64.

The sample, converted

The same file the code sends. Download the input and the output and compare them yourself.

site-report-week-9.json, first 30 of 41 lines

{  "attachments": [    {      "content_id": "progress.week9@calloway-reid.example",      "content_type": "image/png",      "inline": true,      "name": "progress-week-9.png",      "size": 8201    },    {      "content_id": null,      "content_type": "text/csv",      "inline": false,      "name": "rfi-log-week-9.csv",      "size": 321    },    {      "content_id": null,      "content_type": "image/jpeg",      "inline": false,      "name": "east-wall-opening.jpg",      "size": 18032    }  ],  "bcc": [],  "cc": [    "Site Office <site@calloway-reid.example>"  ],  "date": "Mon, 26 Oct 2026 08:30:00 -0700",  "from": [
Input
site-report-week-9.msg (48 KB)
Output
site-report-week-9.json (1.8 KB)
Source
A fictional Outlook message with a weekly building site report, an inline chart and two attachments, written by us and saved to the Outlook file layout by our own script. (CC0-1.0). How it was made
Made by
2026-11-04, API build 9eeeb0640aba

Parameters

Send these as form fields next to the file. Names are case-insensitive. If you set one of the documented options below that we don't support yet, the request fails with a 400 that names it instead of returning a file made without it.

ParameterWhat it does
IgnoreInlineAttachmentsboolean, default falsetrue drops inline parts from attachments: for the sample, the chart with a content ID goes and the CSV and the photo stay. In an .eml, a part is inline when its Content-Disposition says so.
FileNamestringName of the JSON file without .json. week9-meta returns week9-meta.json; by default it is the message's own name.
StoreFileboolean, default falseStore the JSON for 3 hours and return a link to it in Files[].Url instead of the data.

What carries over, and what doesn't

Kept

  • Sender, To, Cc and Bcc as arrays of "Name <address>" strings; the sample lists Noor Haddad as sender and both To recipients
  • The subject, with encoded words decoded in .eml files (=?utf-8?q?Caf=C3=A9_menu?= reads Café menu)
  • The Date: ISO 8601 with the sender's offset for an .eml (2026-11-03T09:15:00+01:00), the saved header text for a .msg (Mon, 26 Oct 2026 08:30:00 -0700)
  • The Message-ID, and has_html_body saying whether there is an HTML body
  • The plain-text body in text_body, with its line breaks
  • For each attachment: name, MIME type, decoded size in bytes, whether it is inline, and its content ID

Lost or not yet supported

  • Every other header: Reply-To, In-Reply-To, References, Received lines and custom X- headers are not in the JSON.
  • The HTML body itself. Only has_html_body says it exists; get the rendering from /v2/convert/eml/to/pdf or msg/to/pdf.
  • Clean text for HTML-only messages. With no text part, text_body is made from the HTML and block boundaries can run together: our test's heading "Menu" and the next paragraph came out as "MenuSoup & bread, $6".
  • A consistent Message-ID form: an .msg keeps the angle brackets ("<week9.20261026.0830@calloway-reid.example>"), an .eml drops them.
  • The Date of a .msg saved without internet headers, such as a draft; date and message_id are then null.
  • Attachment contents. Use /v2/convert/email/to/extract to get the files.

Limits

  • One message per request; two files return 400 "this conversion takes exactly one file".
  • Requests up to 10 MB on the Free plan or 100 MB on paid plans, all files and fields together.
  • A file that is not a message returns 422 "the input file could not be read: this is not an e-mail message". An .eml needs at least one of From, To, Subject, Date or Message-ID.
  • A damaged .msg returns 422 "the Outlook message is damaged"; other Office 97-2003 files return 422 as well.
  • 120 seconds per request.

Where teams use it

Indexing a mail archive

Run each exported .eml or .msg through this route and load the JSON into a search index or database: who sent it, to whom, when, the subject and the plain text, without writing a MIME or Outlook parser yourself.

Routing inbound mail

Decide what to do with a message before converting it: check attachments for a PDF or a spreadsheet, read the sender, and only then send the message or its files to the routes that need them.

Checking a message before a records transfer

Confirm that each file is a readable message and see how many attachments it carries and how large they are, so a batch can be split or flagged before it is converted to PDF.

Questions

What does the JSON look like?

One object with the keys attachments, bcc, cc, date, from, has_html_body, message_id, subject, text_body and to, in that order, pretty-printed. Address fields are always arrays, even with one entry. A missing subject is an empty string; a missing date, message ID or text body is null.

Why do .eml and .msg dates look different?

They come from different places. An .eml's Date header is parsed and written as ISO 8601 with its UTC offset, such as 2026-10-30T14:05:00-05:00. A .msg's date is copied as text from the internet headers Outlook saved with the message, so it stays in the RFC 5322 form, such as Mon, 26 Oct 2026 08:30:00 -0700.

Are inline images counted as attachments?

Yes, unless you send IgnoreInlineAttachments=true. They appear with inline: true and their content_id, like the sample's progress-week-9.png, so you can tell a signature logo from a file someone attached.

Does it read Bcc?

When the file has it. Our test .eml with a Bcc header returned it in bcc; the sample, a received message saved without one, has an empty list. Nothing can be read that the file does not store.

Convert your first EMAIL file in a minute.