OFX / QFX format reference

OFX (Open Financial Exchange) is the standard bank-data interchange format. Almost every U.S. bank, brokerage, and credit union supports OFX export from their online portal. QFX is Intuit's proprietary flavor — same wire format, different file extension, with a magic-bytes header that targets QuickBooks specifically. Solid Accounting reads both interchangeably.

For ad-hoc bank-statement imports, OFX/QFX is usually a cleaner choice than CSV — the format carries structured fields (date, amount, payee, transaction type, FITID for deduplication) without per-bank quirks.

What's supported

ExtensionFormatSource
.ofxOFX (open standard)Most banks, brokerages, credit unions
.qfxQFX (Intuit)U.S. banks targeting QuickBooks specifically
.qboOFX/QFX rebrand by IntuitSame content, alternate extension

Solid auto-detects the format from content (looks for OFXHEADER or <OFX> in the first bytes); the extension is ignored after detection.

Format structure

OFX is XML-like — actually SGML in OFX 1.x, proper XML in OFX 2.x. Both look similar:

<OFX>
  <BANKMSGSRSV1>
    <STMTTRNRS>
      <STMTRS>
        <CURDEF>USD</CURDEF>
        <BANKACCTFROM>
          <BANKID>121000358</BANKID>
          <ACCTID>1234567890</ACCTID>
          <ACCTTYPE>CHECKING</ACCTTYPE>
        </BANKACCTFROM>
        <BANKTRANLIST>
          <DTSTART>20260401</DTSTART>
          <DTEND>20260430</DTEND>
          <STMTTRN>
            <TRNTYPE>DEBIT</TRNTYPE>
            <DTPOSTED>20260415</DTPOSTED>
            <TRNAMT>-642.18</TRNAMT>
            <FITID>20260415-001</FITID>
            <NAME>Linode</NAME>
            <MEMO>April hosting</MEMO>
          </STMTTRN>
          ...

The shape is verbose but unambiguous. Each transaction is an <STMTTRN> block.

Field reference

What Solid reads from each <STMTTRN>:

OFX tagMaps to Solid fieldNotes
DTPOSTEDTransaction dateFormat YYYYMMDD or YYYYMMDDHHMMSS; we use the date portion
TRNAMTAmountPositive (credit) or negative (debit)
TRNTYPETransaction-type hintDEBIT, CREDIT, CHECK, DEPOSIT, XFER, FEE, etc. — used as a default account hint
FITIDExternal IDUnique per transaction per institution; used for duplicate detection
NAMEPayeeFree-text; usually the merchant or counterparty
MEMOMemoAdditional description
CHECKNUMReference numberCheck number when applicable
CHECKBANK (rare)Reference numberUsed by some banks instead of CHECKNUM

What Solid reads from <BANKACCTFROM>:

OFX tagUse
BANKIDBank routing number — surfaced for verification only
ACCTIDAccount number — surfaced for verification, never logged
ACCTTYPECHECKING, SAVINGS, CREDITCARD, MONEYMRKT, LINEOFCREDIT — used as a default account-type hint

For credit cards, the equivalent block is <CREDITCARDMSGSRSV1> with <CCSTMTTRNRS> instead of <BANKMSGSRSV1> and <STMTTRNRS> — Solid reads both shapes.

Date format

OFX dates are YYYYMMDD (no separators) for date-only fields and YYYYMMDDHHMMSS[.XXX][TZ] for timestamps. Solid:

  • Always uses the date portion only — bank-statement imports are date-of-posting, not time-of-posting
  • Ignores the timezone — bank exports rarely have meaningful TZ data

Duplicate detection via FITID

The FITID (Financial Institution Transaction ID) is OFX's killer feature for re-imports. Every transaction has a unique FITID per account; Solid stores it on the imported entry's external_id field. When you re-import a later statement that overlaps with the previous one, Solid recognizes the FITIDs as already-imported and skips them.

This is why OFX is much friendlier than CSV for repeated imports — there's no "did I already import this?" guessing. Re-imports are always safe.

Encoding

OFX 1.x uses an SGML-ish header that declares the encoding (USASCII is most common; sometimes Latin-1). OFX 2.x uses a proper <?xml?> declaration. Solid reads either; almost no OFX file in practice has non-ASCII characters in payee/memo fields.

QFX vs. OFX — the practical difference

QFX has an extra INTU.BID (Intuit Bank ID) tag that authenticates the file to QuickBooks specifically. Some banks only let you download QFX (not OFX) on the assumption that you're a QB user. Solid Accounting reads QFX regardless of the INTU.BID content — we just ignore the QuickBooks-targeting bits and treat the file as OFX.

For practical purposes, you can rename a .qfx to .ofx and most software will still read it. Solid handles either.

Multi-currency

OFX has a <CURDEF> for the statement's default currency and an optional per-transaction <CURRENCY> block for foreign-currency transactions. Solid reads the default; per-transaction currency is captured but treated as advisory (the actual posted amount is what your bank reports, regardless of the underlying source-currency amount).

What OFX/QFX doesn't carry

  • Account names beyond bank account ID — there's no "Operating Checking" label in the file; Solid asks you which Solid account it should map to during the wizard
  • Customer/vendor records — these aren't bank-statement-level data
  • Reconciliation status — OFX doesn't have a "cleared" flag; transactions on a downloaded statement are by definition cleared at the bank, but Solid doesn't auto-mark them cleared (you do that during reconciliation)
  • Categories — some banks include a <CATEGORY> tag; if present, Solid uses it as an account hint, but most banks don't fill this

Common errors

"OFX header missing or invalid" — the file isn't OFX. Some banks call exports "OFX" but actually export CSV or TSV in disguise. Open in a text editor; if the first line isn't OFXHEADER:100 or <?xml, it's not OFX. Use the CSV import wizard instead.

"Unknown TRNTYPE" — a transaction type code Solid doesn't recognize. The transaction still imports, just without a type hint. The full list of common codes: DEBIT, CREDIT, CHECK, DEP/DEPOSIT, XFER, ATM, CASH, FEE, INT, DIRECTDEP, DIRECTDEBIT, OTHER. Anything else is treated as OTHER.

"Date 19700101 detected" — empty or malformed DTPOSTED. Check the affected transaction in your bank's online portal; usually a pending transaction that hasn't fully posted yet.

Date precision off by a day — OFX timestamps have timezone information; if your bank exports in a TZ ahead of yours, a transaction posted at 11pm local could appear as the next day. Solid uses the date portion as-is without TZ conversion. If precision matters, edit the date on the imported entry.

Same transaction imported twice from overlapping statements — should be impossible thanks to FITID. If it happened, your bank may be reusing FITIDs (rare, but it occurs with some smaller institutions). Verify the duplicate has the same FITID; if so, contact us with the bank's name and we'll add an override.

When to prefer OFX/QFX over CSV

  • Re-importing a statement period (FITID makes this safe)
  • Bank gives you both — OFX is more reliable due to structured fields
  • The CSV's quoting is broken — OFX's hierarchical structure avoids quoting bugs

When to prefer CSV: bank only offers CSV, payroll providers (which rarely speak OFX), and any non-banking source.

Cross-references