--- title: "Companies and contacts" description: "The people and organisations behind the applications, as records in their own right — with research notes that survive the search and timelines of their own." icon: "building" --- The CRM is the half of the product that outlives one job hunt. Applications close; what you learned about a company and who you know there does not. ## Companies A company record holds `name`, `website` and `notes`, four lists of tags — `industry`, `size`, `location` and a free `tags` — plus, whenever you open one, every application you have there and every contact who works there. Industry, size and location were single text boxes until they were tags. One company is plausibly both fintech and infrastructure, and hiring in two cities; a typo in a text box was a value of its own forever, where a tag is a row you rename once. Each of the four lists replaces only itself, so setting an industry never clears where the company is. You rarely create one on purpose. Applications create their company automatically, and `capture_job_posting` fills in the website too when the posting names it. `create_company` is for the other case: somewhere you are researching *before* there is an application. Names are unique per person, so creating one that already exists is an error rather than a silent merge. ### The website field earns its keep `website` is the company's **own** domain — `stripe.com`, not a Greenhouse, Lever or Ashby link, which is the job board rather than the employer. Two things depend on it, which is why an assistant is told to set it whenever it learns it. It is what puts the company's logo on your pipeline — a board with logos reads at a glance, and a board without them is a wall of text. And with a [mail or calendar account](/guides/inbox-and-calendar) connected, it is the domain their threads and meetings are matched on: `list_correspondence` reads it off `website`, so everything from that domain counts, not only the people you have added by hand. Logos are fetched by each person's browser from `twenty-icons.com`, which means that service can see which companies are in a pipeline. An admin can turn the whole thing off instance-wide — everyone gets initials on a coloured tile instead, and nothing is stored or deleted either way. See [configuration](/self-hosting/configuration). ### Research notes The `notes` field is where the useful part accumulates. What is worth recording is whatever you will want the night before an interview: - What the company actually does, and how it makes money - The interview loop, if you know it - Who you know there - Why you do or do not want this — the honest version `update_company` **replaces** the `notes` field rather than appending to it. Call `get_company` first, combine what is there with what is new, and write the whole thing back. Losing research by writing over it is the worst outcome available in this part of the product, which is why the [`research_company`](/workflows#research-a-company-into-the-crm) workflow spells the read-first step out. ### The same employer, twice An application creates its company automatically and a capture creates another, so "Stripe", "Stripe, Inc." and "stripe" end up as three rows each holding a slice of the pipeline. `merge_companies` folds one into another: applications and contacts move, blank fields on the survivor are filled from the duplicate, the duplicate's notes are appended under a line saying where they came from, and the duplicate row is deleted. Merging is irreversible and nothing records afterwards which applications came from which side. Call `preview_company_merge` first — it returns exactly what would move without writing anything — and let the person confirm. `keep_id` is the company whose name survives; `merge_id` is deleted. Nothing is de-duplicated by a merge. Two identical role titles on the survivor is the correct result: the alternative is guessing which of two records to destroy. In the app the company page has a **Merge** button, and it pre-selects the other company when the two names reduce to the same key. Deleting a company no longer refuses while applications point at it, and no longer needs to: it and every application still pointing at it go into the archive together, and come back together. The people stay — somebody is a founder at one company and an advisor at another — and simply lose that one link. ### Filters and sorting The **Filter** button opens on the dimensions — Industry, Size, Location, Tags, Gaps — and you step into one to pick from its values, rather than scrolling one list of everything. Typing searches across all of them at once and says which dimension each match came from. Sorting is the column headings, or a **Sort** control beside the filter that lists every key including the ones whose column is hidden on a narrow screen. Dragging the divider between two headings sets their widths, which are saved to your profile rather than the URL, so the list looks the same on every device. ### Filters `list_companies` takes a `search` across name, website, notes and every tag name, four tag cuts — `industryIds`, `sizeIds`, `locationIds` and the kind-agnostic `tagIds` — a `missing` list for the gaps worth fixing in one sitting, a `sort`, and a `filter`: | Filter | Shows | | --- | --- | | `active` | Something still in flight there. | | `applied` | You have ever applied. | | `never-applied` | Researched, nothing sent. | | `with-contacts` | You know someone there. | Every row also carries `lastAppliedAt` and `openApplications`, so "who have I applied to, and what is still live" is one call. ## Contacts Recruiters, hiring managers, referrals, the friend who works there. A contact holds `name`, `title`, `email`, `phone`, `relationship`, `notes`, `tags`, the companies they represent, optionally the application they belong to, and every way you can reach them. `tags` files a person the way `industry` files a company — "referral", "warm intro", "ex-colleague" — and comes out of the same catalogue everyone else's labels do. It replaces the whole set, and `list_contacts` takes `tagIds` to cut to a label as well as finding one through `search`. ### Everywhere they represent `companies` is a list, because people are not one employer each: a founder who advises two of your targets is three links, and an ex-colleague who moves keeps the old company as history. Pass names and any that do not exist yet are created; pass `companyIds` when you already have them. `companies` **replaces** the whole set, like every other array in the API. To add one, read the current list with `get_contact`, append, and write it all back. An empty list detaches them from every company. `applicationId` is still one thread at a time: pass an id to attach, an empty string to detach. Removing someone from an application never deletes the person. ### Where to find them `linkedin` is the one everybody has, and the wrong assumption for everybody else — the founder who only answers on X, the designer whose portfolio is the point. So a contact carries `linkedin`, `twitter`, `instagram`, `github` and `website` as named fields, plus `otherLinks` for the tail that has no end: Bluesky, Mastodon, a Substack. `otherLinks` is a list and **replaces** what is there, like every other array in the API. Read the current one with `get_contact` before writing it back. The fields take a URL or a bare handle — `@bywilliaml` under `twitter` becomes `https://x.com/bywilliaml`. The column is `twitter` and the label in the app is X: renaming a column to follow a rebrand is a migration that buys nothing. ### People have timelines too `log_activity` takes **either** an `applicationId` or a `contactId`, never both. With a contact id it becomes that person's history: their page shows it and their "last touched" date moves. So when you mention talking to someone — a coffee, a call, a reply — that is where it gets remembered, and "when did I last talk to them?" is answered from `get_contact`. ### Pings `nextFollowUpAt` on a contact is where "ping Sarah in two weeks" actually lives. Due pings surface in `list_follow_ups` alongside due applications, on the front page, and in the bell in the top bar. The `ping-due` filter on `list_contacts` is the same question asked directly. In the app it is scheduled from **Today** rather than from the person's own page: a date box halfway down a record you opened to read is not where anyone plans a week. Two other filters: `with-application` and `no-company` — `no-company` means nowhere on file, not "no main employer". `companyId` matches anyone linked to that company, whichever of their hats it is. ## In the app **People** in the sidebar splits into Companies and Contacts, each a filterable list. The entry itself is a link to the CRM; the chevron beside it unfolds the two, and the tabs at the top of either page switch between them. A company page holds its details, its research notes, everyone who represents it, and its roles as job listings — each one a click from the posting it came from. Industry, size, location and its own tags are pickers there: tick to attach, type to create, recolour from the swatch row, delete outright. A contact page holds their details, their tags, their links and their timeline. Wherever a company is named it is drawn as a chip carrying its own favicon, and clicking it opens that company. Under a contact's name those chips are the control: each one has an × that unlinks it, and the button beside them adds another or creates a company that is not on file yet. There is no company text field, because typing into one renamed the company for everyone else attached to it and could only ever hold one. The contacts list shows the first company someone represents and a count of the rest, and each person's tags beside their title. Every link a contact has carries its platform's own mark, read off the URL rather than the field it is filed in — so a YouTube channel in the website slot still shows as YouTube. Contacts attach to applications straight from the CRM rather than being retyped. ## The two workflows that live here Gathers what is already on file, says what is missing, then writes it back combined — without flattening the notes that were already there. Pulls the posting, the timeline, the company research, the people you are meeting, every earlier round and what this employer has already asked into one read. Both are in every client as ordinary tools as well as prompts — see [the workflows](/workflows).