What Is a QBO File? The QuickBooks Web Connect File, and How to Open and Check One
A QBO file is a QuickBooks Web Connect bank download in OFX text. Two readers disagreed on 9 of the 21 damaged copies we made of one. Jump to your question below, or work through it in order.
What Is a QBO File? A bank download in OFX text, made for QuickBooks
Short answer
A QBO file is a QuickBooks Web Connect file, a bank or credit card download in the Open Financial Exchange format. It stores an account, a date range and a list of transactions as text, per FileInfo. IANA lists no fixed first bytes for it.
We checked 65 files from five public projects, and only one is named .qbo. The other 64 use the same layout. Two open readers, ofxparse and ofxtools, agreed on 31 of the 65. We damaged one download 21 ways, and the readers disagreed on 9 of those copies.
To open or import one, read the open steps. To check one, read the check steps. If QuickBooks refuses your QBO file, begin with the eight causes.
A QBO file is a QuickBooks Web Connect file. It is a bank or credit card download in the Open Financial Exchange format, and QuickBooks reads it so you do not type the transactions by hand.
Picture a download from your bank called transactions. You double click it and nothing opens. Picture a second file, statement, from another bank. Both contain the same kind of text, and only the ending differs.
FileInfo describes a QBO file as a financial data file that stores bank or credit card account details and transactions. Intuit is the maker, and the page says the format is based on Open Financial Exchange, called OFX.
The same page names QuickBooks Pro for Windows, QuickBooks for Mac, QuickBooks Online, FreshBooks and two free web tools, a QBO to CSV converter and a QBO viewer. We tested none of them.
IANA registered the media type application/vnd.intu.qbo with the extension .QBO. The record is dated 10/5/1998, lists the magic number as N/A and says the type stores confidential financial information. So a QBO file has no fixed signature.
OFX is older than QuickBooks Online. Wikipedia says Microsoft, Intuit and CheckFree announced it on 1/16/1997 and released version 1.0 on 2/14/1997. Versions up to 1.6 use SGML, and later versions use XML.
Where our QBO files come from
We read 65 files from five public projects. They are beancount-import with 19 files, beangulp with 5, csv2ofx with 22, ofxparse with 14 and ofxtools with 5.
63 of the 65 end in .ofx, one ends in .qfx and one ends in .qbo. The .qbo file is a bank download of 6,807 bytes from the beangulp tests. The files are 145 to 25,833 bytes long and 229,380 bytes in total, and the median is 1,985 bytes.
So this page studies the OFX layout that every QBO file uses, and not 65 files named .qbo. We damaged one credit card download in 21 ways. We had no copy of QuickBooks, and we imported nothing.
QBO file facts at a glance
| Property | Value |
|---|---|
| Meaning | A QuickBooks Web Connect file. It stores the account details and transactions of a bank or credit card download. |
| Ending | .qbo. Banks also name the same layout .ofx or .qfx, so the ending does not name the layout. |
| Maker | Intuit, per FileInfo. |
| First bytes |
IANA lists no magic number. 29 of our 65 files start with OFXHEADER:100, 21 with DATA:OFXSGML, 11 with an XML declaration and 4 with <OFX>.
|
| Layout |
A header of 9 lines, then tags like <STMTTRN> for every transaction. Version 1 files use SGML and version 2 files use XML.
|
| Intuit tag |
The <INTU tag is in the sign on block of 11 of our 65 files, and it is not tied to the ending.
|
| Size limit | Intuit says a transaction file for manual upload to QuickBooks Online must be 350 KB or less, with 1,000 lines at most. |
| Our tests | 65 files, 21 damaged copies, 2 readers, 11 repair commands and a CSV script tested on 43 files. |
Wrong page? A QFX file is the Quicken version of this layout. See how QFX, IIF and CSV files differ.
Which Kind of QBO File Do You Have? Four starts, and the first line names the kind
Four starts name the kind of a QBO file. In our 65 files, 29 start with OFXHEADER:100, 21 with a DATA line alone, 11 with an XML declaration and 4 with bare tags. The ending names none of them.
Read the first line and follow the figure. We tested all four starts with files. The ending is no help, because banks and tools write the same layout under .qbo, .qfx and .ofx.
The four starts in detail
| Start | Files and results |
|---|---|
| OFXHEADER:100 | 29 files. This is the version 1 form with a 9 line header and SGML tags. ofxparse read 27 and ofxtools read 23. Our script printed OK for 27. All 5 beangulp files, including our only .qbo file, start this way. |
| DATA:OFXSGML |
21 files, and all 21 come from csv2ofx. The header has two lines and no OFXHEADER line. ofxparse read 4 and ofxtools read none. Our script warned on all 21.
|
| XML declaration |
11 files. This is the version 2 form, and the first line is <?xml. ofxparse read all 11, ofxtools read 8 and our script printed OK for all 11.
|
| Bare tags |
4 files. The file starts with <OFX> and has no header at all. ofxparse read 1, ofxtools read none, our script warned on 2 and flagged 2.
|
Start with the first line
Open the QBO file in a text editor, or use head -n 3 on Linux or Mac. A full header names the kind at once. If the file opens as unreadable symbols, a different program made it and it is not a text download.
The file command is of little help here. It named 54 of our 65 files plain text and the other 11 XML. It never said OFX or QBO, so it cannot separate a bank download from any other text file.
OFXHEADER:100 means version 1, and <?xml means version 2.
Not sure your file is a QBO file at all? Check it with our script.
What Is Inside a QBO File? Header, sign on block and transactions
A QBO file is text in layers. A header of 9 lines comes first, then a sign on block that can store the INTU.BID tag, then the statement with its transactions. Our example QBO file is 6,402 bytes long and has 27 transactions.
We read these files because the tags are open text, so every value can be checked. Our example QBO file is a credit card download from the beangulp tests, copied to the short name example.qbo. The first lines show the header.
head -n 9 example.qbo
OFXHEADER:100
DATA:OFXSGML
VERSION:102
SECURITY:NONE
ENCODING:USASCII
CHARSET:1252
COMPRESSION:NONE
OLDFILEUID:NONE
NEWFILEUID:NONE
xxd -l 32 example.qbo
00000000: 4f46 5848 4541 4445 523a 3130 300a 4441 OFXHEADER:100.DA
00000010: 5441 3a4f 4658 5347 4d4c 0a56 4552 5349 TA:OFXSGML.VERSI
file -b example.qbo | cut -d, -f1-2
ASCII text, with very long lines (6268)
file -b --mime-type example.qbo
text/plain
OFXHEADER:100 is the header format and VERSION:102 is the OFX version. All 29 of our version 1 files use 102. The 11 XML files show other numbers, from 200 to 220. SECURITY:NONE and COMPRESSION:NONE say that the file has no security layer and no compression.
ENCODING:USASCII and CHARSET:1252 name the text encoding. 29 of our files say USASCII, 21 say UTF-8 and 15 say nothing.
After the blank line the body starts at <OFX>. In our example QBO file the body is on one line of 6,268 characters, so a text editor scrolls it sideways. 9 of our 65 files have a line over 2,000 characters, and the longest has 14,378.
The tags, block by block
The body has a sign on block, then one block for every account. The sign on block stores a status, the server time and the language, and in many files the bank name and ID. Our example QBO file stores <INTU there.
A credit card account is wrapped in <CREDITCARDMSGSRSV1> and a bank account in <BANKMSGSRSV1>. Inside, <STMTTRN> marks one transaction. It stores a type, date, amount and ID, and in most files name and memo.
SGML files, like our example QBO file, close a block tag but leave value tags open, so <CODE>0 joins straight to the next tag. XML files close every tag. Readers that expect the wrong style fail, which explains some of the refusals we saw.
What the tags store
| Part | What it stores and what we saw |
|---|---|
| Header | Nine lines in version 1 files. 29 of our files have the full header, 21 have a DATA line alone and 4 have none. |
| Sign on block |
<SIGNONMSGSRSV1> stores the status and the server time. 64 of our 65 files have it.
|
| Bank account |
<BANKMSGSRSV1> stores the bank ID, the account ID and the type. 35 of our files have it.
|
| Credit card |
<CREDITCARDMSGSRSV1> stores the card account. 7 of our files have it.
|
| Investment account |
<INVSTMTMSGSRSV1> stores positions and trades. 18 of our files have it, and our script counts bank and card transactions only.
|
| Transaction |
<STMTTRN> stores TRNTYPE, DTPOSTED, TRNAMT and FITID, and in most files NAME or MEMO. We counted 207 in 43 files.
|
| Date |
DTPOSTED comes in many shapes. 86 values have 14 digits and 8 values have 8 digits. The rest add a time zone like [-5] or [-7:MST].
|
| Type |
TRNTYPE is DEBIT in 134 cases and CREDIT in 44. Eight other values make up the remaining 29.
|
| Balance |
<LEDGERBAL> stores the balance at a date. 26 of our files have it.
|
| INTU.BID | The Intuit bank ID tag. 11 of our files have it with 7 different values. Our .qbo file stores 12824. |
What the sources say
Wikipedia lists the OFX versions from 1.0 in 1997 to 2.3, and says the OFX consortium joined the Financial Data Exchange group in 2019. It names QFX as an Intuit variant. It says nothing about QBO.
We found no Intuit page that lists the fields of a QBO file. So the layout here comes from our own reading of 65 files and from the ofxtools and ofxparse projects, which parse the same tags.
The map is small. Our script reads the header, the closing tags and four fields of every transaction. It does not read balances, investment trades or the sign on block, so damage there can pass it, as the 21 copies show.
What Did We Find in 65 Bank and Card Files? Two readers, and they did not agree
We read 65 files with two OFX readers, the file command and a 33 line script. ofxparse read 43 and ofxtools read 31. Both read the same 31, and neither read 22. Our script printed OK for 38.
All 65 files come from five public test sets, so this is a study of those projects and not of every QBO file. Only one ends in .qbo. We used the layout, because a QBO file is OFX text with an Intuit tag in the sign on block.
Readers were file 5.45, ofxparse 0.21, ofxtools 1.1.1 and our own script on Python 3.13, all on Linux. A reader passed a file once it returned without an error. We opened no file in QuickBooks, so a pass is not a successful import.
| Test | Result |
|---|---|
| The file command | Named 54 files plain text and 11 XML. It never said OFX or QBO. |
| ofxparse | Read 43 files and refused 22. 18 refusals were an IndexError, and 4 came from the parser itself. |
| ofxtools | Read 31 files and refused 34. 26 refusals were header errors, 6 were spec errors, 1 was a parse error and 1 was a type error. |
| Our script | Printed OK for 38 files, WARN for 24 and FLAG for 3. 22 warnings say the header is not full. The 3 flags are test files with a missing date, bad amount and missing ID. |
| Sizes | 145 to 25,833 bytes, with a median of 1,985 and a total of 229,380. |
| Transactions |
207 <STMTTRN> blocks in 43 files. The other 22 files have none.
|
One layout and four starts
Every file has the OFX tags. 64 of 65 have a sign on block, 35 have a bank account, 7 a credit card and 18 an investment account. The four starts split the files into 29, 21, 11 and 4, and the start predicts how a reader will do.
29 files use the version 1 header with VERSION:102. 11 use XML with versions from 200 to 220. 21 start with a DATA line alone, and all 21 come from the csv2ofx project. Those 21 are the weakest files in the study.
Where the two readers split
Both readers read 31 files and both refused 22. ofxparse read 12 more that ofxtools refused. No file went the other way, so ofxparse is the more lenient reader here. ofxtools checks the header and the spec closely.
ofxtools read none of the 21 DATA line files, because its check finds a malformed header. ofxparse read 4 of them and stopped with an IndexError on 17. A short header is no sure win with either reader.
Two checking files from beancount-import store the 10 digit bank ID 5472369148. ofxtools refused both, because its spec allows 9 characters at most. ofxparse read one of them and refused the other for an empty ledger balance.
The one file named .qbo
The .qbo file has 6,807 bytes, a bank account and a credit card account. It has the tag <INTU. ofxparse read 23 transactions from it. ofxtools refused it, and the first reason is a NUL byte after </.
Without that byte, ofxtools still stopped. The account type of the credit card block reads BJNZDIF, and its list allows only CHECKING, SAVINGS, MONEYMRKT, CREDITLINE and CD. So the .qbo file we have breaks the spec in two places.
ofxtools also warned that INTU.BID is a private extension tag. That fits what we saw, because 11 files have the tag with 7 different values and 9 of the 11 end in .ofx. The tag does not follow the ending.
Names, dates and amounts
Dates come in many shapes. 86 DTPOSTED values have 14 digits, 8 have 8 digits and others add a time zone like [-7:MST]. Two amounts use a comma. Our script accepts both signs and both marks, and it still flags a bad amount like $120.
Read the study with care. It shows what two open readers do with 65 files from five projects. QuickBooks can be stricter or more lenient than either, and we had no copy of it. Bank files from other banks can differ from ours.
What Happens When a QBO File Is Damaged? 21 broken copies, and the readers disagreed on 9
We damaged one credit card download in 21 ways. The two readers disagreed on 9 copies, and neither matched the original on 6. Our script flagged or warned on 13, and 11 kinds of damage have a repair command.
The 21 copies come in three groups of 7. Group A changes the header. Group B changes the length of the file or how it was moved. Group C changes the content. Every copy changes one thing in example.qbo, which is 6,402 bytes long with 27 transactions.
We asked three questions about every copy. What did the reader return, compared with its answer on the original? Did our script flag it? Did one command restore the original, checked by SHA-256 on the healthy files that our script passes?
Copies that split the readers
A2 changes the header number from 100 to 999. ofxparse returned all 27 transactions, and ofxtools refused the file because 999 is not a valid number. Our script printed OK, so it did not notice.
A1 removes the first header line, A3 removes the header and B6 loses the first byte. ofxparse read all three, and ofxtools refused all three. C1 flips one bit, and ofxtools refused it with an IndexError while ofxparse read all 27 transactions.
B2 cuts the file to half, and C7 zeroes the second half. ofxparse returned an empty list and no error for both. That is the worst case in the grid, because 0 transactions looks like a quiet month.
B3 keeps only the header, and C3 sets a date to 20131345. Both readers refused both copies. So refusals by both readers cover only 2 of the 21 copies, and at least one reader returned the original data for 15 copies.
The 13 copies our script flagged or warned on
B2, B3 and B7 lose the closing tag or more, and the script says no </ or no <OFX> tag. A5 adds a byte order mark and B6 loses the first byte. The script says the header is missing or starts wrong.
C1 flips a bit inside a tag name, so a transaction has no type. C3 gives a date that does not exist, and C5 loses a closing </. C7 zeroes half of the file, and the script reports a zero byte and its position.
A1, A3, B4 and C2 only get a warning. A1 and A3 lose part of the header and B4 adds 512 zero bytes after </. C2 repeats a transaction with the same ID. The warnings are weak. 24 of our 65 files get warnings too, and 22 of those only lack a full header.
A5 and B7 show that the script is stricter than the readers. Both readers returned the original data for them, and the script flagged them anyway. A byte order mark and missing closing tag are still worth a repair.
The 8 copies our script passed
A4, A6, A7, B1, B5 and C4 pass the script, and both readers returned the original for all six. They change the version number, remove the INTU.BID tag, relabel the encoding, cut the last newline, swap the line ends and write a comma in one amount.
A2 and C6 are the two that matter. A2 passes the script and ofxtools refuses it. C6 changes one digit in one amount, from -29.00 to -79.00, and the sum of all amounts moves from -989.26 to -1039.26. Both readers returned the wrong total without a warning.
A pass means the structure is sound and not that the numbers are right. Only the bank, second downloads or totals from the statement show a changed amount.
Repairs that worked
We wrote one command per kind of header or ending damage, 11 in all, and tested every one on the healthy files where the damage applies. A hash matched the original for 8 kinds on every file we tried.
A1 writes the first header line back, and A2 and A4 write the right header and version numbers back. A5 cuts the byte order mark. B6 puts the first character back, B4 removes the zero bytes and C2 removes the repeated transaction. C4 changes the comma back into a period.
Three repairs work on most files and not all. A3 rebuilds a standard header, and it matched the original on 10 of 27 files, because banks write different headers. B1 matched on 36 of 38 files and B7 on 25 of 38, because the original files end in different ways.
Our first versions of B1, B6 and B7 failed on some files. B6 broke on files that start with <OFX> or <?xml, and B7 put the closing tag in the wrong place. Repairs that guess can make files worse, so use it on a copy.
What no command repaired
B2 and C7 lose content and B3 keeps only the header. C1 and C6 change bytes inside a value. No rule shows what the original bytes were. A6 removes the INTU.BID tag, and the bank ID inside it is gone.
A7 and B5 need no repair, because both readers returned the original and the script printed OK. C3 and C5 break the date and the closing tag. We tested no repair for them, because a guess could change a value.
Read the grid with care. Every copy changes one thing in one download. Damage in the wild changes many things at once. We imported no copy into QuickBooks, and our repairs rely on rules that fit the files we tried.
What Does Our Expert Say About QBO Files? A note from Neeraj Singh on checking the total
Check the total against your statement before you import. Our two readers disagreed on 9 of 21 damaged copies, and one copy with a changed amount passed every check we have.
Expert insight
“A QBO file is text, and two open readers gave different answers on the same damaged copy. In our test only 8 of 21 copies read the same in every tool. Download a fresh file from your bank first, keep the original and check the total against your statement before you import.”
Why one reader is not enough
A reader can return the wrong data without an error. ofxparse returned an empty list for two damaged copies and wrong totals for two others. A refusal at least warns you that something is wrong.
We had no copy of QuickBooks. If QuickBooks imports your QBO file and the totals match your statement, treat that as the best test. Use the readers on this page when it does not. ofxtools refused 11 of 21 copies, so it makes the stricter second reader.
Copy your QBO file before you repair it. Work on the copy and keep the original untouched. Write down its SHA-256 hash first, so you can show later that the copy came back as it was.
How Do You Open and Import a QBO File? Text editors, QuickBooks and the steps Intuit lists
QuickBooks opens a QBO file by importing it, and a text editor shows what is inside. FileInfo names six programs and Intuit lists the upload steps. We tested none of those programs and read the files with open tools on Linux.
The table lists what the sources name and what we tested. Rows with version numbers are tools we tested. Every other row rests on the page named in it, and we tested none of those.
| Program | What it does |
|---|---|
| QuickBooks Online | FileInfo lists it as a web program with a free trial. Intuit says its upload takes QBO, OFX and CSV files of 350 KB or less. We did not test it. |
| QuickBooks Desktop | FileInfo lists QuickBooks Pro for Windows and QuickBooks for Mac as paid programs. Intuit says Web Connect reads only .qbo files. We tested neither. |
| FreshBooks | FileInfo lists it with a free trial. We did not test it. |
| QBO viewers and converters | FileInfo lists StatementLoom QBO Viewer and the TimeToTime Tools QBO to CSV Converter as free. We tested neither. |
| A text editor | Our 65 files are all text, so any text editor shows the header and the tags. It does not import anything. |
| ofxparse | Version 0.21. A Python library. It read 43 of our 65 files. |
| ofxtools | Version 1.1.1. A Python library. It read 31 of our 65 files. |
| The file command | Version 5.45. It named 54 files plain text and 11 XML. |
Import a QBO file into QuickBooks Online
Intuit lists the manual upload steps on a page dated 8/24/2026. A transaction list can be a CSV, TXT, QBO or OFX file of 350 KB or less. One upload takes up to 1,000 lines, so a longer history needs a shorter date range.
- Download the QBO file from the website of your bank, and keep the first copy.
- In QuickBooks Online, go to All apps, then Accounting, then Bank transactions.
- Select the account tile if one appears, open the Link account menu and choose Upload from file.
- Select your QBO file and choose Continue. Choose the QuickBooks account that gets the transactions, or choose Add New to make one.
- Match the columns to QuickBooks fields if the screen asks, then choose Continue.
- Select the transactions to import, choose Continue, then choose Yes and Done.
Our largest file has 25,833 bytes, far below the limit. Intuit states the line limit for transaction lists with one transaction per line, and we did not test how it counts the lines of a QBO file.
Import a QBO file into QuickBooks Desktop
Intuit explains Web Connect errors on a page dated 8/4/2026. It says to download the QBO file directly from your bank and not from inside QuickBooks. It says the QBO file must be a .qbo file, the only type that Web Connect can read.
Before you start, Intuit says to back up your company file and to use a supported version. We could not read the Intuit page that lists the menu path for the import, so we give none. Follow the prompt that QuickBooks shows when you open the QBO file.
Open a QBO file as text
Open the QBO file in a text editor, or use head -n 9 example.qbo on Linux or Mac. You see the nine header lines and then the tags. Do not edit and save a QBO file you plan to import, because some editors add a byte order mark. Our A5 copy adds one.
What to use for every task
Import into QuickBooks. For QuickBooks Desktop, use the .qbo file from your bank, because Intuit says Web Connect reads only that type. QuickBooks Online also takes OFX and CSV uploads.
Read the numbers. Use a text editor, or convert the QBO file to CSV with our script and open it in a spreadsheet. Check the structure. Use our check script and a second reader.
Install programs from their makers. Take QuickBooks from Intuit and other programs from their own pages. A free web viewer receives your bank data, so try the steps on this page first.
How Do You Check a QBO File? Six steps and a script of 33 lines
Check a QBO file in six steps. Read the first lines, count the transactions, use a script and compare two readers. Our 33 line script printed OK for 38 of 65 files and flagged or warned on 13 of 21 damaged copies.
First reads need no Python. The head command prints the header, and wc prints the length. Count transactions with grep -o. The grep -c command counts lines, and the body of our example QBO file is on one line.
head -n 3 example.qbo
OFXHEADER:100
DATA:OFXSGML
VERSION:102
wc -c < example.qbo
6402
grep -c '<STMTTRN>' example.qbo
1
grep -o '<STMTTRN>' example.qbo | wc -l
27
The first command shows a full header, and the second shows 6,402 bytes. The third prints 1, which is the number of lines with a match. The fourth prints 27, the number of transactions.
Check QBO files with Python
The script reads the start of a QBO file and looks for the OFX tags. It then reads every transaction and checks the four fields that every transaction needs. For every one it tests the type, the date, the amount and the ID.
It warns about short headers, bytes after </, repeated IDs and non ASCII bytes under a USASCII label. It prints OK, WARN or FLAG. It never changes a file.
import re, sys, datetime
def peek(path):
b = open(path, 'rb').read()
t = b.decode('latin-1')
s = t.lstrip()
if b[:3] == b'\xef\xbb\xbf': return 'FLAG', 'starts with a byte order mark'
e = t.rfind('</OFX>')
if b'\x00' in b[:e if e > 0 else len(b)]: return 'FLAG', 'has a zero byte at %d' % b.index(b'\x00')
if not s.startswith(('OFXHEADER:', 'DATA:OFXSGML', '<?xml', '<?OFX', '<OFX>')): return 'FLAG', 'no OFX header at the start'
if '<OFX>' not in t: return 'FLAG', 'no <OFX> tag'
if '</OFX>' not in t: return 'FLAG', 'no </OFX> tag'
n, m = len(re.findall(r'<STMTTRN>', t)), len(re.findall(r'</STMTTRN>', t))
if n != m: return 'FLAG', '%d <STMTTRN> but %d </STMTTRN>' % (n, m)
ids = []
for blk in re.findall(r'<STMTTRN>(.*?)</STMTTRN>', t, re.S):
f = {k: (re.search('<%s>\\s*([^<\\r\\n]*)' % k, blk) or [0, None])[1] for k in ('TRNTYPE', 'DTPOSTED', 'TRNAMT', 'FITID')}
miss = [k for k, v in f.items() if not v]
if miss: return 'FLAG', 'a transaction has no ' + miss[0]
if not re.fullmatch(r'[+-]?\d+([.,]\d+)?', f['TRNAMT'].strip()): return 'FLAG', 'bad TRNAMT ' + f['TRNAMT'].strip()
try: datetime.datetime.strptime(f['DTPOSTED'][:8], '%Y%m%d')
except ValueError: return 'FLAG', 'bad DTPOSTED ' + f['DTPOSTED'].strip()
ids.append(f['FITID'].strip())
if re.search(rb'[\x80-\xff]', b) and re.search(r'ENCODING:USASCII', t): return 'WARN', 'non ASCII bytes but ENCODING:USASCII'
if t[e + 6:].strip('\r\n \x00'): return 'WARN', 'text after </OFX>'
if e + 6 < len(t.rstrip('\r\n ')): return 'WARN', '%d byte after </OFX>' % (len(t.rstrip('\r\n ')) - e - 6)
if len(ids) != len(set(ids)): return 'WARN', 'repeated FITID'
if not s.startswith(('OFXHEADER:', '<?xml')): return 'WARN', 'no full OFX header'
bid = re.search(r'<INTU\.BID>\s*(\w+)', t)
return 'OK', '%d transaction%s, %s' % (n, '' if n == 1 else 's', 'INTU.BID ' + bid[1] if bid else 'no INTU.BID')
if __name__ == '__main__':
for p in sys.argv[1:]: print(*peek(p), p)
Here is what it printed for four healthy files. They are a file with one transaction, an XML file with two, our credit card example and our only .qbo file.
python3 qbo_peek.py small.ofx euro.ofx example.qbo real.qbo
OK 1 transaction, no INTU.BID small.ofx
OK 2 transactions, no INTU.BID euro.ofx
OK 27 transactions, INTU.BID 3101 example.qbo
WARN 1 byte after </OFX> real.qbo
Every answer starts with OK, WARN or FLAG. A healthy answer gives the number of transactions and the INTU.BID value. The warning for real.qbo is the stray byte after </.
python3 qbo_peek.py A1_first_header_line_removed.qbo A5_byte_order_mark_added.qbo B6_first_byte_lost.qbo B7_closing_ofx_removed.qbo C3_date_20131345.qbo C6_one_amount_digit_changed.qbo
WARN no full OFX header A1_first_header_line_removed.qbo
FLAG starts with a byte order mark A5_byte_order_mark_added.qbo
FLAG no OFX header at the start B6_first_byte_lost.qbo
FLAG no </OFX> tag B7_closing_ofx_removed.qbo
FLAG bad DTPOSTED 20131345000000.000[-7:MST] C3_date_20131345.qbo
OK 27 transactions, INTU.BID 3101 C6_one_amount_digit_changed.qbo
A1 loses a header line and gets a warning. A5 starts with a byte order mark. B6 loses the first character and B7 loses the closing tag. C3 stores a date that does not exist. C6 changes one amount, and the script prints OK.
What the script found in our files
| Result | Cases |
|---|---|
| Passed (38 of 65 files) |
The header starts right, both OFX tags are there, every <STMTTRN> closes and has a type, date, amount and ID. Both readers read 31 of these, ofxparse alone read 6 and neither read 1.
|
| Warned (24 of 65 files) |
22 warnings say the header is not full, and 21 of those are the csv2ofx files. One file has text after </, and our .qbo file has one stray byte there. ofxtools refused all 24, and ofxparse read 6.
|
| Flagged (3 of 65 files) |
A missing date, bad amount of $120 and missing ID. Both readers refused all three.
|
| Header and start (A1, A3, A5, B6) | A1 and A3 print a warning about the header. A5 flags a byte order mark and B6 flags a start that is not an OFX header. |
| Cuts and zeroes (B2, B3, B7, C7) |
B2 and B7 print no </ tag, B3 prints no <OFX> tag and C7 prints a zero byte at 3201.
|
| Content (C1, C2, C3, C5) | C1 prints a transaction with no type. C2 warns about a repeated ID. C3 prints a bad date, and C5 prints 27 opening and 26 closing tags. |
| Odd but passed (A2, A4, A6, A7, B1, B5, C4) | These print OK. Both readers returned the original for six of them, and ofxtools refused A2. |
| Passed and wrong (C6) | C6 changes one digit of one amount. The script prints OK, and both readers return a total that is 50 lower. |
The script has limits. It does not read balances or investment trades, so it passes C6. It warns about 24 files, and ofxparse read 6 of them, so warnings are reasons to look closer and not verdicts. The repair commands fix the kinds of damage we tested.
Check order for any QBO file
- Copy your QBO file, write its SHA256 hash and work on the copy.
-
Read the first lines with
head -n 3.OFXHEADER:100or<?xmlis a full header. See the four starts. -
Count the transactions with
grep -oand notgrep -c, because the body of many files is on one line. - Use our script. The first word is OK, WARN or FLAG, and a flag names the problem.
- Read the QBO file with ofxparse and ofxtools, then compare the transaction counts and the total.
- Compare the total with the statement from your bank. We imported nothing into QuickBooks, so passes show sound structure and not an accepted import.
Is a QBO File Safe to Open? Reading is safe, and the file stores account data
Reading the text of a QBO file starts nothing, so it is safe. The risk is the data. A QBO file stores your account IDs, balances and transactions, and IANA calls the type confidential financial information.
We started nothing. Our readers only read text and wrote nothing, and the files are public test data from five projects. We scanned none for malware, and we imported none into QuickBooks.
The IANA record for the type says it stores confidential financial information. That is the main safety fact. Treat QBO files like bank statements, and share them with the same care.
What a QBO file stores
Our .qbo file stores a bank ID, two account IDs and balances for every account. Every transaction stores date, amount and ID, and most also store name and memo. Those names show where you shop.
A QBO file from someone else
Intuit says to download the QBO file directly from your bank. A QBO file from anyone else can add transactions that your bank never made, and they would show up in your books. Compare every total with the statement.
Share a sample with a helper
Before you send files to helpers, replace the digits inside <ACCTID> and <BANKID> with zeros and keep the original. Our script needs neither value, so a helper can still check the structure.
Not sure? Check it first. Copy the hash, read the first lines with our check steps and download a fresh file from your bank if anything looks wrong. Import it last.
Why Will QuickBooks Not Import Your QBO File? Eight causes, and what to do about every one
Most QBO files that will not import fail for one of eight reasons. Read the first lines, use the script and compare two readers. Our script flagged or warned on 13 of 21 damaged copies, and 8 kinds of damage came back byte for byte.
We damaged one QBO file in 21 ways and tested repairs on every healthy file where the damage changes bytes. The table groups what we saw into eight causes.
Every row says what happens to your QBO file and what to try. Fixes work on copies, and none changes the original. We imported no repaired file into QuickBooks, so a repaired file shows only that its structure fits.
| Cause | Result and fix |
|---|---|
| The wrong kind of file (1) | Intuit says QuickBooks Desktop reads only .qbo files through Web Connect. A file named .ofx or .qfx, or a CSV, is another kind. Fix: Download the .qbo version from your bank. QuickBooks Online also takes CSV, TXT and OFX uploads. |
| A header that is wrong or missing (2) |
A1 loses a header line, A2 sets the number 999, A3 removes the header and A4 sets a version of 299. ofxtools refused A1, A2 and A3, and ofxparse read all four. Fix: Write OFXHEADER:100 back as the first line, or restore the full header. A1, A2 and A4 came back byte for byte on every file we tried, and A3 on 10 of 27.
|
| A byte order mark or lost first byte (3) | A5 adds a 3 byte mark, and B6 loses the first character. Our script flagged both. Fix: Cut the mark or write the lost character back. Both came back byte for byte on all 38 files. |
| A file that is cut (4) |
B1 cuts the last byte, B7 loses </, B2 keeps half of the file and B3 keeps only the header. Fix: For B1 and B7, write the end back. It worked on 36 of 38 files for B1 and 25 of 38 for B7. For B2 and B3, download the QBO file again.
|
| Extra bytes after the end (5) |
B4 adds 512 zero bytes, and our .qbo file has one stray byte after </. ofxtools refused both, and ofxparse read both. Fix: Cut everything after </. It worked on all 38 files.
|
| A transaction that repeats (6) | C2 repeats one transaction with the same ID. Both readers returned 28 transactions, and the total moved by 29.00. Our script warned about the ID. Fix: Remove the second copy. It worked on all 19 files. |
| A wrong amount or date (7) | C3 stores the date 20131345 and both readers refused it. C4 writes a comma in an amount and both read it. C6 changes one digit, and both returned a wrong total. Fix: For C4, write a period back. It worked on all 18 files. For C3 and C6, download the QBO file again. |
| Zeroed or cut content (8) |
C1 flips one bit, C5 loses a closing </ and C7 zeroes half of the file. Fix: Ask your bank for a new QBO file. We tested no repair, and no rule shows what the lost bytes were.
|
What Intuit says to try
Intuit lists four steps for Web Connect import errors in QuickBooks Desktop. The page says the common causes are an incomplete or incompatible bank file, a change at the bank or a problem in the company file or the account settings.
- Download a fresh .qbo file from your bank and import it. If that works, disconnect the account and set it up again.
- Sign in to the website of your bank and read its messages. Follow any request, like a check of your identity.
- In QuickBooks Desktop, go to Banking, then Bank Feeds, then Change Bank Feeds Mode. Choose Classic mode and import the QBO file again.
- Make a test company file and import the .qbo file into the same type of bank account. If the test works, the problem lies in your own company file.
If the test import fails, Intuit says the .qbo file is the likely problem. It then points you to your bank. If the test works, the files on this page do not apply, because the cause lies in your company file.
Repairs we tested
One short script covers the 11 fixes. It takes one kind code, the damaged file and a name for the new file. The commands after it are the ones we used, with short file names.
import re, sys
HEAD = [b'OFXHEADER:100', b'DATA:OFXSGML', b'VERSION:102', b'SECURITY:NONE', b'ENCODING:USASCII', b'CHARSET:1252', b'COMPRESSION:NONE', b'OLDFILEUID:NONE', b'NEWFILEUID:NONE']
def fix(b, kind):
eol = b'\r\n' if b'\r\n' in b[:120] else b'\n'
if kind == 'A1': return b'OFXHEADER:100' + eol + b if b.startswith(b'DATA:OFXSGML') else b
if kind == 'A2': return re.sub(rb'^OFXHEADER:\d+', b'OFXHEADER:100', b)
if kind == 'A3': return eol.join(HEAD) + eol + eol + b if b.lstrip().startswith(b'<OFX>') else b
if kind == 'A4': return re.sub(rb'VERSION:\d+', b'VERSION:102', b, count=1)
if kind == 'A5': return b[3:] if b.startswith(b'\xef\xbb\xbf') else b
if kind == 'B1': return b + b'>' if b.endswith(b'</OFX') else (b + eol if b.endswith(b'</OFX>') else (b + b'\n' if b.endswith(b'\r') else b))
if kind == 'B4': return b.rstrip(b'\x00')
if kind == 'B6': return b'O' + b if b.startswith(b'FXHEADER:') else (b'<' + b if b.startswith((b'OFX>', b'?xml')) else b)
if kind == 'B7':
i = len(b.rstrip()); j = i + (len(eol) if b[i:].startswith(eol) else 0); return b[:j] + b'</OFX>' + b[j:] if b'</OFX>' not in b else b
if kind == 'C2': return re.sub(rb'(<STMTTRN>.*?</STMTTRN>)\1', rb'\1', b, count=1, flags=re.S)
if kind == 'C4': return re.sub(rb'(<TRNAMT>\s*[+-]?\d+),(\d+)', rb'\1.\2', b)
return b
if __name__ == '__main__':
kind, src, dst = sys.argv[1:4]
open(dst, 'wb').write(fix(open(src, 'rb').read(), kind))
# 2 first header line lost (A1)
python3 qbo_fix.py A1 A1_first_header_line_removed.qbo A1_fixed.qbo
# 3 byte order mark (A5), first character lost (B6)
python3 qbo_fix.py A5 A5_byte_order_mark_added.qbo A5_fixed.qbo
python3 qbo_fix.py B6 B6_first_byte_lost.qbo B6_fixed.qbo
# compare with the original
sha256sum example.qbo A1_fixed.qbo A5_fixed.qbo B6_fixed.qbo | cut -c1-12
1057dd9fe0fa
1057dd9fe0fa
1057dd9fe0fa
1057dd9fe0fa
The last lines compare hashes. The first 12 characters match for the original and the three repaired files, so the repaired files equal the original. Apply only the fix that matches the flag.
Check QBO files that will not import, step by step
We tested the steps on Python 3.13 and Linux. We imported no file into QuickBooks, and the steps keep the original untouched at every point.
- Copy your QBO file, write its SHA256 hash and work on the copy.
-
Name the start with
head -n 3and the four starts. Only a full header starts withOFXHEADER:100. - Use our check script. A flag or warning names the problem.
- Match the answer to a cause in the table above and try its fix on the copy.
- Read the result with two readers and compare the totals with your bank statement.
- If one fix fails, do not stack another on top. Go back to the copy and try the next cause.
- Import the repaired copy only after you trust the source. We imported nothing, so repaired files show only that the structure fits.
What to send a helper
Short messages get faster answers. Include the details below and add the script output. Its first word gives OK, WARN or FLAG.
Subject: QuickBooks will not import my QBO file
File: name, size in bytes and SHA256 hash
Start: the output of head -n 3
Check: the output of qbo_peek.py
Program: name, version and the exact words of the error
Source: the bank and the date of the download
What no step can fix
Do not try online repair sites. Sites that offer to fix or convert any QBO file receive your upload. The file stores account IDs and every transaction. Try the steps above on a copy first.
Can You Convert a QBO File to CSV? Yes, with a 19 line script that matched 43 files
Yes. A QBO file converts to CSV in 19 lines of Python with ofxparse. Our script wrote 105 rows from the 43 files that ofxparse could read, and every row count, total and date matched the tags in the source.
People convert to CSV to open the transactions in a spreadsheet or to upload them in another form. Intuit lists the CSV rules for QuickBooks Online on the same page as the QBO steps.
The CSV rules from Intuit
The page allows two layouts. One has three columns, Date, Description and Amount. The other has four, Date, Description, Credit and Debit. It asks for one date format in the entire file and recommends day, month, year.
It also says to leave a cell blank when its value is zero, and to move the day of the week into its own column. Our script writes the three column layout with dates in day, month, year order.
A QBO to CSV script
The script uses ofxparse. It reads every bank and credit card account, skips investment accounts and writes one row for every transaction. The description is the payee, or the memo when the payee is empty.
import csv, sys
from ofxparse import OfxParser, AccountType
def qbo_to_csv(src, dst):
ofx = OfxParser.parse(open(src, 'rb'))
rows = 0
with open(dst, 'w', newline='') as f:
out = csv.writer(f)
out.writerow(['Date', 'Description', 'Amount'])
for acct in ofx.accounts:
if acct.type == AccountType.Investment:
continue
for t in acct.statement.transactions:
out.writerow([t.date.strftime('%d/%m/%Y'), t.payee or t.memo, t.amount])
rows += 1
return rows
if __name__ == '__main__':
print(qbo_to_csv(sys.argv[1], sys.argv[2]), 'rows')
python3 qbo_csv.py example.qbo example.csv
27 rows
head -n 4 example.csv
Date,Description,Amount
21/11/2013,JEFFREY'S 0252 NEW YORK,-29
22/11/2013,WHOLEFDS HOU 10236 02124201320,-13.93
23/11/2013,AMAZON.COM AMZN.COM/BI,-54.99
The first pass wrote 27 rows, the same number as the transactions in example.qbo. The amounts keep their signs, so a debit is negative. The first transaction is dated 11/21/2013 and shows as 21/11/2013 in the file.
What we tested
We used the script on the 43 files that ofxparse read and counted the rows against the <STMTTRN> blocks of the bank and card accounts. We then added up the amounts and compared the dates with the first 8 digits of every DTPOSTED.
The counts matched on all 43 files, the sums matched on all of them and the dates matched on all of them. The 22 files that ofxparse refused were skipped, because the script needs a reader that works.
From CSV back to QBO
The csv2ofx project converts CSV into OFX. 22 of our 65 files come from it. 21 of them start with a DATA line alone, ofxtools refused all 21 and ofxparse read 4. None of them has an INTU.BID tag, so they are OFX files and not bank downloads.
We imported none of them into QuickBooks and give no method for CSV to QBO. If you build a file from a CSV, use our check script and read it with two readers first.
Keep the QBO file. A CSV drops the IDs and the account details. Keep the original QBO file until the books match the statement.
How Does a QBO File Differ From QFX, IIF and CSV Files? Close neighbors, and the ending does not separate them
QBO files have close neighbors in money software. QFX is the Quicken version and OFX is the open standard. IIF, QDF and CSV are different layouts. In our 65 files, the ending and the INTU.BID tag did not separate the first three.
Several kinds of file get mixed up with QBO files because they contain bank data. The table lists them. Every row ends with its source.
| Type | What separates it |
|---|---|
| QBO | A QuickBooks Web Connect file in OFX text. IANA lists the type application/vnd.intu.qbo. Source: IANA and FileInfo. |
| QFX | The Quicken version of the layout. FileInfo calls it similar to OFX but proprietary to Quicken. Source: FileInfo and Wikipedia. |
| OFX | The open standard behind both. FileInfo says it is SGML based and was standardized in 1997. Source: FileInfo and Wikipedia. |
| IIF | A QuickBooks data format. FileInfo says it stores tab delimited text and opens in QuickBooks and Excel. Source: FileInfo. |
| QDF | The main data file of Quicken for Windows. It stores accounts, transactions and balances. Source: FileInfo. |
| CSV | Comma separated text. Intuit takes a CSV with three or four columns for manual upload. Source: Intuit. |
QBO or QFX
Wikipedia says that Intuit products use OFX for Direct Connect and QFX for Web Connect. Our one .qfx file and our one .qbo file have the same header, except for one value. The SECURITY line reads NONE in the first and TYPE1 in the second.
Both have an INTU.BID tag, 3120 in the QFX and 12824 in the QBO. So the tag does not separate them, and 9 of the 11 tagged files end in .ofx. Read the QFX file page for the Quicken side.
QBO or OFX
OFX is the standard, and QBO files follow it. FileInfo says OFX was standardized in 1997 by Intuit, Microsoft and CheckFree. 54 of our 65 files have no Intuit tag.
QBO or IIF and CSV
An IIF file is tab delimited text that QuickBooks exports and imports. CSV files have comma separated columns. Both are spreadsheet shapes. QBO files have tags and store bank statements. Read the IIF file page for the QuickBooks export.
Which one do you have
What Is the QBO File Format Made Of? The facts we could check, and where they came from
A QBO file is OFX text with an Intuit tag. Facts below come from our own checks of 65 files and 21 damaged copies. Sources are FileInfo, IANA, Wikipedia, Intuit and the ofxparse and ofxtools projects.
| Part | What we could check |
|---|---|
| Maker | FileInfo lists Intuit as the maker of the QBO file. Wikipedia says Microsoft, Intuit and CheckFree developed the OFX standard. |
| Name | FileInfo describes a financial data file based on Open Financial Exchange. IANA registers the media type application/vnd.intu.qbo with the extension .QBO. |
| First bytes |
IANA lists the magic number as N/A. 29 of our 65 files start with OFXHEADER:100, 21 with DATA:OFXSGML, 11 with an XML declaration and 4 with <OFX>.
|
| Layout |
A header of 9 lines in version 1 files, then an <OFX> block with a sign on block and one block for every account. Every transaction is a <STMTTRN> with a type, date, amount and ID.
|
| Versions |
All 29 of our version 1 files use VERSION:102. Our 11 XML files use versions from 200 to 220. Wikipedia lists OFX 1.0 in 1997 and 2.3 as the latest, with a reference document dated 10/16/2020.
|
| INTU.BID | An Intuit tag in the sign on block. 11 of our files have it with 7 different values, and ofxtools calls it a private extension tag. |
| Dates and amounts |
DTPOSTED has 8 or 14 digits and in some files a time zone. TRNAMT is a signed decimal. Debits are negative.
|
| Sizes | Our files are 145 to 25,833 bytes long, and the median is 1,985 bytes. Intuit sets a manual upload limit of 350 KB and 1,000 lines. |
| Security | IANA says the type stores confidential financial information and asks for HTTPS from the sender. |
| Media type | application/vnd.intu.qbo, registered 10/5/1998. The file command names our files plain text or XML. |
| Our tests | 65 files, 21 damaged copies, 2 readers, 11 repair commands and a CSV script. The file command, ofxparse, ofxtools and a 33 line script all read our files on Linux. |
About the values we list
Facts about the layout come from our own reading of 65 files and from the pages we name. We found no Intuit page that lists the fields of a QBO file, so we claim none for the parts we could not read in our files.
Where we found no record, we say so. We read no Intuit page for the Desktop menu path, and we tested no version of QuickBooks.
What we left out
We imported no file into QuickBooks Online or Desktop. We used no web viewer and scanned no file for malware. Our readers and scripts worked on Linux, and QuickBooks can accept or refuse files that they treat differently.
64 of the 65 files are not named .qbo. They come from the beancount-import, beangulp, csv2ofx, ofxparse and ofxtools tests. Our damaged copies come from one credit card download and change one thing at a time. Files from other banks can differ from ours.
Sources checked
For the type, see the FileInfo page on QBO files and the IANA record for application/vnd.intu.qbo. For the standard, see the Wikipedia article on Open Financial Exchange and the FileInfo page on OFX files.
For the import steps, see the Intuit page on manual uploads and the Intuit page on Web Connect errors. For the neighbors, see the FileInfo pages on QFX, IIF and QDF files.
For the readers, see the ofxparse project page and the ofxtools project page. Every count on this page came from files and scripts in our research folder.
Frequently Asked Questions About QBO Files
What is a QBO file?
A QBO file is a QuickBooks Web Connect file. It stores the account details and transactions of a bank or credit card download as text in the Open Financial Exchange format. FileInfo lists Intuit as the maker, and IANA lists no fixed first bytes.
How do I open a QBO file?
Any text editor shows the contents, because a QBO file is text. To use the data, import the QBO file into QuickBooks. FileInfo also lists FreshBooks, free QBO viewers and free QBO to CSV converters. We tested none of those.
How do I import a QBO file into QuickBooks?
In QuickBooks Online, go to Bank transactions, open the Link account menu and choose Upload from file. Intuit says the QBO file must be 350 KB or less with 1,000 lines at most. QuickBooks Desktop reads only .qbo files through Web Connect.
What is the difference between QBO and QFX?
QFX is the Quicken version of the same layout, and QBO is the QuickBooks version. Wikipedia says Quicken uses QFX for Web Connect. Our one .qfx file and our one .qbo file differ in one header value, SECURITY, and both have an INTU.BID tag.
What is the difference between QBO and OFX?
OFX is the open standard, and a QBO file follows it. Microsoft, Intuit and CheckFree announced OFX in 1997. In our 65 files, 9 of the 11 that have the Intuit INTU.BID tag end in .ofx, so the ending does not separate them.
Is a QBO file safe to open?
Reading the text starts nothing, so reading is safe. The risk is the data. A QBO file stores account IDs, balances and transactions, and IANA calls the type confidential financial information. Share it like bank statements and download files only from your bank.
Can I convert a QBO file to CSV?
Yes. A 19 line Python script with ofxparse wrote 105 rows from the 43 files that ofxparse could read, and every row count, total and date matched the source. Intuit takes a CSV with three or four columns for manual upload.
Why will my QBO file not import?
Eight causes cover what we saw in damaged files. They are the wrong kind, a bad header and a byte order mark. The rest are a cut file, extra bytes, a repeated transaction, a wrong amount and zeroed content. Download a fresh QBO file first.
How can I check if a QBO file is damaged?
Read the first lines, count the transactions with grep -o and read the QBO file with two readers. Our script also tests the header, the closing tags and four fields of every transaction. It passed 8 of 21 damaged copies, so only your statement finds the rest.
Do all readers agree on a damaged QBO file?
No. ofxparse and ofxtools disagreed on 9 of our 21 damaged copies, and neither matched the original on 6. ofxparse returned an empty list without an error for two copies, so a refusal is a better sign than a quiet answer.
Can a damaged QBO file be repaired?
Some damage can be repaired. 11 kinds of header and ending damage have a repair command, and 8 of them came back byte for byte on every file we tried. Cut files and changed amounts did not, because the bytes are gone. Keep the original.
What MIME type is a QBO file?
IANA registered application/vnd.intu.qbo with the extension .QBO on 10/5/1998 and lists the magic number as N/A. The file command names our files plain text or XML, so it does not name the type.
Still Stuck With a QBO File? Eight routes out, depending on what went wrong
Read the first lines and use the check script. The cause table lists what to try in order.
The four starts name the kind from the first line, the source and the tag.
Is it a Quicken download? A QFX file uses the same layout, and the guide to QFX files covers the Quicken side.
Is it a QuickBooks export in tab text? The guide to IIF files covers that format.
Is it a Quicken data file? The guide to QDF files covers the file that stores an entire Quicken book.
Is it a spreadsheet? The guide to XLS files covers the format that opens a converted CSV.
Is it a file type you do not know? Browse the file extension resource library, or send it on the submit a file type page.
Do you need the format facts? Read the format part for the layout, the tags and the sources of QBO files.