A better investor list schema for seed founders
A seed round is not one flat investor list. Split firms, people, paths, conversations, and asks so the next move becomes queryable.
The spreadsheet that fights you back
Open the average seed founder's investor tracker and you find one wide sheet. Row 14 is "Sequoia." Row 15 is "Roelof Botha." Row 16 is "warm intro via Dana." Row 17 is "first call went well, wants to see retention." Row 18 is "Sequoia (seed program)." Four of those rows describe the same conversation and the fifth is a person who works at the firm in row 14, but the sheet treats all five as peers.
By week three the columns have mutated. Someone added "Status" and someone else added "Stage" and they mean different things now. "Notes" holds a paragraph that contradicts the "Next step" column. You sort by "Priority" and the rows scatter because half of them are firms, half are people, and a few are just reminders to send an email. The tracker stopped being a model of your round. It became a pile.
This is not a discipline problem. You did not forget to be tidy. The structure was wrong from the first row, because a fundraise is not a list. It is a set of related objects, and a flat spreadsheet can only represent one kind of object cleanly at a time.
What a flat list mixes
Every investor spreadsheet is silently trying to hold five different things in the same rows:
A firm is a fund. It has a thesis, a check size, a stage, and a fund cycle. "Index Ventures" is a firm. It does not take meetings. It does not reply to email. It cannot like you.
A person is a human at a firm who decides, advocates, or blocks. "Mike at Index" is a person. The associate who took your first call and the partner who has to sponsor you are two different people with different power, and your flat sheet usually collapses them into the firm's row.
A path is how you reach a person: a warm intro, a portfolio founder, a cold line, an event. The path has its own status. "Dana agreed to intro me to Mike, hasn't sent it yet" is a fact about a path, not about Mike and not about Index.
A conversation is a thread of contact over time: the intro, the first call, the partner meeting, the follow-up, the silence. It has a date, a channel, and a next move. One person can carry several conversations across two different rounds.
An ask is the specific thing you want next from a specific person: take the call, send the deck to a partner, confirm the check, make one intro. The ask is where momentum lives, and it is the one thing a flat sheet has nowhere to put.
When these five share a table, every column becomes a compromise. "Status" has to describe a firm and a path and a conversation at once, so it describes none of them. You lose the ability to ask simple questions: which firms have I not yet found a path into? Which conversations have gone quiet for more than ten days? Which asks are sitting with me versus sitting with someone else?
The schema: five objects, not one list
Separate the objects. Each becomes its own small table, linked by IDs. This is a normalized model, and at seed scale it fits in five tabs of one spreadsheet. You do not need a database.
Firm
| Field | Type | Example |
|---|---|---|
| `firm_id` | id | FIRM-007 |
| `name` | text | Index Ventures |
| `stage_focus` | enum | pre-seed, seed, A |
| `check_size` | range | $1M–$3M |
| `thesis_fit` | enum | strong, plausible, stretch |
| `lead_or_follow` | enum | leads, follows, either |
| `status` | enum | not started, in path, in conversation, passed, committed |
Person
| Field | Type | Example |
|---|---|---|
| `person_id` | id | PER-031 |
| `firm_id` | link | FIRM-007 |
| `name` | text | Mike R. |
| `role` | enum | partner, principal, associate, scout |
| `decision_power` | enum | decides, sponsors, screens |
| `notes` | text | Led two infra seeds in 2025 |
Path
| Field | Type | Example |
|---|---|---|
| `path_id` | id | PATH-052 |
| `person_id` | link | PER-031 |
| `via` | text | Dana K. (portfolio founder) |
| `type` | enum | warm intro, portfolio ref, cold, event |
| `status` | enum | identified, requested, sent, landed, dead |
| `strength` | enum | strong, weak |
Conversation
| Field | Type | Example |
|---|---|---|
| `conv_id` | id | CONV-088 |
| `person_id` | link | PER-031 |
| `last_touch` | date | 2026-06-09 |
| `channel` | enum | email, call, meeting, message |
| `stage` | enum | intro, first call, partner mtg, diligence, decision |
| `temperature` | enum | hot, warm, cooling, cold |
Ask
| Field | Type | Example |
|---|---|---|
| `ask_id` | id | ASK-104 |
| `conv_id` | link | CONV-088 |
| `the_ask` | text | Send deck to second partner |
| `owner` | enum | me, them |
| `due` | date | 2026-06-16 |
| `done` | bool | false |
A single live situation now reads cleanly across the objects: Index Ventures (FIRM-007, seed, leads, strong fit) → Mike R. (PER-031, partner, decides) → reached via Dana K. (PATH-052, warm intro, landed) → conversation at partner-meeting stage, last touched June 9, cooling (CONV-088) → next ask: send deck to the second partner, owned by me, due June 16 (ASK-104).
That is the same information your flat sheet was holding. The difference is that you can now query it.
What this buys you
The point of separating objects is not neatness. It is that each useful question maps to one object.
Where are my coverage gaps? Filter Firm for `status = not started`. Those are funds with no path yet. Which intros are stuck? Filter Path for `status = requested` older than five days. Someone agreed to intro you and never sent it. That is the cheapest momentum in your whole round and a flat sheet hides it. What is going cold? Filter Conversation for `temperature = cooling` and `last_touch` more than ten days ago. What do I have to do today? Filter Ask for `owner = me` and `done = false`, sorted by `due`. That filter is your real to-do list, and it never existed in the old sheet because asks had nowhere to live.
The old "Priority" column was guesswork because it tried to rank firms, people, and tasks together. Now priority is a property of the ask, scoped to a conversation, attached to a person, at a firm. Ranking becomes obvious instead of vibes.
What to keep simple at seed
A normalized model can metastasize into an enterprise CRM if you let it. At seed you are running maybe 40 to 80 firms over six to ten weeks. Resist the urge to over-build.
Keep the five objects and nothing more. No custom fields until you have hit the wall twice without them. Use enums, not free text, for anything you will filter on, because `temperature = cooling` is queryable and "kinda gone quiet?" is not. Do not track firms you will never reach. A firm with no plausible path and no thesis fit is not a row, it is a distraction. And do not log every email body in the sheet. The Conversation row holds the state of the thread, last touch and stage and temperature, not a transcript. The transcript lives in your inbox where it already is.
The schema earns its keep precisely because it is small. Five tables, a handful of enums, IDs that link them. That is enough to make a round legible and not so much that maintaining it becomes its own job.
Where this stops being a spreadsheet
Five linked tabs work. They also rot, for one boring reason: you have to update them by hand, and you update them last, after the call, after the inbox, after the standup. The Conversation `last_touch` dates drift out of date. The Path that went stale never gets flipped to dead. The model is correct and increasingly fictional.
The objects in this schema already exist in your sources. The firm and person live in your investor exports and the partner's LinkedIn. The path lives in the intro thread in your inbox. The conversation lives in your calendar and your meeting notes. The ask is the sentence at the bottom of the last email. RoundOS reads those sources and keeps the objects current from them, so `last_touch` reflects the actual last email, a path flips to landed when the intro thread shows the handoff, and a conversation flags as cooling when ten days pass with no reply. Same five-object model, maintained from the round instead of from your willpower, with the open asks owned by you surfaced as the next moves to make.
You can build the model in a spreadsheet today. The schema is the valuable part. The hard part is keeping it true.
Split the list into the objects that actually move.
Re-file the messiest 20 rows into firm, person, path, conversation, and ask, then work the asks you own first.