Obscura

Fund Annual Census Reports (N-CEN)

Form N-CEN annual census reports, one row per registered fund complex: who audits it, who underwrites it, the compliance officer, board composition, and the year's flags for material weaknesses, NAV errors, legal proceedings and financial support.

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

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

What one row means

One **Form N-CEN** annual census filing - the registrant-level half. N-CEN is the annual report every registered investment company files under Rule 30a-1. It replaced Form N-SAR: measured in the EDGAR full indexes, 2018 Q2 carries **1,062 `NSAR` filings and zero `N-CEN`**, and 2018 Q3 carries 198 `NSAR` and **139 `N-CEN` + 12 `N-CEN/A`**, the earliest dated **2018-09-07**. That is the changeover, and it is the floor of this dataset. # This is the STRUCTURED one Unlike the shareholder reports it sits beside (`edgar_fund_shareholder_reports`, which is prose), an N-CEN's payload is a single `primary_doc.xml` in SEC's own `ncen` namespace - schema-validated, one element per Form item. Everything in this table and in `edgar_ncen_series` is read off that XML, never inferred. # WHY THERE ARE TWO TABLES The Form has a registrant part (Items A-C.1: who the fund complex is, its directors, its CCO, its auditor, its underwriter) and a **per-series part** (Item C: one complete block per fund, with that fund's adviser, custodian, net assets, commissions and lending revenue). The two grains are genuinely different and the fan-out is severe - EQ Advisors Trust's 2024 census (`0001752724-25-052137`) is **3.4 MB carrying 110 series blocks**, Pacific Select Fund's states 122. Flattening them into one row would either lose 109 funds or repeat the registrant 110 times. This table is the registrant row; `edgar_ncen_series` is the fund row. One collector fills both from ONE pass over ONE bronze object, exactly as `edgar_nport_filings`/`edgar_nport_holdings` do. # `total_series` IS NOT `series_reported`, AND THE DIFFERENCE IS REAL `total_series` is Item B.5 - how many series the REGISTRANT has. `series_reported` is how many Item C blocks this filing actually carries. They are usually equal (Boyar 1/1, EQ Advisors 110/110, Securian 11/11) and sometimes wildly not: **Allspring Funds Trust's `0001752724-25-052135` states `total_series = 73` and carries ONE series block**, because a registrant whose series have different fiscal year ends files a separate N-CEN per fiscal-year group and each one reports only the series in its own group. So `SELECT total_series` answers "how big is this trust" and `count(edgar_ncen_series)` answers "how many funds does this filing describe". Using either for the other is wrong by a factor of 73 on a real 2025 filing, which is why both are stored rather than one being derived. # NOT EVERY N-CEN HAS SERIES, DIRECTORS OR AN AUDITOR The Form's sections are keyed to `investment_company_type`. An **N-6 insurance separate account** (Minnesota Life Variable Life Account, `0001752724-25-051617`) files a `registrantInfo` block and nothing else - no Item C series, no `directors`, no `publicAccountants`, no `total_series`. An **N-2 closed-end fund** (Cornerstone Total Return, `0001752724-25-052190`) does carry Item C. Every column that only some company types state is therefore nullable, and a NULL here is the Form not asking, never a parse gap. See `docs/datasets/edgar_ncen_filings.md`.

One row per One row per N-CEN or N-CEN/A submission, keyed by its ACCESSION. The key is the accession and NOT the archive path because EDGAR indexes a submission under one path per associated registrant; keying on the path would duplicate any census filed on behalf of more than one CIK. An amendment (N-CEN/A) is its OWN row with its own accession - it is never merged over the original, because the pair is the restatement record and collapsing it would destroy the only evidence that a census was corrected..

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_ncen_filings: 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 (SEC moves that field across the corpus; 4.88% of all EDGAR filings carry a back-dated one). N-CEN carries NO embargo - evidence class B, CONFIRMED: over 45 N-CSR-family and N-CEN submissions sampled from the 2025-03-10 dissemination day, 45/45 state FILED AS OF DATE = 2025-03-10 = the day's feed partition, and 44/45 were ACCEPTED that same calendar day (max acceptance 17:24:37 ET, inside EDGAR's 17:30 cut-off). The single exception was accepted Friday 2025-03-07 18:13:11, after the cut-off, and rolled forward to the Monday - which is dissemination working exactly as documented, not a lag. period_end is the Form's own reportEndingPeriod (Item A.2), the fiscal year the census DESCRIBES; it precedes availability by the statutory 75-day filing window and is never an availability anchor.

Refresh cadence

Obscura refreshes edgar_ncen_filings 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 - 41 columns

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

ColumnTypeDescription
accessiontext · not nullPK. SEC accession number of the submission, e.g. `0001752724-25-052122`. The key is the accession, not the archive path: EDGAR lists one submission under one path per associated registrant.
filenametext · not nullThe PRIMARY registrant's SEC EDGAR Archives path for this submission (`edgar/data/{cik}/{accession}.txt`), derived from the payload's own first `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.
period_enddateThe fiscal period the census DESCRIBES - the Form's own `generalInfo/@reportEndingPeriod` (Item A.2), falling back to EDGAR's `CONFORMED PERIOD OF REPORT`. Always earlier than `available_date`: Rule 30a-1 gives 75 days after fiscal year end, and every 2025-03-10 sample states 2024-12-31. NEVER an availability date.
is_short_periodbooleanTRUE when the registrant states the reporting period was SHORTER than 12 months (`generalInfo/@isReportPeriodLt12`) - a newly formed or newly liquidated fund complex, or one that changed its fiscal year end. Read it before comparing `monthly_avg_net_assets` across filings: an annualised figure and a stub-period figure are not the same measurement.
accepted_attimestamp with time zoneWhen SEC ACCEPTED the submission (`<ACCEPTANCE-DATETIME>`), US-Eastern wall clock stored under a UTC type. Deliberately NOT the availability date: an acceptance after EDGAR's 17:30 ET cut-off is disseminated the NEXT business day, which is exactly what `0001133228-25-002365` (accepted 2025-03-07 18:13:11, disseminated 2025-03-10) shows. NULL on a row ingested from the dissemination feed, whose envelope does not carry this stamp.
filed_as_ofdateSEC's LEGAL filing date (`FILED AS OF DATE`). Kept for parity with `edgar_filings`; never an availability date - measured in prod, 4.88 % of all EDGAR filings carry a back-dated value here.
form_typetext · not nullThe submission type exactly as EDGAR states it: `N-CEN` or `N-CEN/A`. The family has exactly these two literals, confirmed across 2018 Q3 (139 + 12) and the 2025-03-10 dissemination day (33 + 0).
is_amendmentboolean · not nullTRUE when this is an amendment (`N-CEN/A`) restating an earlier census. The amendment is a SEPARATE row with its own accession, never a merge over the original. Derived from `form_type`, and the migration CHECKs the derivation as a biconditional rather than trusting the writer.
cikbigintCentral Index Key of the registrant, read from the Form's own `registrantCik` and falling back to the SGML header's first `FILER:` block.
company_nametextThe registrant's name as the Form states it (`registrantFullName`), e.g. `Boyar Value Fund Inc`, `ALLSPRING FUNDS TRUST`. Note this is the FILER'S spelling and differs in case and punctuation from EDGAR's conformed `COMPANY CONFORMED NAME` in the same submission's header.
registrant_leitextThe registrant's Legal Entity Identifier (`registrantLei`), 20 characters, e.g. `54930000Q0UK48QTMX79`. The Form asks for it directly, which makes N-CEN one of the few EDGAR families carrying an LEI at all. NULL where the registrant states `N/A` - normalised rather than stored as the literal string, which would sort and join as if it were an identifier.
investment_company_typetextWhich registration form the company is registered on, from `filerInfo/investmentCompanyType`: `N-1A` (open-end mutual fund / ETF), `N-2` (closed-end fund), `N-3`/`N-4` (variable annuity separate account), `N-6` (variable life separate account), `N-5`, `N-8B-2`. **This column determines which of the Form's sections exist** - an `N-6` states no series, no directors and no auditor at all - so it must be read before any other column's NULL is interpreted.
registrant_classification_typetextThe registrant's own classification of itself (`registrantClassificationType`), which usually but not always repeats `investment_company_type`. Kept separately rather than collapsed: where the two disagree the disagreement is the filer's statement, not a parse error.
schema_versiontextSEC's `ncen` XML schema version for this submission, e.g. `X0404`. The Form has been revised since 2018 and elements have been added; this is the only in-band record of WHICH revision produced a row, and it is what an analyst should check before treating a NULL as an absence rather than as a field that did not yet exist.
sec_file_numbertextThe registrant's Investment Company Act file number (`investmentCompFileNo`), e.g. `811-08253`. Effectively always an `811-` number on this family - it is the 1940 Act registration itself.
registrant_statetextThe registrant's principal-office state as an ISO 3166-2 subdivision code (`registrantstate`), e.g. `US-NY`, `US-OH`. NOTE the `US-` prefix: N-CEN uses ISO codes, NOT the bare two-letter EDGAR state codes that `edgar_filings` and `edgar_foreign_reports` carry, and the two do not join without normalisation.
registrant_countrytextThe registrant's principal-office country as an ISO 3166-1 alpha-2 code (`registrantcountry`), e.g. `US`.
registrant_citytextThe registrant's principal-office city (`registrantcity`), verbatim as filed.
total_seriesintegerItem B.5 - how many series the REGISTRANT has in total. **This is NOT the number of series this filing reports on**: Allspring Funds Trust's `0001752724-25-052135` states 73 here and carries ONE Item C block, because series with different fiscal year ends are censused in separate filings. Compare with `series_reported` before using either. NULL on the company types that have no series concept (N-6 separate accounts).
series_reportedinteger · not nullHow many Item C series blocks this filing actually carries - i.e. exactly how many `edgar_ncen_series` rows this accession produced. Stored rather than left to a `count(*)` so the registrant row alone is enough to spot the `total_series` divergence above, and so a truncated parse would be visible as a disagreement with the child table rather than silently looking complete.
director_countintegerHow many directors the registrant states on its board (Item B.9). NULL where the Form does not ask - N-6 and N-4 separate accounts have no board of their own. **The count includes interested and independent directors**; `interested_director_count` splits it.
interested_director_countintegerHow many of `director_count` the registrant marks as INTERESTED persons under Section 2(a)(19) (`isDirectorInterestedPerson = Y`) - i.e. affiliated with the adviser or underwriter rather than independent. Boyar Value Fund states 1 of 3. The independent count is the difference, and the ratio is the governance measure this column exists for.
cco_nametextThe name of the registrant's Chief Compliance Officer (Item B.10), e.g. `Jared Lahman`. A PERSON's name, and the reason this dataset is `Restricted`-adjacent in spirit even though it is public record: it is SEC-published, but it is people data and should be treated as such downstream.
is_cco_changedbooleanTRUE when the registrant states its CCO CHANGED since the last filing (`isCcoChangedSinceLastFiling`). A compliance-turnover signal that is otherwise invisible: SEC publishes no CCO register, and this is a year-over-year delta the filer states directly.
public_accountant_nametextThe registrant's independent public accountant (Item B.12), e.g. `Cohen & Co. Ltd`. Fund-complex auditor concentration is measurable from this column alone across the whole 26,240-filing corpus.
pcaob_numbertextThe auditor's PCAOB registration number, e.g. `925`. Text, not an integer: it is an identifier and the Form permits `N/A`, which is normalised to NULL.
is_accountant_changedbooleanTRUE when the registrant states its independent accountant CHANGED during the period (`isPublicAccountantChanged`). Auditor changes at a fund complex are a documented governance signal and the Form asks the question directly.
is_material_weaknessbooleanTRUE when the accountant's report identified a MATERIAL WEAKNESS in internal control (`isMaterialWeakness`). The single highest-value boolean on the Form and almost always FALSE, which is precisely what makes a TRUE worth finding.
is_qualified_opinionbooleanTRUE when the accountant's report was OTHER than unqualified (`isOpinionOffered` - the Form asks whether any opinion other than an unqualified one was offered). A qualified, adverse or disclaimed opinion on a registered fund.
is_accounting_principle_changebooleanTRUE when the registrant reports a CHANGE IN ACCOUNTING PRINCIPLE or practice during the period (`isAccountingPrincipleChange`). A comparability break that a naive year-over-year read of `edgar_ncen_series` measures would otherwise miss.
is_nav_error_paymentbooleanTRUE when the registrant reports a NAV ERROR that required a payment to shareholders or by shareholders to the fund (`isPaymentErrorInNetAssetValue`). A pricing-failure event, self-reported.
is_legal_proceedingbooleanTRUE when the registrant states a legal proceeding against it or its affiliates was pending or concluded in the period (`isPreviousLegalProceeding`).
is_fidelity_bond_claimbooleanTRUE when a claim was FILED against the fidelity bond during the period (`coveredByInsurancePolicy/@isClaimFiledDuringPeriod`). Distinct from `is_legal_proceeding`: this is a loss actually claimed, not a suit.
is_financial_support_providedbooleanTRUE when an affiliated person provided FINANCIAL SUPPORT to a fund during the period (`isFinancialSupportDuringPeriod`) - a sponsor propping up a fund, most often a money market fund. Rare and materially informative.
is_first_filingbooleanTRUE when this is the registrant's FIRST N-CEN (`isRegistrantFirstFiling`) - the complex's arrival on the census.
is_last_filingbooleanTRUE when the registrant states this is its LAST N-CEN (`isRegistrantLastFiling`) - the complex de-registering. The cleanest fund-complex-death signal EDGAR publishes, and it is a forward-looking statement made by the filer, not an inference from a gap in filings.
principal_underwritersjsonb · not nullOrdered JSON array of the registrant's principal underwriters (Item B.13) as `[{"name":…,"file_number":…,"crd":…,"lei":…,"state":…,"country":…,"is_affiliated":…}]`; `[]` where none is stated. An array rather than scalars because a complex can name several, and unlike the per-series adviser this multiplicity is not bounded by the Form.
books_records_locationsjsonb · not nullOrdered JSON array of the offices where the registrant's books and records are kept (Item B.4) as `[{"name":…,"city":…,"state":…,"country":…,"description":…}]`. This is where the fund's administrator and accounting agent physically sit, and it is stated even by the N-6 separate accounts that state almost nothing else.
document_countintegerNumber of documents in the submission (`PUBLIC DOCUMENT COUNT:`) - typically 2, being `primary_doc.xml` plus the accountant's internal-control report.
has_internal_control_reportboolean · not nullTRUE when the submission attaches the independent accountant's INTERNAL CONTROL report (`attachmentsTab/isIPAReportInternalControl`, corroborated by an `INTERNAL CONTROL RPT` document member). Required of registrants that do not file it with an N-CSR.

Access edgar_ncen_filings

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_ncen_filings",
    symbols=["NVDA", "AAPL"],
    start="2024-01-01",
)

Create a free account Browse all 122 datasets

Frequently asked questions

What is in the edgar_ncen_filings dataset?

Form N-CEN annual census reports, one row per registered fund complex: who audits it, who underwrites it, the compliance officer, board composition, and the year's flags for material weaknesses, NAV errors, legal proceedings and financial support. One **Form N-CEN** annual census filing - the registrant-level half. N-CEN is the annual report every registered investment company files under Rule 30a-1. It replaced Form N-SAR: measured in the EDGAR full indexes, 2018 Q2 carries **1,062 `NSAR` filings and zero `N-CEN`**, and 2018 Q3 carries 198 `NSAR` and **139 `N-CEN` + 12 `N-CEN/A`**, the earliest dated **2018-09-07**. That is the changeover, and it is the floor of this dataset. # This is the STRUCTURED one Unlike the shareholder reports it sits beside (`edgar_fund_shareholder_reports`, which is prose), an N-CEN's payload is a single `primary_doc.xml` in SEC's own `ncen` namespace - schema-validated, one element per Form item. Everything in this table and in `edgar_ncen_series` is read off that XML, never inferred. # WHY THERE ARE TWO TABLES The Form has a registrant part (Items A-C.1: who the fund complex is, its directors, its CCO, its auditor, its underwriter) and a **per-series part** (Item C: one complete block per fund, with that fund's adviser, custodian, net assets, commissions and lending revenue). The two grains are genuinely different and the fan-out is severe - EQ Advisors Trust's 2024 census (`0001752724-25-052137`) is **3.4 MB carrying 110 series blocks**, Pacific Select Fund's states 122. Flattening them into one row would either lose 109 funds or repeat the registrant 110 times. This table is the registrant row; `edgar_ncen_series` is the fund row. One collector fills both from ONE pass over ONE bronze object, exactly as `edgar_nport_filings`/`edgar_nport_holdings` do. # `total_series` IS NOT `series_reported`, AND THE DIFFERENCE IS REAL `total_series` is Item B.5 - how many series the REGISTRANT has. `series_reported` is how many Item C blocks this filing actually carries. They are usually equal (Boyar 1/1, EQ Advisors 110/110, Securian 11/11) and sometimes wildly not: **Allspring Funds Trust's `0001752724-25-052135` states `total_series = 73` and carries ONE series block**, because a registrant whose series have different fiscal year ends files a separate N-CEN per fiscal-year group and each one reports only the series in its own group. So `SELECT total_series` answers "how big is this trust" and `count(edgar_ncen_series)` answers "how many funds does this filing describe". Using either for the other is wrong by a factor of 73 on a real 2025 filing, which is why both are stored rather than one being derived. # NOT EVERY N-CEN HAS SERIES, DIRECTORS OR AN AUDITOR The Form's sections are keyed to `investment_company_type`. An **N-6 insurance separate account** (Minnesota Life Variable Life Account, `0001752724-25-051617`) files a `registrantInfo` block and nothing else - no Item C series, no `directors`, no `publicAccountants`, no `total_series`. An **N-2 closed-end fund** (Cornerstone Total Return, `0001752724-25-052190`) does carry Item C. Every column that only some company types state is therefore nullable, and a NULL here is the Form not asking, never a parse gap. See `docs/datasets/edgar_ncen_filings.md`.

How do I avoid look-ahead bias with edgar_ncen_filings?

Filter on edgar_ncen_filings.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 (SEC moves that field across the corpus; 4.88% of all EDGAR filings carry a back-dated one). N-CEN carries NO embargo - evidence class B, CONFIRMED: over 45 N-CSR-family and N-CEN submissions sampled from the 2025-03-10 dissemination day, 45/45 state FILED AS OF DATE = 2025-03-10 = the day's feed partition, and 44/45 were ACCEPTED that same calendar day (max acceptance 17:24:37 ET, inside EDGAR's 17:30 cut-off). The single exception was accepted Friday 2025-03-07 18:13:11, after the cut-off, and rolled forward to the Monday - which is dissemination working exactly as documented, not a lag. period_end is the Form's own reportEndingPeriod (Item A.2), the fiscal year the census DESCRIBES; it precedes availability by the statutory 75-day filing window and is never an availability anchor. 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_ncen_filings?

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_ncen_filings". The column schema is public at https://api.obscura.trade/v1/catalog/edgar_ncen_filings.

Can I filter edgar_ncen_filings by company or symbol?

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

How often is edgar_ncen_filings updated?

Obscura refreshes edgar_ncen_filings 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…