Skip to content
stmtai

Explainer

OFX, QFX and QBO files: what is inside

OFX sits behind bank download buttons; QFX and QBO are its Quicken and QuickBooks variants. The tags, why FITID matters, why QuickBooks rejects .qbo files.

8 min read · Last reviewed · by the stmtai team

OFX, Open Financial Exchange, is the file format behind most "download to Quicken" and "download to QuickBooks" buttons in online banking. A .qfx file is OFX with a few Intuit-specific tags added for Quicken, and a .qbo file is the same idea for QuickBooks. All three carry the same core: a sign-on block, a block for each account, and one STMTTRN record per transaction holding a date, an amount, a name and a unique ID. That ID is the reason these formats exist, because it lets the receiving software recognise a transaction it has already imported. This guide walks through the structure, the differences between the three extensions, and what to look at when QuickBooks refuses a file.

Where OFX came from

OFX was published in 1997 by Microsoft, Intuit and CheckFree as a common way for personal finance software to talk to banks. It merged three vendor protocols, Microsoft's Open Financial Connectivity, Intuit's OpenExchange and CheckFree's payment protocol, and over the following years displaced the older QIF export, which had no transaction IDs and no account identifiers. It was designed as a two-way protocol: the software sends a request to a bank's OFX server and the server replies with a statement. The files you download from online banking are the reply half of that exchange saved to disk, which is why every file opens with response tags (the RS in SIGNONMSGSRSV1 stands for response) even though no request was sent from your machine.

The specification is now maintained by the Financial Data Exchange, the body behind the FDX API that North American banks are adopting for app connections. File download over OFX is not disappearing at the same pace, because it needs no registration on the customer's side.

Two generations of syntax

OFX 1.x: SGML

Versions 1.0 through 1.6 use SGML. Opening tags are required, closing tags are optional for elements that hold a value, and the file begins with plain-text headers separated from the body by a blank line. This is what most banks still generate, because it is what Quicken and QuickBooks Desktop have read since the format appeared.

OFXHEADER:100
DATA:OFXSGML
VERSION:102
SECURITY:NONE
ENCODING:USASCII
CHARSET:1252
COMPRESSION:NONE
OLDFILEUID:NONE
NEWFILEUID:NONE

<OFX>
<SIGNONMSGSRSV1>
<SONRS>
<STATUS><CODE>0<SEVERITY>INFO</STATUS>
<DTSERVER>20260630120000
<LANGUAGE>ENG
<FI><ORG>Example Bank<FID>12345</FI>
</SONRS>
</SIGNONMSGSRSV1>
<BANKMSGSRSV1>
<STMTTRNRS>
<TRNUID>1
<STATUS><CODE>0<SEVERITY>INFO</STATUS>
<STMTRS>
<CURDEF>USD
<BANKACCTFROM>
<BANKID>021000021
<ACCTID>123456789
<ACCTTYPE>CHECKING
</BANKACCTFROM>
<BANKTRANLIST>
<DTSTART>20260601
<DTEND>20260630
<STMTTRN>
<TRNTYPE>DEBIT
<DTPOSTED>20260603
<TRNAMT>-1200.00
<FITID>2026060300123
<NAME>ACME SUPPLIES LTD
<MEMO>INVOICE 4471
</STMTTRN>
</BANKTRANLIST>
<LEDGERBAL>
<BALAMT>16550.00
<DTASOF>20260630
</LEDGERBAL>
</STMTRS>
</STMTTRNRS>
</BANKMSGSRSV1>
</OFX>

Notice that <CODE>0 has no closing tag while <STATUS> does. That is legal SGML and a regular source of trouble for anyone who tries to parse a 1.x file with an XML library.

OFX 2.x: XML

Version 2.0 arrived in 2000 and switched to XML. Every element is closed, the plain-text headers become an XML declaration and an OFX processing instruction, and the body uses the same tags in the same order:

<?xml version="1.0" encoding="UTF-8"?>
<?OFX OFXHEADER="200" VERSION="220" SECURITY="NONE" OLDFILEUID="NONE" NEWFILEUID="NONE"?>
<OFX>
  <SIGNONMSGSRSV1>...</SIGNONMSGSRSV1>
  <BANKMSGSRSV1>...</BANKMSGSRSV1>
</OFX>

The 2.x line continued through 2.1.1, 2.2 and 2.3, adding security and multi-factor features for live connections. For a downloaded statement the difference from 1.x is syntax, not content.

The structure

Whichever syntax, a bank statement file has three layers.

Sign-on: SIGNONMSGSRSV1

Server time, language, and the FI block naming the institution by ORG and FID. For a downloaded file this is boilerplate, but Quicken and QuickBooks Desktop read the FID and compare it against their institution directory.

Account block: BANKMSGSRSV1 or CREDITCARDMSGSRSV1

Bank and savings accounts use BANKMSGSRSV1 wrapping a STMTTRNRS, which holds the status block and the STMTRS. Credit cards use CREDITCARDMSGSRSV1 wrapping a CCSTMTTRNRS and CCSTMTRS, with CCACCTFROM in place of BANKACCTFROM and no BANKID. Investment accounts use INVSTMTMSGSRSV1, a separate set of tags this guide does not cover.

Inside the statement response sit CURDEF for the currency, the account identifier block, BANKTRANLIST holding every transaction between DTSTART and DTEND, and the balances.

Transaction: STMTTRN

TagMeaningNotes
TRNTYPETransaction typeCREDIT, DEBIT, INT, DIV, FEE, SRVCHG, DEP, ATM, POS, XFER, CHECK, PAYMENT, CASH, DIRECTDEP, DIRECTDEBIT, REPEATPMT or OTHER. Many banks use only CREDIT and DEBIT.
DTPOSTEDPosting dateYYYYMMDD, optionally followed by HHMMSS and a timezone in brackets, such as 20260603120000.000[-5:EST].
DTUSERDate initiatedOptional. When the customer made the transaction, if it differs from posting.
TRNAMTAmountSigned. Negative is money out. Decimal point (the specification also permits a comma, which some European banks use), no thousands separator.
FITIDFinancial institution transaction IDRequired. Must be unique within the account; the specification does not say for how long, but any reuse defeats duplicate detection.
CHECKNUMCheque numberOptional.
NAMEPayee32 characters in the specification, which is why payee names arrive truncated.
MEMOMemoUp to 255 characters. The rest of the narrative goes here.

Balances: LEDGERBAL and AVAILBAL

LEDGERBAL is the booked balance at DTASOF, normally the end of the statement period. AVAILBAL is the available balance including pending items. Only LEDGERBAL is required. There is no opening balance element in a standard statement response, so software that wants one works backwards from the closing balance and the transactions.

FITID and duplicates

FITID is what makes OFX a better import format than CSV or QIF. The bank assigns each transaction a string that is unique within the account and, at any bank that does it properly, never reused. When you import a file, the software records every FITID it has seen. Import a second file covering an overlapping range and the transactions with known FITIDs are skipped. Download the last ninety days every month and nothing doubles up.

This only works when the bank does it properly. Problems you will meet:

  • FITIDs that change between downloads for the same transaction, so nothing matches and everything duplicates. Some banks build the ID from the download time.
  • FITIDs that are not unique, typically a date plus a running balance. Two transactions for the same amount on the same day collide and one is dropped.
  • Converters that generate FITIDs by hashing date, amount and description. Consistent across runs, but two identical transactions on one day get the same hash unless the converter appends a sequence number.

If an import drops transactions you can see in the file, or duplicates ones you already have, FITID is the first place to look.

QFX: OFX for Quicken

A .qfx file is an OFX file with an INTU.BID element in the sign-on block, sometimes with INTU.USERID as well. INTU.BID is a number from Intuit's directory of institutions that have signed a licensing agreement for Quicken's Web Connect. Quicken will not import a plain .ofx file, and it refuses a .qfx whose INTU.BID does not match an institution it recognises. This is a commercial control rather than a technical one; the transactions inside are ordinary OFX.

Quicken checks the INTU.BID against its online directory at import time, which is why an old .qfx from a bank that has since left the programme can stop importing.

QBO: OFX for QuickBooks

A .qbo file is the same arrangement for QuickBooks. It carries INTU.BID, and QuickBooks Desktop also reads INTU.USERID and checks FID and ORG against Intuit's directory. QuickBooks Online's manual upload on a bank account accepts .qbo, .qfx and .ofx files as well as CSV, with a limit of 350 KB and 1,000 lines per upload, and does not enforce the institution directory the way Desktop does; it still validates the structure and rejects malformed files with a message that rarely says what is wrong.

Why QuickBooks rejects a .qbo

The messages are vague, so here are the causes in rough order of frequency:

  1. INTU.BID missing or not in Intuit's list, or FID and ORG inconsistent with that BID.
  2. A transaction with no FITID, or an empty one.
  3. Dates outside the DTSTART to DTEND range, or a DTASOF earlier than the last transaction.
  4. Characters QuickBooks cannot handle in NAME or MEMO: ampersands, angle brackets or accented letters in a 1.x file that does not escape them.
  5. NAME longer than 32 characters or MEMO longer than 255.
  6. A BANKMSGSRSV1 wrapper around what is actually a credit card account, or the reverse.
  7. Several accounts in one file, which QuickBooks Desktop handles and QuickBooks Online often does not.
  8. Line endings or an ENCODING header that does not match the actual bytes.

Run the file through the .qbo checker before importing; it reports these structural problems by line so you can fix the file rather than guess. The QuickBooks import guide covers the import steps and what to do when a file is accepted but the transactions land in the wrong account.

What to do with an OFX file

If your accounting software imports OFX, use it in preference to CSV. Xero, QuickBooks Online, Sage, FreeAgent and GnuCash all read it, Quicken needs the .qfx variant, and FITID-based deduplication is the reason to prefer it. Importing into Xero covers the Xero side.

If all you need is the OFX as a spreadsheet, the free OFX to CSV tool reads .ofx, .qfx and .qbo in your browser tab, without an upload, and writes CSV, Excel or a Xero CSV; it also writes a .qbo when a plain .ofx has to go into QuickBooks Desktop. If you have a PDF statement and need a .qbo, stmtai reads OFX as an input alongside PDF, scanned images, CSV and QIF, applies its balance check where the file carries balances, and writes Excel, CSV, QuickBooks .qbo or Xero CSV. It does not read or write investment OFX; for INVSTMTMSGSRSV1 files, use the software the file was downloaded for.

Questions

Can I rename a .ofx file to .qfx or .qbo and import it?

Renaming changes nothing inside the file. Quicken and QuickBooks Desktop look for INTU.BID in the sign-on block and reject a file without one whatever its extension. QuickBooks Online is different: its upload accepts .ofx and .qfx directly, so there is no need to rename anything for it.

Can I open an OFX file in Excel?

A 2.x XML file opens through Data, From XML, though the nested structure lands in awkward columns. A 1.x SGML file will not parse as XML because of the unclosed tags, and Excel shows it as one long text column. In both cases converting to CSV first gives a cleaner result than fighting the import wizard.

My bank only offers a .qfx download but I use QuickBooks. Will it work?

It depends which QuickBooks. QuickBooks Online uploads a .qfx directly, since its bank upload accepts .qbo, .qfx, .ofx and CSV. QuickBooks Desktop does not: its Web Connect import checks the extension and the institution directory and will refuse the .qfx even though the content is nearly identical. For Desktop, ask the bank whether it has a QuickBooks download, or download the PDF or CSV of the same statement and convert that to .qbo.

Does an OFX file include the opening balance?

No. The standard statement response carries LEDGERBAL, the closing booked balance at DTASOF, and optionally AVAILBAL. There is no element for the balance at DTSTART, so software that shows an opening balance has calculated it by subtracting the transactions from the closing figure. If you need to prove the file is complete, compare that calculated opening balance to the printed statement.

What does TRNTYPE OTHER mean?

It means the bank did not map the transaction to one of the named types and is leaving classification to you. Some banks send OTHER for everything except deposits and card payments. Accounting software generally ignores TRNTYPE and relies on the sign of TRNAMT for direction and on NAME and MEMO for categorisation, so an OTHER value costs you nothing in practice.

Related guides

All guides · All banks and formats