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
| Tag | Meaning | Notes |
|---|---|---|
| TRNTYPE | Transaction type | CREDIT, DEBIT, INT, DIV, FEE, SRVCHG, DEP, ATM, POS, XFER, CHECK, PAYMENT, CASH, DIRECTDEP, DIRECTDEBIT, REPEATPMT or OTHER. Many banks use only CREDIT and DEBIT. |
| DTPOSTED | Posting date | YYYYMMDD, optionally followed by HHMMSS and a timezone in brackets, such as 20260603120000.000[-5:EST]. |
| DTUSER | Date initiated | Optional. When the customer made the transaction, if it differs from posting. |
| TRNAMT | Amount | Signed. Negative is money out. Decimal point (the specification also permits a comma, which some European banks use), no thousands separator. |
| FITID | Financial institution transaction ID | Required. Must be unique within the account; the specification does not say for how long, but any reuse defeats duplicate detection. |
| CHECKNUM | Cheque number | Optional. |
| NAME | Payee | 32 characters in the specification, which is why payee names arrive truncated. |
| MEMO | Memo | Up 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:
- INTU.BID missing or not in Intuit's list, or FID and ORG inconsistent with that BID.
- A transaction with no FITID, or an empty one.
- Dates outside the DTSTART to DTEND range, or a DTASOF earlier than the last transaction.
- Characters QuickBooks cannot handle in NAME or MEMO: ampersands, angle brackets or accented letters in a 1.x file that does not escape them.
- NAME longer than 32 characters or MEMO longer than 255.
- A BANKMSGSRSV1 wrapper around what is actually a credit card account, or the reverse.
- Several accounts in one file, which QuickBooks Desktop handles and QuickBooks Online often does not.
- 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.