Every PDF-to-ESX converter on the market claims it produces files that import into Xactimate. Very few can tell you what Xactimate actually checks when it imports a file — because the import rules are undocumented.
This article documents the structural rules Xactimate enforces when it imports an ESX file — the sections, line-item linkage, and code rules that determine whether a file imports cleanly or is rejected. We publish this because we believe the team that understands these rules better than anyone should be the one you trust to generate your files.
1. The File: One Structure, One Job
An .esx file has a very specific structure. Get any of these details wrong and Xactimate returns the dreaded "Invalid file format" before it even looks at your estimate.
| Property | What Xactimate expects | Why it matters |
|---|---|---|
| Archive packaging | Standard ZIP archive (stored, not compressed) | A compressed outer archive is rejected |
| Archive metadata | Standard DOS/FAT metadata | Non-standard archive metadata is rejected |
Photo members (.JPG) | Standard JPEG image files | Photo members that aren't standard JPEG images are rejected; the large majority of exports store photos as plain images |
| Estimate document | The file's estimate document member | Holds the estimate itself |
The estimate document is carried inside the archive in Xactimate's native project-file format. You don't need to inspect the archive internals to verify a file — the checks below cover the document and code rules Xactimate applies on import.
Everything below is what the estimate document looks like.
2. The Root Document: Sections in a Fixed Order
The document root has its children in a strict order. In the files we've seen, the order never varies:
PROJECT_INFO → GROUP → PARAMS → COMPANY_HEADER → SALESTAXES → ADM →
CLAIM_INFO → CONTACTS → EMBEDDED_PL → MINIMUMS → UNITS → ITEM_TAGS →
COMPONENTS → SUPP_EVENTS → AUDIT_DOC → SESSION_STATS → EXT_FILES
Two things stand out to anyone who has seen a spec sheet for a "compatible" generator:
- There is no
<TOTALS>section. Real files never have one. Adding one is a reliable way to produce a file Xactimate rejects. - Line items live in the embedded price list (
EMBEDDED_PL). TheGROUP/SUMMARY/SUMMARY_ITEMvariant that some generators emit is rejected by current Xactimate builds.
3. PROJECT_INFO: The Attribute That Prices the File
PROJECT_INFO carries identity and pricing-context attributes. Two matter more than any others:
profile="8D"— contractor mode: retail/contractor pricing context, where overhead and profit typically apply.profile="5L"— carrier mode: insurance/carrier context, matching the carrier-approved RCV and excluding O&P.
The export-mode switch flips both the profile attribute and the O&P treatment; they travel together. A file that mixes them prices the claim wrong.
4. Line Items: The Price-List Master, ITEM, and SUMMARY_REF Linkage
Two element families work as a pair, and getting the linkage wrong is the most common silent failure in generated files.
The price-list master is what gets priced. It is a single line-item element that carries the identity and pricing-context attributes — cat/catId/itemId/sel, the activity variant (act), unit, lifeExpectancy, source/sourceDescription, coverage, and the skClass/skGroup sketch-classification linkage — with one child activity element holding the displayed unit price as the sum of labBase + labMarkup + labBurden + matCS + mkt + equ.
The rules that matter:
- No price attributes. The price-list master carries zero
UC=/unitCost/priceattributes. Xactimate prices from its own loaded price list viacatId/itemId/sel. Writing prices into the master element is a known import reject. - The displayed unit price lives in
SUM_ACTIVITY: the sum oflabBase + labMarkup + labBurden + matCS + mkt + equ. Removal lines (act="-") carry labor and equipment only; install lines (act="+") carry material and labor. Phase codes: 66 = removal, 86 = install. skClass/skGroupare the sketch-classification linkage. Missing them means price-list re-link failure on import.- Empty
<SUM_ACTIVITIES/>= "Not in Price List" on import — the line shows up unpriced.
ITEM is the line on the estimate, and it references the price-list master:
<ITEM id="ITM1" type="S" dateTimeStamp="..." user="..." xid="608408">
<SUMMARY_REF sumRef="SUM1" lineNum="1" calc="72.28" qty="72.28"
depType="D" recoverable="1"/>
</ITEM>
The three rules that catch almost every generated file:
- Linkage is
SUMMARY_REF sumRef="SUM#"→ the price-list master withid="SUM#". calcmust equalqty(it does in the overwhelming majority of exports).calcis not qty × price — Xactimate computes the dollar extension itself from its price list. Writing qty×price intocalcmakes imported line totals wrong.xid="608408"is a constant in the majority of exports. The old assumption that ITEM xid must equal the price-list master's id is wrong.
F9-style notes are separate type="N" attached="1" ITEM elements with \5Crtf-escaped RTF text — which is why "preserves F9 notes" is a real feature, not a checkbox.
5. CAT|SEL Codes: The Language Xactimate Prices In
A line item's identity is cat|sel — for example RFG|300S (roofing, architectural shingles) — with an optional activity variant: + (install/add), - (remove), and & (remove & replace, stored as act="&" in XML).
The sel= charset in Xactimate project files is A-Z a-z 0-9 # + . / - only. That restriction is exactly why corrupted catalog data is dangerous: entity characters can leak into SEL codes — one polluted catalog snapshot carried hundreds of SEL variants with stray ">" characters (for example APP|CKIT> and RFG|ARMV>>), up to four arrows deep. Files containing those codes are rejected on import with "Invalid file format", or worse, import with broken lines.
There are dozens of categories (RFG roofing, PNT painting, SFG soffit/fascia/gutter, DRY drywall, DMO demo, INS insulation, WDW/WDA windows/doors, HVC HVAC, ELE electrical, SDG siding, and more). A catalog built from verified Xactimate price-list data covers virtually all of them.
6. What Xactimate Does on Import
Understanding the format means understanding what happens at import time:
- Xactimate reads each line's
cat/sel/actand looks up the currently loaded price list bycatId/itemId. - It ignores the file's
priceList=stamp for repricing — a fresh import prices against the list currently loaded in the app. This is why the same file can show different totals on different machines. SUM_ACTIVITYvalues are the displayed unit price;MODIFICATION unitPriceis the file's recorded price; neither overrides the price-list lookup.- Codes not present in the loaded list → "Not in Price List" per line.
In other words: the file is a structure plus an identity, not a priced document. Generators that bake prices into the file are fighting the platform — generators that nail the structure and the codes are working with it.
7. How to Verify an ESX File Before You Import It
You do not need to be a format expert to catch the common failures. Run these checks on any file before it goes to an adjuster — or paste it into our free ESX File Validator, which automates all of them in your browser.
- Check the file. The file must open as a standard ZIP archive. Photo members must be standard JPEG images.
- Confirm the root. Open the document XML; the root element must be
XACTDOCwithPROJECT_INFO,CLAIM_INFO,SALESTAXES, andEMBEDDED_PLpresent. No<TOTALS>section. - Verify
lastCalcGrandTotalis present and positive, and that it matches the PDF's RCV when that is the goal. - Scan every SEL code against the charset
A-Z a-z 0-9 # + . / -. Any other character is a red flag — especially stray ">" arrows. - Check
calcequalsqtyon everySUMMARY_REF, and thatactvalues are only+,-, or&. - Confirm no
UC=price attributes on the price-list master and noGROUP/SUMMARYline-item structure.
8. The Receipt: Where These Rules Come From
This is not theory. The rules above come from real-world conversion work and the import failures that taught us what Xactimate rejects.
The point: anyone can claim to be "verified." We publish the failure modes and the import rules. That is the difference between a converter and a format lab — and it is why ESXPress output is verified against Xactimate's import rules before it ships.
9. What This Means for Your Workflow
If you are a contractor or supplementer buying ESX conversion, the format knowledge above is your buying checklist: does the tool preserve the price-list/line-item linkage? Does it price every line against the current catalog? Does it keep calc == qty? Does its output match the PDF's RCV on a real claim? Those questions separate tools that ship files from tools that ship headaches.
ESXPress converts carrier PDFs to import-ready ESX files in about two minutes — with every line resolved against an 18,054 SEL dictionary, automated verification that flags anything it can't resolve, and the structural checks in this article run automatically on every export. The free validator at /tools/esx-validator gives you the same checks on any file, no signup required.