Expense Classification
Sail ingests transaction-level and item-level expenses and classifies each one, with fine-grained detail, against a rules engine. Every expense ends up in one of four outcomes, eligible, ineligible, needs itemization, or needs a letter of medical necessity. This page explains what each outcome means, what triggers classification, and how you find out once it finishes.
What expense classification is
Classification, called “adjudication” in Sail’s API and webhooks, is how Sail decides whether an expense is a permitted expense under a specific set of rules.
Today, Sail classifies against Section 213(d) of the US tax code and IRS Publication 502, the same rules HSA, FSA, and HRA administrators use to decide what counts as a qualified medical expense. The result lives on the Expense object’s section_213d_classification field, the field your integration checks for the outcome.
However, other rules can be set up for your account on request, beyond the Section 213(d) default rule set. Classification runs automatically on every expense, whether it comes from a synced card, bank, or store connection, or from a batch of transactions you push yourself through an external connection.
The four outcomes
section_213d_classification.status surfaces one of four outcomes:
eligible: the expense qualifies as a Section 213(d) medical expense.ineligible: the expense doesn’t qualify.itemization_required: Sail can’t classify the expense yet, it needs itemization. See below.lmn_required: Sail can’t classify the expense yet, it needs a Letter of Medical Necessity. See below.
Once an expense is eligible, it can be reimbursed from the user’s HSA/FSA. See Reimbursement for the preconditions, the status lifecycle, and how a reimbursement can fail.
Needs itemization
itemization_required applies to transaction-origin expenses, meaning origin.type: transaction. It means the purchase came from a mixed-basket merchant (a store like Walgreens or Target that sells both eligible and ineligible items in the same transaction), so Sail can’t tell what was actually bought from the transaction alone. See Transaction-Level and Item-Level Expenses for the difference between transaction- and item-level data.
Needs letter
lmn_required applies to product-origin expenses, meaning origin.type: product. It means the item is dual-purpose (something with both a medical and a non-medical use, like a general-purpose humidifier), and it becomes eligible only with a Letter of Medical Necessity from the user’s provider.
What triggers classification
Classification runs automatically as soon as expense data lands in Sail, regardless of source. That includes expenses synced from a card, bank, or store connection, and expenses you push yourself through Push Transactions on an external connection. You never call a separate “classify this” endpoint, classification happens as part of processing the expense itself.
How you find out the result
Classification results arrive by webhook, not by polling. What you get depends on how the expense entered Sail.
- From a synced connection:
expense.createdfor a new, already-classified expense, orexpense.updatedwithsection_213d_classificationlisted inchangesif an existing expense’s classification changes. - From a pushed batch:
transactions.ingestedfires at the job level once the whole batch finishes, listingexpense_ids. Sail also firesexpense.createdper new expense within that batch, the same as a synced connection.
Once notified, the result is available from Get Expense or List Expenses. See Receiving New Data for how to verify and deduplicate any webhook delivery, classification included.
Resolving needs itemization or needs letter
For itemization_required, attach an itemized receipt through Upload Receipt or an upload_receipt flow of the Connect Account Widget. Either path triggers asynchronous reclassification. The outcome arrives as a receipt.processed webhook, listing the resulting child expenses, or receipt.failed if the receipt is unreadable.
Next steps
- To push your own transaction data and retrieve eligibility results, see Classify Your Own Transactions.
- To see how expense data enters Sail in the first place, see Transaction-Level and Item-Level Expenses.