Skip to content
Tier 1 Schema

Parse Shopify Orders

Extract Shopify order confirmations into typed JSON — order number, line items, totals, fulfillment status, and customer details from every store email.

Shopify sends a detailed order confirmation email for every purchase, but extracting line items, totals, and fulfillment state from HTML templates across dozens of store themes is fragile work. MailFrame normalizes every Shopify order confirmation into the same typed JSON shape regardless of the store’s branding or template customizations.

It works on order confirmation emails, shipping notification emails, and shipment status update emails — any raw MIME email you send to the API.

Fields MailFrame extracts

FieldTypeExampleNotes
order_numberstring#1001Human-readable order identifier including the # prefix
reference_idstringgid://shopify/Order/5678901234Shopify internal GID when present in email headers
customer_emailstringalex@example.comEmail address on the order
customer_namestringAlex RiveraFull name as entered at checkout
total_centsinteger8997Order total in minor units
currencystringusdISO 4217, lower-cased
line_itemsarraysee outputEach item: title, quantity, price_cents
shipping_statusenumshippedOne of pending, shipped, delivered, returned
fulfillment_statusenumfulfilledOne of unfulfilled, fulfilled, partial, cancelled
datestring2026-05-21Order date normalized to ISO 8601

Sample input

A typical Shopify order confirmation email looks like this:

From: orders@myawesomestore.myshopify.com
Subject: Order confirmation #1001 - My Awesome Store
Date: Wed, 21 May 2026 14:22:00 -0500
To: alex@example.com

Hi Alex,

Thank you for your purchase! We're getting your order ready.

Order #1001
Placed on May 21, 2026

Items ordered:
  Classic Logo Tee (Size M, Black) x2    $29.99 each
  Canvas Tote Bag x1                     $14.99

Subtotal:  $74.97
Shipping:  $4.99 (Standard)
Taxes:     $9.99
Total:     $89.97 USD

Ship to:
Alex Rivera
123 Maple St
Austin, TX 78701

Payment: Visa ending in 5678

Structured JSON output

{
  "order_number": "#1001",
  "reference_id": "gid://shopify/Order/5678901234",
  "customer_email": "alex@example.com",
  "customer_name": "Alex Rivera",
  "total_cents": 8997,
  "currency": "usd",
  "line_items": [
    { "title": "Classic Logo Tee (Size M, Black)", "quantity": 2, "price_cents": 2999 },
    { "title": "Canvas Tote Bag", "quantity": 1, "price_cents": 1499 }
  ],
  "shipping_status": "pending",
  "fulfillment_status": "unfulfilled",
  "date": "2026-05-21"
}

JSON Schema definition

Every field is validated against the schema before delivery. You can copy this as a starting point and tighten it for your own use case:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "shopify_order",
  "type": "object",
  "required": ["order_number", "customer_email", "total_cents", "currency", "line_items"],
  "properties": {
    "order_number": { "type": "string", "pattern": "^#[0-9]+" },
    "reference_id": { "type": "string" },
    "customer_email": { "type": "string", "format": "email" },
    "customer_name": { "type": "string" },
    "total_cents": { "type": "integer", "minimum": 0 },
    "currency": { "type": "string", "minLength": 3, "maxLength": 3 },
    "line_items": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["title", "quantity", "price_cents"],
        "properties": {
          "title": { "type": "string" },
          "quantity": { "type": "integer", "minimum": 1 },
          "price_cents": { "type": "integer", "minimum": 0 }
        }
      }
    },
    "shipping_status": { "type": "string", "enum": ["pending", "shipped", "delivered", "returned"] },
    "fulfillment_status": { "type": "string", "enum": ["unfulfilled", "fulfilled", "partial", "cancelled"] },
    "date": { "type": "string", "format": "date" }
  }
}

Use-case examples

The parsed Shopify order output fits naturally into common e-commerce workflows:

  • Order reconciliation — match order_number against your internal order system to confirm every storefront order is accounted for.
  • Fulfillment tracking — monitor fulfillment_status and shipping_status changes across order confirmations and shipping notifications to drive internal fulfillment pipelines.
  • Customer analytics — aggregate total_cents and line_items by customer_email to build per-customer spend profiles or lifetime value models.
  • Inventory impact — sum quantities across line_items to project inventory drawdown from new orders as they arrive.
  • Cost breakdown — store the raw line_items array alongside total_cents to track product-level vs aggregate revenue in your data warehouse.

Because the extraction is synchronous and typed, each of these workflows can run inline — parse the email, validate the output, and write to your database in a single request-response cycle.

Parse via the API

POST the raw email (MIME or plain text) to /v1/parse with the schema you want to extract against:

curl https://api.mailframe.ai/v1/parse \
  -H "Authorization: Bearer $MAILFRAME_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "schema": "shopify_order",
    "input": { "type": "email", "raw": "<base64-encoded MIME>" }
  }'

Prefer automation over manual forwarding? Inbox forwarding — BCC’ing your Shopify store’s notification email to a unique inbox address MailFrame assigns you — is on the roadmap. Until it ships, POST the raw email to /v1/parse as shown above.

Planned webhook delivery

Async webhook delivery is in early design. When it ships, MailFrame will POST a signed envelope to your endpoint with an HMAC-SHA256 signature, exponential-backoff retries, a dead-letter queue, replay endpoints, and a delivery dashboard.

The reliable path today is the synchronous /v1/parse response. Signed webhook delivery, DLQ, replay, and the webhook dashboard are planned — gate your critical downstream logic on the synchronous API response returned by POST /v1/parse.

{
  "event": "parse.completed",
  "parse_id": "parse_c3d7e9",
  "schema": "shopify_order",
  "data": {
    "order_number": "#1001",
    "customer_email": "alex@example.com",
    "customer_name": "Alex Rivera",
    "total_cents": 8997,
    "currency": "usd",
    "line_items": [
      { "title": "Classic Logo Tee (Size M, Black)", "quantity": 2, "price_cents": 2999 },
      { "title": "Canvas Tote Bag", "quantity": 1, "price_cents": 1499 }
    ],
    "shipping_status": "pending",
    "fulfillment_status": "unfulfilled",
    "date": "2026-05-21"
  },
  "received_at": "2026-05-21T19:22:08Z"
}

Integration tips

Expect schema-validated output

MailFrame validates every extraction against the JSON Schema before returning it. If a required field is missing or a type doesn’t match, the parse returns a validation error instead of malformed data. Your code never needs to check types at runtime.

Handle optional fields gracefully

Fields like reference_id and customer_name depend on the email content and may not always be present. Your integration should treat optional fields as nullable and handle missing values — for example, falling back to the sender’s email domain when no customer name is available.

Send raw email, not a screenshot

The API accepts raw MIME or plain-text email (base64-encoded in the JSON body). For Shopify emails this means forwarding the actual email content — opening the .eml file or extracting the raw source from your email provider. Screenshots and PDF exports are not supported (PDF input is on the roadmap).

Validation checklist

Before using parsed Shopify order data in production:

  • Required fields are presentorder_number, customer_email, total_cents, currency, and line_items are guaranteed when the parse succeeds. If your workflow depends on optional fields (reference_id, customer_name, shipping_status, fulfillment_status), add explicit null checks.
  • Currency is consistent — all monetary values are in minor units via total_cents. Convert to display format (e.g. $89.97) in your UI layer, not before storing.
  • Line items are non-empty — an order with zero parsed line items may indicate a Shopify template the parser has not seen before. Gate downstream processing on line_items.length > 0.
  • Dates parse correctly — the date field is ISO 8601 (YYYY-MM-DD). Validate that it produces a valid date object in your language of choice.
  • Enums match your domain modelshipping_status and fulfillment_status use fixed enum values. Map them to your internal status model rather than relying on string comparison against display text.
  • Test with real emails — Shopify stores use customized templates. Always test against actual emails from the stores you integrate with, not just the sample above. Sign up for a test order on a Shopify store to get a representative input.

Other schemas

Ship this schema in production

Define your fields once, then POST raw email to /v1/parse. MailFrame returns typed JSON in the HTTP response. (Unique inbox forwarding and signed webhook delivery are on the roadmap.)

Request early access