Obscura

Broker-Dealer Annual Reports (X-17A-5)

Annual audited reports (Form X-17A-5) filed by every registered broker-dealer, including the independent accountant who signed the audit and whether a material weakness was reported - disclosed nowhere else, since these firms file no 8-K. Filings are routinely back-dated by months or years, so each row also carries the measured gap between the report's own date and the day the SEC actually published it.

edgar_broker_dealer_reports - the dataset name to pass to the Obscura API.

Category Regulatory Columns 38 Refresh Every 6 hours Entity key cik Point-in-time available_date

What one row means

One **Form X-17A-5 Part III** annual audited report filed by a broker-dealer - the only public window into the balance sheet of an entity that, in the overwhelming majority of cases, files NOTHING ELSE on EDGAR. Every broker-dealer registered under Exchange Act Section 15 must file an annual report audited by an independent public accountant (Rule 17a-5(d)). The registrant is usually not a public company: it has no 10-K, no proxy, no XBRL and no ticker. This filing, and its `008-` broker-dealer registration number, is the whole of its public record. # THE FINANCIAL STATEMENTS ARE A PDF. THIS TABLE IS THE COVER SHEET. That was measured, not assumed. On every one of the 10 electronically filed X-17A-5 submissions in the 2024-02-14 dissemination feed, the financial content is a single `<TYPE>FULL` **PDF** (`Public.pdf`, `bhspub.pdf`, `cheval_12312023-fins3.pdf`, …) and there is no XBRL, no XML financial statement and no tagged FOCUS report anywhere in the submission. There is therefore no balance sheet to extract without OCR, and this table follows the `UPLOAD`/`CORRESP` precedent: it stores the METADATA SEC itself structures and the document manifest that points at the PDF, and it stores no financial figure at all. What that leaves is still the point of the dataset: * **`accountant_name` - WHO AUDITS THIS BROKER-DEALER, per year.** A change of auditor at a broker-dealer is a signal nothing else in the catalogue carries, because the registrant files no 8-K Item 4.01. * **`material_weakness` - the registrant's own Y/N declaration**, stated in the structured cover rather than buried in the PDF. * the fiscal period covered, the `008-` registration number, and the registrant's identity and domicile. # `is_paper` IS THE ROW'S MOST IMPORTANT FLAG, AND IT IS NOT AN ERA SEC accepts this form on PAPER as well as through EDGAR, and it publishes the paper ones as an auto-generated stub: accession `9999999997-YY-NNNNNN`, a `<PAPER>` header flag, one placeholder document naming a Document Control Number, and NO content whatsoever. Those rows carry the header columns and NULL for every structured-cover column, and `is_paper` says so. The paper and electronic populations COEXIST for a decade - they are not two eras with a boundary, which is why this is a per-row flag rather than a declared `regime`. Counted from the quarterly form indexes: 2011Q1 3,678 paper / 0 electronic; 2015Q2 376 / 0; **2016Q1 2,753 / 440** (the first electronic filings); 2018Q1 2,089 / 884; 2022Q1 1,308 / 1,338; 2025Q1 719 / 1,401; **2026Q1 0 / 2,136** (paper gone). See `docs/datasets/edgar_broker_dealer_reports.md` and `docs/availability/edgar_broker_dealer_reports.md`.

One row per One row per X-17A-5 or X-17A-5/A submission, keyed by its ACCESSION. A broker-dealer files one annual report per fiscal year, so the natural reading is one row per (broker-dealer, fiscal year) - but the key is the accession because an amendment (X-17A-5/A) and a re-filed period are separate submissions that must both survive. The archive path would be an equally unique key on this family (measured 80 accessions / 80 index paths over three dissemination days spanning 2024-2026: X-17A-5 never fans out, unlike EFFECT at 19 paths or 25-NSE at 2), and the accession is used anyway so the key rule is the same one every EDGAR document dataset here uses..

Point-in-time availability

Every Obscura dataset carries available_date: the calendar day the publisher made the row available, day-of, with no session rounding. It is the one column a backtest filters on, and it means the same thing on every dataset in the catalog.

For edgar_broker_dealer_reports: filing_join: available_date is the EDGAR DISSEMINATION day, taken from the bronze object's own day partition, NEVER from the header's FILED AS OF DATE. WHY: this family is the worst back-dating offender on EDGAR after the SEC-side correspondence forms - 87,521 of 104,685 X-17A-5 rows (83.6%) were disseminated LATER than the date they are stamped with, and the mechanism is the paper channel: SEC scans and releases paper filings in batches weeks or months after receipt. Measured on the 2024-02-14 feed day: 27 of the 28 paper submissions carry an earlier legal filing date, mean lag 91.3 days, MAX 1,447 days (a 2019-12-31 fiscal year stamped 2020-02-28 and first disseminated 2024-02-14); the 10 electronic submissions on the same day all carry zero lag. Using FILED AS OF DATE would therefore publish four years of look-ahead on a single row. Evidence class B (observed dissemination-day membership against a stated earlier filing date); see docs/availability/edgar_broker_dealer_reports.md. period_start/period_end are the AUDITED FISCAL PERIOD and are never availability anchors.

Refresh cadence

Obscura refreshes edgar_broker_dealer_reports every 6 hours - the most frequent scheduled job that re-collects or re-exports it. This is Obscura's own pipeline cadence, not the upstream publisher's release schedule; when a row became public is recorded per row in available_date.

Schema - 38 columns

The full public column list for edgar_broker_dealer_reports, with the meaning of every field. The same schema is served unauthenticated at https://api.obscura.trade/v1/catalog/edgar_broker_dealer_reports.

ColumnTypeDescription
accessiontext · not nullPK. SEC accession number of the submission. Two shapes, and the difference is the whole `is_paper` story: a filer-generated `0001019586-24-000001` for an electronic filing, and SEC's own `9999999997-YY-NNNNNN` for a scanned paper one.
filenametext · not nullThe registrant's SEC EDGAR Archives path for this submission (`edgar/data/{cik}/{accession}.txt`), derived from the payload's own `FILER:` block rather than from whichever index row was walked, so it is the same value on every ingestion path. The join key into `edgar_filings`.
available_datedatePublic availability date: the EDGAR DISSEMINATION day, recovered from the bronze object's day partition. The point-in-time anchor and the only date a backtest may key on. On a paper filing this is routinely MONTHS after `filed_as_of` - see the dataset's availability note.
period_startdateFirst day of the audited fiscal period (`PERIOD START:` / `<PERIOD-START>`, corroborated by `<periodBegin>` in the structured cover). Normally the fiscal year start.
period_enddateLast day of the audited fiscal period (`CONFORMED PERIOD OF REPORT` / `<PERIOD>`, corroborated by `<periodEnd>`). The fiscal year end the audited statements are as of - a REPORTING period, never an availability date.
accepted_attimestamp with time zoneWhen SEC ACCEPTED the submission (`<ACCEPTANCE-DATETIME>`), US-Eastern wall clock under a UTC type. Provenance only: an after-hours acceptance is disseminated the next morning, and on a paper filing the acceptance stamp is the day SEC keyed it in rather than the day it published it. NULL on a row ingested from the dissemination feed, whose envelope does not carry this stamp - a fact about the envelope, not a decoder gap.
filed_as_ofdateSEC's LEGAL filing date (`FILED AS OF DATE`). Kept as provenance and as the input to `dissemination_lag_days`; it is NEVER an availability date on this family, where 83.6 % of rows are back-dated.
dissemination_lag_daysinteger`available_date - filed_as_of` in whole days: how long SEC held this report before it became publicly readable. Zero on every electronic filing measured; a mean of 91 and a maximum of 1,447 on paper ones. Materialised so the look-ahead this dataset exists to avoid is visible as a column instead of an argument. NULL when either date is absent.
form_typetext · not nullThe submission type exactly as EDGAR states it: `X-17A-5` or `X-17A-5/A`. Measured as the complete family on five quarterly form indexes spanning 2011-2026 - no other literal appears.
is_amendmentboolean · not nullTRUE when this is an amendment (`X-17A-5/A`) restating an earlier annual report. Roughly 2-3 % of the family (55 of 2,285 in 2024Q1). Derived from `form_type`; the migration CHECKs the derivation rather than trusting the writer.
is_paperboolean · not null**TRUE when this is a PAPER filing SEC scanned and released as a stub.** The header carries `<PAPER>`, the accession is `9999999997-…`, and the submission contains ONE placeholder document naming a Document Control Number instead of any content - so every structured-cover column on this row is NULL and no PDF exists to point at. This is a fact about the FILING CHANNEL, not an era: paper and electronic coexisted from 2016Q1 (2,753 / 440) to 2025Q1 (719 / 1,401), and paper reached zero only in 2026Q1.
has_structured_coverboolean · not nullTRUE when the submission carries the machine-readable `primary_doc.xml` cover (`http://www.sec.gov/edgar/seventeenafiler`) that fills `accountant_name`, `material_weakness` and the rest. FALSE on every paper stub, and the direct test of whether the structured-cover columns on this row mean "no" or "not stated".
cikbigintCentral Index Key of the filing broker-dealer, from the header's `FILER:` block.
company_nametextThe broker-dealer's name as EDGAR conforms it, e.g. `CHEVAL CAPITAL, INC.`, `UHLMANN PRICE SECURITIES, LLC`.
sec_file_numbertext**The `008-` BROKER-DEALER REGISTRATION NUMBER** (`008-49491`), from `SEC FILE NUMBER:`. This is the identifier that joins an X-17A-5 to the firm's Form BD record and to FINRA's registration data - and for a firm with no ticker and no other filing, it is the only durable identifier it has besides its CIK.
film_numbertextEDGAR's `FILM NUMBER:` for the submission. On a PAPER filing this is the **Document Control Number** the auto-generated stub instructs a reader to quote when requesting the original document from SEC, which makes it the only route from this row to the actual report.
irs_numbertextThe registrant's IRS Employer Identification Number as text (leading zeros are significant). EDGAR's all-zero placeholder is normalised to NULL rather than stored as a nine-zero string that reads like a real identifier.
state_of_incorporationtextWhere the broker-dealer is INCORPORATED, as an EDGAR state-or-country code (`VA`, `IL`, `NY`, `DE`). A different fact from `business_state` - a Delaware LLC operating out of Chicago states both.
business_citytextThe registrant's HQ city from its `BUSINESS ADDRESS` block, verbatim.
business_statetextThe registrant's HQ state/country code from its `BUSINESS ADDRESS` block - where the firm OPERATES, as distinct from where it is incorporated.
fiscal_year_endtextThe registrant's fiscal year end as EDGAR's four-digit `MMDD` (`1231`, `0930`, `0331`). Text, not a date: it names a recurring day, not an instant.
accountant_nametext**THE AUDITOR.** The independent public accountant's name exactly as the registrant states it in the structured cover (`<accountantName>`) - `Rubio CPA PC`, `Pamela Ohab`. NULL on every paper filing. A year-over-year change in this column at one `cik` is an auditor change at a broker-dealer, which is disclosed nowhere else in the public record because the registrant files no 8-K.
accountant_typetextThe accountant's declared qualification (`<accountantType>`), e.g. `Certified Public Accountant`. NULL on paper filings.
accountant_citytextThe accountant's city, from `<accountantAddress>`. Together with `accountant_state` it separates a national audit firm from a local one without name matching.
accountant_statetextThe accountant's state-or-country code, from `<accountantAddress>`.
material_weaknessboolean**The registrant's own MATERIAL WEAKNESS declaration** from `<materialWeakness>`: TRUE for `Y`, FALSE for `N`, NULL when the submission states nothing (every paper filing). A firm declaring a material weakness in its internal control over compliance is the single highest-signal field on the form, and it is stated in the structured cover rather than only inside the PDF.
registrant_typetextWhat kind of registrant is filing, from `<typeOfRegistrant>` - `Broker-dealer`, and the OTC-derivatives-dealer and security-based-swap variants the form also admits. NULL on paper filings.
registrant_subtypetextThe registrant sub-type when the form states one (`<subTypeOfBDRegistrant>`); rare - 1 of 10 measured electronic filings - and NULL otherwise.
contact_person_nametextThe name of the person the registrant nominates as the contact for this filing (`<contactPersonName>`). NULL on paper filings.
contact_person_phonetextThat contact's telephone number, verbatim and unnormalised (`7035497390`, `3122644400`).
oath_person_nametextWho swore the oath or affirmation required by Rule 17a-5(e)(2) (`<signPersonName>`) - normally a principal of the firm.
oath_titletextThat person's title (`<oathTitle>`), e.g. `President`, `Managing Member`. The de facto senior-officer record for a firm that files no proxy.
oath_signed_ondateThe date on the oath (`<signDate>`). Usually the fiscal period end rather than the day it was signed - measured equal to `period_end` on 10 of 10 electronic filings - so it is stored as its own column and is deliberately NOT a conformed event date.
oath_notarizedbooleanThe registrant's `<confirmNotarizedFlag>`: TRUE when it confirms the oath was notarised. NULL on paper filings.
live_test_flagtext`<liveTestFlag>` from the structured cover - `LIVE` on everything that reaches dissemination. Kept because a `TEST` value would mean the row is not a real filing, and the parser refuses rather than stores that case.
document_countintegerNumber of documents in the submission (`PUBLIC DOCUMENT COUNT:`). 2 on a typical electronic filing (the XML cover plus one PDF), 1 on a paper stub, 3 when the firm attaches two years of audits.
exhibitsjsonb · not nullOrdered JSON array of every document in the submission as `[{"type":…,"sequence":…,"filename":…,"description":…}]`. The `<TYPE>FULL` entries are the audited financial statements as PDFs - this inventory is how a consumer reaches them (`https://www.sec.gov/Archives/edgar/data/{cik}/{accession-no-dashes}/{filename}`), and it is deliberately all this table stores of them.
report_document_countinteger · not nullHow many `<TYPE>FULL` public-report PDFs the submission carries. 1 on a typical filing, 2 when a firm files two fiscal years at once, 0 on a paper stub.

Access edgar_broker_dealer_reports

Two delivery paths, one identifier. Both require an Obscura account and an active subscription; the catalog entry and the schema above are public.

import obscura

client = obscura.Client("obs_live_…")

df = client.query(
    dataset="edgar_broker_dealer_reports",
    symbols=["NVDA", "AAPL"],
    start="2024-01-01",
)

Create a free account Browse all 122 datasets

Frequently asked questions

What is in the edgar_broker_dealer_reports dataset?

Annual audited reports (Form X-17A-5) filed by every registered broker-dealer, including the independent accountant who signed the audit and whether a material weakness was reported - disclosed nowhere else, since these firms file no 8-K. Filings are routinely back-dated by months or years, so each row also carries the measured gap between the report's own date and the day the SEC actually published it. One **Form X-17A-5 Part III** annual audited report filed by a broker-dealer - the only public window into the balance sheet of an entity that, in the overwhelming majority of cases, files NOTHING ELSE on EDGAR. Every broker-dealer registered under Exchange Act Section 15 must file an annual report audited by an independent public accountant (Rule 17a-5(d)). The registrant is usually not a public company: it has no 10-K, no proxy, no XBRL and no ticker. This filing, and its `008-` broker-dealer registration number, is the whole of its public record. # THE FINANCIAL STATEMENTS ARE A PDF. THIS TABLE IS THE COVER SHEET. That was measured, not assumed. On every one of the 10 electronically filed X-17A-5 submissions in the 2024-02-14 dissemination feed, the financial content is a single `<TYPE>FULL` **PDF** (`Public.pdf`, `bhspub.pdf`, `cheval_12312023-fins3.pdf`, …) and there is no XBRL, no XML financial statement and no tagged FOCUS report anywhere in the submission. There is therefore no balance sheet to extract without OCR, and this table follows the `UPLOAD`/`CORRESP` precedent: it stores the METADATA SEC itself structures and the document manifest that points at the PDF, and it stores no financial figure at all. What that leaves is still the point of the dataset: * **`accountant_name` - WHO AUDITS THIS BROKER-DEALER, per year.** A change of auditor at a broker-dealer is a signal nothing else in the catalogue carries, because the registrant files no 8-K Item 4.01. * **`material_weakness` - the registrant's own Y/N declaration**, stated in the structured cover rather than buried in the PDF. * the fiscal period covered, the `008-` registration number, and the registrant's identity and domicile. # `is_paper` IS THE ROW'S MOST IMPORTANT FLAG, AND IT IS NOT AN ERA SEC accepts this form on PAPER as well as through EDGAR, and it publishes the paper ones as an auto-generated stub: accession `9999999997-YY-NNNNNN`, a `<PAPER>` header flag, one placeholder document naming a Document Control Number, and NO content whatsoever. Those rows carry the header columns and NULL for every structured-cover column, and `is_paper` says so. The paper and electronic populations COEXIST for a decade - they are not two eras with a boundary, which is why this is a per-row flag rather than a declared `regime`. Counted from the quarterly form indexes: 2011Q1 3,678 paper / 0 electronic; 2015Q2 376 / 0; **2016Q1 2,753 / 440** (the first electronic filings); 2018Q1 2,089 / 884; 2022Q1 1,308 / 1,338; 2025Q1 719 / 1,401; **2026Q1 0 / 2,136** (paper gone). See `docs/datasets/edgar_broker_dealer_reports.md` and `docs/availability/edgar_broker_dealer_reports.md`.

How do I avoid look-ahead bias with edgar_broker_dealer_reports?

Filter on edgar_broker_dealer_reports.available_date, the day the publisher made the row public. For this dataset that date is derived as follows - filing_join: available_date is the EDGAR DISSEMINATION day, taken from the bronze object's own day partition, NEVER from the header's FILED AS OF DATE. WHY: this family is the worst back-dating offender on EDGAR after the SEC-side correspondence forms - 87,521 of 104,685 X-17A-5 rows (83.6%) were disseminated LATER than the date they are stamped with, and the mechanism is the paper channel: SEC scans and releases paper filings in batches weeks or months after receipt. Measured on the 2024-02-14 feed day: 27 of the 28 paper submissions carry an earlier legal filing date, mean lag 91.3 days, MAX 1,447 days (a 2019-12-31 fiscal year stamped 2020-02-28 and first disseminated 2024-02-14); the 10 electronic submissions on the same day all carry zero lag. Using FILED AS OF DATE would therefore publish four years of look-ahead on a single row. Evidence class B (observed dissemination-day membership against a stated earlier filing date); see docs/availability/edgar_broker_dealer_reports.md. period_start/period_end are the AUDITED FISCAL PERIOD and are never availability anchors. A query of the form WHERE available_date <= '<as-of date>' never sees a row before it existed.

In what formats can I get edgar_broker_dealer_reports?

As a Parquet bulk export (POST https://api.obscura.trade/v1/download) or as JSON from the typed query API (POST https://api.obscura.trade/v1/query), both with dataset="edgar_broker_dealer_reports". The column schema is public at https://api.obscura.trade/v1/catalog/edgar_broker_dealer_reports.

Can I filter edgar_broker_dealer_reports by company or symbol?

Yes. edgar_broker_dealer_reports carries cik, the column the API's symbols filter resolves against.

How often is edgar_broker_dealer_reports updated?

Obscura refreshes edgar_broker_dealer_reports on a every 6 hours schedule - that is the most frequent scheduled job that re-collects or re-exports the table. It is Obscura's own pipeline cadence, not the upstream publisher's release schedule; when the publisher makes a row available is described by the availability rule above, and is recorded per row in available_date.

Related datasets

CFTC Commitments of Traders (COT)The CFTC's weekly Commitments of Traders report: how commercial, non-commercial and small traders are positioned in each… EPA Environmental Enforcement ActionsEnvironmental enforcement actions and penalties from the EPA's ECHO database. One row per case, with the facility, the s… EPA Regulated Facilities and ComplianceEPA-regulated facilities and their compliance history, from ECHO: one row per facility, with location, industry, permit … 13F Filing MetadataMetadata for every 13F report, the quarterly filing where large institutional managers list their U.S. equity holdings. … 13F Institutional HoldingsThe line-item positions inside each 13F: which manager held which security, and how much, each quarter. Deep history is … 13F Other Included ManagersWhich other manager reports a fund's 13F holdings, from the 13F-NT notices managers file when their positions appear on … SEC 8-K Item Codes and Material EventsThe item numbers reported on each 8-K (5.02 officer changes, 2.01 acquisitions, 1.01 material agreements, and so on), so… Asset-Backed Securities Distributions (Form 10-D)Form 10-D distribution reports for asset-backed securities: which trust paid out, for which distribution period, its dep…