Skip to content
Tier 3 Schema

Parse Apple App Store Receipts

Extract Apple App Store receipt emails into typed JSON — order ID, Apple ID, purchased items, subscription type, tax, totals, and renewal status, automatically.

Apple sends a “Your receipt from Apple” email for every App Store, subscription, and in-app purchase, but the itemized breakdown lives inside a styled HTML table that varies by region and purchase type. MailFrame normalizes every Apple receipt into typed JSON you can feed directly into your subscription management or expense tracking system.

It works on App Store purchase receipts, in-app purchase confirmations, and subscription renewal emails from Apple.

Fields MailFrame extracts

FieldTypeExampleNotes
order_idstringML8X9R2KTPApple order number
document_nostringMJDQ4LL/AInternal document number when present
apple_idstringtaylor@icloud.comApple ID (email) associated with the purchase
itemsarraysee outputEach item: title, type, price_cents
subtotal_centsinteger999Pre-tax subtotal in minor units
tax_centsinteger82Tax charged in minor units
total_centsinteger1081Grand total in minor units
currencystringusdISO 4217, lower-cased
datestring2026-05-21Purchase date normalized to ISO 8601
renewalbooleantruetrue if this is a subscription auto-renewal

Sample input

A typical Apple App Store receipt email looks like this:

From: no_reply@email.apple.com
Subject: Your receipt from Apple.
Date: Thu, 21 May 2026 08:02:00 -0700
To: taylor@icloud.com

Dear Taylor,

Thank you for your purchase.

Apple ID: taylor@icloud.com
Order ID: ML8X9R2KTP
Document No.: MJDQ4LL/A
Billed to: Visa ending in 1234

May 21, 2026

  Fantastical — Calendar & Tasks
  Annual Subscription (auto-renewal)       $39.99

Subtotal:   $39.99
Tax:         $3.28
Total:      $43.27 USD

This subscription renews automatically. Manage subscriptions in Settings.

Structured JSON output

{
  "order_id": "ML8X9R2KTP",
  "document_no": "MJDQ4LL/A",
  "apple_id": "taylor@icloud.com",
  "items": [
    {
      "title": "Fantastical — Calendar & Tasks Annual Subscription",
      "type": "subscription",
      "price_cents": 3999
    }
  ],
  "subtotal_cents": 3999,
  "tax_cents": 328,
  "total_cents": 4327,
  "currency": "usd",
  "date": "2026-05-21",
  "renewal": true
}

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": "apple_app_store_receipt",
  "type": "object",
  "required": ["order_id", "apple_id", "items", "total_cents", "currency", "date"],
  "properties": {
    "order_id": { "type": "string" },
    "document_no": { "type": "string" },
    "apple_id": { "type": "string", "format": "email" },
    "items": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["title", "type", "price_cents"],
        "properties": {
          "title": { "type": "string" },
          "type": { "type": "string", "enum": ["app", "subscription", "in_app"] },
          "price_cents": { "type": "integer", "minimum": 0 }
        }
      }
    },
    "subtotal_cents": { "type": "integer", "minimum": 0 },
    "tax_cents": { "type": "integer", "minimum": 0 },
    "total_cents": { "type": "integer", "minimum": 0 },
    "currency": { "type": "string", "minLength": 3, "maxLength": 3 },
    "date": { "type": "string", "format": "date" },
    "renewal": { "type": "boolean" }
  }
}

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": "apple_app_store_receipt",
    "input": { "type": "email", "raw": "<base64-encoded MIME>" }
  }'

Prefer a fully automated pipeline? Inbox forwarding — sending your Apple receipts 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.

Webhook delivery

When extraction completes, MailFrame POSTs a signed envelope to your endpoint. The signature is an HMAC-SHA256 of the raw body using your webhook secret, sent in the MailFrame-Signature header, with exponential-backoff retries on failure.

{
  "event": "parse.completed",
  "parse_id": "parse_f5a8b3",
  "schema": "apple_app_store_receipt",
  "data": {
    "order_id": "ML8X9R2KTP",
    "apple_id": "taylor@icloud.com",
    "items": [
      {
        "title": "Fantastical — Calendar & Tasks Annual Subscription",
        "type": "subscription",
        "price_cents": 3999
      }
    ],
    "subtotal_cents": 3999,
    "tax_cents": 328,
    "total_cents": 4327,
    "currency": "usd",
    "date": "2026-05-21",
    "renewal": true
  },
  "confidence": { "order_id": 0.99, "total_cents": 0.98, "renewal": 0.95 },
  "received_at": "2026-05-21T15:02:14Z"
}

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