Sail

Enrich Transactions with Item-Level Data

Sail lets users connect their merchant accounts and retrieves their order history with product-level details. Instead of a flat transaction such as 49.00atWalgreens,youcanretrieveindividuallineitems,suchasbandages(49.00 at Walgreens, you can retrieve individual line items, such as bandages (8.99), shampoo (12.99),andathermometer(12.99), and a thermometer (27.02).

In this guide, you’ll create a user, connect a merchant account through Sail’s connect widget, and pull back item-level expenses.

Requirements

Before you start, make sure you have:

Step 1: Connect a merchant account

To get item-level data, your user needs to log into their merchant account. Create a Connect Widget session with connection_type set to store. Sail returns a single-use URL that you embed in your app as an iframe or redirect. Your user enters their merchant credentials inside Sail’s Connect Account Widget, and those credentials never touch your servers.

curl -X POST https://live.savewithsail.com/api/v1/hosted-sessions \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": "usr_abc123",
    "flow": "connect_account",
    "options": {
      "connection_type": "store"
    }
  }'
{
  "url": "https://<HOSTED_SESSION_URL>",
  "expires_at": "2026-08-10T15:31:07Z",
  "flow": "connect_account"
}

Open the url in an iframe or redirect your user to it. The session is single-use and the expires_at field tells you when it stops working. You can check which merchants Sail supports through the List Merchants endpoint.

Step 2: Listen for webhooks

After your user completes the login, Sail syncs the merchant’s order history. Listen for these webhook events to know when data is ready:

EventWhat it means
connection.createdYour user finished the connect widget and the connection exists.
connection.status_changedThe connection moved to a new status (for example, aggregating to active).
connection.syncedA sync finished. Check the expenses_updated flag to know if new expenses landed.

When you receive connection.synced with expenses_updated: true, the data is ready to fetch.

Note#

The first connection sync pulls up to 15 months of order history from the merchant, not only new orders.

Step 3: Pull item-level expenses

Once the sync completes, fetch the user’s expenses. Each item-level expense from a store connection represents a single product from an order.

curl "https://live.savewithsail.com/api/v1/users/usr_abc123/expenses?source_type=store" \
  -H "Authorization: Bearer sk_live_..."
{
  "data": [
    {
      "id": "exp_9f2c",
      "connection_id": "conn_8e3a",
      "name": "Digital Thermometer",
      "description": "Digital Thermometer - Forehead",
      "date": "2026-08-05",
      "amount": 27.02,
      "status": "eligible",
      "source_type": "store",
      "origin": {
        "type": "product",
        "detail": "Digital Thermometer - Forehead"
      },
      "merchant": {
        "name": "Walgreens",
        "supported_merchant_id": "mer_walgreens"
      },
      "enrichment": {
        "category": "Pharmacies",
        "subcategory": "Drug Stores"
      },
      "parent_expense_id": null,
      "section_213d_classification": {
        "status": "eligible",
        "category": "Health Monitoring Devices",
        "reasoning": "Digital thermometers are eligible medical devices under Section 213(d)."
      }
    }
    // ... 2 more items (Bandages $8.99, Shampoo $12.99)
  ],
  "pagination": {
    "limit": 25,
    "offset": 0,
    "total": 3
  }
}

Amounts are decimal numbers in USD (for example, 27.02 means $27.02).

Each item-level expense includes:

  • source_type: "store" — it came from a merchant connection.
  • origin.type: "product" — it’s an individual product, not a flat transaction.
  • enrichment — Sail adds a category and subcategory for each product.
  • section_213d_classification — whether the expense qualifies as a tax-deductible healthcare expense under IRS Section 213(d). To learn more about how classification works, see the Classify your own transactions guide.