A technical reference for the Open Financial Exchange format, with the header fields, the transaction block, a fully annotated sample file and the differences between OFX 1.x SGML and OFX 2.x XML. Need to produce one? Upload a PDF statement and download a spec correct OFX.
Upload your bank statement
Drop file here or click to upload
PDF, JPG, PNG, BMP, HEIC, TIFF
Uploading...
OFX, short for Open Financial Exchange, is an open specification for moving financial data such as bank and credit card statements between institutions and finance software. An OFX file is a plain text document holding a signon block, an account block and a list of transactions, each carrying a posting date, an amount, a unique transaction ID and a description. Two syntaxes are in active use: OFX 1.x is SGML based and starts with colon delimited header lines, while OFX 2.x is well formed XML. The current banking specification is version 2.3, and both families are still accepted across the market.
OFX looks like XML but frequently is not, the documentation sits behind a specification most people never read, and small omissions break an import with no useful error message.
OFX 1.x is SGML, where closing tags are optional and a plain XML parser fails immediately. OFX 2.x is strict XML. Code written for one silently rejects the other.
A 1.x file opens with colon delimited lines such as OFXHEADER:100 and DATA:OFXSGML, followed by a blank line. Feed that to an XML library and it throws before reaching a single transaction.
A file can look complete and still be rejected. A missing LEDGERBAL balance block is a frequently reported trigger for Quicken parse errors in the OL-220 to OL-226 family.
FITID must be unique within an account. When a generator reuses IDs, finance software either drops transactions as duplicates or imports the same row twice.
OFX uses YYYYMMDD, optionally followed by a time and a bracketed timezone offset. Writing 2026-07-31 instead of 20260731 invalidates the field.
Banks publish statements as PDFs. Hand writing an OFX file for a few hundred transactions is not realistic, which is where a converter earns its place.
If you have a PDF statement and need an OFX your software will accept, the extraction reads the transaction table and writes the structure out correctly, including the fields that are easy to omit.
The output carries the signon, account and transaction list blocks in the order the specification defines, so parsers do not stall partway through.
The closing balance block is written every time, which is the omission most often blamed for parse failures in Quicken.
Every transaction receives a distinct financial institution transaction ID, so imports match cleanly instead of collapsing into duplicates.
Posting dates are written as YYYYMMDD rather than a locale format, which removes the most common validation failure.
Debits are written negative and credits positive in TRNAMT, so the register balance ties to the printed statement.
The same extraction exports a Quicken flavored QFX or a legacy QIF when your software expects one of those instead.
The practical route when you need a valid OFX file and all you have is the statement.
Add the PDF or a scan of the bank or credit card statement covering the period you need.
Tip: Scanned and photographed statements work too, since the text is read with OCR.
Review the extracted table against the printed statement, confirming dates, descriptions and signed amounts before exporting.
Tip: Compare the closing balance first. If it ties, the rows underneath are almost always right.
Download the OFX file and import it into your finance software the same way you would import a bank download.
Tip: Pick QFX rather than OFX if the destination is Quicken, since Quicken expects its own variant.
The format sits between banks and finance software, so it turns up in accounting, bookkeeping and development work alike.
Importing client statements into accounting software where OFX is the cleanest supported route.
Writing or debugging a parser and needing the header rules, the tag hierarchy and the required fields in one place.
Diagnosing why a downloaded file will not import, and producing a replacement that does.
Moving statement data between institutions and internal systems on a repeatable monthly cycle.
OFX stands for Open Financial Exchange. It is an open specification for exchanging financial data, most commonly bank statements, credit card statements and investment statements, between financial institutions and personal or business finance software. An OFX file is plain text containing a signon block, an account identification block and a list of transactions, each with a date, an amount, a unique ID and a description.
The specification was created in 1997 by Microsoft, Intuit and CheckFree to replace a patchwork of proprietary download formats. It is maintained today by a consortium of financial application, aggregation and financial services providers working through the OFX work group at the Financial Data Exchange. The latest OFX Banking specification is version 2.3.
The single most important fact about OFX is that the version determines the syntax. Anything numbered 1.x is SGML. Anything numbered 2.x is XML. They are not interchangeable, and both remain in circulation.
| Version | Syntax | How the file starts | Notes |
|---|---|---|---|
| 1.0.2 | SGML | OFXHEADER:100 | The most widely deployed legacy version. Many bank downloads and most QFX files still use it |
| 1.0.3 | SGML | OFXHEADER:100 | Incremental revision of the 1.0 line |
| 1.6 | SGML | OFXHEADER:100 | Final SGML release before the XML transition |
| 2.0.3 | XML | <?xml version="1.0"?> | First widely used XML generation, header moved into a processing instruction |
| 2.1.1 | XML | <?xml version="1.0"?> | Common target for modern server implementations |
| 2.2 | XML | <?xml version="1.0"?> | Adds later message set revisions |
| 2.3 | XML | <?xml version="1.0"?> | The current OFX Banking specification |
Here is a trimmed OFX 1.0.2 bank statement download with one transaction. The colon delimited header, the blank line that terminates it, and the absence of closing tags on value carrying elements are all characteristic of the SGML generation.
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>20260731120000
<LANGUAGE>ENG
</SONRS></SIGNONMSGSRSV1>
<BANKMSGSRSV1><STMTTRNRS>
<TRNUID>1001
<STATUS><CODE>0<SEVERITY>INFO</STATUS>
<STMTRS>
<CURDEF>USD
<BANKACCTFROM>
<BANKID>121000248
<ACCTID>000123456789
<ACCTTYPE>CHECKING
</BANKACCTFROM>
<BANKTRANLIST>
<DTSTART>20260701
<DTEND>20260731
<STMTTRN>
<TRNTYPE>DEBIT
<DTPOSTED>20260715
<TRNAMT>-64.20
<FITID>20260715-0001
<NAME>SHELL OIL 574733
</STMTTRN>
</BANKTRANLIST>
<LEDGERBAL>
<BALAMT>4182.55
<DTASOF>20260731
</LEDGERBAL>
</STMTRS>
</STMTTRNRS></BANKMSGSRSV1>
</OFX>An OFX 2.x file carries the same tag hierarchy underneath, but every element closes properly and the header becomes a processing instruction such as <?OFX OFXHEADER="200" VERSION="211" SECURITY="NONE" OLDFILEUID="NONE" NEWFILEUID="NONE"?> sitting under the standard XML declaration.
In a 1.x file the header is the block above the first blank line. Every line is a key, a colon and a value, with no spaces. Parsers read this block first to decide how to handle everything after it.
| Field | Typical value | What it controls |
|---|---|---|
| OFXHEADER | 100 | Header version. 100 signals the SGML generation, 200 the XML one |
| DATA | OFXSGML | The content type of the body that follows |
| VERSION | 102 | Specification version without the dots, so 102 means 1.0.2 and 211 means 2.1.1 |
| SECURITY | NONE | Application level security. NONE is normal for a downloaded statement file |
| ENCODING | USASCII | Character encoding of the body, USASCII or UTF-8 |
| CHARSET | 1252 | Code page paired with the encoding, 1252 being Windows Latin-1 |
| COMPRESSION | NONE | Reserved for compressed payloads, effectively always NONE in practice |
| OLDFILEUID | NONE | Identifier of the previous file in an incremental exchange |
| NEWFILEUID | NONE | Identifier of this file, used to pair requests with responses |
STMTTRN is the element that carries one transaction, and it is the part most people care about. Four fields do the real work, and omitting any of them is the usual reason a file will not import.
| Tag | Required | Format | Purpose |
|---|---|---|---|
| TRNTYPE | Yes | DEBIT, CREDIT, CHECK, FEE, INT, XFER and others | Classifies the transaction so software can categorize it |
| DTPOSTED | Yes | YYYYMMDD, optionally with HHMMSS | The date the transaction posted to the account |
| TRNAMT | Yes | Signed decimal, no currency symbol or thousands separator | The amount, negative for money out and positive for money in |
| FITID | Yes | String unique within the account | Lets software recognize a transaction it has already imported |
| NAME | Usually | Text, commonly capped near 32 characters | Payee or short description shown in the register |
| MEMO | No | Free text | Longer detail that did not fit in NAME |
| CHECKNUM | No | Text | Check number where the transaction is a written check |
Outside the transaction list, LEDGERBAL carries the closing balance as BALAMT plus a DTASOF date. It is not part of STMTTRN, but leaving it out is one of the most commonly reported causes of a rejected file, so treat it as mandatory in practice.
OFX 1.x uses SGML, where a tag carrying a value does not need a closing counterpart, so <TRNAMT>-64.20 is complete on its own. OFX 2.x requires well formed XML with every element closed. The header differs too: 1.x uses colon delimited plain text lines, while 2.x moves that information into an XML processing instruction. The simplest way to tell them apart is to read the first line. OFXHEADER:100 means SGML, and an XML declaration means 2.x.
The extension is .ofx. You will also meet close relatives that use the same underlying specification with a different extension: .qfx is Intuit's Quicken variant, .qbo is the QuickBooks variant, and .ofc is the older Open Financial Connectivity format that OFX replaced. All are plain text, so any of them opens in a text editor even when the finance software refuses them.
QFX is Intuit's licensed flavor of OFX. Structurally a QFX file is an OFX file, with the same header and the same tag hierarchy, plus Intuit specific elements including INTU.BID, a bank identifier Quicken checks on import. That extra field is why Quicken often rejects a plain .ofx file even though the contents are otherwise valid, and why renaming the extension is not a reliable workaround. There is a fuller breakdown in the comparison of OFX, QFX and QBO formats.
Yes. OFX remains a standard route for delivering statement data, the specification is still being revised, and the format is accepted by a wide range of finance and accounting software. Its role has shifted as banks moved toward API based aggregation for live feeds, but OFX stays the practical option for importing history, for filling gaps a feed missed, and for any workflow where a file needs to move between systems. Xero, for one, recommends OFX where possible for manual statement imports.
Support is broad, though the accepted variant differs by product. The table below covers the programs people ask about most.
| Software | Preferred file | Notes |
|---|---|---|
| Quicken | QFX | Imported as a Web Connect file. Plain OFX is often refused because INTU.BID is absent |
| Microsoft Money | OFX | Reads standard OFX directly, which is why the format persists among long term users |
| QuickBooks Desktop | QBO | Uses the QuickBooks Web Connect variant rather than plain OFX |
| Xero | OFX | Manual import accepts OFX, QFX, QIF and CSV, and Xero recommends OFX where possible |
| GnuCash | OFX | Imports OFX and QFX through its bundled import assistant |
| Moneydance and Banktivity | OFX | Both read standard OFX files without a Quicken specific identifier |
You convert one. Banks publish statements as PDFs and do not offer OFX for older periods, so the practical route is to extract the transaction table from the statement and write it out in OFX structure. Upload the PDF at the top of this page, check the extracted rows against the printed statement, and export. The generator writes the header, the account block, a unique FITID per transaction and the LEDGERBAL closing balance, which are the pieces hand built files usually miss.
For the conversion itself, the bank statement to OFX converter is the main tool, with credit card statement to OFX covering card statements and investment statement to OFX handling brokerage documents. Already holding data in a spreadsheet? The CSV to OFX converter goes the other direction, and converting OFX to CSV opens a file you cannot otherwise read. Quicken users should generate a QFX with the PDF to QFX converter instead.
An OFX file is plain text, so any editor such as Notepad, TextEdit or VS Code opens it and shows the raw tags. That is enough to inspect the header or confirm a transaction exists, but it is unreadable as a statement. To see the transactions as rows you can sort and total, convert the file to a spreadsheet. There is a step by step walkthrough in how to open an OFX file in Excel.
Five causes account for most failures. The file is 1.x SGML and the importer expects 2.x XML, or the reverse. LEDGERBAL is missing, which Quicken reports through the OL-220 to OL-226 error family. FITID values repeat, so transactions are silently dropped as duplicates. Dates are written in a locale format instead of YYYYMMDD. Or the destination is Quicken and the file lacks INTU.BID because it is plain OFX rather than QFX. The guide to fixing OFX import errors in Quicken works through each one, and the Quicken connection errors reference decodes the specific codes.
OFX, or Open Financial Exchange, is an open specification for moving financial data such as bank and credit card statements between institutions and finance software. An OFX file is plain text holding a signon block, an account block and a list of transactions, each with a posting date, a signed amount, a unique ID and a description. The current banking specification is version 2.3.
OFX 1.x is SGML based, so closing tags are optional and the file opens with colon delimited header lines such as OFXHEADER:100. OFX 2.x is well formed XML with every element closed and the header expressed as an XML processing instruction. Read the first line to tell them apart. Both generations are still supported across the market.
The extension is .ofx. Related variants share the same underlying specification: .qfx is the Quicken flavor, .qbo is the QuickBooks flavor, and .ofc is the older Open Financial Connectivity format OFX replaced. All are plain text and open in any text editor even when finance software rejects them.
A 1.x file starts with header lines like OFXHEADER:100 and DATA:OFXSGML, then a blank line, then an OFX element containing a signon response, a BANKACCTFROM account block, a BANKTRANLIST holding one STMTTRN per transaction, and a LEDGERBAL closing balance. Values follow their tags without closing counterparts.
QFX is Intuit's licensed flavor of OFX. The structure is the same, but a QFX file adds Intuit specific elements including INTU.BID, a bank identifier Quicken checks during import. That is why Quicken frequently rejects a valid plain OFX file, and why renaming the extension does not reliably work.
Each STMTTRN needs TRNTYPE, DTPOSTED as YYYYMMDD, TRNAMT as a signed decimal with no currency symbol, and FITID as an identifier unique within the account. NAME is expected in practice. Outside the transaction list, the LEDGERBAL closing balance should be treated as mandatory since omitting it commonly breaks imports.
Convert a statement you already have. Banks publish PDFs and rarely offer OFX for older periods, so upload the PDF statement and export OFX. The generator writes the header, the account block, a unique FITID for every transaction and the LEDGERBAL balance, which are the elements hand built files most often omit.
Yes. The specification is still being revised, currently at version 2.3 for banking, and a wide range of finance and accounting software accepts OFX. Live bank feeds have moved toward API based aggregation, but OFX remains the practical route for importing history, filling gaps a feed missed, and moving statement data between systems.
Turn a PDF statement into a spec correct OFX file.
Build an OFX file from data you already hold in a spreadsheet.
Read an OFX file as rows you can sort and total.
Generate the Quicken flavored variant with INTU.BID.
Get started converting bank statements to OFX.
USD
per month
billed as
$288 yearly
Choose speed vs accuracy when extracting
| Base AI Faster | 2,500 pages |
| Pro AI Best accuracy | 500 pages |
Scale statement conversion across your team with automation.
USD
per month
billed as
$888 yearly
Choose speed vs accuracy when extracting
| Base AI Faster | 10,000 pages |
| Pro AI Best accuracy | 2,000 pages |
Enterprise-grade bank statement conversion and controls.
USD
per month
billed as
$ yearly
Choose speed vs accuracy when extracting
| Base AI Faster | pages |
| Pro AI Best accuracy | pages |