> ## Content Index
> Fetch the complete content index at: https://www.incomestead.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# What an IBKR Flex Query Actually Exports — and What It Leaves Out
- URL: https://www.incomestead.com/blog/what-an-ibkr-flex-query-exports/
- Published: 2026-09-24T08:22:12.000Z
- Updated: 2026-09-24T08:22:12.000Z
- Description: Configure it for more than one section and it stops being a spreadsheet. Four of its fields will give you a wrong number without ever flagging one.
- Author: Stefano Starkel
- Tags: Governance, #stage-2

An IBKR Flex Query exports whatever you configured it to export — and once you ask for more than one kind of data, it stops being a spreadsheet. Tick positions, trades, cash and dividends, turn on the two options that add section codes and header records, and you get all four stacked inside one file, each with its own column headers, separated by marker rows. I have parsed a live weekly one every week for over a year to run my own governed book, and the single most useful thing I can tell you is this: the file will hand you a wrong number without ever telling you it did. One un-stripped trailing space in one column name silently zeroed my settled cash — which flipped my margin zone — and nothing anywhere reported an error.

TL;DR

- A Flex Query is a report template, so what your export contains is whatever you ticked — which means nobody can tell you what is in your file except your file.
- Once you enable section codes and header records — which in practice you want as soon as you pull more than one section — it stops being a flat CSV and becomes sections framed by marker rows, which a spreadsheet will open as gibberish.
- Its real danger is not the data it omits but the four fields that look like answers and are not: dividend accruals that are not cash, an expiry that books in two places, an assignment that books zero, and column names that differ between sections and fail in silence.

On this page

- [What does an IBKR Flex Query actually export?](#what-does-an-ibkr-flex-query-actually-export)
- [Why won't the file open properly in a spreadsheet?](#why-wont-the-file-open-properly-in-a-spreadsheet)
- [The four fields that will give you a wrong number](#the-four-fields-that-will-give-you-a-wrong-number)
- [What it leaves out entirely](#what-it-leaves-out-entirely)
- [What a governed read of the export looks like](#what-a-governed-read-of-the-export-looks-like)
- [Frequently asked questions](#frequently-asked-questions)

## What does an IBKR Flex Query actually export?

Whatever you told it to. That is not evasion — it is the first thing to understand about the format. Interactive Brokers describes Flex Queries as "highly customizable report templates for Activity Statements," and says they "allow you to include and exclude information at the individual field level" ([IBKR Campus, "Activity Flex Query"](https://ibkrcampus.com/campus/glossary-terms/activity-flex-query/?ref=incomestead.com)). So there is no canonical field list. Two people can both run "an Activity Flex Query" and hold files with almost no overlap.

The shape is configurable too, and this is the part I got wrong for longer than I should have. Two separate delivery options — one that adds header and trailer records, one that prefixes each row with a section code and line descriptor — decide whether the file carries framing at all. IBKR documents both as toggles: enabling the first adds begin- and end-of-file, -account and -section rows, and enabling the second prefixes your selected fields with section-code and line-descriptor columns ([IBKR, "Delivery Configuration and General Configuration"](https://www.ibkrguides.com/reportingreference/reportguide/delivery%20configuration%20and%20general%20configuration.htm?ref=incomestead.com)). Leave them off on a single-section query and you get an ordinary one-header CSV that opens in Excel perfectly well. Turn them on, which is what you want once more than one section shares a file, and column one of every row becomes a marker rather than data:

| Marker            | What it means                                                 |
| ----------------- | ------------------------------------------------------------- |
| BOF / BOA         | Beginning of file, beginning of account                       |
| BOS,<CODE>,<name> | A section begins — e.g. BOS,POST,"Position; trade date basis" |
| HEADER,<CODE>,…   | That section's column names                                   |
| DATA,<CODE>,…     | That section's rows                                           |
| EOS / EOA / EOF   | End of section, account, file                                 |

Each section carries a short code. I can only report the ones I see in my own exports, so treat this as observed rather than as a published vocabulary. On my weekly pull the ones that matter are `POST` (the position snapshot), `CRTT` (the cash report, where account-level dividend and bond-interest totals live), `FXPO` (FX positions), `TRNT` (trades, carrying the open/close indicator, realised P&L and cost basis), `OPTT` (option events — expiry, assignment, exercise) and `CDIV` (change in dividend accruals). There are others I ignore.

Two numbers are worth holding onto, because they are the whole argument for reading your own file rather than trusting a description of it. A test fixture I had been reasoning from framed **seven** sections. The live query it was supposed to represent framed **twenty**. A stale one-line comment in my own code, written against that fixture, asserted the weekly pull carried no trade rows — and believing it nearly cost me a second query, a second credential and a second daily request to IBKR, all to fetch data that was already sitting in the bytes I had. One command against a real statement refuted it.

> Never take the section list from a fixture, a tutorial, or your own memory. Take it from the file in front of you, every time.

## Why won't the file open properly in a spreadsheet?

If it opens as one clean table, the framing options are off — which tells you nothing about how many sections are inside, only that the file will not tell you where one ends and the next begins. That is its own hazard, and a quieter one. The section-boundary problem in this section is about framed files; the four field problems after it apply to any export, framed or not. A framed multi-section file is a different animal: a spreadsheet expects one header row and then data, and this file has a header row *per section*, plus marker cells in column one that mean nothing to a spreadsheet. Open it in Excel or Sheets and you get a column of `DATA` and `HEADER` strings beside fields that shift meaning every few dozen rows. Nothing errors. It simply looks like a mess, and the natural response — delete the odd rows, keep the ones that look like positions — throws away the framing that told you which section each row belonged to.

So the format pushes you off the spreadsheet before you have computed anything at all — one concrete version of [the point where a tracking spreadsheet stops being enough](https://www.incomestead.com/blog/portfolio-tracking-spreadsheet-vs-software/).

## The four fields that will give you a wrong number

These are not omissions. They are worse than omissions, because an absent field is obvious and a confidently wrong one is not. Each of the four below cost me a real correction.

The four silent ones

**1 · Dividend accruals are not dividend cash.** `CDIV` is *Change in Dividend Accruals*. A row coded `Po` is the accrual posting on the ex-date — money you are owed, not money you have. The row coded `Re` reverses that accrual — normally on the pay-date, as the cash actually lands. But a reversal only tells you the accrual is gone, not that you were paid: accruals also get cancelled, re-rated or restated for withholding, and a position closed before the pay-date reverses without paying you anything. Sum the postings and you book income you have not received; treat every reversal as a receipt and you book income that never arrived. Reconcile reversals against the cash report rather than trusting either on its own.

**2 · An expiry can book in two places.** If you pull both sections, an option expiring worthless appears in `TRNT` as a closing execution carrying the full realised P&L, *and* in `OPTT` as an expiration event. Read both sections and add them up and you have counted the same premium twice.

**3 · An assignment books zero.** An assigned option shows realised P&L of `0`, which looks like a free trade and is not. The premium has already been folded into the assigned stock's cost basis — a call's premium into the sale proceeds, a put's premium reducing the basis of the stock you acquired. Credit the opening premium separately and you double-count again, in the opposite direction.

**4 · Column names differ between sections.** In my exports, `TRNT` spells it `TransactionType` while `OPTT` spells the same concept `Transaction Type`, with a space; and it is `Put/Call`, not `PutCall`. I have not found either documented, which is rather the point. Look up the wrong spelling and you match nothing — and code that matches nothing usually reads as if it worked.

The fourth one is the one that reaches the governance layer, so it is worth following all the way through. Column names arrive in the `HEADER` row, and a benign reformatting on IBKR's side can leave a trailing space on one of them. My parser looked up `EndingSettledCash`; the file offered `EndingSettledCash `. The lookup missed and defaulted to zero. Settled cash went to zero, which moved the margin figure, which moved the [zone I govern the book to](https://www.incomestead.com/blog/using-margin-safely/) — the four bands I run my own leverage in, Clear, Harvest, Freeze and Forced, where the band you are in decides whether this week is a normal week or an acting week — and no part of the chain raised anything, because from the inside every step had behaved exactly as written.

> One invisible character in a column name is enough to change which zone your leverage reads in. The file will not tell you. That is the argument for governing the read, not just the book.

If any of that sounds like a programmer's problem rather than an investor's, consider what the four failures have in common: every one of them corrupts an *income* number or a *margin* number. Those are the two readings a leveraged, income-oriented book is actually run on. The distinction between premium you have booked and premium you have merely accrued is the same one I draw in [realised versus unrealised options income](https://www.incomestead.com/blog/realized-vs-unrealized-options-income/) — and this file is where the distinction either survives or quietly dies.

## What it leaves out entirely

Three things, and none of them is a defect — they are simply outside what a broker statement is for.

**Any classification of your holdings.** The export knows a symbol, a quantity and a currency. It does not know that this position is income machinery and that one is a long-term core holding. Whatever strategy structure you run, you supply it; the broker never will.

**Any notion of a target.** There is no allocation percentage in the file, no band, no threshold. The export tells you what you hold. It has no opinion about what you *meant* to hold, which is the entire content of allocation drift.

**Any memory.** Each pull is a single point in time. There is no prior week inside it, so every week-over-week comparison you want has to come from snapshots you kept yourself. A broker export cannot tell you a number is moving in a direction — only what it is today.

> Your broker keeps a record of your account. It does not keep a record of your intentions — and allocation drift, the thing you are trying to govern, is precisely the distance between the two.

That third one is the quiet argument for a process rather than a habit. It is also the reason a governed book keeps its own history: the record I describe in [running a portfolio like a governed institution](https://www.incomestead.com/blog/portfolio-governance/) exists because the broker's does not.

## What a governed read of the export looks like

Four rules, in the order they earn their place.

**Enumerate the sections on every pull, from the file itself.** Not from last month's memory, not from a tutorial, not from a fixture. A one-line scan of the `BOS` markers tells you what you actually received this week, and it is the cheapest check in the whole chain. Run this against your own export:

The section census

grep '^BOS' your-flex-export.csv

One line per section, each naming its code and its human label. Run it every week and compare against last week's. A section that silently stopped arriving is the failure you would otherwise find months later, in a number that had quietly been computed from less data than you thought. If your export is unframed, this returns nothing — which is itself the answer: you have no section markers, so nothing downstream can tell one section from another either.

**Treat a missing field as an event, not a default.** This is the rule I did not have when the trailing space cost me a zero. A lookup that fails should raise something a human sees; if it quietly substitutes a zero, the number it produces is indistinguishable from a real one. Silence is the failure mode, not wrongness.

**Reconcile against a second source and let the broker win.** I cross-check classifications against a separate positions export, but where the two disagree on a quantity or a cost basis I take the broker's — it is the entity that actually holds the securities. In one case a third-party feed carried a quantity roughly 850 times the true one on a single symbol, and a cost basis that diverged on another. Disagreements get recorded, not resolved by preference.

**Know which errors mean "try again" and which mean "stop."** IBKR's Flex Web Service returns numeric error codes, and they are not interchangeable. `1001` — a statement that could not be generated right now — is documented and genuinely transient; IBKR's own guidance is to try again shortly, though the cooldown I observed ran to hours rather than seconds, so I back off further than the wording suggests. The documented throttling code is `1018`: "Too many requests have been made from this token… Limited to one request per second, 10 requests per minute (per token)." What actually bit me was neither: an *undocumented* code, `1025`, absent from IBKR's published table, which runs 1001 to 1021 ([IBKR, "Flex Web Service Version 3 Error Codes"](https://www.ibkrguides.com/clientportal/performanceandstatements/flex3error.htm?ref=incomestead.com)). I read it — on my own evidence and not on any documentation — as an accumulated-failure lockout, because further attempts deepened it rather than clearing it. Whether that reading is correct barely matters. The rule that falls out of it does: **a code you cannot find in the documentation is a stop-and-inspect, never a retry.** Statement generation is also business-day oriented, so a weekend of failures may be nothing more than a weekend.

Only the first is a pure by-eye check — a scan of the markers in a text editor. The second is a property of whatever reads the file for you, and the last two need a second export and a live request respectively. None of them needs software you have to buy. What they require is the decision to treat the export as evidence that needs verifying rather than as an answer that arrived.

Do this next

The export is one input to a process. If you want to see how well governed the process around it actually is — data, margin, allocation and the habits that hold them together — score it. The Governance Score takes a handful of honest answers about how you run the book and returns a number with its weakest component named.

[Run the Governance Score →](https://www.incomestead.com/blog/governance-score/#tool-governance-score) and see which component is carrying your lowest mark.

## Frequently asked questions

### Is an IBKR Flex Query a CSV file?

It depends on how you configured it. A single-section query with the framing options switched off produces comma-separated output that behaves like an ordinary CSV. But turn on the header-and-trailer-records and section-code options — which are what let you tell one section from another in a multi-section pull — and the result is a framed statement rather than a single table: marker cells in column one (`BOS`, `HEADER`, `DATA`, `EOS`) divide the file into sections, each with its own column names. A spreadsheet will open that without complaint and display it incoherently.

### What sections does an Activity Flex Query contain?

Whatever you selected when you built the template — Interactive Brokers describes Flex Queries as report templates configurable at the individual field level, so there is no fixed answer. Common section codes include `POST` for the position snapshot, `CRTT` for the cash report, `TRNT` for trades, `OPTT` for option events such as expiry and assignment, and `CDIV` for changes in dividend accruals. Read your own file's `BOS` rows to see what yours contains.

### Why don't the dividends in my Flex export match the cash in my account?

Most often because the dividend section reports *accruals* rather than cash. A posting row records a dividend you are owed as of the ex-date; a reversal row removes that accrual, usually on the pay-date when the cash arrives — but also when an accrual is cancelled, re-rated or restated, in which case no cash ever came. Summing postings books income in the wrong week and in an amount you do not yet hold; treating every reversal as a payment books income you never received. Account-level cash totals live in the cash report section, and that is what the accruals should be reconciled against.

### Does a Flex Query tell me my asset allocation?

No. It reports what you hold — symbol, quantity, currency, value — and carries no classification of those holdings and no targets to compare them against. Allocation drift is the gap between what you hold and what you intended to hold, and the intention half never appears in a broker export. You supply it, and you keep it somewhere it cannot be edited in the same place you measure against it.

### What does Flex error 1025 mean, and should I retry?

`1025` does not appear in IBKR's published Flex Web Service error table, so nobody can tell you authoritatively what it means — including me. In my own use it behaved like an accumulated-failure lockout: further attempts made it worse rather than better. The documented code for throttling is `1018`, too many requests from one token. The safe rule is that an undocumented code is a stop-and-inspect, not a retry. Contrast `1001`, which is documented and transient — IBKR says to try again shortly, though in practice I wait considerably longer. Because statement generation follows business days, a run of weekend failures may not be a fault at all.

By **Stefano Starkel**

This is education, not personalized advice. I run a leveraged, income-oriented book myself and write from that experience; I am not a licensed adviser. Everything here describes a file format and how I read it — the field names, section codes and error behaviours are what I have observed in my own exports and may differ in yours, because a Flex Query is a template you configure. Verify against your own file before you rely on any of it, and route tax treatment of dividends or assignments to a CPA.

Incomestead recommends. You decide.