Skip to content
Skip to main content

Parse receipts and orders from email

Every e-commerce order generates a trail of email — order confirmation, shipping notification, delivery update, return label, refund receipt. The data you actually need is locked inside unstructured HTML, and writing your own parser means maintaining merchant-specific templates for Amazon, Walmart, Target, and thousands of other retailers, each with its own format that can change without notice.

ExtractAI handles that part for you. It watches the inbox, detects order/shipment/return email, and pushes structured JSON through webhooks: order numbers, line items, carrier names, tracking links, refund totals. No parsing, no regex, no template maintenance. 30,000+ merchants out of the box, Google and Microsoft only.

inbound order email ─▶ ExtractAI detects + extracts ─▶ message.intelligence.order webhook
inbound shipping email ─▶ ExtractAI detects + extracts ─▶ message.intelligence.tracking webhook
inbound return email ─▶ ExtractAI detects + extracts ─▶ message.intelligence.return webhook
webhook handler routes by type
store order/shipment/return records
periodic backfill ─▶ Order Consolidation API ─▶ join orders + shipments + returns by order_id

Three webhook triggers feed the real-time path. The Order Consolidation API gives you the same data on demand — useful for backfills or building a unified dashboard.

Make sure you have the following before starting this tutorial:

  • A Nylas account with an active application
  • A valid API key from your Nylas Dashboard
  • At least one connected grant (an authenticated user account) for the provider you want to work with
  • Node.js 18+ or Python 3.8+ installed (depending on which code samples you follow)

You also need:

  • ExtractAI enabled in your Nylas Dashboard (see Activate ExtractAI below)
  • A Google or Microsoft grant — ExtractAI does not support IMAP connectors
  • OAuth scopes: gmail.readonly for Google, or Mail.Read for Microsoft (add Mail.Read.Shared if you need access to shared mailboxes)
  • A publicly accessible HTTPS endpoint for webhook delivery. During development, use VS Code port forwarding or Hookdeck to expose your local server.
  • Express (Node.js) or Flask (Python) installed in your project.

Before you can receive order data, you need to turn on ExtractAI in the Nylas Dashboard:

  1. Log in to the Nylas Dashboard.
  2. Select ExtractAI from the left navigation.
  3. Click Enable ExtractAI.

Nylas automatically creates a Pub/Sub channel subscribed to the three ExtractAI triggers. Do not delete this channel from the Notifications page — if you do, the ExtractAI APIs stop working.

For full setup details, see the ExtractAI documentation.

Create a webhook subscription that listens for all three ExtractAI triggers. This tells Nylas to send a POST request to your endpoint whenever it detects an order confirmation, shipping update, or return notification in any connected grant’s inbox.

Replace <NYLAS_API_KEY> with your API key and <YOUR_WEBHOOK_URL> with the public HTTPS URL where your server is listening.

Nylas returns the webhook object with a webhook_secret. Save this value — you need it to verify incoming notifications.

When you create the webhook, Nylas sends a GET request to your endpoint with a challenge query parameter. Your server must return the exact value in a 200 response within 10 seconds. No JSON wrapping, no extra whitespace — just the raw string.

Once the webhook is active, Nylas sends a POST request every time ExtractAI detects order, shipment, or return data in an email. Each notification type has a different payload structure, so your handler needs to route based on the type field.

Here is what a message.intelligence.order notification looks like (trimmed for clarity):

Notice that unit_price and total_amount are in cents, not dollars. A value of 4999 means $49.99. This is consistent across all ExtractAI responses. For the full payload schema, see the notification schemas reference.

Webhooks give you real-time notifications, but sometimes you need to pull data on demand. The Order Consolidation API lets you query for all orders, shipments, or returns associated with a grant. This is useful for building initial views, backfilling data, or running periodic syncs.

The shipment and return endpoints follow the same pattern — swap consolidated-order with consolidated-shipment or consolidated-return:

The Node.js and Python functions are identical to fetchOrders above — just change the URL path. All three endpoints return paginated results via next_cursor. If the response contains a next_cursor value, pass it as a page_token query parameter to fetch the next page.

The real value of ExtractAI shows up when you combine orders, shipments, and returns into a single view per order. The Order Consolidation API already links shipments and returns to their parent orders through order_id, so the join is straightforward.

The result is a flat list you can render directly in a dashboard, with each order carrying its shipments and returns inline.

  • Prices are in cents. Every monetary value in ExtractAI responses — order_total, unit_price, refund_total, tax_total — is in the smallest currency unit. 5863 means $58.63, not $5,863.00. Divide by 100 before you render. This is the bug you will ship if you don’t read this bullet.
  • Null fields are normal. Not every merchant includes every field. image_url, discount_total, shipping_total, gift_card_total, and sometimes merchant.name come back null. Always use fallbacks; never assume a field is populated.
  • IMAP is not supported. ExtractAI works only with Google and Microsoft grants. The Order Consolidation API returns an empty response for IMAP grants. Filter your grant list before you query.
  • Object IDs are not stable. As Nylas receives more email for an order (confirmation, then shipping, then delivery), it may update the ExtractAI object IDs. Use order_number and tracking_number as your primary keys — never the ExtractAI ID.
  • Historical backfill depends on setup order. Nylas only extracts data for grants authenticated after you configure ExtractAI webhooks. Enable the webhook before connecting users if you want the up-to-30-day backfill on day one.
  • Don’t ship without dedup. At-least-once delivery means the same order notification can arrive twice. Dedupe on order_number or tracking_number, not webhook ID.
  • Watch the confidence_score. Most extractions come back with 1 (high confidence). Lower scores signal an ambiguous email or unusual merchant format. Log them separately so you can review without polluting the main flow.