People
Every director and officer who files with the SEC, rolled up across the companies they file for: how many companies they appear at, how many of those seats are board seats versus officer roles, and the span of their public filing record. Keyed by the person's own CIK, so a name-spelling change does not split them in two.
people — the dataset name to pass to the Obscura API.
What one row means
One SEC insider (director and/or officer) rolled up across every company they file for — a read-only `people` MATERIALIZED VIEW over `person_roles` (itself derived from `edgar_insider_transactions`). Refreshed nightly by `RefreshGovernanceViews`. `owner_cik` is the stable person key (SEC assigns one CIK per reporting person, so name-spelling drift doesn't fragment them).
One row per One row per owner_cik (the person's SEC Central Index Key)..
Derived in-database from person_roles.
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 people: snapshot: available_date = max(source filing available_date) across all the person's roles — the day this aggregate row first became fully backed by public Form 4 filings. Refreshed nightly.
Refresh cadence
Obscura refreshes people every weekday — 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 — 8 columns
The full public column list for people, with the meaning of every field. The same
schema is served unauthenticated at https://api.obscura.trade/v1/catalog/people.
| Column | Type | Description |
|---|---|---|
| owner_cik | bigint · not null | SEC Central Index Key of the person; the stable per-person join key across all filings and to `person_roles` / `edgar_insider_transactions`. |
| owner_name | text | The person's reported name (most recent value seen across their filings). |
| companies | bigint | Number of distinct companies this person holds any insider role at. |
| director_seats | bigint | Count of those companies where this person is a director. |
| officer_seats | bigint | Count of those companies where this person is an officer. |
| first_seen | date | Earliest date this person became publicly visible in filings — the minimum filing (public-disclosure) date across all their roles. A natural occurred-on span bound, not the row's availability. |
| last_seen | date | Most recent filing (public-disclosure) date this person appears in — the upper bound of their public-appearance span. |
| available_date | date | PUBLIC-availability date = max(source filing available_date) = last_seen: the aggregate row is fully backed by public data once the person's latest Form 4 is disclosed. The point-in-time column to filter/join on. |
Access people
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="people",
symbols=["NVDA", "AAPL"],
start="2024-01-01",
)
Create a free account Browse all 95 datasets
Frequently asked questions
What is in the people dataset?
Every director and officer who files with the SEC, rolled up across the companies they file for: how many companies they appear at, how many of those seats are board seats versus officer roles, and the span of their public filing record. Keyed by the person's own CIK, so a name-spelling change does not split them in two. One SEC insider (director and/or officer) rolled up across every company they file for — a read-only `people` MATERIALIZED VIEW over `person_roles` (itself derived from `edgar_insider_transactions`). Refreshed nightly by `RefreshGovernanceViews`. `owner_cik` is the stable person key (SEC assigns one CIK per reporting person, so name-spelling drift doesn't fragment them).
How do I avoid look-ahead bias with people?
Filter on people.available_date, the day the publisher made the row public. For this dataset that date is derived as follows — snapshot: available_date = max(source filing available_date) across all the person's roles — the day this aggregate row first became fully backed by public Form 4 filings. Refreshed nightly. A query of the form WHERE available_date <= '<as-of date>' never sees a row before it existed.
In what formats can I get people?
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="people". The column schema is public at https://api.obscura.trade/v1/catalog/people.
Can I filter people by company or symbol?
Yes. people carries owner_cik, the column the API's symbols filter resolves against.
How often is people updated?
Obscura refreshes people on a every weekday 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.