What's new on Employbl.

The shipping log, newest first — built in public, one entry per change. For what the product is, start with the homepage; for what agents can do with our data, see the MCP docs.


October 2026 (2026-10-21) — The homepage now says who it is for

  • The homepage headline is written for one person: someone deciding which tech companies are worth applying to. It reads "Know which companies are worth applying to," and the lines under it say how, in terms you can check: every live role is read from the company's own job board and removed when they remove it, every funding round names its investors, and the tech stack comes from what they're hiring for. Free, no card, no expiry. The old headline described the dataset; this one asks the reader's question. The "how it works" steps below it now name what shipped: the company record, Jobs for You with its reasons, and the tracker.
  • Founders get their own line in the hero and their own page. employbl.com/for-companies now says plainly why to claim a page here rather than buy an employer-branding program: the page is the record itself, assistants read it live over MCP, and you claim it, write it and publish it in your brand the same day, with no demo call. A new FAQ entry compares it with Built In's AI-visibility product, quoting Built In's own page with the date we read it.
  • The sign-up prompt on every job page says what the account is for. "Read the full brief, free", with the funding and stack behind the role named in the proof line, instead of a bare "Create free account". Across the site, "team" has left the promise: the people data is thin, so the copy says funding, investors, stack, headcount and live roles.
  • The About page, the site title and the summary assistants read (llms.txt) say the same thing, and llms.txt no longer quotes prices that stopped being true in September: candidates never pay, claiming a company page is free, and Company Premium is annual on the published ladder.

October 2026 (2026-10-21) — The newsletter has a home on employbl.com

  • Every issue of the Saturday briefing now has a page at employbl.com/newsletter — the archive, newest first, and each issue at its own address with the companies it names linked to their profiles. Until now the issues lived only on a newsletter vendor's domain.
  • The subscribe form is ours. The box at the end of every blog post and on the newsletter page now adds your address to Employbl's own list, with a confirmation email first if you don't have an account (one click, nothing is sent until then). A signed-in reader subscribing their own address is on the list immediately.
  • Issues will arrive from connor@employbl.com. The newsletter is moving onto the same sending setup as every other Employbl email — one unsubscribe link, one place to manage preferences — and the move is being made issue by issue, so nothing changes in your inbox until it is proven. Your existing subscription carries over; nothing to do.

October 2026 (2026-10-21) — 45 rounds from the week of October 16–21, 28 companies new to the dataset

  • The funding rounds announced between October 14 and 21 are on employbl.com/funding-rounds, each one checked against the company's own release or filing before it went in. Among them: Tenstorrent's $1.5B Series E, Air Space Intelligence's $325M Series C, Arda's $160M Series A, Eka Robotics' $150M Series A, Town's $108M Series B, Peak Energy's $108M Series B, Estuary Biotherapeutics' $93M Series A, Dream Labs' $90M seed, Reliable Robotics' $90M Series D and Stand's $70M Series C. Where the newsletter and the release disagreed, the release won: Arda's round is $160M, not the $232M total; Sunlight AI's seed is the $17.4M the company states.
  • 28 companies joined the dataset through those rounds — Estuary Biotherapeutics, Mueon, Fission, Arda, Eka Robotics, Dream Labs, Baba, Tolan, Firefly, IMIO, Sunlight AI, Jooba, Different, Coherence Neuro, Erebor, Qualitate, AuxoAI, International Dance League, Electric Plant Company, Asymptote Labs, Pennant, Vinyl Health, Rebel Audio, Scuba, Satlyt, GUDEA, Mecka and Alleviate Health — plus Era, Heron Power, Tacit Labs and State Affairs from the week's hiring newsletters. Six of them had their job boards attached within minutes of being created.
  • Two rounds the dataset already held under a securities filing now carry their announced names: RapidCanvas's $29M filing is its Series B, and Mural's page now lives at the company's current domain, muralpay.com, so the Tether-led $15M Series A landed on the existing company rather than a duplicate.
  • Automation Strategy Group's page carries the founding year, LinkedIn page and street address from the company's own site after its first representative claimed it.

October 2026 (2026-10-19) — See the page you would be publishing, in your own colours

  • Your company dashboard now shows the page Company Premium publishes, side by side with what the public web gets today. On the left, the record Employbl maintains: headquarters, headcount, your latest round, the roles verified on your own job board, the technologies read out of your job posts. On the right, the same URL carrying your story, your products, your customers, your case studies and your FAQ — painted in your brand colours. Until now the dashboard listed the sections you had written and told you they were "saved · visible only to you"; you had to imagine the rest.
  • It is the page, not a mock-up of it. The right-hand column is rendered by the same code that renders a paying company's profile, reading the same words and the same funding history, so nothing in the preview is a promise the published page would not keep.
  • If you have not set your brand colours yet, the preview says so and links to where you set them. The published page carries your palette; the preview is the only place you can see that before you pay, because the public page serves one cached copy to everybody.
  • If you have not written anything yet, it sends you to the editor rather than showing you an empty page.

October 2026 (2026-10-19) — Jobs for You learns, and shows its evidence

  • Four comparison pages: Employbl vs Built In, Wellfound, Crunchbase and LinkedIn. Each one opens with what the other product does well, quotes every claim about it from its own pages with the date we read them, and then sets the two side by side: where the listings come from, whether funding and investors sit on the job page, who pays, and whether you can take the data with you.
  • The REST API returns CSV. Add format=csv to /api/v1/companies, /jobs or /funding-rounds and the same results come back as a spreadsheet-ready file: nested fields as dotted columns, lists joined, pagination in headers. Documented at employbl.com/docs.
  • "General Application" and "Join Our Talent Community" posts no longer show up in search or in Jobs for You. Every careers page carries one; they are not roles, and ~550 of them were ranking alongside real openings. They take effect in search on the next full index rebuild.
  • Every free dataset we have cut is now listed on one page, newest first, at employbl.com/downloads. Each one was previously reachable only from the newsletter issue that announced it.
  • A comped company's published profile now appears in the homepage's featured profiles. The slot required a card on file, so the one comped page never rendered there.
  • Every recommended job now carries the facts you need to accept or reject it: the level, the pay band, the company's size, and when we last confirmed the role on the employer's own job board. The ranking already knew all of this; the row showed none of it. Pay appears only when it clears the same trust gate as the job page itself, so the row never states a number the page would hide. A company with no logo gets its initials instead of a stock placeholder.
  • You can tell the ranking it was wrong. Thumbs up, thumbs down with a reason (wrong location, wrong role, wrong seniority, pay), or hide. A hidden or thumbed-down role leaves the list immediately and stays out; a thumbs-up boosts other roles at that company; "hide all in Boston" or "hide non-remote" are one tap after a location complaint. The MCP tools could do this since September; the web page could not.
  • The Jobs for You page was rendering flush against the sidebar and the top of the window, and the match list stretched the full width of the screen. It now sits in the same frame as every other signed-in page and the list is a single reading column, so a job title is a line you can read rather than a row you scan.

October 2026 (2026-10-14) — 78 companies' job boards were skipped because we asked their ATS too fast

  • Last night's sync gave up on 78 Ashby-hosted boards after being rate-limited, and those companies' pages kept showing roles that may already be filled. When an applicant tracking system answers "too many requests", the sync deliberately changes nothing — better a stale listing than wrongly deleting a real job — but the consequence is that the page stays stale until the next night. One by one, 1,388 boards each hit the same limit, retried for about seven seconds on their own, and gave up; nothing told the rest of the run to ease off, so they all kept arriving at the same rate. The first refusal came 23 seconds into a 78-minute run.
  • Now the whole sync slows down the moment a provider pushes back, and the boards that were refused get a second attempt. The first rejection widens the gap between every subsequent request to that provider, up to a bounded limit, and the pacing relaxes by itself once the provider is answering normally again. Any board that was turned away purely for speed is retried after a short cooldown, so its roles are confirmed the same night instead of the next one.
  • Technology pages were timing out for some visitors. Pages like kubernetes are built on first request and cached until the next release, and they were being built on a slower machine than the company and job pages. Right after a release, when every one of them has to be rebuilt at once, some visitors waited 15 seconds and then saw an error. They now get the same hardware the company pages do.

October 2026 (2026-10-14) — "Add skills & background" now opens the form it names

  • The button that told you to add skills now takes you to the skills editor. On Jobs for You, the dashboard and the AI chat, "Add skills & background" linked to a page that showed signed-in users a "Create your profile" pitch for a moment and then dropped them on their own profile with nothing open. A member wrote in to ask where the form was. The profile page has had a direct link into the skills editor since July; nothing was using it. Every one of those buttons now lands in the editor.
  • It no longer asks for what you already gave us. The same member had uploaded a résumé; we had read 27 skills and five past roles out of it, and still showed him a 60% profile strength and a button offering to add skills. Past roles now count toward profile strength, and once a profile has skills or work history the button says "Edit profile" instead.
  • Work history is editable from Claude and any MCP client, not just appendable. update_work_experience closes out a role that has ended, reopens one, fixes a title or dates; delete_work_experience removes an entry. get_profile now shows each entry's id, which is what both take. Server version 0.21.0, 29 tools.
  • If you sign in with Google on your company's email, the dashboard now tells you your company has a page to claim. Registration with an email and password already spotted that; Google sign-in from a job page deliberately treats you as a job seeker, because most people on a work email are. One line, dismissable for good, linking to the claim page.
  • Personal mailboxes under other countries' domains — hotmail.fr, yahoo.co.in, outlook.de — are now recognised as personal. They could previously be used to claim a company whose website happened to be that host.

October 2026 (2026-10-14) — The companies that raised in the last three weeks, as a spreadsheet

  • A free download of every US company that raised since 22 September and is hiring today. 50 companies, $4.39B raised between them, 979 open roles — company, round, amount, date, headquarters, open-role count and a link to each page. Every role was confirmed on the employer's own applicant tracking system on the day the file was cut. Get it here; it needs a free Employbl account. The window starts the day after the previous list was cut, so no company appears in both.

October 2026 (2026-10-13) — A warehouse supervisor was not being paid $936,000

  • 71 jobs were advertising salaries roughly twelve times too high, and they were the first thing you saw when you sorted by pay. A Warehouse Supervisor II at $804,000–$936,000. A Customer Success Associate at $852,000. An urgent-care veterinarian at $1.8M. Each of those is a real, correctly-stated annual range — $67,000–$78,000, $71,000, $150,000 — that we multiplied by twelve, because the posting mentioned a monthly figure somewhere else and we read that as the unit of the salary. One of them was a $300-a-month commuter benefit, seventy characters from the actual pay.
  • If you filtered for $200,000 and up, these were what you got. They outranked every genuinely high-paying role on the site, and the roles whose true pay would have matched your filter were pushed below them.
  • Fixed, and the existing listings corrected. A pay period now has to belong to the number it describes: it has to be nearer to that figure than to any other, it cannot be separated from it by a different dollar amount, and it has to make sense for the size of the figure — nobody is paid $165,000 a month. 70 listings were corrected to what their posting actually says and one that could not be read at all had its salary removed. We checked the change against all 14,178 listings carrying a parsed salary: 65 changed, seven gained a salary they should have had all along, and none that had a correct salary lost it.
  • A related improvement we tried and backed out. Treating the words "total compensation" as a sign that a figure was base-plus-commission fixed two sales listings and broke 109 ordinary ones, where the phrase was just boilerplate near a perfectly good salary range. It is not in.

October 2026 (2026-10-13) — The weekly report to claimed companies stopped arriving, and nothing said so

  • If you claimed your company page, your Monday report had not been sent since 21 September. The email tells a company rep how many people looked at their page that week, how many clicked through to apply, and how many arrived from an AI assistant. It is deliberately not sent when the week's numbers are all zero, because a table of zeros is noise — and a counting bug made every company's numbers read zero. Three Mondays in a row it considered seventeen companies, sent nothing, and recorded the run as a success. The counts are correct again.
  • Why it went unnoticed, and what now notices. Our analytics provider quietly returns only the first hundred rows of a query that does not ask for a limit, and says so in a flag we were not reading. The question had grown to 5,126 rows — one per company and event — so the hundred that came back were an arbitrary sample, and never included the companies being reported on. The query now asks only about the companies that could receive a report, and refuses to accept a truncated answer at all. A new check added on 10 October — a job that runs, succeeds, and writes nothing three times running — is what found it.
  • Company and job pages: asking for a company by its exact name now also gets you that company's data. The 10 October fix stopped the wrong-company redirect; the page itself was still fetching its content under the lower-cased name, so where two companies' names differ only in capitalisation it could render the other one's description, funding and headcount at the right URL. Both halves now agree. Ethos (ethos.com, 73 open roles) and ethos (etho.io) are two separate reachable pages, as are Numeral (gonumeral.com, 24 roles) and numeral (numeral.com, 15).
  • Company and job slug listings are stable across pages. The endpoints that enumerate our catalogue paged through results without a fixed order, so the same company could appear on two pages and another on none.

October 2026 (2026-10-10) — 321 company pages were sending visitors to a different company

  • If two companies' names differ only in capitalisation, one of them had an unreachable page. Employbl carries 309 such pairs — distinct businesses that happen to share a name, like Ethos (ethos.com, 71 open roles) and ethos (etho.io, none). Asking for one would permanently redirect you to the other, and which one won was essentially arbitrary. In the Ethos case the page with 71 jobs was the one you could not reach. Clara (140 roles), Rebuild (123), Spire (42), Fora (38), Weave (37), Flex (34) and MURAL were all affected the same way. Asking for a company by its exact name now always gets you that company.
  • A side effect of the same bug: those pages had stopped refreshing. The redirect dropped the information that marks a refresh as coming from us, so our own bot protection turned it away. Their job counts and funding could sit stale indefinitely.

October 2026 (2026-10-09) — "Senior Product Marketing Manager" is a senior role, not a management one

  • The job feed stopped treating 3,435 individual-contributor roles as management jobs. If you told us you want management roles, the feed was boosting things like Senior Product Marketing Manager, Senior Customer Success Manager, Creative Director and Backend Software Engineer – Assistant Vice President — titles that carry a management word but describe an individual contributor. The rule that was meant to exclude them only recognised four exact phrases, so anything with a word in the middle slipped through. It now knows the same thirty-odd families the seniority labeller already did, and 645 roles that genuinely are management — supervisors, SVPs — are correctly included for the first time.

October 2026 (2026-10-09) — Company and job pages update again when their data changes

  • Fixed: changes stopped reaching company and job pages. When a company's job board is connected, or its funding or headcount is corrected, the page is supposed to refresh within moments. Since around 5 October every one of those refreshes had been failing silently, so a page could keep showing yesterday's numbers until the next time the site was deployed. One company had 63 open roles live in our data while its public page still said zero. The cause was our own bot protection answering the site's internal refresh request as though it were a scraper.
  • Job seniority labels corrected on 43 roles. A "Director of Engineering" or a "Manager, Field Engineering" was labelled Senior rather than Director or Manager, left over from before those rungs existed. They now carry the right label, so the seniority filter on job search and the match strength on your feed both read correctly for them. We checked the other 188 roles that looked similar and they were already right — "Senior Product Marketing Manager" really is a senior role, not a management one, and nothing was changed there.

October 2026 (2026-10-09) — Typing your city gets you the same jobs as clicking it

  • Typing "San Francisco" into the location field now means the whole Bay Area, the same as picking the San Francisco pill. The feed's new location filter expanded a metro you clicked, but matched a city you typed as plain text — so the 194 people who had only ever used the typeahead got a narrower feed than everyone else, and never knew. Typing San Francisco, Los Angeles, New York, Seattle, Chicago, Austin, Miami, Denver or San Diego now opens the same commute shed the pill does.
  • One city, several spellings. Job listings arrive from hundreds of job boards, which do not agree on how to write a place: 8,000 roles say "New York" and 2,500 say "New York City"; 1,600 say "Bengaluru" and 1,300 say "Bangalore"; 1,400 Washington D.C. roles say "Washington" and 5 say "Washington D.C.". The filter matched one spelling and silently dropped the rest — someone who typed Washington D.C. was seeing 5 jobs out of 1,400. It now treats all the spellings of a place as that place, including for people who clicked the New York pill.
  • Still only one Washington, and only one Dublin. Spellings are grouped per state, so "Washington, Georgia" does not inherit the capital's listings and "Dublin, California" means the Bay Area suburb rather than the capital of Ireland.
  • The feed is also about three times faster to build. Finding the roles in your metros was doing roughly 420,000 disk-page reads per feed — about 81% of all the work the query did — because of how the location check was written. It now reads the same data in two passes instead of one per job: the same results, in 1.6 seconds instead of 4.6.

October 2026 (2026-10-09) — Your feed respects where you said you want to work

  • A San Francisco candidate was shown a Boston job as a "Strong match". Where you want to work was never a filter on the "For You" feed — it was a small bonus, worth at most 5 points of a 25-point match score, so a role 3,000 miles away could outrank everything local and still be labelled Strong. If you have named places in your preferences, the feed now only shows roles in those places, roles that are remote (when you said remote), or roles whose location we do not know. Naming a metro includes the metro: "San Francisco" now means Oakland, Berkeley, Palo Alto, Mountain View and San Jose too, not the city limits. The same rule applies to new roles at companies you watch — following a company no longer overrides where you want to work, just as it already did not override what work you want.
  • Titles that list seven technologies no longer win on length. Each of your technologies named in a job title added to the score with no ceiling, which quietly made keyword-stuffed agency postings — "Lead OR Full Stack Developer (React, TypeScript, Go/ Java/Python/Node.js, AWS)" — the highest-scoring shape on the site. That bonus is now capped at two, in line with the cap that already applied to technologies found in the job description.
  • The same job posted twice under two requisition numbers shows once. Staffing firms post one role in several cities with a different req id appended to each title, and the duplicate check compared titles exactly, so both appeared.

October 2026 (2026-10-09) — Your experience is connected to the company, logo and all

  • Add Experience has a company picker. Typing a company name now suggests Employbl companies as you type, with their logos, and the company that is what you typed comes first — not whichever row the database handed back. Where two companies share a name, the suggestion you probably mean comes first: one that has raised money or employs more than a thousand people, largest employer first. Typing "appl" offers Apple before four funded startups; typing "octave" offers the Octave that raised a seed round before the one that did not. Before this the field was plain text: typing "Octave" offered nothing, and the entry you saved had no connection to the Octave page on Employbl. Picking a suggestion links the two. You can still type any employer, including one we don't carry — the field never blocks a name it doesn't recognise, and nothing you type gets corrected or replaced.
  • Experience entries show the company's logo and link to its page. On your own profile and on the public one. Entries that aren't linked to a company keep the briefcase icon and read exactly as before.
  • Existing entries get linked too, where the name matches a company unambiguously: 99 entries across 49 people now carry a logo that didn't before. A name that two companies share is left alone rather than guessed at — the wrong employer on a résumé is worse than a missing logo. A company that writes a trademark symbol into its own name ("ThinAir™") is matched by someone who typed it without one.
  • Two fixes to the same form while we were in there. Leaving the end date blank without ticking "I currently work here" saved a role that displayed as "Jan 2024 –" with nothing after the dash — the form now asks for one or the other, and older entries already in that state show just the start date. And a newly added role appeared at the bottom of the list instead of in date order until the page was reloaded.

October 2026 (2026-10-09) — Your job matches have their own page, and the AI chat knows who you are

  • "Jobs for You" is in the sidebar. The recommender — open roles ranked against your skills, saved searches and the companies you watch — has existed since July and was only reachable mixed into the "Home" feed and as four rows at the bottom of a job page. It now has a page of its own, named what it is, showing what matched and why, with the match strength on every row.
  • A filled-in profile is enough to get matches. The home feed waited on the preferences questions, so someone who had uploaded a resume — skills read out of it, searches saved, companies watchlisted, all of which the ranking already uses — was asked to set preferences instead of being shown their matches. The feed now runs on whatever you have given us, and the preferences ask shrinks to a single line above the results.
  • The AI chat can read your Employbl account. It had the dataset search tools and nothing else, so asked "what should I apply to?" it could only filter the index rather than rank it for you, and asked what it knew about you it had to say it could not see your profile. It can now pull your profile, your preferences and your saved searches, call the recommender for jobs and companies, compare two to five companies side by side, find companies similar to one you name, and find who is hiring near an address. It can also change your account when you tell it to: a preference you mention in passing ("actually only remote", "nothing below 200k") updates your preferences, a role it does not have gets added to your work history, and a search you describe gets saved with alerts. It makes the change and tells you what it changed and where to edit it, rather than asking you to confirm each one; deleting a saved search is the one thing it checks on first. Adding or removing a skill touches only that skill. Uploading a resume is still the /profile page's job.
  • The chat says what it costs before you spend it. The free daily message allowance was only shown after you had already used one. It is now on screen when the page opens, with why it exists: every message runs a Claude model on our account. Underneath it, a panel that connects Employbl to Claude, ChatGPT, Cursor or any other MCP client in a few steps — that route is free and far less restricted (60 requests a minute, 5,000 a day), because there the model is yours and we only pay for the query.
  • Fixed: the chat box swallowed what you typed. A message longer than one line scrolled its own first lines out of sight inside a one-row box, so you could not read back what you had written before sending it. The box now grows as you type and only scrolls once it is tall enough. Typing also stays available while an answer is coming back. Reported by a user on 2026-10-09.
  • We were underselling the job index by a third. Every page that cites a job count said "75,000+". That floor was set in July, deliberately low because duplicate listings from shared ATS boards were inflating the raw count; the database guard that makes those duplicates impossible landed in September and nobody re-checked the number. There are 118,097 live roles today — 118,017 of them at distinct URLs. The advertised floor is now 100,000+, which is true under the strictest way of counting.

October 2026 (2026-10-08) — Connecting an MCP client no longer loops on email verification

  • Fixed: "Verify your Employbl email address, then reconnect" forever. Connecting Claude Code (or any MCP client) opened the authorize page, you clicked Authorize, and the client came back with that message and an "Authenticate" option that opened the same page again. The token exchange refuses an unverified account, which is right — but the authorize page never checked, and the message promised a verification link that accounts created before email verification existed never received, with no way to request one. The authorize page now shows "Verify your email first" with a send button when the account is unverified, the confirm endpoint refuses the same accounts, and the client-side message now says where to resend. Reported by a user on 2026-10-08.
  • Closed roles were being flushed correctly and logged as failures. When the sync deactivates a listing the worker asks the site to re-render its page, which now returns 404 as intended; the re-render helper throws on any non-200 and the route reported it as a 500, so every closed-role flush read "0/22 ok" in the worker log while the pages were already serving not-found. The route now reports a not-found re-render as the success it is, and names the error otherwise.
  • People Data Labs enrichment removed. The post-verification lookup that tried to prefill a candidate's profile from their email or LinkedIn URL had hit its account cap on every call and was a miss on most of the rest. Gone, with the PDL_API_KEY env var.

October 2026 (2026-10-08) — A company that raises the same amount twice keeps both rounds

  • The second $10M was being thrown away. When a funding round came in, we checked whether the company already had a round of that exact amount and currency — and if it did, we skipped the new one. With no time limit. So a company that raised $10M in 2024 and $10M again in 2026 showed the first round and silently lost the second, and the same was true of every repeat at the same size. The check is worth keeping for what it was built for: when two sources report one raise a few days apart, that really is a duplicate. It now only applies inside a 45-day window — the same window the rest of the funding pipeline already uses for "one raise, reported twice". Grants, debt facilities and crowdfunding tranches, which repeat at identical amounts by design, are never folded together at any distance.

October 2026 (2026-10-07) — Claiming a company profile is easier to find

  • Three places to claim, where an employee actually looks. An unclaimed company page now has a "Work at {Company}? Claim this profile" button in the header (where the rep's Edit button sits once claimed), a "Stack wrong or out of date?" line under the tech stack, and a "Hiring team?" line under the open roles. The low-contrast banner under the tag chips is gone. Job listing pages ask the same in the company sidebar: recruiters and hiring managers check their own postings.
  • The claim page says what claiming is. It leads with what matters: this is the record ChatGPT, Claude and Google read about the company, and claiming controls that source. The old promise of a 30-day Premium trial (removed in September) is gone; publishing in your brand is Company Premium, $67 a year for the first 25 companies. Visit counts shown to a rep now exclude bot traffic.
  • Assistants and the API point at the claim. The company's own claim link now appears in the page's schema.org markup, in the MCP get_company answer for an unpaid company with a story, and in the REST response beside the Premium link.
  • A question, not a survey. Companies without Google Workspace can say so with one link on the claim page; if enough do, a Microsoft 365 path gets built.
  • Signing up with a work email claims the company — once the address is verified. Someone who registers with an email on a company's own domain used to be silently linked to it with none of what a claim brings. Now the match is recorded at signup, and the moment they click the verification link the claim is theirs: the company is marked claimed, the welcome emails and the page enrichment start, and Connor is told. The verification email and the welcome screen both say so. Editing the page still takes one Google Workspace sign-in, which both point at. Google sign-ups already worked this way.

October 2026 (2026-10-06) — Merged-away funding rounds are gone from totals, and from pages

  • 553 companies showed more raised than they had. When two sources report the same raise twice, a nightly pass folds the duplicate into the real round and retires the copy. It updated the latest round but never the "total raised" figure, and the routine that maintains that figure only ever moves it upward — deliberately, since an external total often knows rounds we do not. So a retired duplicate stayed in the total permanently. Anthropic read $143.7B against $128.7B of real rounds; across all 553 companies the overstatement was $34.8B. Fixed, and the fold now takes the retired round back out of the total itself. Companies whose stored total is larger than every round we hold are untouched — that figure is more complete than ours, not inflated.
  • And the retired duplicates were still being listed. Three places read funding rounds without honouring that retirement: the company record an AI assistant reads over MCP and the API, the company sidebar on every job page, and a claimed company's own preview. Anthropic's 2026-04-24 raise appeared twice — once as the Series H it is, once as the retired "Corporate Round" copy. All three now show the folded history.

October 2026 (2026-10-06) — Employbl inside ChatGPT

  • Employbl now has a surface built for ChatGPT. ChatGPT plugins are MCP servers, and Employbl has served MCP since early 2026 — but the existing server carries 27 tools, most of which exist to edit your profile, preferences and saved searches. Those mean nothing to someone asking about a company mid-conversation. There is now a second endpoint, /api/chatgpt/mcp, with the nine read-only tools that do: company search, job search, recent funding rounds, a single company profile, similar companies, a side-by-side comparison, one job listing, and a keyword search/fetch pair. Nothing on it can write to your account.
  • A company renders as a card, not a wall of text. Ask ChatGPT about a company and the answer comes back as a card — logo, what they do, where they are, size, total raised, the last three rounds with their investors and a link to the filing or announcement each was verified against, the tech stack read out of their live job postings, and how many roles are open. The card links to the full profile on Employbl.
  • The existing server is untouched. https://www.employbl.com/api/mcp still has all 27 tools, the same URL, the same keys, and the same limits (60 calls a minute, 5,000 a day). Claude, Cursor, Codex and everything else connected to it see no change. The two surfaces share one set of tool definitions, so a filter added to one is in the other the same day.
  • Connecting still signs you in. The ChatGPT surface uses the same OAuth sign-in as every other client, so what it reads is read as you. A listing in ChatGPT's plugin directory is the next step; until then it is added the way any custom connector is.

October 2026 (2026-10-06) — The companies hiring on Hacker News, and seven weeks of missing head offices

  • Hacker News "Who is hiring?" is now a source. Every month a few hundred companies post the roles they are filling in the HN thread. A new lane reads it, matches each poster against the catalog, and does two things: creates the US companies we did not have (47 from the September and October threads, with funding history and head office where Diffbot knows them), and goes looking for the job board of companies we already had but carried no roles for (57 of them had posted on HN while showing as "untracked" here).
  • 1,015 head-office locations and 107 funding rounds caught up. The weekly early-stage company sweep had been running every Monday since late August and silently doing nothing — it could not reach the database and reported success anyway. It is fixed, and the backlog it should have written is in: every company created since then now has its HQ on the map and its rounds on its page. A second bug dropped the head office of any company outside the US (London, Berlin, Toronto); those are filled too.

October 2026 (2026-10-05) — Hydration noise: a scraper fleet, iOS auto-links, and one metric instead of a flood

  • The hydration errors were mostly a bot. PostHog's weekly digest showed 7.7K exceptions, 90% React hydration mismatches. All but a sliver came from one headless-Chrome fleet: a single Chrome 151 / Windows user agent across 2,600 IPs in 2.5 days, one page per visit, no clicks, 7-14 errors per load. No other Chrome version produced a single mismatch. The fleet (and a Linux Chrome 146 sibling) now meets a verification challenge at the edge — it was also ~1,000 uncached page renders a day on the Vercel bill.
  • iPhones were still at 6-8%. Friday's fix switched off WebKit's phone-number auto-linking; iOS also rewrites dates, street addresses and emails into links before React can compare the page, and a job page is full of all three. All four detections are now off.
  • One number, not a dozen events. A hydration mismatch is recoverable (React re-renders on the client; the visitor sees the page) and it never crashes anything, so PostHog now receives one hydration_mismatch event per page load and code instead of up to fourteen exceptions. The error tracker is for crashes again; the rate by browser and route stays measurable.
  • Job and company pages now ask your browser to prove itself, once an hour. On the first job or company page you open, Vercel shows a one-second "Security Checkpoint" that completes on its own in any real browser, then stays quiet for an hour. It exists because most of the traffic to those pages was never people: headless browsers on rented residential addresses, one page each, copying the listings. Search engines and the AI assistants that send visitors — Google, Bing, OpenAI, Anthropic, Perplexity, Apple — are recognised by the addresses they publish and never see it.

October 2026 (2026-10-05) — Website screenshots, captured in-house

  • Company website screenshots are now taken by our own browser. The 1280×800 picture of a company's homepage on its profile, the homepage funded strip and the browse sort used to come from a paid screenshot API with a cap of 2,000 captures a month, so backfills were rationed and about 3,300 recently funded companies were still waiting for "next month". The worker now runs headless Chromium itself (lib/screenshots/, Dockerfile.worker), at no per-capture cost and with no monthly cap, so the waiting companies can be captured in one run. A capture that lands on a bot-protection page ("Just a moment…", "Access Denied") is rejected rather than stored, which the old service could not promise. The failure vocabulary the rest of the pipeline reads is unchanged.

October 2026 (2026-10-04) — Funding Radar retired

  • The weekly Funding Radar email is gone. It went to about fifty people every Monday with the rounds at companies matching their preferences, and in the fortnight before it was retired three people clicked anything in it. Funding data on the site is unchanged — every round still shows on company pages, /funding-rounds and in the feed on your dashboard, which uses the same matching — but nobody is emailed about it any more. The Funding Radar switch is gone from email preferences; "Unsubscribe" links in old Funding Radar emails still work and now simply confirm the digest no longer exists. The only paid extra left on a legacy Candidate Premium subscription is uncapped AI chat, and the pages and emails that still said otherwise have been corrected.

October 2026 (2026-10-02) — The dashboard loads again

  • Hotfix: the signed-in dashboard crashed for most visitors since September 30. Every visit to /dashboard from the September 30 release onward threw "Application error: a client-side exception has occurred" for roughly two in three signed-in visitors (a Crisp report brought it in; PostHog showed 19 of 30 dashboard visitors hit it on October 1). The feed card on the dashboard borrowed a number formatter from the funding-digest email module, and that release made the email module construct its SES client from server-only configuration at load time, so the browser bundle for the dashboard now tried to read a secret and the page died before React drew anything. The formatter has its own dependency-free home (lib/funding/formatGuardedAmount.ts), and a new test (lib/clientBoundary.test.ts) walks every component's imports and fails the build if any chain reaches Prisma, the SES client, NextAuth or another server-only module — the class of bug no type check or unit test could see.
  • Fewer pages re-render on arrival in Safari. About one in seven page views in Safari (and one in forty elsewhere) logged a hydration mismatch, which makes React throw the server-rendered page away and draw it again. Two causes, both fixed: WebKit was turning salaries, listing ids and zip codes into tappable phone links before React could compare the page (format-detection is now off), and three brief pages stamped "Updated" with the deploy date on the server and today on the client; the hub job dates also shifted a day near midnight depending on timezone. Nothing looked broken; the page just did its work twice.
  • Fifteen minutes of errors after the release, then a smaller connection pool. About twenty minutes after the day's release went out, every page that reads the database returned an error for roughly fifteen minutes: the deploy empties the page cache, crawlers re-request thousands of pages at once, and each of the ~50 server instances that spun up kept five idle database connections open after going quiet — more than the database allows. The idle connections were cleared by hand, each instance now keeps at most two, and the database itself closes any connection idle for two minutes.

October 2026 (2026-10-01) — every email now knows whether it arrived

  • The delivery log closes the loop. Until now "sent" in the email log meant only that Amazon accepted the message; one that bounced fourteen hours later still read as sent. Every send now records the message id Amazon returns, and the bounce/delivery webhook stamps the same row with what happened next — delivered, delayed, bounced or complained — so the admin email center shows delivered and bounced counts per kind and a Delivery column per message, and a bounce can be traced to the exact send that caused it. Logging moved into the one function every email passes through, so no sender can forget it or record a send that never left; a failure is now a retry, not a quiet miss.

  • Unsuppress. A person whose address was blocked by mistake (an inbox that was full for a week) can be unblocked from the Suppressions tab in one click. Spam complaints stay final.

  • Four technologies the skills extractor was skipping. OpenAI, Anthropic, Stripe and pgvector each had a row in the skills table that had never been reviewed, and the extractor only matches curated, categorised technologies — so roughly 7,000 open roles that name one of them showed no such skill, and none had a technology page. They are curated now (OpenAI and Anthropic under AI/ML, Stripe under payments, pgvector under databases, SvelteKit under frameworks), duplicate Kubernetes and SvelteKit rows were folded onto the real ones, and the 7,057 listings that name one of them were re-scanned the same day. /tech-stacks/openai, /tech-stacks/anthropic, /tech-stacks/stripe and /tech-stacks/pgvector exist now; the company lists on them fill in with the nightly roll-up.

  • A job board's tenant has to be the company. On Workday and SmartRecruiters the board's address names the employer, and 42 of the 87 Workday boards on the site named somebody else — almost always a company that had been acquired, whose website now sends visitors to the acquirer, so the acquirer's careers page had been attached to the acquired company's profile: RoadBotics showing Michelin's 500 roles, NGINX showing F5's, OSIsoft showing AVEVA's. A new audit (scripts/audit-board-tenant-mismatch.ts, rule and cases in lib/jobs/discovery/tenantMismatch.ts) finds these from the address alone and separates the clear cases — the company's own website resolves to another domain — from the ones a person should read. First run: 16 clear cases carrying 2,572 listings, 18 to review, 7 brand boards correctly hosted by a parent (Slack under Salesforce, Zipcar under Avis Budget) left alone. Applied the same day: 14 boards retired and 2,543 listings taken down; CO-OP Financial Services and CM Group kept, since those are rebrands (Velera, Marigold) to rename rather than acquisitions.

  • Saved jobs and the application tracker accept changes only from their owner. The update and delete routes for a saved job checked that you were signed in, not that the row was yours. Fixed (#750).


September 2026 (2026-09-29) — A listing that closes now leaves its page within the hour

Job pages are cached until the next release, and until today nothing refreshed a page when the sync found its listing gone from the employer's board. A role that closed on Monday stayed up — title, description, apply button — until whenever the next deploy happened, which could be days. Company pages had this fixed on September 10; the listing pages did not.

  • Closed listings flush their own page. Every sync that deactivates listings, and the daily sweep that retires listings from companies whose board has gone, now asks the site to re-render those pages, which return "not found" from then on. Crawlers that come back get the 404, not the ghost.
  • The stat pages refresh daily. The Bay Area map page, the metro map pages and the homepage recompute their numbers every morning after the job-board sync, instead of only on deploy.

September 2026 (2026-09-29) — The Bay Area map's Jobs and By zip layers work, "hiring most" counts Bay Area roles, and the page works for everyone who is not signed in

Reports from the first days of the rebuilt Bay Area map, and what a real browser found when we finally put the page in one:

  • Switching to Jobs or By zip showed an empty map. The switch used to clear the companies layer's data; on the new basemap the map kept trying to draw the old pins against the cleared data and stopped painting altogether (an error the browser logged nine times a second). Layers are now hidden and shown instead of cleared. The zip layer also disappeared once you zoomed to street level; it no longer does.
  • "Hiring most in the Bay Area" now counts roles in the Bay Area. It used to rank companies by their nationwide open-role count, which put a cookie chain with 1,200 store postings (25 of them here) near the top and SpaceX (headquartered in Hawthorne) first. Each tile now shows the roles located in the region, and the headquarters-by-city table counts roles the same way.
  • The hero picture and the share card were broken for anyone without a browser on employbl.com. The map picture was fetched straight from Mapbox with a token that only answers requests referred from employbl.com, so every crawler, every link unfurl (Slack, iMessage, X, ChatGPT) and every local dev server got a 403 — for four days the page's social card was a broken image. The picture is now rendered by Employbl itself and cached for a day; no Mapbox token appears in the page at all.
  • Signed-out visitors get the neighbourhood tour too. The eight chips (Whole Bay, SoMa, Financial District, Mission Bay, South San Francisco, Palo Alto, Mountain View, Oakland & Berkeley) now switch the picture for visitors, the way they fly the live map for members — the value of the map is visible before the sign-up button, and it still costs no interactive map load.
  • More ways to find the page. It is linked from the homepage, the metro map hub, the San Francisco metro page and the eleven Bay Area city pages, and it carries a schema.org Dataset description for Google's dataset search.

September 2026 (2026-09-25) — Every map shows something before you sign in, and every map's sign-up button is counted

The maps outside the Bay Area page had not caught up with it. The small map on each company and job page was an empty grey box for visitors; the map view of the companies search showed a "Map preview" placeholder; the metro pages still promised a "free 7-day trial" that stopped existing in August. And behind the scenes the small map was the most expensive thing on the site: it loaded a full interactive map on every signed-in company or job page view, whether or not anyone looked at it.

  • Company and job pages show a real map to everyone. The offices (or the on-site locations of the role) are drawn as tangelo pins on a picture of the neighbourhood, built with the page. Signed in, an Open interactive map button turns it into the live map — so the interactive load happens only when it is wanted. Signed out, the picture carries the one sign-up button.
  • The companies map view previews the real place. /companies?view=map now shows a signed-out visitor the country, or the metro whose chip they picked, instead of a placeholder.
  • Metro pages tell the truth. /map/<metro> says "free with an account", sends a signed-out visitor to sign up and a signed-in one straight to the live map, and its neighbourhood list links into the city pages that exist.
  • The interactive mini-map is on the same monochrome basemap as the big map, with tangelo markers.
  • Every sign-up button on a map now reports where it was clicked (register_cta_click with sources minimap-company, minimap-job, map, map-<metro>, map-metro-<metro>), and the mini-map reports both the click that opens it (map_static_click) and the load (map_loaded), which it never did before.

October 2026 (2026-10-01) — Email preferences in one place, unsubscribe from everything, change your address

  • Email preferences — every switch on one page: job alerts, Funding Radar, product updates, company reports, the newsletter, and each saved search's frequency. Reach it signed in, from your profile, or from the "Manage email preferences" link now in the footer of every email we send (that link works for 30 days without logging in).
  • Unsubscribe from everything. One click stops every email except the ones you ask for directly — a verification link, or a reply to an intro you accepted. Job alerts included: the old "unsubscribe" left those running.
  • Every email now says who it's from and where — Lombard Labs, 600 California St, San Francisco — along with why you're getting it. The unsubscribe link and the preference link sit under that on every message, and no template or edit can leave them out.
  • Change your email address. A wrong address at signup used to mean "sign out and register again." Now you set the new one, we send a link to it, and your old address keeps working until you click. If mail to your address is bouncing, the verification page says so and offers the change right there instead of a resend button that does nothing.
  • Marking one of our emails as spam now also unsubscribes you from everything, so what you see in your preferences matches what we do.

September 2026 (2026-09-30) — Emails stop chasing dead inboxes, and every alert has its own off switch

  • An address whose mailbox has been full for weeks drops off the send list on its own. Until now a job alert or onboarding email kept going out to an abandoned inbox every day, forever, because the failure it produces is the "temporary" kind that mail providers never retire. Three such failures in a row with nothing delivered in between now pauses that address for ninety days; a later successful delivery clears it. Hard failures and spam complaints stop mail immediately and permanently. Verification emails and intro replies — mail you asked for and are waiting on — still go through a temporary pause.
  • Every job-alert email carries its own unsubscribe link, and it pauses only that alert. Your other saved searches, and the Funding Radar or product-update setting, are untouched. The same one-click unsubscribe now works from the Gmail and Yahoo "Unsubscribe" buttons for every email we send.
  • Replies to any Employbl email reach a person, and every message now ships with a plain-text version alongside the HTML.

September 2026 (2026-09-25) — One address per idea: the footer, the nav and old links all agree now

Employbl had grown a second, sometimes a third, URL for the same thing: a "Job Search" link that went to /jobs in the footer and to a separate landing page in the menu; company lists by technology under both /tech-stacks/react and /company-collections/react; industries under both the curated /industries pages and the older collection tags, with a footer column pointing at a third page that only listed the old ones. Search engines were handed both copies of everything.

  • The footer and the Product menu now point at the same places, one column per family: Jobs (search, by department, by title, remote, San Francisco), Companies (search, industries, tech stacks, headquarters, collections, map), Tech stacks, Industries, Headquarters, Investors & stages, and Employbl. Duplicated links are gone.
  • Old addresses keep working. The retired job-listings landing page and its city pages send you to the job search; the fifty-odd /job-listings/role/… links still floating around the web, which had been dead ends, land on the matching title or department page; the older technology and industry collection pages send you to their /tech-stacks and /industries twins; /tech-industries goes to /industries.
  • Search engines get one copy. The sitemap no longer lists the redirected pages, and pages that were never meant to be indexed (chat, onboarding, downloads) are out of it. Every marketing page now carries a canonical tag, and a few pages that rendered two or three headline tags render one.
  • The long-retired /jobs/search/… pages answer 410 instead of redirecting forever.

September 2026 (2026-09-25) — The Bay Area map is a landing page again

Map of tech companies in the SF Bay Area was the one map on the site that predated the live map product: a zip-code choropleth whose company counts had been frozen since the day it shipped in 2024, behind a blurred picture for anyone not signed in. Rebuilt:

  • Live numbers. Companies headquartered from Marin to San Jose, roles open on their own applicant systems, companies hiring right now, and capital raised in the last 90 days — all computed from the dataset when the page is built, with the "as of" date in the kicker.
  • A real preview for visitors. Anyone can now see the Bay Area with the sixty most actively hiring headquarters marked, plus headquarters by city, the twelve companies hiring most, and the largest rounds of the last 90 days — all readable without an account. One button opens the live map with a free account.
  • The live map, with a tour. Signed in, the same page opens Employbl's interactive map centred on the Bay, with chips that fly into SoMa, the Financial District, Mission Bay, South San Francisco, Palo Alto, Mountain View and the East Bay. The old density-by-zip view survives as a By zip layer next to Companies and Jobs.
  • Companies get their own ask — claim the profile to own the record answer engines read, and to move the pin from a zip centroid to the real address.
  • A new basemap for every map. The interactive map — here and on the companies search — moves to Mapbox Standard in monochrome: paper-and-ink streets, no point-of-interest clutter, real 3D buildings when the tour tilts the camera. Company pins are tangelo, clusters and the jobs heat are press blue.

September 2026 (2026-09-25) — Jobs by department, jobs by title, and technology pages that show the jobs

Three linked page families for "where are the jobs, and what do they ask for":

  • Jobs by department — thirteen pages, one per department (Engineering, Sales, Product, Data & ML, …). Each shows the open-role count, companies hiring, remote share and the median posted base pay; the titles those roles are actually given; the technologies the postings ask for; the newest openings; who is hiring the most; and the seniority mix of the roles that state one.
  • Jobs by title — 46 title pages, from Senior Software Engineer (954 companies hiring) to Executive Assistant. A title is matched on the start of the posting's own title, so "Sr. Software Engineer, Payments" and "Senior Software Engineer II" land on the same page and "Software Engineering Manager" does not. Bare ranks (Director, Manager, VP) are seniority, not jobs, and get no page.
  • Technology pages are jobs-first. /tech-stacks/python now opens with the newest roles that ask for Python, the departments they sit in, a median pay figure, and a link to the official documentation, above the companies, co-occurring technologies and common titles it already listed. Common titles link through to their title page.

Everything on these pages is readable without an account, and every listing is in the page for search engines and answer engines. The newest-openings list shows five roles clear and blurs the rest behind one button, "Get Engineering job alerts": sign up from there and the account starts with a saved search scoped to that department, title or technology, and the alert lands in the inbox when new roles open. A signed-in reader sees the full list and a link into the jobs search with the same filter applied. Pay figures appear only where fifty or more postings state a yearly range we parsed with high confidence.


September 2026 (2026-09-25) — Filter jobs by department, and technology pages link to the official docs

  • A Department chip on /jobs. Engineering, Data & ML, Product, Design, Marketing, Sales, Customer Success, Operations, Finance, People & Recruiting, Legal, IT, Healthcare — the same thirteen the company page's job rows have shown since 2026-09-23, now a filter with live counts. It reads the department we classified from the title and the employer's own label; roles the classifier could not place are left out of the counts rather than guessed. The MCP search_jobs tool and REST GET /jobs accept the same department value (server v0.19.0), so "sales roles at Series B companies" is no longer a title guess.
  • Job alerts scoped by technology now stay scoped. A saved search carrying a tech-stack filter had been emailing every new role, not just the React or Python ones — the filter was saved but never read back when the alert ran. Fixed, and department scoping rides the same path.
  • Every curated technology can carry a link to its official documentation. 217 of the 383 technology pages have one today, hand-picked, no generated prose; the rest can be filled in from the admin taxonomy page. The link renders on /tech-stacks/[slug] with the rest of the hub-page work that follows.

September 2026 (2026-09-24) — Company profiles: one tag row, a rail that stays put, a wider tech stack

Three follow-ups from the same Svix review:

  • The tags under the description are one plain row. The "Filed under" label is gone, and so is the odd pair of "Industry" and "Industries" headings above two separate rows — those were two taxonomies (the curated industry pages and the older collection tags) shown as if they were one with a typo. They now sit in a single row, industries first, with any duplicate name dropped.
  • The right-hand rail stays on screen as you scroll a long profile when signed in, the way the left sidebar does. If its cards run longer than the window it scrolls on its own.
  • Tech stack categories sit side by side instead of stacking one under another down a mostly empty column.
  • A company's tech stack is what it builds with, not what it plugs into. The profile generator was reading a company's integrations page as its stack, so a sales tool that connects to Clay, Gong and Outreach showed those as its own tooling. The generator now leaves out anything the site names as an integration, and Octave's page shows the stack the company actually reports.
  • Logo upload works for claimed companies. Every upload from the company dashboard had failed since it shipped on 2026-09-11 with a bare "Upload failed": the route's S3 client was reading credentials the production environment does not carry. It now uses the same credentials as every other image upload. Found because RemotePeople's co-founder reported it.
  • RemotePeople's profile corrected at the company's request: the name, headquarters, description and logo, and a $1.3M seed round that had no primary source behind it is retracted. Its address moves to /companies/remotepeople with a permanent redirect from the old URL once this release is live.
  • Funding rounds drop the "Diffbot knowledge graph" line. The footer already credits Diffbot for every round that has no filing or announcement; rounds that do have one still link to it.

September 2026 (2026-09-25) — Company profiles: what a company writes is published when it subscribes

Employbl sells one thing to companies: the profile page. Until today a company that claimed its page for free had its own account of itself — product, customers, case studies, culture, FAQ — shown to signed-in Employbl members, with paying moving it to the open web. That made a free page read as complete, and it converted nobody. Now:

  • A free claim is the record Employbl maintains — funding, headcount, headquarters, ATS-verified open roles, the tech stack read from job posts, industries, similar companies, a screenshot of the website. That is what every visitor, search engine and AI assistant sees.
  • Everything the company writes is published when it subscribes — tagline, team, hiring focus, interview process, product, customers, case studies, culture, its own FAQ — on the page, in its own brand, and in the structured data and API responses that ChatGPT, Claude, Perplexity and Google read. Until then it is saved and visible only to the company's own rep, as a preview of the page they would get.
  • No member exception. Signing in no longer reveals an unpaid company's profile.
  • Search and the map no longer show a company's tagline unless it is published, and eleven Employbl-written profiles for companies that never claimed them have come down.

Company Premium is $67 a year for the first 25 companies, and the price a company joins at is kept for as long as it stays.


September 2026 (2026-09-24) — Job levels for the other half of the corpus

More than half of live listings had no level, so the level filter on /jobs and in the MCP server could not see them. Most of those titles simply do not state one: "Software Engineer, Backend" is a mid-level opening unless the posting says otherwise, and the site now treats it that way. What changed, all read from the title:

  • A plain individual-contributor title is mid-level. Recorded as an assumption, not a reading, so anything that finds the real level in the posting later overrides it.
  • Management titles state their rank. Manager and Supervisor are manager; Director and Head of are director; VP, Chief and President are executive. Product, Program, Account and Customer Success managers stay on the individual-contributor ladder, as does an Art Director.
  • The sales ladder reads by segment. Sales and business development reps are junior; Enterprise, Strategic, Majors and Named account executives are senior.
  • Lead is staff when it leads a craft (Lead Data Scientist, Analytics Lead).
  • "Specialist I", "Engineer 3" and non-English intern titles now read as junior, senior and intern.
  • Nurses, technicians, drivers, welders, retail crew and other roles our ladder does not describe are left unlevelled on purpose, as are the "General Application" posts every careers page carries.

Checked against a 616-title answer key before shipping: 95.5% of the levels the rules write agree with the key, 97.9% on the blind holdout half.


September 2026 (2026-09-23) — Company profiles: a readable contents menu, richer job rows, and no more overlap

A pass over the company profile after a review of Svix:

  • The contents menu is legible — larger type, an icon per section, and the order a candidate actually scans in: Locations, Funding, Tech Stack, Open Roles, Leadership, Similar Companies. The page's sections now render in that same order.
  • Collections sit under the description as a "Filed under" row (industries and collections), instead of a section at the bottom. Tech-stack and investor tags are left out of it because the Tech Stack and Funding sections already list them.
  • Job rows say more than the title — location, Remote, level, department and the pay range where we know them.
  • The job list no longer runs under the right-hand rail when signed in, and the signed-in frame no longer leaves a wide dead gutter on the right.
  • "×2" on a technology now explains itself — hover for "Mentioned in 2 of Svix's open job postings", with a one-line key under the section label.
  • Similar companies get real cards — bigger logos and names, HQ city and stage, a line of description, and a sentence saying how they were picked (same industries, ranked by funding-stage adjacency and hiring activity, or hand-picked by the company). The duplicated "Similar companies" label is gone.
  • Chips are square everywhere, including the collection browser in the right rail. The page title reads "Svix — Profile, Jobs & Funding".

September 2026 (2026-09-23) — Company pages work again on older Safari

A visitor on Safari 16.3 opened a company profile and got a page that could be read but not used: the text was all there, and no tab, button or menu on it did anything. The AI chat panel is bundled into every company, collection and location page, and its markdown renderer carries a regular expression using lookbehind — a syntax Safari only learned in 16.4. Safari checks regular expressions when it reads the file, not when it runs them, so one unreadable expression killed every script that shipped alongside it. The chat panel's renderer now loads only when the chat is actually opened, so the page no longer depends on it. A test now walks the same import chain the bundler does and fails if that renderer ever creeps back into a public page's startup code. The changelog page you are reading had the same dependency for the same reason; it now turns this file into HTML when the site is built, so no markdown machinery reaches your browser at all.


September 2026 (2026-09-22) — A free dataset: 100 companies that just raised and are hiring

Employbl now publishes datasets you can download, starting with 100 companies that just raised, and are hiring right now — every US company in the index with an equity round of $48.5M or more in the last 90 days and at least one open role confirmed on its own applicant tracking system. 100 companies, $31.0B raised between them, 4,366 open roles, as a CSV with the round, the date, the headquarters and a link to each company's page. Debt, private-equity, post-IPO and secondary transactions are excluded, so every row is a venture round.

The page is public and says exactly what is in the file; the download itself needs a free Employbl account. No card, no trial, no expiry.


September 2026 (2026-09-22) — The API is free, and job search can find a country

The 100-call limit is gone. Every verified Employbl account now gets the whole MCP server and the whole REST API, with no call allowance and no paid tier for volume — a free account and a paying one make identical calls. The only ceiling left is the rate limit, 60 calls a minute and 5,000 a day per key, which is abuse protection and is the same for everyone.

You can now search for jobs in a country. search_jobs and GET /jobs take a country filter — ISO codes, with country names and three-letter codes understood too, so "Spain", "ESP" and "ES" all work. Before this, asking for jobs outside the US meant listing exact city keys, and the keys people reasonably guessed were wrong: outside the US those keys carry an empty state segment, so London is London__GB with two underscores. That is now documented, and a key written the other way is corrected rather than silently returning nothing.

A search that finds nothing now says why. It used to answer "No job listings matched those filters" whichever of your filters was the problem. It now names the filter value that matched nothing, says how many listings the rest of your filters would have returned on their own, and lists the countries that do have listings right now. The query description also states plainly that it matches job titles and company names only — a place name typed into it was never used as a location filter, and used to return results from everywhere.


September 2026 (2026-09-22) — The rule-based classifiers get graded too

Every measurement this week was of the new judgment model; the rules it sits beneath had never been checked. A blind sample of what the rules wrote, keyed by hand, put the seniority rules at 96% and the department rules at 89%. Two families account for most of the seniority misses and are fixed: "Member of Technical Staff" is a plain engineer title and "Staff Pharmacist" is a clinician on staff, so neither carries the Staff rank any more (751 listings lose a wrong level). On the department side, a Design Engineer, an RFIC Layout Designer or a solar System Designer is an engineer, not a designer (114 listings move to Engineering). The rest of the department gap is recorded for a decision on which reader should win.


September 2026 (2026-09-22) — Twenty funding-round stages taken back, thirty-four duplicate companies folded together

Two clean-ups from reading data with a second pair of eyes. When a funding round arrives from an SEC filing it has a size and a date but no stage name, and since mid-September a press-page reader has been filling in "Series B" or "Seed" from the announcement. A re-read of every one of those 71 labels by a typed-judgment model, followed by a human reading of every disagreement, found twenty-two that the cited page never actually states — a "$150M in new funding" post filed as Growth, an "oversubscribed financing" as Series D, a stage copied from a startup-directory card, and one page about a different company with a longer name. All twenty-two are back to "Series Unknown", honestly, and the same three questions now gate every new label before it lands, so a stage has to be stated in the article's own words, about this company, on a page that is not a listing. Separately, 59 pairs of company records that shared a name but not a website were checked site by site: 34 were one company under two domains (Apollo, Blind, Gem, Gong, Front, Titan, Placer.ai, Carbyne, Rescale, Coalition, Mattermost among them) and are now one record each, with jobs, rounds and founders carried across; 25 that merely share a name — Revv the calibration company and Revv the event app, Onehouse the data platform and Onehouse the sofa maker — stay apart.


September 2026 (2026-09-22) — Manager, Director and Executive are levels now

The seniority filter on jobs had six rungs, all of them individual-contributor: intern through principal. A Manager, a Director or a VP had no level at all — and once every unlevelled title had been read, nearly one in four turned out to be exactly that. Three management rungs join the filter today: Manager (Manager, Senior Manager, Supervisor, a team lead over a function), Director (Director, Senior Director, Head of), Executive (VP, SVP, C-suite, President, General Manager). They are assigned by the same typed-judgment pass that fills the other levels, reading the title alone, and only when it is sure; on a hand-keyed sample the model had never seen, every management level it wrote was right. Relationship titles that merely contain the word — Account Manager, Customer Success Manager — stay unlevelled on purpose. The rule-based classifier also stops calling a "Senior Engineering Manager" senior: 3,931 such titles were re-read, and 17,111 listings carry one of the three new levels tonight. The pass now runs nightly, so a new listing gets its level within a day. The MCP search_jobs tool and REST GET /jobs accept the same nine values (docs v0.17.2), and the natural-language job search maps "management roles" onto them instead of onto a value nothing matched.


September 2026 (2026-09-21) — Job levels and departments where the rules gave up, at a cent a thousand

Every listing has a seniority level and a department when its title states one, and until now "states one" meant a regular expression recognised the word. It filed a Quality Inspector under People, a Head of Government Affairs under Sales, and left 80,000 titles with no level and 15,000 with no department because it would rather say nothing than guess. A second pass now asks a model that answers typed questions instead of writing text — TypeSafe's Jev — one title at a time, and writes an answer only when it is confident; on a sample of titles keyed by hand before the model ever saw them, every level and every department it wrote was right, and the whole backlog costs about three dollars. Across the whole backlog it filled 2,790 levels and 8,035 departments, and found that nearly one unlabelled title in four is a Manager, Director or VP — a rank the level filter does not yet offer. Separately, 1,482 pairs of companies that share a name but not a website were ranked for whether they are one company under two domains — 59 clearly are (Blind, Pie, Placer.ai, Front, Titan, and eleven that are the same website with and without www) and go to a review list, never merged by a machine. Two families of title turned out to fool the model however the instructions were worded — an "L2 Support" tier and a consultancy's "Principal Consultant" grade both read as seniority ranks — so 28 wrong levels were taken back out and both are now settled in code rather than asked about.


September 2026 (2026-09-21) — 93 US funding rounds from the first three weeks of September

The funding data caught up with the month. 93 rounds dated 1–21 September, $19B+ across them, are on the site, in the Funding Radar digest, and behind the MCP recent_funding_rounds tool — Crusoe's $3.9B Series F, Cognition's $2B Series E, The Boring Company's $3B, Stoke Space's $1B Series E, Positron AI, Harvey, Temporal, Forus, Medici's $250M on David, and eighty-odd smaller ones down to a $4M seed. Every round was verified against a primary source (the company's release, the wire, or the outlet that broke it) and dated from that source rather than the newsletter that mentioned it. Twelve companies are new to Employbl as a result, among them Celero Communications, Solstice Oncology, BrainChild Bio, Poseidon Aerospace, Lightfield, Aslan and Epsilon Health.


September 2026 (2026-09-21) — No weekly report when there is nothing to report

The Monday "how your profile performed" email no longer goes out for a week with zero profile views. Since the 17th every claimed company received one regardless, meant as a nudge — in practice it was a table of five zeros. A week with a view, a save, or a click still gets its report; a quiet week gets nothing.


September 2026 (2026-09-21) — A withheld story says so, and counts who asked

An unpaid company's story is still absent from every machine-readable surface, but absence used to be silence: an assistant reading MCP get_company, the REST detail, or the page's JSON-LD saw nothing and told its user nothing. Each now carries one sentence in Employbl's words — where signed-in members read the story, and how the company makes it public with Company Premium — never the company's own text. JSON-LD uses schema.org's paywall vocabulary (WebPage.isAccessibleForFree=false + hasPart), REST adds story_withheld {note, member_url, unlock_url}, MCP docs at v0.17.1. The locked panel on the company page also records a story_withheld_view event with the company and the referrer class (ChatGPT, Perplexity, Claude, Google, LinkedIn, …), so "how many people hit the locked part of your page, and from which assistants" is a number from today on.

September 2026 (2026-09-20) — One weekly email, not three

The Thursday feed digest is gone. It was one of three weekly emails leaving the same sender to overlapping people, alongside the Monday funding digest and the Saturday newsletter, and a week's worth of "new for you" belongs in the Saturday issue. Nothing else changes: the dashboard feed, job alerts and the funding digest keep running, and anyone who has opted out of email stays opted out.


September 2026 (2026-09-18) — The part you pay for is actually withheld now

Yesterday's change said a free claim's story reaches signed-in Employbl members rather than the open web. It was half true: the page blurred that section rather than withholding it, so the text was still sitting in the page source where any crawler could read it. Now it genuinely isn't there. An unpaid company's own words — what you build, your customers, case studies, culture and perks, your news, your own Q&A — are left out of the public page entirely and loaded only for signed-in members. Anonymous visitors see which sections exist and an invitation to sign in, never the content.

The same rule now covers every machine-readable copy of that content, not just the page: the structured data answer engines quote directly, the Employbl MCP server, and the public REST API. Two of those were leaking more than the page ever did — an unpaid company's highlights, FAQ, investor list and product description were being served to any AI assistant that asked. Company facts are unchanged and stay public everywhere: tagline, work model, hiring focus, team size, tech stack, and your ATS-verified open roles.

September 2026 (2026-09-17) — Free to claim, paid to reach the whole web

The 30-day company trial is gone, and with it the question no company could answer: what am I actually buying? A claim is free and never expires. Your facts — tagline, work model, hiring focus, team size, tech stack and your ATS-verified open roles — are on the public web either way, and generating your profile from your website is free too. What $99/mo buys is reach for the rest: everything you write about yourselves (what you build, your customers, case studies, culture and perks, your news, your own Q&A) renders for signed-in Employbl users on a free claim, and on the open web — in your own brand colours — when you pay. You own everything in both columns either way, and you keep it if you cancel.

Your dashboard now says this outright: a "who can see what you've written" panel lists every section of your page in two columns, one per audience, and marks the ones you haven't written yet. Profile generation moved to the free side — a company that can't fill its profile has nothing to buy reach for. AI-visibility analytics, the interested-candidate panel, intros and the MCP team seats stay with Premium. The company welcome emails are now clocked from the day you claim rather than a trial countdown, and there are three of them instead of five.


September 2026 (2026-09-16) — Search is free, company branding is not: the price now depends on when a company joins

The pricing page has one sentence on it now. Everything a candidate does — search every company and ATS-verified role, read full profiles, set alerts, save jobs, use the map and the AI assistant — is free, with no card and no expiry. Companies claim and publish their Employbl-maintained page free too. The one thing Employbl sells is Company Premium: the company's page in its own brand, with its product and features, customer outcome cards, photos, news and story, plus the dataset in Claude for the team. Its price is progressive and annual: the first 25 companies pay $67 for the year, companies 26–50 pay $199, 51–100 pay $399, and from company 101 the list price is $804/yr ($67 a month, billed annually). A company keeps the price it joined at for as long as it stays subscribed; cancel, and the branded page comes down and rejoining costs whatever the ladder says then. The current price and the spots left are live on /pricing, /for-companies, the homepage and the company dashboard, and every one of those re-renders the moment a company pays. Candidate Premium ($25/mo) is no longer offered to new accounts; existing subscribers keep it unchanged. Behind it: one Stripe price per tier found by lookup_key, a billing_tier stamp on premium_company_profiles that is the slot counter and is never cleared on churn, and a comped_at column for complimentary access (Octave is slot 1). The two STRIPE_COMPANY_*_PRICE_ID environment variables are retired.

September 2026 (2026-09-16) — The customer block survives a ten-site audit

Running the wall-logo resolver read-only across Supio, Descope, Arize AI, Harmonic Security, Sendoso, Cortex, Clay, Vanta, Ashby and Retool showed the other ways a "customers" section lies: captioned photos and testimonial headshots sharing a block with the logos ("A group of people posing for a picture", "CTO"), an investor wall whose class says logos and only its heading says "Backed by", the company's own logo, G2 badges, and a hundred-name customers page with no cap. Alt text now has to read like a name; a block whose heading says investors, press, awards or integrations is skipped; investors (the profile's, the extraction's, and the funding rounds') and the company itself are excluded outright; badge issuers never publish; the list caps at thirty. An image that was looked at and is not a logo offers the rep nothing, and a logo whose image and filename agree on a name is confirmed even when our table lacks the company (Thomson Reuters, AT&T).

September 2026 (2026-09-16) — A wall logo is named by what vouches for it, never by its filename

Octave's "trusted by" wall serves Supio's logo as supit.avif with no alt text, and the generator title-cased the filename and published "Supit". Image-only logos are now named in two steps before anything goes live: the page's own hints (filename stem, a link's host) and then the logo image itself, read by a small vision model, are each checked against the companies table, and only a name the table carries is published, in the table's spelling ("Sauce Labs", "DISQO", "Arize AI"). A name nothing vouches for is parked in a new "logos we could not match" strip in the company editor, where the rep adds it as a customer or dismisses it. Two Octave logos with a generic Frame.svg filename, unreadable before, now resolve to the companies they show. unconfirmed_customers on premium_company_profiles; sharp is a declared dependency for the worker's rasterising.

September 2026 (2026-09-15) — A customer is who the company's site says it is

The profile generator was listing companies that merely appeared on a website as its customers — a customer's own customers named inside a case study, example accounts in a demo, integration partners. Octave's page briefly claimed Mercury, Perplexity, Databricks and Navan. Now a name counts only when the site vouches for it: its "trusted by" logo wall, its customers page, or a case study about that company. Integrations are never customers, and regenerating a profile replaces the list instead of adding to it, so a wrong name cannot outlive the crawl that produced it. "Backed by" reads the investors on the company's funding rounds when the profile has none of its own.

September 2026 (2026-09-15) — Free means free: the "7 days" is gone from every signup surface

The free account has had no expiry since August, but five pages still promised "email alerts and API keys free for your first 7 days" — a countdown to something that no longer counts down. Copy corrected on the register page, the homepage pricing card, the pricing page, the verify-email wall and the jobs banner. Subscription checkout no longer attaches a seven-day Stripe trial either: a card entered today buys access today. The 30-day trial that starts when a company first claims its profile is unchanged. Also fixed: a failed Stripe webhook write used to be acknowledged as handled, so Stripe never retried it; it now retries.

September 2026 (2026-09-15) — Claimed company pages get products, case studies, photos, news and a company story

A claimed company's page now wears the company's own colours: the brand band under the masthead is read from the company's website — its background, its logo, its social-card image as the hero — and its accent colour marks the section labels. The profile is structured the way the company's own site is: one product with its named features (not five invented "products"), what developers can build on, what it integrates with. Customer stories are outcome cards — the headline number, the customer, one attributed quote — pulled from each story page on the site. All of it is drafted from the site without a crawler credit, and the company signs off: edit, delete, add. A claimed company can now fill the part of its page no dataset has. Products — what you sell, as you name it, first product leading. Case studies — named customer stories; when the customer is a company on Employbl, its chip links to their page. Photos — a hero image that replaces the website screenshot under the masthead, plus a gallery of product screenshots and team photos. In the news — press links, merged automatically with the announcement pages already attached to the company's funding rounds, newest first. And the story fields a candidate reads first — the one-liner, why join now, who the team is, how the interview process works — which the profile generator now drafts from the company's own site and the company then edits. A Q&A block is the company's own — questions and answers written by them, never generated — published as FAQ structured data, and the products as a Product list, so answer engines can quote both. Products, case studies, photos and news show while the company is on its trial or subscribed; the rest of the profile stays live either way. Also: two FAQ blocks that had been saved in an older format never rendered; they do now.

September 2026 (2026-09-15) — "AI companies" now finds AI companies in chat, MCP and the API

Asking Employbl AI for "Series B AI companies in SF hiring senior engineers" returned no companies and a fallback list of individual jobs — the index has 23. The assistant filtered on industry: ["AI"], a legacy Diffbot tag that nothing carries; the curated sector filter ("AI & Machine Learning") was missing from the chat tools, declared on the wrong MCP tool since July, and silently ignored on job search. sector now works on find_companies and search_jobs (chat, MCP v0.16.1, and REST GET /jobs), the tools list every sector and subsector so an assistant cannot misspell one, and shorthand in either parameter — AI, fintech, devtools, climate, healthtech and the rest — is mapped to the sector instead of returning nothing.

The same vocabulary gap was hiding in recommendations. Onboarding stores an industry preference as a legacy Diffbot slug (artificial-intelligence-software), and the recommended-jobs search, recommended-companies search and the onboarding "jobs for you" email filtered the index on that slug, which matches nothing — so every candidate who picked an industry (189 accounts, 178 of them from the last month) got no recommendations at all. The preference now filters on the curated sector it maps to; the same San Francisco + AI preference goes from 0 matching jobs to 4,600.

September 2026 (2026-09-14) — Five more job boards we can read: Breezy, JazzHR, SmartRecruiters, Recruitee, Workday

The review of recently funded companies found 2,125 private companies with a round in the last year and no jobs on Employbl. For 450 of them we already knew where their jobs were — a Breezy, JazzHR, SmartRecruiters, Recruitee or Workday careers site — and had no way to read it. All five are supported now, with the full description, location, remote status and posting date for each role. First pass: 180 boards and 3,677 listings from the first four; Workday — the system most larger companies run (Axiom Space, Verily, Devoted Health, X-energy, Genesys) — attaching now. Companies that looked like they weren't hiring show their openings as the syncs land.

September 2026 (2026-09-14) — 207 more duplicate rounds folded; 20 funded companies get their URL back

The 12-month funding pull found a second class of twin: the same raise under the same stage name a day apart — Fish Audio's $52M seed on Jul 27 and Jul 28, Paper's $34M Series A, Fluxco's $26M seed, and 195 more across the archive. Most came from one company merge on Aug 25 that matched rounds on the exact date, when Diffbot's date and the announcement's differ by a day. The nightly reconcile now folds those too (amounts within 10%, dates within 45 days, never for grants, debt or post-IPO instruments a company genuinely repeats), the merge does the same at merge time, and Anthropic's two "Corporate Round" copies of its Series H tranches are gone — the company's 12-month total reads $108B, not $123B. The same merge had kept the discovery slug (fish-audio-924000) and retired the plain one; 20 companies are back on /companies/fish-audio, /companies/sent, /companies/bidbus and the rest, and merges now keep the linkable slug.

September 2026 (2026-09-14) — 475 duplicate funding rounds folded

Diffbot sometimes delivers one raise twice — a "Series B $1B" and a "Series Unknown $1B" on the same day. The nightly reconcile now folds those (475 on the first pass), so a company page and the /funding-rounds search show each raise once, under its stage name. Investor lists on ~2,000 older rounds were also brought onto the current data shape so nothing appended to them can hide them again.

September 2026 (2026-09-13) — Stage names on the biggest rounds; 3,400 companies get their city back

A review of the last 12 months of funding data (4,166 rounds, 3,547 companies) found two gaps and closed them. City: 1,470 recently funded companies — every company created through the Diffbot import since June — had a headquarters on file but no city on the company row, so they were missing from the /funding-rounds city filter and from every city sweep; backfilled (3,403 companies) and the importer fixed. Stage names: Diffbot delivers 1,246 rounds from the last two years as "Series Unknown", OpenAI's $122B and Waymo's $16B among them. The press labeler that names SEC filings now runs on those too, largest first, with the same guards and a new one: "Growth" is accepted only when the announcement actually says so. Two rounds Diffbot had hung on the wrong company (Project Prometheus's $6.2B and $12B on a San Jose namesake; PayPal's entire history on Braintree) are retracted from the wrong row and cited on the right one.

September 2026 (2026-09-12) — Funding rounds from SEC filings, corpus-wide, with the source on every round

  • ~500 funding rounds added from primary sources in two days. Every US company raising equity files a Form D with the SEC within days of the first sale. Employbl now reads those filings — the SEC's quarterly datasets for the last two years, matched against every company in the index, plus a weekly scan of new filings — and adds the round with the filing itself as the source. Rounds no other database had: Qualia $50M (Aug 2026), Rightway Healthcare $155M, Alzheon $500M, Teal Health $23M, Grammarly $348M, Databricks $666M, and 300+ more. A filing carries the money and the date but not the stage; where the company's announcement names it ("Series C"), that label is attached with a link to the announcement.
  • Every round says where it came from. Under each round on a company page: SEC Form D linking to the EDGAR filing, Announcement · qualia.com linking to the press release, or Diffbot knowledge graph. The same citation travels with the round through the MCP get_company tool, so an AI assistant can cite the filing rather than assert the number.
  • Namesakes stay out. A filing is attached only when the issuer's legal name is one the company is known by, in the same city — with the street address, founding year, round-size history and one-issuer-one-company checks behind it. The rules were built from 40 retractions over two evenings; all 40 were namesakes.
  • Company-page stat values wrap on phones instead of pushing the page sideways.

September 2026 (2026-09-11) — A claimed company can correct its own facts, and every number says who reported it

  • Companies that claim their profile can now correct headcount, founding year, funding rounds, and upload their logo. Until now those were "maintained by Employbl" and the only way to fix a wrong one was to email support — which is exactly what the first rep to claim this week did, with three corrections. Each is edited from the company dashboard (headcount and founding year also through the update_company_profile MCP tool). Rounds can be corrected, removed, or added with a link to the public announcement.
  • What candidates see says who said it. A headcount or round the company entered is labeled company-reported next to the value; one Employbl checked against a filing or announcement is labeled verified; a figure from public data sources shows as before. The point of locking these fields was that candidates could trust them — the label is that trust made visible instead of enforced by a lock.
  • Employbl's own data pipelines no longer put the old value back. Every value now records who asserted it, and the nightly refreshes (knowledge graph, website crawl, logo sweep, funding imports) leave anything a company or Employbl support entered alone — including after a round is corrected, which previously would have been re-imported as a second copy.
  • Placeholder logos are detected. A company whose stored "logo" was the generic favicon fallback (a 700-byte gradient square — Maven Bio's for months) is now treated as having no logo, and the real one is fetched or can be uploaded.
  • Every correction is logged — who, what, from what, to what, and the source link they gave — and posted to the ops channel.

September 2026 (2026-09-11) — A claimed company gets a full profile on its own

  • A claimed company's recent funding round is looked up on the open web, not just in the knowledge graph. Maven Bio's $3.1M seed (April 2025) was on Crunchbase and the CEO's own announcement and missing from Employbl for five months, because the bulk data source never picked it up. Claiming a company now also searches announcements for it, extracts the round from the primary source, and adds it with a link to that source — with checks that the announcement is about this company (same website or HQ, a stage that makes sense after the rounds already held) so a namesake's raise cannot land on the wrong page.
  • Claiming a company now fills its page automatically. When a team member claims or creates their company, Employbl immediately looks up what is publicly known about it — description, headquarters, headcount, founding year, social links, funding rounds — fetches the logo, classifies the industry, drafts and publishes the profile narrative from the company's own website, and starts looking for its jobs board. Previously most of that only happened if the rep finished an optional setup quiz in the browser; a rep who skipped it left a page with a name, a link and nothing else, which is also what AI assistants were shown when asked about the company.
  • Email links carry attribution. Links in Employbl's emails (job alerts, funding digest, onboarding) now identify which email they came from, so a visit from an email is counted as such. No open-tracking pixels — clicks only.

September 2026 (2026-09-11) — Company and job pages stop timing out under load

  • Fewer blank errors on company and job pages. A page nobody had visited since the last deploy was rendered from cold, and when several arrived at once the server ran out of its 10-second budget and returned a timeout, about 130 an hour on the worst day. The functions that render those pages now get a full CPU and 15 seconds, and no longer load a 10 MB brand-icon library and a map renderer they never used on the server. The pages themselves are unchanged.

September 2026 (2026-09-11) — 558 companies show their real website, 181 show their real name

  • Companies that rebranded or moved now point at their real site. Rocket Lab, TripActions (now Navan), Cerebras, IonQ, Cognition, Repl.it (now Replit), ColdQuanta (now Infleqtion), Lambda, and 550 more were still linked under a domain that now redirects somewhere else — a stale link on the company page and a wrong answer for anyone asking an AI assistant what the company's website is. Every one was re-checked against two independent sources before the change; acquisitions and unrelated domains that happened to be reused were left alone. Company records that turned out to be the same business under two names were merged.

September 2026 (2026-09-10) — Every listing records when its employer's ATS last confirmed it, and a weekly accuracy check

  • Every job listing now carries the date its employer's applicant-tracking system last confirmed it. The nightly sync stamps every role it sees on the board; a role the ATS stops listing is retired the same night, and the gap between the two is now measurable rather than assumed. Every board also records when it was last synced, whether that succeeded, and how many roles it held.
  • A weekly blind accuracy check. Each Sunday a random sample of 100 live listings is re-fetched from the ATS and graded: still listed, gone, board gone, or could not be verified. The share confirmed live is recorded with a date and will be published once a few weeks of readings exist; anything under 98% is treated as a sync bug to fix, not a fact about the data.
  • Roles attributed to the wrong company are gone. An ATS board belongs to exactly one employer, but 72 boards were attached to more than one company that shared a name — six companies called Beam all showed the same Greenhouse jobs. Every group was checked against the board itself and each company's own site: 151 attachments retired and 9,937 borrowed listings taken down. Most of those boards belonged to a company we did not list at all (a UK healthcare staffing firm's 2,650 roles were showing on three unrelated companies called Pulse).
  • Duplicate live listings can no longer be created. 443 twin rows (the same role inserted twice by two syncs running at once) were removed and a database rule now refuses a second live copy.
  • Funding rounds record where they came from. Rounds read from the Diffbot knowledge graph now carry the source, the entity they were read from, when it was fetched, and the investors it listed. Rounds imported from newsletters already carried an announcement link.
  • Company pages are faster to look up. The database had no index on the company slug, so every company page render scanned all 31,000 rows. Two other declared-but-missing indexes were added and a column and table left over from a retired login system were removed.
  • Your profile's work history, education and projects can only be edited or deleted by you. The per-row update and delete routes checked that you were signed in but not that the row was yours, and a row that no longer existed came back as a server error. Both now answer "not found" unless the row belongs to the caller.
  • Every funding round now says where it came from. 72,033 rounds read from the Diffbot knowledge graph carry the entity and fetch date they were read from; the 224 imported from newsletters already carried the announcement. The latest-rounds page (/funding-rounds/latest) now lists only rounds with a primary-source announcement attached, so its "verified" claim is structural rather than incidental.
  • Four funding-round facts reconciled against the companies' own announcements. ElevenLabs' Series C and Vanta's Series D take the dates on the companies' posts (each was a day early); Waymo's $16B round loses the "Series D" label Waymo never used; Verkada's $41.2M stands because it is exactly the amount on the company's amended SEC Form D.

September 2026 (2026-09-09) — Your feed stops recommending the wrong kind of work

  • "New at a company you watch" now respects what you do. The feed used to surface every new role at a watched company — a program-manager and a sales role for an engineer who watches OpenAI. Roles at watched companies now have to fit your stated role, by the listing's department or its title, the same rule the ranked feed has used since early September.
  • "Wrong role" thumbs-downs teach the feed. Pass on a job with that reason and roles in the same department are pushed down for 30 days. Your own stated roles are never demoted, so one bad engineering posting cannot sink an engineer's feed.
  • Job pages use the same header as every other page: kicker, title, company and location on one line, logo at the right. The centred layout with the oversized logo tile is gone.

September 2026 (2026-09-09) — Every job filter on the page, a real location filter, and faster collection pages

  • Job search filters are all on the page now. The "All filters" drawer is gone. Quick chips (Remote, Level, Funding stage, Salary, Posted, Role type) sit on the first row; below them Location, Industries, Tech stack, Investors, Company size and "only companies I watch" are always visible, with a one-line note on what each one does. Clear all filters in one click.
  • Location was the filter nobody could find. It existed only inside the drawer. It is now the first control in the panel: pick one or more cities and see roles based there. Pair it with the Remote chip only if you want remote roles anchored in that city.
  • Two filters that silently did nothing now work: a state in the URL was parsed by the server but never sent by the page, and the Remote chip did not recognise the value saved searches from the old drawer carry.
  • Collection and city pages are fast and sit inside the app for members. /company-collections, each collection and each city page ran several slow steps back to back, then re-fetched their own first page the moment they loaded — that spinner every visitor saw is gone, and a cold page builds in a fraction of the time. Signed-in members get the same three-column layout as the dashboard on all of them.

September 2026 (2026-09-09) — A funding feed anyone can read, and a badge for your careers page

  • Recent funding rounds is now public. Every verified US round from the last 30 days — amount, stage, investors, and the lead where the announcement named one — with each company's live open-role count beside it. No account, no email, no wall. The full searchable archive still lives on the members' page.
  • It says what it is current through, and it lists only rounds we have verified against a primary source. Rounds raised in another currency are left out rather than converted at a rate we cannot date, and a company we have no job feed for reads "no openings tracked" — a statement about our coverage, not about their hiring.
  • Claimed companies get an embeddable badge. A one-line snippet on your dashboard puts your live open-role count on your own careers page; it updates itself from your applicant tracking system and links back to your profile. It never renders "0 open roles" — when the feed is quiet it just says the profile is live.
  • "Total raised" on a company page now moves when a new round is imported. Wafer showed $800,000 above a $40M Series A for a week: the newsletter importer refreshed the latest round but not the running total. Nineteen companies were off the same way, and 45 others had no total at all despite having priced rounds; all 64 are corrected, and the importer now raises the total itself. It only ever raises — where a company-level source knows rounds we do not, the larger figure stands.
  • Thumbs-down has a "Wrong role" reason. The five choices were location, remote, seniority, pay and "just not interested"; a program-manager listing recommended to an engineer fit none of them. The same role category works through the MCP rate_job and dismiss_job tools.
  • Newly funded companies get a logo the moment they are added. Companies created from a funding announcement showed an "image coming soon" placeholder on the newsfeed and every card until someone ran a manual sweep; Onos Health sat that way for a week. The importer now fetches the logo as it creates the row, and the backlog has been swept.
  • Company, job and profile pages keep the dashboard around you when you are signed in. Clicking a company or role from your feed used to land on the public marketing page: top nav, footer, no way back to your desk. Signed-in members now get the same three-column layout as the dashboard on company profiles (with the MCP card, your shortcuts and the collection browser in the right rail), and the app sidebar on job listings, the public funding feed and profiles. Anonymous visitors see the pages exactly as before.
  • Companies without a logo no longer show a broken image on their profile page. The image was rendering as a broken icon with alt text for every company that had none; it now falls back to the website favicon, then to nothing.
  • The cream is gone. Every page, panel and section that sat on the warm paper tint is now plain white with hairline rules, the paper-grain texture is retired, and the one remaining tint is a hue-less near-white on hover. White and simple.
  • "Open roles" on a company page is the real count. It was counting a 25-row preview, so any company with more than 25 openings showed exactly 25 — 808 companies, including Brain at 33. The page also refreshes itself now whenever a nightly sync adds or removes that company's listings, instead of waiting for the next deploy.

September 2026 (2026-09-08) — Signing up with Google puts you on the weekly, with a visible way off

  • Google sign-ups are now subscribed to the weekly roundup by default, the same as the sign-up form's checked-by-default box. Three quarters of new accounts arrive through Google, and that path never asked, so most people who signed up never heard from us again.
  • The box is always visible. On the welcome screen, the career-quiz wrap-up and the dashboard preferences card, pre-set to your current answer. Untick it and you are off the list and removed from our mailing provider, not just muted. The unsubscribe link in every email works too.
  • Accounts we never asked were added the same evening: 166 verified accounts from the last 90 days, no welcome email. If that is not for you, one click on any of the three screens or in any email.

September 2026 (2026-09-08) — Search, tightened: suggestions, honest empty states, one industry list, investors you can type

  • Both search boxes suggest as you type. Job titles with the company, or company names with a tagline, from the live index, and a "did you mean" line when the term looks like a typo. Picking one searches it.
  • "No results" now says which filter to drop. Each active filter gets a row with the count you would get without it — "Remove Level: Senior → 1,204 roles". On both pages.
  • The Funding stage chip on jobs works. It had written a parameter the page never sent; 72 uses last month filtered nothing.
  • Salary filter says what it hides. Only about 12% of listings state pay. The chip now prints the share for your current search instead of silently dropping the rest.
  • Listing age is visible. A "90+ days old" mark on job cards for postings we first saw more than three months ago — 13.5% of active listings — and an "Older than 90 days" option under Posted so you can look at exactly those. We say no ghost jobs; now you can check.
  • Role type filter on jobs. Forward deployed, applied AI, solutions engineering and founding roles, read from the title. The facet no other job board carries.
  • Investors are typed, not picked from a list of 62. Any of the ~38,000 investors on a tracked funding round, on both jobs and companies, with the number of companies each one backs.
  • Jobs and companies share one industry list. The jobs drawer used a 2023 tag list; it now uses the same sectors and subsectors the companies page does, so "Fintech" means the same thing in both places.
  • Shared jobs links no longer carry your account id. Every filter click on jobs had been writing internal session values into the address bar.
  • Two pieces of dead search code removed; option lists on companies now hide values with no indexed company.

September 2026 (2026-09-08) — Four company filters came back, and the map is the same search

  • Company HQ Location, Investment Stage, Venture Capital Firms and Company Collections are back on the companies page. They disappeared for every signed-in user on 2 September, when the service that supplied their option lists was retired without anyone noticing the page still asked it. Anonymous visitors kept seeing them, from a snapshot dated 2023. The lists now come from our own database and refresh hourly. Reported by Connor on 8 September; six days out.
  • The map is now a view of the companies search, not a separate page. Toggle between list and map without losing the search bar, the sidebar or a single filter. Every filter applies to both — industry, tech stack, HQ city, stage, investor, collection, hiring status, public-only, founded-after, and the keyword. Before, the map had its own four filters and ignored the rest; a metro shortcut also wiped whatever you had set. The old map link redirects here.
  • Founded after is a filter on both views. It used to exist only on the map.
  • Keyword on the map plots the best 2,000 matches and says so; the list still paginates all of them.
  • We check every option now. The audit that runs before releases walks every value each filter offers through the real search, and now through the map too, and flags any that return nothing. It is how a missing option list will be caught next time.

September 2026 (2026-09-07) — Take Employbl with you

  • Found a job here from ChatGPT? You can take Employbl back with you. If you arrived from an AI assistant, the job page and your dashboard now show how to connect Employbl to it — ChatGPT, Claude or Cursor — so your assistant can search every live role, company and funding round for you, not just the one you landed on. Three suggested questions about that job are right there to copy.
  • Connecting is documented for every client, step by step. The docs' first section is now a per-client guide: ChatGPT, Claude (claude.ai and Desktop), Claude Code, Cursor, VS Code, Codex CLI, Gemini CLI, Windsurf, and anything else that speaks MCP. One-click links for Cursor and VS Code; exact config files for the rest. Sign in with your Employbl account when the client asks — no token to paste. The first 100 calls are free.

September 2026 (2026-09-07) — The industry filter works again

  • Filtering companies by industry returned 0 results for most industries. Pick "AI & Machine Learning" on the companies page and the count read 0, against 1,953 companies actually tagged with it. Any industry with an "&" in its name — 13 of 17 sectors, 40 of 58 subsectors — did the same. A candidate wrote in on 7 September: "How are there 0 startups with an industry filter for AI?"
  • The cause was the "&" itself. The filter value was sent to the search API without being URL-encoded, so the ampersand split "AI & Machine Learning" into two meaningless parameters. The search index was fine the whole time; the question just never arrived intact.
  • Same fix covers the search box and the funding-rounds page. A free-text query containing "&", "+" or "#" ("R&D", "C++", "C#") was mangled the same way, and the industry filter on funding rounds shared the code. All of it is now encoded on the way out, with a test that round-trips those characters.
  • The jobs page had the same bug in its own code. Filtering jobs by tech stack for "C#" or "C++" returned nothing — "#" starts a URL fragment and "+" turns into a space. Both work now.
  • Three "Sort by" options on the companies page did nothing. Recently founded, Most raised and Least raised fell back to the default order. They sort now (the index needs one rebuild first; until then they keep falling back rather than erroring).
  • Two companies filters did nothing. "Public companies only" and "Company Collections" (Has Woman Founder, 4 Day Work Week, the city Startups-to-Watch lists) returned the full, unfiltered list. Both are wired to the index now, effective on the same rebuild.
  • How we found the rest. We wrote a check that pushes every option every filter offers through the real search path and reports the ones that come back empty or unchanged. That is what turned up the dead sorts and the dead checkboxes, and it runs before releases from now on.

September 2026 (2026-09-05) — You can delete your account

  • There is now a way to delete your account, and it deletes the data too. Profile page, bottom of the page: it removes your profile, saved jobs and searches, résumé file, job alerts, feedback, API tokens and email history. Type your own email address to confirm — not a password, because most accounts sign in with Google and don't have one.
  • We added this because someone asked and we had no answer. A candidate wrote in on 5 September: "Your website doesn't let me delete my account or even change my name." Both halves were true. The name half was a bug, fixed the same day.
  • Billing records stay, without you attached to them. The subscription row survives so the books still balance, with your user id and email cleared from it. Everything that identifies you is gone.
  • The newsletter goes too. Signing up subscribes you to it, so deleting the account removes you from the mailing list in the same step — no more "I deleted my account and you still email me".

September 2026 (2026-09-07) — Tell us where you actually are

  • You can now say where you live, and it can be anywhere. Onboarding asked one location question — "where do you want to work" — against a fixed list of nine US metros plus Remote. If you lived in Mumbai, Toronto or Boise, there was no way to say so: the closest available answer was "Remote". Onboarding now asks two separate questions, and both search all 150,890 cities in 194 countries.
  • "Where do you want to work" is no longer nine cities. Same typeahead, as many cities as you like, Remote still one click. Existing selections are untouched.
  • Your city now reaches the parts of the product that use it. Anything outside those nine metros used to be discarded on the way to job matching — so a stated location outside them had no effect on your recommendations. It does now, including through the Claude/MCP update_preferences tool, which previously rejected any city it didn't recognise.

September 2026 (2026-09-05) — Job alerts are free

  • Email alerts on your saved searches now cost nothing. Save a search, switch it to daily or weekly, and new matching roles come to you. This was the flagship paid feature; it is now the flagship free one. Premium is machine access: unlimited MCP + REST API calls past the free 100, the full weekly funding digest, and uncapped AI chat.
  • Why we changed it. Most people who find Employbl arrive from an AI assistant, land on one specific job, and — if that job isn't right — never come back. An email when a role like it opens is the only thing that reaches them, so putting it behind a subscription meant almost nobody ever got one.
  • Alerts now work for any job, not just seven kinds of job. The alert we offer at signup only understood engineering, product, data, design, marketing, sales and operations. If you arrived for a nursing, accounting, audit or assistant role, you were offered nothing at all. It now reads the role from the job title itself.
  • And they follow the job you arrived on, however you signed up. The offer used to depend on a link parameter that signing up through Google, or from the nav, quietly dropped — so most people who came for a specific job never got the alert for it.
  • A bug that came with it: switching on the alert during signup used to quietly cancel the whole onboarding email sequence, including the "here are your actual matches" email sent the next day. Everyone who turned on an alert got none of them. Fixed — and the mechanism that caused it is gone rather than patched.

September 2026 (2026-09-06) — Your week, in your inbox

  • A weekly email of your feed, every Thursday morning. The same thing your dashboard shows — funding rounds at companies you follow, roles that match you and why, new openings at companies you watch, companies worth a look — with one rule: it never repeats what you have already seen. Anything that was on your dashboard, or in last week's email, is left out. If there isn't enough genuinely new to fill it, we don't send it.
  • One feed instead of two. The "For You" tab on the jobs page was a second, thinner version of the same recommendations, ranked differently. It's gone; the link now takes you to your dashboard feed, which shows the funding rounds and companies the tab never did.
  • Rating things in the feed changes next week's email, not just the next page load.

September 2026 (2026-09-05) — Your dashboard is now a feed, and Claude gets 100 calls on us

  • The dashboard is a feed. One column, newest first: funding rounds that match your preferences ("Onos Health raised $17M — Series A · a stage you follow · 6 open roles"), the roles that match you and why, companies you may like, and new roles at companies you watch. Every item takes a thumbs up, a thumbs down (it asks why), a save, or a hide — and the feed learns from all of it: a thumbs-down on a company demotes its jobs too, saving a round watches the company so its next openings show up under "Hiring now". "Show me more" never repeats what you've seen; "Refresh with new picks" starts over with the last week excluded and says so honestly when there's nothing left.
  • Connect Claude for free. Any verified account can now add the Employbl MCP server to Claude Code, Claude Desktop, Cursor or any MCP client and make 100 tool calls — no subscription. The tools that tune your recommendations (profile, preferences, rating and hiding jobs, saved searches) never count and keep working after the 100. Premium is unlimited. The dashboard card shows how many calls you've used and the last thing your assistant asked. The same allowance applies to the REST API.
  • Job recommendations stopped timing out for people with strong profiles. The matching query evaluated one regular expression per skill on your resume for every open role; past ~20 skills Postgres recompiled them on every row and the request took over a minute — precisely for the accounts with the most to match. It now compiles one pattern per signal and runs in well under a second.
  • Housekeeping: the quiz's "where are you in your search" answer is kept with your preferences instead of dropped; signed-in company profile views are remembered so "companies you researched" can become a feed section; the MCP server is v0.14.0.

September 2026 (2026-09-04e) — We can now read BambooHR job boards

  • BambooHR is a supported ATS. We had already spotted a BambooHR careers page at 157 companies — most of them linked from the company's own site — and had no way to read it, so those companies looked like they weren't hiring. We can now sync them, with the full job description, location and remote status for each role. Their openings appear as the boards get attached.
  • Remote BambooHR roles are labelled remote. BambooHR states remote as a setting rather than in the location text, and a remote role's location field is usually blank with the hiring region recorded separately — so reading the location alone would have labelled these roles wrong, or dropped their city entirely.
  • Behind the scenes: two fixes to how we spot boards in the first place, both of which help every ATS that puts the company name in a subdomain. We no longer mistake an ATS vendor's own image and marketing hosts (or its shared demo account) for a company's board, and we now read a board link correctly when a page has stored it in escaped form.

September 2026 (2026-09-04d) — Your recommendations now read the whole job posting

  • Job recommendations match on the technologies in the posting, not just the words in the title. Until now, "Jobs For You" compared your skills against job titles only — so a backend role built entirely on Go and Postgres, titled "Backend Engineer", carried no skill signal at all. We already extract the technologies from every job description; the feed now uses them. On a test profile that took the pool of roles with a real skill match from a few hundred to more than twenty thousand.
  • Skills from your resume now actually connect to the dataset. A bug meant a skill saved from your resume was stored as a brand-new entry rather than linked to the technology we tag jobs with — the "TypeScript" on your profile was a different record from the "TypeScript" on every TypeScript job. Nothing you listed could be matched. Every profile has been repaired, and the skills you add from here on resolve properly.
  • We understand how resumes actually phrase things. "Data Analysis with Pandas", "Pandas DataFrames" and "Data Wrangling with Pandas" are now all recognised as pandas, instead of three unrelated entries that matched nothing. Same for "TailwindCSS" (Tailwind CSS) and "OpenAI APIs".
  • The "why this matched" chips tell the truth. They now name the technologies the score actually used — including ones found in the posting body — instead of only the ones that happened to appear in the title.
  • Also live from the same release: every correction from the tech-stack audit below is now visible on company profiles and /tech-stacks/ pages. Those pages are cached until a deploy, so the fixes landed in our data first and reach you now.

September 2026 (2026-09-03) — Tech stacks got a lot more honest

  • We audited every technology we claim a company uses, and threw out the bad ones. Eight entries in our taxonomy carried short nicknames that collide with ordinary English: the abbreviation for reStructuredText is "reST", which was quietly matching every job description that said "REST API" — or just the word "rest". It was the 9th most common technology in our entire dataset, and out of 5,770 job postings tagged with it, exactly one actually mentioned it. Also removed: "CS" matching "BS in CS", "GA" matching "Atlanta, GA", "Lambda" matching lambda expressions, "CDC" matching the health agency, and "Fabric" matching, well, fabric.
  • Real technologies stopped being thrown away. A rule meant to filter out office tools ("we chat on Slack") was also catching languages whose names are ordinary words — Go, Rust, Ruby, React, Swift, Spark. If a posting mentioned one of them only once, we discarded it. That hid genuine stack information on 63–76% of those mentions, across company profiles, the job Tech Stack filter, and every /tech-stacks/ page. Slack and Greenhouse still get filtered; Go and React no longer do.
  • Every one of the 104,869 open roles was re-scanned against the corrected taxonomy, and all company tech stacks rebuilt from the results. If a company profile showed you something odd before, it should be gone now.
  • Behind the scenes: our extraction pipeline could previously only ever add technologies to a listing, never correct or remove one — so every earlier attempt to fix the taxonomy had no effect on existing data. That's fixed, and there's now a quality-measurement tool so we catch this class of error by measuring instead of by noticing.

September 2026 (2026-09-04c) — Recommendations that respect your role, and a cleaner app

  • Job recommendations now require role fit. Watching a company no longer puts its finance or legal openings in an engineer's "Jobs For You" — when you've told us what you do, every recommendation has to look like that work (by role, your skills, or your saved-search keywords). Company affinity now orders results within your field instead of overriding it, and the "Strong match" label is earned against a fixed bar, not just "best of this batch."
  • Company names are back on company search. A layout bug had been rendering search cards with the name invisible; fixed.
  • The dashboard leads with the MCP server. The install command for connecting Claude (or any MCP client) to Employbl now sits at the top of your dashboard; the stat-tile board that mostly showed zeros is gone, and the application tracker moved down the sidebar.
  • Job search page is tighter — removed the dead space between the tabs, the search bar, and the results.
  • The company claim setup's proof screen now sells honestly: companies with real traction see their own live numbers, everyone else sees Employbl's sitewide AI-referral traffic — never a row of zeros.

September 2026 (2026-09-04b) — Claiming your company is now a guided setup

  • New company claims go through a short guided setup — one question per screen: what you want Employbl to do for you first, how the team works, what you're hiring for, the stack, team size, where you post roles. Every answer lands on your public profile as you go, and the interstitials show your company's real numbers: profile views, AI-assistant referrals, and how often you already appear in AI answers.
  • It ends with your profile actually live. The final screen runs the real one-click profile generation — the checklist advances when the crawl and the publish actually happen, not on a timer — and your quiz answers are never overwritten by the generated draft: what you typed wins, what we extracted fills the gaps.
  • Skippable, and never asked twice. Skip on the first screen and you land on your dashboard; the profile-completion checklist there remains the way back in. Existing claimed companies are unaffected.
  • The claim funnel is also properly measured now — from the first sign-in click through claim, setup, and dashboard.

September 2026 (2026-09-04) — The quiz is now the onboarding

  • Every new account now gets the career quiz. Sign up without any context — no job page, no company page — and instead of a one-screen preference form, your first screen is the same quiz that runs at /start: one question at a time, real dataset proof between steps, and a live count of the roles and companies that match you before your dashboard loads. Skippable, and never shown twice.
  • Signups that already told us something keep their shortcut. Create an account from a job page and your preferences are still pre-filled from that job — eleven questions would be a step backward when we already know what you were reading.
  • Your LinkedIn URL now improves your matches the moment you add it. Adding it during onboarding (or later, from your profile) triggers a profile-enrichment pass that used to run only once, before the URL existed.

September 2026 (2026-09-03) — The 60-second career quiz

  • New: a career quiz at /start. Answer a few quick questions — what you do, your level, industries, cities, salary floor, company stage — and we run a live search over the dataset and tell you exactly how many open roles and hiring companies match you, before you create an account. The count is real, computed the moment you finish: no fake progress bars.
  • Your answers carry over. Create a free account at the end and your preferences are already set — the dashboard, job recommendations, and funding radar are tuned from minute one. No re-answering the same questions.
  • Optional resume and LinkedIn step. Right after signup you can drop in a resume (we parse it into your profile) or your LinkedIn URL — both optional, both make matches sharper.
  • Preferences also gained Management as a level and $50k+/$75k+ salary floors.

September 2026 (2026-09-03) — Search by any investor, click any investor

  • Filter companies and jobs by any of ~38,000 investors — not just the few dozen big-name funds. The investor filter previously recognized only a curated tag list; it now draws from our per-round funding records, so "companies backed by Bonfire Ventures" works the same as "backed by Sequoia". The AI-assistant tools accept the same names.

  • Every investor name is now a link. Click an investor on any funding card — company page or job page — and land on the company search pre-filtered to their portfolio. Trust an investor's judgment? Browse every company they've backed that we track, and who's hiring.

  • Investor data now keeps itself fresh. New funding rounds arriving through our bulk pipeline get their investor lists attached automatically every night from data we already hold — no manual runs, no external API costs. (This closes the gap that had left a third of rounds showing no investors.)

  • Funding rounds now list their investors — on company profiles, and newly on job pages too. The company page showed investors only for rounds imported through our oldest pipeline; recently imported rounds silently showed none. All eras of the data now render, and the funding card on every job page gained the same investor line — so "Series A · $17M · led by Foo Ventures" reads at a glance while you're looking at a role.

  • Lead investors, recorded from here on. As new rounds come in, we capture who led — taken only from the announcement's own words ("led by"), never guessed from ordering. Leads show with a small "(lead)" marker and will accumulate into a dataset almost nobody publishes for job seekers: which investors actually lead rounds, at which stages.

  • The AI-assistant company lookup (get_company) now includes each round's investors as well, so assistants citing Employbl can answer "who backed this company, and when" in one call.

  • Search jobs by the technologies they actually use. A new Tech Stack filter on the jobs page matches against what's written in each posting — we extract technologies from every job description against a curated taxonomy of 383 tools, so "React" means the posting mentions React, not that someone tagged it. Works alongside every existing filter.

  • Three job filters that silently did nothing now work. Seniority, Minimum Salary, and Posted Within updated the page URL but were dropped before reaching the search — selecting them changed nothing. Fixed.

  • New: startup rosters by stage and city. Thirteen live pages like "Early-stage startups hiring in San Francisco" — every Pre-Seed/Seed/Series A (or Series B/C) company headquartered in a city with open roles right now, ranked by funding, with the same table you can sort and page through. Sign up from one and your preferences arrive pre-filled with that stage and city.

  • Company comparisons now show real tech stacks. The AI-assistant tools (get_company, compare_companies) previously showed a stack for only the handful of companies that declared one; they now also show the stack derived from each company's own job postings — about 4,100 companies.

  • Tech-stack search finds more companies. Legacy lowercase tags ("react") and curated names ("React") are now folded together, so filtering companies by a technology no longer misses companies whose stack was recorded in the older format.

  • The map's Pre-Seed filter works again. It was comparing against a spelling of the stage that no company record uses, so it always returned nothing.

  • Hundreds of pages search engines couldn't find are now in the sitemap. The industry hub pages and all 383 technology pages were never registered in any sitemap; the new startup rosters, both hub families, and correct canonical URLs for the location job boards are all now advertised to crawlers.

  • Sign up from a job page, and you go back to that job. Most people find Employbl because an AI assistant or a search result pointed them at one specific role. Creating an account used to end on a generic dashboard; it now ends where you started — on the job you were reading — with your preferences already filled in from it: what the role is, how senior, where, and what kind of company. Change anything; it's a guess, not a decision.

  • "Email me when similar roles open," set up from that job. One visible checkbox at signup creates a saved search built from the role you came for — senior marketing roles, remote, say — and turns on alert emails for two weeks so you can feel what the paid tier does before deciding. Uncheck it and nothing is created; delete or edit the search any time.

  • Job pages now show where to go next. More open roles at the same company, and similar roles at companies in the same industry — real links, picked by the same engine that powers your matched-jobs feed. Signed-in visitors also get a personalized "similar roles picked for you" rail.

  • Salary on the job page — when we trust the number. Roles whose posting carried an explicit yearly range now show it ("$150K–$210K") in the summary strip, and the same figure goes into the structured data search engines read. About 10,000 open roles qualify today. Hourly figures, stale imports, and low-confidence parses show nothing — a wrong salary is worse than none.

  • Every company profile now has a "similar companies" section. It used to exist only on the handful of hand-curated premium profiles; it's now computed for all 30,000+ companies from shared industry, funding stage, and hiring activity.

  • Search engines can finally see the whole site. A long-standing off-by-one in our sitemap index meant the first ten thousand job pages — and the first thousand company pages — were missing from what crawlers were told about, and one advertised sitemap didn't exist at all. Fixed; the index now enumerates every page.

  • Richer structured data throughout. Job postings now carry their validity window, salary, and industry; company pages describe founding year, headcount, and headquarters — so AI assistants and search engines quoting Employbl have more of the record to quote.

  • More paths between pages. Job pages link to their company's industry hubs, company pages link to their city's company directory, and the dashboard's browse card gained a Sector row — the live dataset is easier to walk, for people and for crawlers.

  • Your first email is now your actual matches. The day after you verify, you get real open roles pulled from what you told us in setup — the title, the company, the salary, and a line saying why it matched ("senior level · in San Francisco"). It used to show the same three companies to everyone regardless of what you'd asked for. If we can't find at least two good matches, you get the general welcome instead of a thin list.

  • New accounts no longer start a 7-day trial, because there's nothing to count down to. The account is free and doesn't expire. Premium is a subscription you start when you want the automation layer — email alerts on saved searches, MCP and API keys, and the full weekly funding digest — not something that switches itself off after a week. Anyone whose trial is currently running keeps it until it ends.

  • The emails stopped talking about a deadline. The welcome sequence used to count down your remaining days and end with "here's what you lose". It now explains what's free, what Premium adds, and leaves it there. Your first-week recap is a recap, not an expiry notice.

  • The upgrade banner waits its turn. It used to be suppressed by the trial and would have greeted every new free account on day one. It now appears only after an account has had a couple of weeks to be useful.

  • Signing up with Google now links you to your company. If your work email matches a company we track, you get connected to it — that already worked when signing up with a password, and now works both ways.

August 2026 (2026-08-28) — The setup question now asks what you do

  • Onboarding now asks what you do, first. Engineering, data/ML, product, design, marketing, sales, or operations — and your matched jobs actually use the answer. An accountant no longer gets a feed of senior engineering roles; an engineer sees engineering roles at the top, each tagged with why it's there ("Engineering role", "matches your city").
  • Match scores now say something honest. Every top result used to read "100% match" because scores were graded on a curve against each other. Matches are now tiered — "Strong match", "Good match", "Match" — based on how much of your profile a role actually lines up with.
  • Verifying your email no longer blocks your dashboard. The full-page "verify your email" wall is now a slim banner — you can see your matches immediately and verify when the email arrives. The verify link itself lands on a page whose next step is your matches, not a form.
  • Saving one preference no longer erases another. Editing your industries from the profile page could silently wipe your saved seniority, minimum compensation, and skills; cancelling the edit-preferences dialog could wipe everything. Uploading a résumé could overwrite preferences you'd just set. All three are fixed — partial saves now merge with what you've already told us.
  • First-time greeting, first time only. New accounts get "Welcome", not "Welcome back", and the dashboard no longer flashes a generic version of itself before your matches load.

August 2026 (2026-08-25b) — One question instead of three forms

  • New accounts now get asked one thing: what kind of companies, and where. Pick an industry, a city or two, your level, and your dashboard fills with matching companies and roles. That's the whole setup.
  • If you signed up while reading about a company, we've already filled it in. Land on Anthropic's funding section, create an account, and AI/ML and San Francisco are preselected when you arrive. Change anything you like — it's a guess, not a decision.
  • The old setup asked for three things that did nothing. It collected a department (stored in a column nothing on the site reads), then a LinkedIn URL and a postal address, and then sent you to a payment page — before you'd seen a single job. It's gone.
  • Recommendations no longer wait for a résumé. The dashboard used to hold back matched jobs and company recommendations until you'd both uploaded a profile and set preferences. Preferences alone are enough now. Adding your background still sharpens the ranking, and there's a prompt for it once you can see what it's sharpening.
  • The preference lists finally match what the search can do. The setup card offered five cities and five funding stages while the rest of the product understood ten and seven — so half of what the recommendation engine could filter on couldn't be picked anywhere. One list now, everywhere.

August 2026 (2026-08-25) — Employbl is free to use

  • There is now a free Employbl account, and it doesn't expire. Search every company and every open role, save jobs, build a watchlist, track applications, browse funding rounds, use the map, and ask the AI assistant — all of it, for as long as you like, without paying. Previously a new account got seven days of everything and then lost most of the product; the dashboard would send you to a pricing page instead of letting you in. That doesn't happen any more.
  • What you pay for is the part that runs while you're not looking. Premium is now email alerts on your saved searches, MCP and API keys for using Employbl's data in Claude or your own tools, and the full weekly funding digest. Everything else is free. Existing subscribers keep everything they already had.
  • The AI assistant is free, five messages a day. It searches the same live index the rest of the site does — "which Series B AI companies in SF are hiring senior engineers" is a question it can actually answer. The counter is shown in the chat header, and it resets at midnight UTC. Premium is uncapped.
  • You can save a search for free; the emails are the paid part. Saving is free and the alert schedule is visible either way, so it's clear what upgrading buys.
  • The Bay Area map is open to any account. It was Premium-only.
  • Signing up still gets you a seven-day trial of the paid features — the difference is where you land when it ends. You keep your account, your saved jobs, your searches and your dashboard, and lose only the alerts and the keys.

August 2026 (2026-08-24c) — The last two pages that didn't fit a phone

  • The company collections and locations pages put two 320px filter boxes side by side. On a 390px phone that made the page 511px wide, so — before this week's initial-scale=1 fix — Safari zoomed the whole page out to fit it. The Company Stage and HQ Location filters now stack on a phone and sit side by side from tablet up. That one change covers every page built on the company table: the collections pages, the per-location pages, and the peninsula list.
  • /for-companies was 580px wide because of a one-line install command. The MCP install command can't wrap, and it was setting the minimum width for its whole section — dragging the page out to 190px past the screen. The command now scrolls sideways in its own box, the way it was always meant to, and the section fits.
  • Both are confirmed fixed by measurement, not by eye — scripts/check-mobile-overflow.ts reports the page exactly as wide as the screen at 320, 375, 390 and 430 pixels. Desktop is unchanged.

August 2026 (2026-08-24b) — Company profiles fit on a phone again

  • Public company profiles were rendering at about half size on iPhone. A single open-role row with a multi-city location ("San Francisco, CA | New York City, NY | Seattle, WA | London, United Kingdom") was pinned against shrinking, so it pushed the page to roughly twice the width of the screen. Safari's response to a page wider than the phone is to zoom the whole thing out to fit — so every section, not just that row, came out at ~50%. Anthropic's profile was the one that showed it, because its job board is the one carrying five cities in a single location line.
  • Role rows now stack on phones. The job title sits above the location instead of beside it, and a long location line is trimmed with an ellipsis — hover or long-press still gives you the full list. Desktop is unchanged. Both the signed-out preview and the signed-in full list are fixed.
  • The page is pinned at 1:1. Pages now declare initial-scale=1, so a future overflow shows up as a short sideways scroll on one section instead of silently shrinking every page on the site. Pinch-zoom still works.

August 2026 (2026-08-24) — Salary and seniority filters that actually filter

  • The salary and experience-level filters on /jobs had nothing to filter on. Both have been in the interface, in the API and in the MCP server for a long time, but almost no listing carried the data — 1,076 of 104,448 open roles had a salary and 1,163 had an experience level. We now read both out of the job description itself, so the filters return real results instead of almost none.
  • The experience-level filter used labels that could never match anything. It offered "Entry", "Mid-level", "Management" and "Executive" while everything else in the product — the API, the MCP server, the recommendation engine — worked in terms of Intern, Junior, Mid-level, Senior, Staff and Principal. Filtering for "Junior" never matched the 485 junior roles that were sitting right there. The two vocabularies are now one.
  • Some jobs advertised a salary of "$20". Where a role was paid hourly, the hourly rate had been stored as though it were an annual salary — so a $20/hour shift-lead role displayed as $20 a year, and was filtered out of any search asking for real money. Those are corrected, and hourly pay is now converted to an annual figure before it is shown or filtered on.
  • We would rather show nothing than show you a wrong number. Job descriptions are full of dollar figures that are not pay — funding rounds, revenue targets, budgets, 401(k) match caps, and the on-target earnings sales roles quote, which are base plus commission rather than a salary. Where we cannot tell that a figure is someone's pay, we leave the field empty instead of guessing.
  • So the salary filter covers some roles, not all of them, and it is worth knowing which. About one open role in eight now carries a salary. Nearly half mention pay somewhere in the description, but most of those don't print the number — they say "the range for this role is posted below" and put it in their applicant tracking system's own pay widget. Reading those directly is what we're doing next. As a sanity check on all of this: coverage in states with pay-transparency laws — California, New York, Colorado, Washington — is roughly double what it is in Texas and Florida, which is exactly the gap those laws should produce.
  • Retired job listings are no longer kept forever. Roles that closed more than 90 days ago are removed along with the data hanging off them, which makes the whole site's job data meaningfully faster to search.

August 2026 (2026-08-23d) — Signing out now actually signs you out

  • "Sign out" didn't always end your session. Signing in with Google left a second session behind that sign-out started closing but never waited for. Because that session can hand you a fresh login on its own, the next page load could put you straight back in as if you'd never left.
  • Your session key stayed valid after you signed out. Sign-out only removed the key from your browser; the key itself kept working for its full 90-day life. It's now revoked on our side the moment you sign out, so a copy that outlives your browser — a second tab, a shared computer — is dead.
  • One "Sign out" button didn't go anywhere. In the mobile menu on marketing pages it signed you out and left you sitting on the same page, still looking signed in. Every sign-out control now takes you back to the homepage, and the page is reloaded from scratch so nothing from your session is left on screen.
  • A dead link on the verify-your-email screen. "Signed up with the wrong email? Sign out and register again" led to a page that doesn't exist. It signs you out now.

August 2026 (2026-08-23c) — 6,100 more open roles, and New York jobs that finally show up on a map

  • Job-feed coverage went 13.5% → 15.2%. 518 companies gained a job board and 6,137 job listings became visible — Cursor's 113 roles, Kong's 79, Equip Health's 66, Blockstream's 54, Thumbtack's 48. All of them previously read as "we don't track this company's jobs."
  • Seven in ten of those boards came from the company's own careers page, not from guessing. Asking a company where its jobs are turns out to be both cheaper and more reliable than trying tokens against every applicant tracking system, so that's the question we ask first now.
  • New York jobs were invisible to location search. Our city lookup stores the city as "New York City"; applicant tracking systems write "New York". The names never matched, so 6,851 New York listings had no coordinates and never appeared in a location filter or a "jobs near me" search. Fixed, along with the same problem for "SF", "Bay Area", "St. Paul" and postings that write their city as "Hybrid - San Francisco". Listings with a location on the map went from 86,288 to 152,213.
  • We now read Workable job boards. 167 companies host their jobs there and we could see the boards but couldn't open them. Their roles will appear as those boards sync.
  • A job board belonging to a company in London briefly appeared on a New York company's profile. Three different companies are called Kernel and two of them share a web address shape, so the check that's meant to prove a board belongs to you couldn't tell them apart. Removed within the hour. The fix is to read the jobs themselves — a board advertising six London roles does not belong to a New York food company — which caught it where no amount of name matching could.

August 2026 (2026-08-23b) — Job listings that are actually open, and descriptions that stop disappearing

  • We were showing roles that no longer exist. A company's job board could never go from "12 open roles" to zero — when an employer closed every role, the sync couldn't tell "this board is empty" from "this request failed", so it kept the old listings forever. We found 1,511 listings across 170 boards whose apply links were already dead: Plaid, Tractian, WHOOP, Saronic and Mistral among them. Every one of those was a 404 you'd have hit after clicking through. They're gone now, and a board that empties out will empty out here too.
  • Job descriptions had been quietly going missing. When an applicant tracking system was slow to answer, the sync wrote an empty description over the one we already had. Listings missing a description are down from 679 to 240, and Greenhouse — our largest source at 66,000 listings — went from 148 missing to zero.
  • Some companies' jobs had silently stopped updating entirely. A single duplicated row could jam a company's whole feed, and Zoox's 239 roles and Roblox's had been frozen that way. Also fixed: job postings with very long URLs were being dropped instead of saved, and boards belonging to companies we'd removed were still being fetched.
  • Job-feed coverage went 9.2% → 13.5%, and the nightly sync now finishes in a fraction of the time — the Y Combinator pass alone went from ~87 minutes to 6.5. Faster syncs mean listings that reflect today rather than last night.
  • The duplicate company records are gone. 1,127 duplicate or defunct company rows were removed along with the stale data hanging off them, so search results and counts stop double-counting the same company. Watchlists and claimed profiles were moved to the surviving record, never deleted.

August 2026 (2026-08-23) — Company locations that are actually where the company is

  • Most company pins were city centroids, not addresses. 18,637 of our 29,899 geocoded company locations sat on a point shared with at least ten other companies — roughly 5,000 in San Francisco stacked on one spot, 3,100 in New York, 1,200 in Los Angeles. 6,917 of them had a full street address sitting in the same database row, unused. Those are now geocoded from the address: 17,094 locations are address-precise, up from 10,991, and another 4,677 resolve to a zip.
  • The centroids weren't even in the right neighbourhood. The point every "New York" company shared was in Park Slope, Brooklyn. San Francisco's was out near Golden Gate Park.
  • Search by zip, or by distance from anywhere. "Which Series A companies are in 94133?" and "seed fintech within 5 miles of Oakland" are now single queries, on the website's data layer, the MCP server and the REST API. Location filters combine with funding stage, sector, tech stack and headcount, and they match satellite offices rather than only headquarters.
  • Companies with more than one office finally show more than one office. Every location record we held was flagged as a headquarters — there were literally zero branch offices in the database, though the maps had been built to display them. Branch offices are now derived from the cities where a company advertises on-site roles, and the company profile lists every office with its own address instead of picking one at random and labelling it "Headquarters."
  • We removed thousands of wrong zip codes. Our data provider stamps a placeholder zip on companies whose real one it doesn't know: 3,130 San Francisco companies were all marked 94115. Where we could check against a real street address, those companies averaged more than a mile from that zip. 7,434 placeholder zips were cleared rather than left to give confident, wrong answers.
  • Map and radius search got faster. A missing database index meant every "companies near here" query scanned the whole table; the same query now runs in a sixth of the time.

August 2026 (2026-08-22) — 3,400 more open roles, from data we already had

  • Job-feed coverage went 12.0% → 12.6%. 180 companies gained a job board and 3,430 job listings became visible — Cohere's 150, Brillio's 121, Flagship Pioneering's 89, Hudson River Trading's 69, Spring Health's 65.
  • No new data was bought and no pages were fetched. The ATS links were already in company records we'd paid for months ago; nothing had ever read them. Zero network calls, zero vendor credits.
  • Being sure it's your board matters more than finding more boards. A company record can pick up stray links belonging to a similarly-covered company, so a link is only trusted when it lines up with the company's own domain, name, or the owner the ATS reports. That blocked three boards belonging to entirely different companies. One slipped through — two companies are named Pinwheel, and the wrong one's roles showed for a few hours before we caught and removed them.
  • Every company checked before today gets checked again. The check got better, so the old "we looked and found nothing" answers were retired rather than left to stand.
  • Then we started working through the companies nobody had ever looked at. 1,500 done, 222 more job boards found, and the search got roughly twice as efficient along the way — asking a company's careers page before guessing at their ATS, and not chasing six URL variations that almost never pay off. Coverage is 13.3%, up from 9.2% two days ago, with 101,244 open roles now visible. 22,029 companies still to check.

August 2026 (2026-08-21c) — 5,794 more open roles you can actually see

  • Job-feed coverage went 9.2% → 11.4%. We checked every US company that raised in the last six months without a job feed (1,342 of them), then every company whose domain matches a Y Combinator listing (1,580 more). 683 gained a board.
  • 5,794 job listings are now visible on Employbl that weren't this morning. Perplexity's 110 roles, Athelas's 102, Hadrian's 138, Whatnot's 131, Etched's 131, Lambda's 78.
  • Y Combinator was by far the biggest unlock — 500 of the 689 new boards. Seed-stage YC companies frequently post only to Work at a Startup, so they were structurally invisible to us. Rippling added another 20.
  • Nothing gets attached unless we're confident it's yours. Three separate near-misses were caught and blocked during the run, each of which would have shown another company's jobs on the wrong profile — including a 190-role board belonging to a same-named company. When two companies appear to claim one board, we record it for a human rather than guess.

August 2026 (2026-08-21b) — Finding where companies actually post their jobs

  • We only had a job feed for 9% of companies. This goes after the other 91%. Employbl pulls listings from a company's applicant tracking system, and for ~27,700 companies we'd simply never found theirs. New discovery runs cheapest-first: what we already have cached, then a direct check against the ATS APIs, then the company's own careers page — all free — and only falls back to paid page-rendering as a last resort.
  • Two new job sources: Y Combinator and Rippling. YC's Work at a Startup boards are now matched by exact domain against YC's public directory (6,192 companies cached), so seed-stage YC companies that only post there are no longer invisible. Rippling ATS boards are ingested too.
  • New companies get their job board automatically. The weekly funding importer creates company records; it now kicks off board discovery for each one, so a company that just raised doesn't sit at "no job feed yet" until someone runs a script by hand.
  • We won't attach a board unless we're sure it's yours. Guessing a company's ATS token is easy to get wrong — a check against the board's registered owner stopped us attaching a defense contractor's cleared-engineering roles to a same-named pre-seed startup. When two companies appear to claim the same board, we record it for a human instead of guessing.
  • Open-role counts update immediately. Attaching a board used to leave the count at zero until the following Monday, so a company with 138 open roles briefly read as having none.

August 2026 (2026-08-21) — We stopped telling you a company isn't hiring

  • "Not currently hiring" is gone, because it usually wasn't true. Employbl syncs job listings from a company's applicant tracking system — and we only have a feed for about 9% of the 31,635 companies in the index. For the rest we'd never found their job board, but the site and the MCP tools both reported that as "not currently hiring." Of the 38 companies that raised in this week's funding import, 35 had no synced feed — including Whatnot, which was hiring for 132 roles at the time we said it wasn't.
  • Three states instead of two. A company now reads as having open roles, having a synced job board that's currently empty, or not having a job feed on Employbl yet. Only the middle one is a statement about the company; the last one is a statement about our coverage, and it now says so.
  • Recommendations stopped hiding most of the market. get_recommended_companies defaulted to only returning companies with synced listings, so personalized recommendations could never surface a company whose board we hadn't found. That filter is now off by default.
  • "Sort by most hiring" actually sorts by most hiring. It had been falling through to the default browse order, which leads with companies that have a website screenshot.
  • Clearer filter labels. The map and funding-rounds "Hiring now" checkboxes now read "Has job listings", matching company search — they filter on what we've ingested, not on who's hiring.

August 2026 (2026-08-20) — Company members get one world, and it works

  • Company always wins. An account linked to a claimed company is a company account, period — no job-seeker dashboard, no "Search Jobs", no candidate upsells, regardless of how the account was originally created. Every home/logo/Dashboard link routes company members to their company dashboard.
  • The sidebar stays put. Companies, Funding Rounds, and the Map now keep the app sidebar for signed-in users — clicking around the product no longer drops you back into marketing chrome. Marketing pages (homepage, pricing, blog, docs) keep the marketing nav, with Dashboard in the corner.
  • Fewer links, all working. The "Your Company" sidebar group is now three links that reliably work — Dashboard, Edit Profile, Public Page — and Edit Profile no longer bounces existing claim holders into the claim funnel.
  • Fixed the crash on brand-new company profiles. A company created minutes ago has no jobs/locations/tags yet; the profile page assumed those lists existed and crashed. Now covered by a regression test.
  • Company dashboard analytics can no longer take the page down. Every external analytics call (PostHog page views, HogQL demand/AI-visibility, the MCP-mentions scan) has a hard 4–5s budget enforced at the source — including in the database itself — and fails to zeros instead of timing out the page.

August 2026 (2026-08-19d) — Company pages that resolve, and dashboards that don't time out

  • Company URLs now work in any casing. /companies/octavehq and /companies/OctaveHQ resolve to the same profile — the stored slug is canonical and other spellings redirect to it. Previously the public profile and the company dashboard used two different slug-matching rules, so a URL could 404 on one and load on the other.
  • A hiccup can no longer freeze a profile into a 404. Company profiles are cached until the next deploy; a transient backend error during that first render used to be cached as "page not found" for everyone until we shipped again. Transient failures now retry on the next visit — only a genuine "this company doesn't exist" is cached.
  • Company dashboards stopped timing out. The analytics calls behind the dashboard (page views, AI-visibility) now run in parallel with hard time limits instead of serially with none — a slow analytics day degrades those numbers to zero instead of 504-ing the whole page. Database indexes were added for the company-slug and claim lookups every dashboard visit makes.

August 2026 (2026-08-19c) — One nav for the whole product

  • Public pages stopped shape-shifting when you sign in. Marketing pages (homepage, blog, pricing, public company profiles) now always show the marketing top nav — signed in, the right corner becomes a Dashboard link and your avatar menu instead of "Sign in / Start free trial". The app sidebar appears only on actual app pages, so browsing the public site no longer wraps everything in the app shell.
  • Company members get a company-first sidebar. If you're a member of a claimed company, the app sidebar leads with a "Your Company" section — Dashboard, Edit Profile, Candidates, Billing, and your public page. Members without a job-seeker profile don't see "Search Jobs", the job tracker, or the candidate-premium upsell at all (their billing is the company plan); people who are both keep both worlds in one nav.
  • The company dashboard joined the app. The rep dashboard and profile editor now live inside the same shell as everything else — same sidebar, same sign-out, real navigation back to the rest of Employbl — instead of a disconnected standalone page. Mobile gets matching bottom-nav tabs.
  • No more dead ends for company accounts. A company-only member who lands on the job-seeker dashboard is taken to their company dashboard — previously an expired candidate trial could bounce them into the candidate subscription page they had no reason to see.

August 2026 (2026-08-19b) — Google sign-in counts as verification, and the company funnel tells the truth

  • No more "verify your email" after signing in with Google. Google OAuth proves you own the mailbox, so it now counts as email verification everywhere — including for company reps, whose accounts previously slipped through without the verified flag and hit the wall on their dashboard. Returning email/password users who sign in with Google get verified the same way, and their 7-day trial starts if it never had.
  • Company sign-in no longer quietly turns reps into job seekers. Signing in from the company login with a work email we don't have a company for used to silently create a candidate account and drop you on the job-seeker dashboard. It now routes you to "Add your company" (two minutes, domain-verified); personal-email sign-ins get pointed at the right explanation instead.
  • The claim page now says what's actually wrong. If you're signed in with an email that belongs to a different company, it links you to your own dashboard. If your company isn't on Employbl yet, it says so and offers to add it — instead of telling everyone to "switch Google accounts."

August 2026 (2026-08-19) — One sign-in, recognized everywhere

  • Signing in with Google no longer leaves you half signed in. Employbl ran two parallel sign-in systems — the email/password session and the Google (company) session — and each half of the site only checked one of them. Sign in with a company Google account and the homepage still showed "Sign in" and "Start free trial", admin pages said "Not an admin", and the site generally treated you as a stranger. Google sign-ins now carry the same session the rest of the site reads, existing signed-in sessions heal themselves on the next page load (no re-login needed), and signing out signs you out of both.
  • The company dashboard stopped asking existing claimants to claim again. If you'd already claimed your company but were signed in with email/password, the dashboard bounced you into the "claim your company" funnel you'd already completed. It now sends you to the one-click Google verification for your dashboard instead. Edits still require the domain-verified Google session — that gate is the point — but the path to it is now honest.

August 2026 (2026-08-18) — The whole site reads like a newspaper now

  • Every public page speaks the same editorial language. The news-desk redesign that started on the homepage now covers the entire site: the blog reads like a front page (lead story, Most Read rail, hairline story list), company profiles open like printed briefs with a stats strip, /companies and /jobs got proper mastheads, and funding rounds render as a wire desk — dateline rows, amounts in monospace.
  • One accent, used sparingly. Orange marks the single primary action on each page plus live-data signals; press blue handles links and everything secondary; hairline rules replace card shadows throughout. Collections, city hubs, tech-stack and VC-firm pages, the map chrome, pricing, and the sign-in/up pages all follow suit.
  • The footer became a masthead. Site-wide footer rebuilt as a newspaper-style colophon — wordmark, mission line, and the full link directory on the dark press-blue base.
  • Signed-in surfaces match. The app sidebar, dashboard, tracker, and profile chrome share the same palette, so crossing from the marketing site into the product no longer feels like changing websites.

August 2026 (2026-08-18) — Recommendations stay in your country, and feedback got a vocabulary

  • No more jobs from the wrong side of the planet. Recommended jobs are now filtered to your country (jobs with no location data still pass, so sparse listings aren't punished). Before this, location was only a ranking bonus — of 74,000 active listings, about 27,000 anchored solely abroad could reach a US feed. Built after a California candidate kept getting recommendations based in India. The main job search is unchanged; this gates recommendations only.
  • Say why with one tap. Thumbs-down now offers multiple-choice reasons — wrong location, not remote, wrong seniority, compensation, just not interested — plus the optional write-in. Dismissing a job asks (optionally) why, and thumbs-up takes a reason too, so good matches teach the feed as much as bad ones. Picking "wrong location" or "not remote" offers the matching hide-all rule on the spot.
  • The full "For You" page can finally talk back. Feedback controls existed only on the dashboard widget; the /jobs For You tab now has the same thumbs, reasons, and hide-rules on every row.
  • Passing on a company twice quiets the whole company. Two or more passes on one employer's roles mildly demote the rest of their listings in your feed.
  • MCP callers get the same vocabulary. rate_job and dismiss_job accept a structured reason_category (and dismiss takes a free-text reason now). Fixed update_preferences erasing hide-rules on unrelated changes. Server v0.10.0.

August 2026 (2026-08-06) — Teach "Jobs For You" what you don't want

  • Every recommended job now takes feedback. Thumbs-up a job and more like it rank higher; thumbs-down or dismiss it and it's gone — from the web feed and from anything an AI assistant pulls via MCP. Thumbs-down takes an optional one-line "why" so the reason is on record, not guessed.
  • Hide a whole category in one move. Seeing roles in a city you'd never take, or non-remote jobs when you only want remote? Dismiss one and Employbl offers to hide all jobs in that location — or every non-remote role — for good. The rule sticks across the feed and MCP. (Built after a candidate kept seeing jobs in India she couldn't remove.)
  • "Why this matches you" on each job. Every match now shows the reason it surfaced — a skill in the title, a company you watch, your city, the funding stage you asked for — so the ranking isn't a black box. No AI cost: it's the same signals the recommender already scores.
  • See more without leaving the page. A "Show more matches" control reveals more of your feed in place.
  • All of it works from AI assistants too. New MCP tools rate_job, dismiss_job, and hide_jobs_matching mean "stop showing me jobs in India" or "thumbs down that one — too senior" is a single instruction to Claude or any MCP client. Server v0.9.0.

August 2026 (2026-08-05) — A new way of describing what Employbl is

  • Employbl is a live dataset of tech companies — and the site now says so. The homepage leads with "A live dataset of tech companies you don't have to build yourself." The product is the maintained record: funding, tech stack, hiring, and team, kept current across 30,000+ companies and 75,000+ ATS-verified roles. The web app, AI chat, MCP server, and REST API are four ways to read the same records, and there's now a section on the homepage that says exactly that.
  • The page argues it end to end. New vitals strip under the hero (index size plus the 30-minute ATS sync cadence, because "live" is a claim that needs evidence). "Why we exist" is now the honest version: this information is public but scattered across thousands of ATS boards, filings, and career pages, and it goes stale in weeks — so everyone rebuilds it badly. The four pillars became the four things that make a dataset worth relying on: coverage, freshness, provenance, portability.
  • For companies, the pitch changed. It was written as a hiring tool. It isn't one. Companies claim a profile to control what AI assistants say about them when someone asks — answer-engine optimization — and to point the same dataset at their own market for target lists and buying signals. /for-companies now leads with those two jobs; the candidate-demand features are still there for when you're hiring, just no longer the headline.
  • Pricing reframed as one dataset with two ways to use it: $25/mo for deciding where to work, $99/mo for getting found and finding customers.
  • Retired /for-recruiters and /for-researchers. Both sold a recruiting-led version of the company story that is no longer the offer, and both routed into the same claim funnel. They now redirect to /for-companies.

August 2026 (2026-08-04) — The company side of the site, rewritten

  • /for-companies rebuilt around what Company Premium actually does. The page now leads with what AI assistants and candidates find about you, then walks through the three things Employbl does for a company — visibility (own the profile AI reads, one-click generation, AI-referral analytics), demand (view counts, interested candidates, double-opt-in intros), and intelligence (the full MCP toolkit for the team). Four concrete workflows show the plain-English questions a recruiter or founder actually asks, and a new "what you'll learn from Employbl" section points at the free intelligence — funding velocity, tech-stack shifts, hiring patterns by stage and city.
  • The 30-day free Company Premium trial is finally on the marketing pages. Every first claim has started 30 days of Premium — no card — since July 30, but the site only ever quoted "$99/mo". It's now on the company page, the pricing page, and the homepage, alongside a three-step getting-started path: claim free, trial starts itself, teammates self-join by work domain.
  • /pricing rebuilt as two equal columns — one for the person deciding where to work, one for the company being decided about — on the same editorial design as the rest of the site. The company plan now lists what it includes instead of a one-line MCP mention.
  • "For companies" is in the top navigation. It was previously reachable only from the footer.
  • Homepage copy tightened. The hero deck now opens with what Employbl actually is ("market intelligence for your job search — like Crunchbase, but for deciding where to work") before listing what it does. The MCP tools on the homepage describe what they get you rather than every filter they accept, the AI assistant section says plainly why it beats asking a general chatbot (it reads today's listings and rounds, not training data), and repeated phrasings across section headlines were varied so the page reads as one argument.
  • Copy corrections: the homepage advertised "7 MCP tools" (there are 24), and 19 files across the site still claimed 90,000+ job listings — the verified figure after the duplicate-listing sweep is 75,000+. Every dataset number on the site now derives from one shared source, so pricing, docs, search, chat, the MCP tool descriptions, and the marketing pages can't drift apart again.

August 2026 (2026-08-01) — Website-enriched profiles + a PR-wire funding lane

  • Newly-added companies now fill themselves in from their own websites. A new enrichment pass reads each company's site (about, team, careers, pricing pages) and backfills what was missing — description, founders, headquarters, social links, logo, and headcount — without ever overwriting a fact we already had. ~180 recently-added companies enriched in the first pass; thin single-page sites are flagged and skipped gracefully rather than guessed at.
  • Funding rounds now flow straight from the press wires. Beyond the newsletter fast lane, a new discovery lane reads the PR Newswire venture-capital feed directly, extracts each round, and stages it — gating out fund closes, acquisitions, debt facilities, grants, and non-US companies before anything is verified and imported. First rounds in: Bidbus (Series A, $15M), Ratio Therapeutics (Series C, $70M), and Eileen (Pre-Seed). All live in recent_funding_rounds, the REST API, and site search immediately.
  • Under the hood: every funding source — newsletters, PR wires, FinSMEs/TechCrunch, web search — now feeds one deduped staging queue, so the same round is never researched or imported twice.

July 2026 (2026-07-31) — Funding data is current again

  • This week's funding rounds are live the week they were announced. A new fast lane imports rounds from funding newsletters — each one verified against a primary source (the company's own announcement or press release) before it lands. First batch: 16 US rounds from the week of July 31, from Seed through Series D (including K2 Space's $500M Series D and Antora Energy's $550M Series C). Funding data previously lagged ~6 weeks behind announcements.
  • The recent_funding_rounds MCP tool, REST API, and site search all serve the new rounds immediately.
  • 8 newly-funded companies got profiles: FluxCo, Klaimee, Meshy, Inner Logic, DataBahn, Discern, CAIS, and Paper (paper.design). Full enrichment (team, tech stack, headcount) follows in the next data pass. (PR #469)

July 2026 (2026-07-31) — Companies: your profile, your links

  • Careers page link. Claimed companies can add their careers page URL — it renders under "Hiring at {Company}" on the public profile (web editor or the update_company_profile MCP tool, server v0.8.3).
  • Funding announcement links. Companies can attach the public announcement (press release or blog post) to each funding round — the round links out from the profile. Round names, amounts, and dates remain independently maintained by Employbl.
  • Editable headquarters address. Claimed companies can correct their HQ street address; the profile map pin re-geocodes automatically.
  • Edits go live instantly. Saving from the company editor now refreshes the public page immediately — no waiting on the next site deploy. Customer chips on company profiles also link to the customers' own Employbl profiles (with logos), and founders link to LinkedIn where we have it.

July 2026 (2026-07-31) — Cleaner funding data + fresher company profiles

  • Duplicate funding rounds are gone sitewide. A 2026-07-09 dedup soft-deleted ~69K duplicate rounds, but the API serving company pages never filtered them out — so many companies showed the same round twice. The duplicates are now fully removed, and investor names that only existed on the deleted copies were merged into the surviving rounds first (PR #461).
  • Investor lists show every named investor. The Investors section previously only showed investors that have an Employbl collection page (e.g. Y Combinator, a16z). It now also lists every investor named on any funding round.
  • "Updated" date reflects profile freshness. The date in the company-page header now uses the most recent of the company record and the premium profile's publish/update time — a freshly published profile no longer shows a months-old date.
  • Behind the scenes: profile generation now waits up to 90s for slow company websites instead of silently falling back to a thinner data source, and empty profile sections no longer render bare headers.

July 2026 (2026-07-31) — Companies: own what AI says about you

  • AI-visibility analytics. Company dashboards now show how AI assistants send candidates your way: profile visits referred by ChatGPT, Perplexity, Gemini, and Claude, plus your company's appearances in AI answers served through Employbl's MCP. The weekly profile report includes the same numbers. Your published profile is the text AI assistants read about you — keeping it sharp is answer-engine optimization.
  • Claimed profiles get featured placement. A new homepage strip spotlights companies that claimed their profile (clearly labeled — the funding and headcount facts stay independently maintained), and the newsletter's company-spotlight slot now prefers claimed profiles.

July 2026 (2026-07-31) — Companies: meet the candidates who found you

  • Intro requests are live. The company dashboard's Interested Candidates panel now has a Request Intro button: candidates who saved or applied to your roles get a private email and choose whether to connect. If they accept, both sides get each other's contact — if they decline (or do nothing), the company learns nothing at all. Double-opt-in by design; limited to 5 requests per company per week so every request stays warm. (PR #454)
  • Your trial, in numbers. Near the end of a company premium trial, the wrap-up email now mirrors what actually happened — profile views, interested candidates, intros, your team's MCP usage — instead of a generic pitch.
  • A principle, made permanent: companies only ever see candidates who chose them. No resume database, no talent search — the only candidates a company can meet are the ones who engaged with its roles. That's what keeps candidate trust (and candidate traffic) the foundation of the whole product.

July 2026 (2026-07-30) — Companies: 30-day free premium trial + one-click profile generation

  • Every company now gets 30 days of Employbl Premium free the first time someone claims it — no card required. The trial includes the full MCP toolkit for up to 10 teammates, profile analytics, and profile generation. Your dashboard shows days remaining; when the trial ends, your published profile stays live.
  • Generate your company profile in one click. The dashboard's new Generate button drafts your profile from your website with AI — positioning, tech stack, hiring focus, culture — and publishes it immediately. Polish anything afterwards in the editor. (PR #447)
  • A welcome email series now walks new company reps through the trial: what's included, generating the profile, connecting your team to the MCP server, how teammates get seats (sign in with your work domain — no invites), and what happens at trial end.

July 2026 (2026-07-30) — View other candidates' profiles

  • Logged-in members can now view each other's profiles. Visiting another member's profile URL previously showed you your own page; it now renders their profile read-only — about, experience, education, projects, and skills. Email, resume, and job-search preferences stay private, and members who opted out of profile visibility remain hidden. Logged-out visitors get a sign-in prompt. (PR #444)

July 2026 (2026-07-30) — Company dashboard sign-in reliability

  • Fixed: company reps could get bounced between their dashboard and the public company page in a repeated sign-in loop. A database hiccup during a session check could silently drop the rep's company access mid-session. Company access is now established once at sign-in and survives transient database failures. (PR #442)
  • Under the hood: session replay enabled for signed-in candidates and company reps (never anonymous traffic), sign-in events now recorded on every auth path, and MCP/API tool calls keep an audit trail (inputs + result preview) so we can review answer quality. (PRs #443, #445)

July 2026 (2026-07-28) — Email verification no longer errors on re-click

  • Fixed: reloading or re-clicking an email verification link showed a false "Invalid or expired verification token" error. The link is single-use under the hood, so the first click always worked — but any second visit (reload, second device, mail-app browser handoff) told already-verified users their signup was broken. The page now recognizes verified accounts and shows "you're all set" instead. (PR #438)

July 2026 (2026-07-28) — Company reps: flag incorrect tech-stack entries, plus editing polish

  • Flag a wrong tech-stack detection in one click — the company edit page shows the technologies detected from your open roles as read-only chips; each has a small flag (⚑) so reps can report an incorrect entry for review instead of emailing us. Flags land directly in our review queue.
  • Shipped earlier in the same polish pass (PR #379): the tech-stack editor suggests canonical technology names as you type (free text still works), spellings normalize automatically on save ("ReactJS" → "React") so declared stacks merge cleanly with job-derived ones, and admins can un-review curation misfires from /admin/technologies without SQL.

July 2026 (2026-07-25) — Trial-end mirror email

  • On the last day of your trial, we now show you what you built — companies researched, applications started, jobs saved, searches watching — and what staying keeps running: saved-search alerts, Funding Radar, and your tracker. If you didn't get a chance to dig in, the email says that honestly instead of inventing stats.

July 2026 (2026-07-21) — Email cleanup: one-click unsubscribe everywhere, consistent sender, tidier inbox

  • Every recurring Employbl email now has a working opt-out: the trial welcome series gained a one-click unsubscribe (and respects your email preferences), and companies receiving weekly profile-analytics reports get a "stop these reports" link. Job-search alerts remain controlled per-search from Saved Searches.
  • Monday emails staggered — weekly job alerts, Funding Radar, and company analytics no longer all land in the same minute.
  • Consistent sender + look: everything now comes from the same address with the same visual style (goodbye leftover indigo templates), with UTF-8 fixed so em dashes render properly in every client.
  • Saved-search email alerts now default to weekly when you save a search (you can still pick daily); the dashboard Watchlist tile now opens your bookmarked companies directly.
  • Under the hood: dead saved-jobs code removed, verification-email resends rate-limited, one shared email client.

July 2026 (2026-07-21) — Funding Radar: personalized weekly funding digest

  • Funding Radar is live — a weekly email for members: companies matching your stage, industry, and location preferences that just raised, with open-role counts and investor names. Fresh capital becomes headcount first; the radar tells you before the roles hit the boards. Free members get the top matches as a teaser; premium and trial members get the full list. Sends Mondays.
  • One-click unsubscribe — every radar email footer carries a signed unsubscribe link (/api/email/unsubscribe); preferences remain editable from the dashboard.
  • Guardrails baked in: only verified accounts with preferences set receive it, never an empty digest, corrupt funding amounts are suppressed rather than shown, and a 7-day dedup window prevents double-sends.

July 2026 (2026-07-18) — API developer experience: OpenAPI spec, usage meters, rate-limit headers

  • Machine-readable OpenAPI 3.1 spec at /api/v1/openapi.json — import into Postman, generate clients, or point an AI agent at it. Derived from the same source as the docs page, so it can't drift.
  • Every API response now carries X-RateLimit-Remaining-Minute / -Day headers so clients can pace themselves before hitting a 429.
  • API key page upgraded — /profile/mcp is now "API keys & MCP": each key shows a live usage meter (calls today against the 5,000/day budget), and the copy reflects that one key drives both the MCP server and the REST API.
  • Copy buttons on every code block in the developer docs.
  • The API is now a listed premium feature on the pricing page, in the site navigation, and in llms.txt for AI answer engines.

July 2026 (2026-07-18) — Public REST API v1 for premium members

  • Six read-only REST endpoints under /api/v1 — companies search, company profile, similar companies, jobs search, job listing detail, and recent funding rounds — serving the same indexes as the MCP tools over plain HTTP for scripts, notebooks, and integrations. Authenticated with the same Bearer token as the MCP server (Profile → MCP), premium-gated, with per-token rate limits (60/min, 5,000/day) shared across MCP and REST and every call audit-logged. Responses use a consistent { data, meta } envelope with typed error codes.

July 2026 (2026-07-18) — Developer docs redesigned: three-column layout, REST API reference

  • /docs rebuilt in the editorial design system — Laravel-docs-style three-column layout with a sticky section nav on the left, an "on this page" rail on the right (scroll-spy highlights the section you're reading), and the content restyled from generic gray/blue cards to the paper/ink editorial kit. On mobile the nav becomes a pinned horizontal strip.
  • New REST API reference section documenting all six v1 endpoints with parameter tables, curl examples, the response envelope, and error codes.
  • Docs content now lives in data files (lib/docs/) so tool and endpoint changes update the page without touching layout code.

July 2026 (2026-07-18) — AEO phase E: collection-page summaries + AI-referral tracking; simpler top nav

  • Every company-collection page now opens with a plain-language summary computed from live data at build time — company count, how many are venture-funded, the most common headquarters city, tracked capital, and open roles. Stat tiles are great for humans scanning; a prose sentence is what an AI answer engine can actually quote.
  • AI answer-engine referrals are now tracked in PostHog — a saved weekly insight breaks down visitors referred by ChatGPT, Perplexity, Claude, Gemini, Copilot, and Bing. The baseline surprised us: ChatGPT already sent 707 visitors in the last 30 days, more than any channel we weren't measuring.
  • The top navigation for signed-out visitors is simpler: Product, Pricing, Blog, Docs. Company search and job search now live inside a two-column Product panel alongside funding rounds, tech stacks, the map, and the intelligence tools — one menu for the whole product instead of three overlapping ones.

July 2026 (2026-07-17) — AEO phase B: FAQ blocks with structured data across the key pages

  • Six pages now answer the questions people actually ask AI assistants — homepage, About, company search, tech stacks, company collections, and funding rounds each carry a visible FAQ block with matching FAQPage structured data, rendered from the same content so the schema can never drift from the page. Questions ladder to the brand positioning: what Employbl is, where the data comes from (ATS-verified listings, job-derived tech stacks), how it differs from LinkedIn/Indeed/Wellfound, and what's free vs. premium.
  • Fixed: the company search page was invisible to crawlers. The entire page body — including its breadcrumb structured data — rendered behind a client-side auth check, so search engines and AI crawlers saw only a loading spinner. Schema and the FAQ block now server-render outside the gate.
  • About page refreshed — stale "20,000+ companies" copy corrected to canonical numbers, meta description now carries the positioning one-liner, and 230 lines of dead commented-out markup removed.

July 2026 (2026-07-17) — AEO phase A: llms.txt, blog schema, honest dataset numbers

  • llms.txt is live at the site root — a map for AI answer engines (ChatGPT, Perplexity, Claude) with Employbl's positioning one-liner, key facts, and the canonical pages worth citing. Pairs with the existing AEO-tuned robots.txt (citation bots allowed, trainers/scrapers blocked).
  • Blog posts now emit BlogPosting structured data (JSON-LD) — author, dates, images — so answer engines can parse and cite the data-journalism pieces properly.
  • Dataset numbers corrected sitewide — the site was underselling. Pages claimed 25,000+ companies and 61,000+ jobs; production actually holds 30,000+ companies, 90,000+ live ATS-verified listings, and 75,000+ funding rounds (verified against the database 2026-07-17). Every page, meta description, MCP tool description, and stat tile now cites the same canonical numbers from one shared constant, so they can't silently drift apart again.

July 2026 (2026-07-17) — Funding rounds dashboard for members

  • Signed-in members now get a live funding-rounds dashboard at /funding-rounds — filter 59K+ tracked rounds by round stage (Pre-seed through Series D), industry, amount raised (min/max USD), announcement date range, and headquarters state, with a "hiring now" toggle and recency/amount sorting. Each result shows the company (linked to its profile), a one-line description, industry, round, amount, date, named investors, and open-role count. Anonymous visitors still see the marketing landing at the same URL. The search API and results UI had been built during Phase 17 but never mounted on a page; this wires it up, adds the date-range, max-amount, and industry filters, and drops the free-text search box in favor of pure filters. Investor-name filtering needs a Typesense schema change and is deferred to a follow-up.
  • Funding rounds search index now carries industry + tagline. The Typesense funding_rounds collection gained a faceted sector field (curated industry taxonomy) and a display-only tagline (premium-profile tagline, falling back to the company description) — rebuilt with zero downtime via the versioned-collection alias swap.
  • "Funding Rounds" added to the logged-in sidebar under Explore.

July 2026 (2026-07-17) — Companies search: all filters always on screen

  • The "All filters" slide-over drawer on /companies is gone. Every filter — industries, investment stage, tech stacks, HQ location, VC firms, company collections, plus the hiring/public toggles — now sits in an always-visible panel between the search bar and results, same pattern as the funding-rounds dashboard. Active filters render as dismissable pills at the top of the panel, and a "Clear all filters" action lives inline. Removed the drawer, the chip bar it launched from, and three orphaned filter components that nothing rendered.

July 2026 (2026-07-16) — Blog editorial audit: 10 posts rewritten with real findings, 12 removed; draft-leak fix (#407)

  • Every post published since June 1 audited against a new bar: a data finding worth reading, ≥800 words, evidence for every claim. All 22 were 133–378-word stubs. Ten were rewritten from live dataset research and republished at their original URLs — including "Forward Deployed Engineer Is Now a Bigger Job Market Than Sales Engineer" (638 active FDE listings across 241 companies, up from 3 companies in 2024 — now out-listing Sales Engineer at 426), "AI Companies Rank 7th in Tech Hiring. Defense Ranks 4th.", and "Waymo Has 397 Open Roles and Only 4 of Them Are Sales". Every piece now states the scope of our index (Greenhouse/Lever/Ashby, startup-heavy), offers competing hypotheses for why the finding looks the way it does, and closes with methodology. Twelve posts with no insight and near-zero traffic were unpublished.
  • Fixed: Sanity drafts were publicly renderable (#407). The server-side Sanity client's token routed reads to the raw perspective, so any studio draft — including "unpublished" posts — rendered at /blog/<slug> and appeared in the blog index. The client now reads the published perspective only, and single-post queries apply the same status/date filter as list queries.

July 2026 (2026-07-16) — Blog restored after 20-hour outage + editorial covers live sitewide (#404, #405)

  • Every blog post page had been crashing since 2026-07-15 14:38 UTC ("Application error: a client-side exception has occurred") — found while verifying the new covers, invisible to error tracking. Root cause: pages/blog/[slug] re-exports its data fetching from a shared feature module, which defeats Next.js server-code elimination, so the Prisma client had silently shipped in the blog's browser bundle for months; PR #398's connection-pool hardening added a server-env read at Prisma module scope, and the env guard (correctly) crashed the browser for it. Fixed with a type-only import + dynamic import() in getStaticProps (#405); the blog's browser bundle no longer contains Prisma at all. Bisected via Vercel's per-deployment URLs. Repeat visitors may hold the broken page in browser cache for up to 10 days (the sitewide Cache-Control max-age); fresh loads are fine.
  • The 67 backfilled editorial data-covers are live on /blog and every post page — PR #403 touched only scripts/docs so it never triggered a deploy (build-skip rules working as intended); #404's deploy flushed the ISR cache and shipped them.
  • External job links no longer go through the Next.js router (#404) — malformed ATS URLs (double-slash paths) threw Invalid-href errors on job pages. Also fixed 10 company slugs containing "/" (legacy slug generator) that made those profile URLs unroutable — e.g. /dev/agents is now reachable at /companies/dev-agents.

iPhone Safari rendered the homepage at about two-thirds width with a white gutter down the right side. One element — the MCP section's one-line install command — was intrinsically wider than the phone viewport, which forced the mobile layout wider and made Safari zoom the whole page out to fit. The command now scrolls inside its own box, and long inline code on /changelog wraps instead of stretching the page. All public pages audited at iPhone width; the site fills the screen edge-to-edge again — just in time for the traffic the newsletter and LinkedIn push is about to send here.

July 2026 (2026-07-13) — Smarter job alerts + personalization fixes (#388, #390)

  • "Jobs For You" is back and much better. A data regression had silently emptied the dashboard feed for two weeks (a freshness filter pointed at a column the job sync stopped writing). Fixed — and the scoring got a rebalance while we were in there: what role you want (your saved-search keywords, your skills in the title) now outranks how similar a company is to ones you follow, jobs at companies you watchlist get a direct boost, and no single employer can sweep your whole feed. Engineers stop seeing sales jobs.
  • Saved-search alert emails redesigned. Each job now shows company, funding stage, location, remote, and salary range at a glance; the subject line tells you how many matches and where ("23+ new Remote engineer roles — Reddit, Anthropic + more"); and "See all matches" reopens the live search with your filters applied.
  • Your industry preferences actually matter now. Stated interests (AI/ML, FinTech, …) were being matched against a retired tag system and never influenced recommendations; they now score against the curated industry taxonomy.
  • Company claim flow unstuck. Signing in with the wrong Google account no longer loops silently — the page names the mismatch and offers the account picker.

July 2026 (2026-07-12) — Public changelog page

This document went public: new /changelog page renders it with the editorial layout kit (Masthead + typography pass, .md cross-references neutralized to plain text), linked from the footer. Static at build time — the changelog only gains entries when we deploy anyway. Part of the GTM activation plan (docs/content/gtm-activation-plan.md): build-in-public trust signal, standing feed for the newsletter's "what we shipped" section and Friday LinkedIn posts, and an AEO surface. Also: scripts/screenshot-section.ts now passes --no-sandbox when running as root, so remote-container sessions can take screenshots.


July 2026 (2026-07-12) — First-principles search UX: /jobs + /companies get one-row filter chips (#381, #382, #383)

Both in-app search pages rebuilt around the same principle: search bar → one chip row → results. No duplicate filter surfaces, no page furniture.

/jobs (#381):

  • Job result rows lead with the job: full-weight wrapping title, decision line (company · stage chip · location · Remote badge · green salary), relative recency right-aligned, letter-tile logo fallback. Killed the per-row "View Job" button, company taglines, and the company pill wall (including the "$614174976 raised" string bug).
  • FilterChipBar replaces FacetStrip: Remote toggle, Level / Funding stage dropdowns with live facet counts, Salary ($100K+…$250K+), Posted (day/week/month), "All filters" opens the drawer.
  • Save-search affordance rides the filter row (right-aligned chip): "Save search" when unsaved; "Saved · {name}" opening the edit modal when the current query matches a saved search. In-page saved-search list removed — recall lives in the sidebar's pinned searches + /saved-job-searches.

/companies (#382, #383):

  • Same chip row: Hiring toggle, Funding stage + Industry dropdowns with live Typesense facet counts (sector added to facet_by; the search API now returns facets). "All filters" opens the drawer; drawer-applied filters (tech, investors, HQ, collections, keyword, map area) surface as dismissable indigo chips in the row. Header's duplicate Filters button and the ActiveFiltersPills row deleted. Chip primitives shared across both pages (components/filters/FilterChipPrimitives.tsx).
  • Bug fix: useCompaniesSearch never forwarded sector, founded_after, or founded_before to the API — the Phase 26 industry filter and part of Phase 23 NL-compiled searches were silently ignored (Fintech + Kubernetes + hiring returned 723 results; correct answer is 105). Verified on prod post-deploy: sector=Fintech + Hiring → 428 companies, Airwallex/Stripe/Okx up top.

July 2026 (2026-07-12) — Job pages load reliably after deploys (#384)

Job detail pages intermittently timed out (10s, billed as Function Duration) in bursts right after every deploy: the deploy empties the ISR cache, crawlers regenerate many pages at once, and each regeneration made an HTTP round-trip to the Go API. Two fixes:

  • Page data now comes from direct database queries (lib/jobs/jobListingPage.ts) — no HTTP hop, response shape verified field-by-field against the old endpoint. Bonus: a transient error can no longer cache a permanent 404 for a job that exists.
  • Database connection pool settings tuned for serverless concurrency (the previous config serialized concurrent page renders through a single connection).

Measured on the next deploy: the regen burst cleared in about a minute with a handful of cold-start stragglers, then hundreds of straight 200s — previous deploys stormed timeouts for minutes. Also closed out: Phase 23 NL search live-API test suite passed 6/6, and the Phase 26 industry classification backfill completed (28.5K companies classified, 0 API failures on the final run).

July 2026 (2026-07-11) — Curated industry taxonomy replaces Diffbot classifiers (Phase 26)

Diffbot's DBpedia-style industry tags ("Software Companies" covered ~90% of the database) replaced with an operator-vocabulary taxonomy, end to end in one day:

  • 26a: industries (17 sectors → 58 subsectors, seed of record in lib/industries/industryTaxonomy.ts) + company_industries tables; /admin/industries.
  • 26b: LLM classification (Haiku batches; description + premium copy + Diffbot hints + derived tech stack + job titles → primary sector + ≤3 subsectors with confidence). Nightly classify-company-industries job for new companies; full backfill run at ship time. Spot-checks: Okta → Cybersecurity/Identity & Access, Sezzle → Fintech/Payments, Anduril → Aerospace & Defense/Defense Technology.
  • 26c: Typesense sector (facet) + subsector fields; /companies Industries filter now sector-grouped taxonomy names (sector param; legacy ind tag-id URLs still resolve); MCP find_companies sector param (server v0.8.2, /docs updated); new /industries + /industries/[slug] SEO pages (stats, subsectors, who's-here grid, adjacent subsectors); industry chips on company profiles.
  • 26d: populate-company-tags no longer writes industry or legacy company-tech-stack Spatie tags (investors still sync). Existing taggings stay read-only; /company-collections unaffected.

July 2026 (2026-07-11) — Homepage profile proof + dual pricing + taxonomy-backed tech filter (Phases 21a + 21e)

Homepage (21a):

  • "What's in a profile" blocks 02/03 finally have product shots: Waymo's job-derived tech-stack section and Sierra's founder cards (Bret Taylor career chips); block 01 re-captured as a tight crop of Waymo's funding section. Captions name the intelligence ("TECH STACK FROM OPEN ROLES · NOT SELF-REPORTED").
  • Company Premium card on the homepage — $99/mo · 10 seats alongside the candidate card (previously a footnote link). pricing_cta_clicked PostHog events on both CTAs with source: "homepage".

Search + MCP (21e):

  • /companies tech-stack filter sources the curated taxonomy via new /api/technologies (searchable by name or category); filter values are technology names matched against the Typesense union — ts=Kubernetes → 767 companies. Legacy tag-id URLs still work.
  • MCP find_companies advertises job-derived stack matching (server v0.8.1, /docs updated).

July 2026 (2026-07-10) — Tech-stack section rebuild + technology intelligence pages (Phase 21c)

The tech stack becomes a first-class surface — on company profiles and as its own page network.

  • Company profile tech-stack section rebuilt (features/companies/TechStackSection.tsx, replaces the flat mono chips in PremiumProfile): grouped by category (engineering leads), simple-icons logos, per-tech open-role counts, and provenance labels — "From open roles" (job-derived) vs "Company-reported" (declared) — the same transparency instinct as the profile firewall. Renders for every company with derived data (2,434 companies), not just the 11 published premium profiles. New "Tech Stack" TOC entry.
  • /tech-stacks/[slug] — 304 technology intelligence pages (383 as of 2026-09-03) (editorial kit: Masthead + StatStrip): one-line definition, open-role/company/remote-share stats, who's-hiring grid (top 12 companies by listing count), co-occurring technologies, common role titles. getStaticProps + fallback: "blocking", no revalidate per the Vercel cost rules.
  • /tech-stacks index rewired from legacy company-collection tag links to the curated technology pages, grouped by category with live job counts.
  • skills.description backfilled with LLM one-liners (264 technologies) via scripts/backfill-technology-descriptions.ts.
  • Derived-stack JSON now carries logo_slug (aggregation re-run across all 2,434 companies).

July 2026 (2026-07-10) — Company tech stacks aggregated from job listings (Phase 21b-3)

job_skills now rolls up to a per-company derived stack.

  • companies.tech_stack_from_jobs — denormalized JSON ([{id, name, slug, category, listings}], top 20, confidence ≥ 0.5). Backfilled: 2,434 companies across 299 technologies. Waymo → C++/Python/PyTorch/TensorFlow/JAX; Vercel → Next.js/Vercel/TypeScript.
  • aggregate-company-tech-stack worker job (daily 8:15am UTC, after extraction), full-rebuild idempotent, clears stale stacks; admin Run Now + CLI script.
  • Typesense tech_stack filter now matches a union: job-derived stack ∪ Spatie tech tags ∪ published premium-profile declared stacks — unenriched companies become findable by technology for the first time. Applies on next companies sync.
  • Premium tech_stack column deliberately NOT renamed (live-prod breakage); two-table split keeps derived vs declared sources separate.
  • Taxonomy pruning continues: CMS, EDR, ACH, APT unreviewed (generic acronyms/standards, not products) — 297 technologies now.

July 2026 (2026-07-10) — Job-derived tech-stack extraction (Phase 21b-2)

The dead job_skills pipeline (last write March 2025, ~1% coverage, out-of-repo) is replaced by an in-repo, dictionary-first extractor. No LLM calls at extraction time — the curated taxonomy's names + aliases compile into one word-boundary matcher.

  • Backfill: 187,282 job_skills rows across 45,683 active listings (51%) covering 2,560 companies, confidence-scored by mention count.
  • extract-job-skills-scheduled worker job (pipeline queue, daily 7:15am UTC after the job-listings sync) keeps new listings extracted incrementally via the new job_listings.skills_extracted_at stamp; admin Run Now wired. CLI: scripts/extract-job-skills.ts (--force rescans after taxonomy changes).
  • False-positive control (lib/skills/technologyDictionary.ts): deny list for English/domain collisions ("GTM" is go-to-market, "Assembly" is General Assembly, "backbone of our platform") and job-post boilerplate (LinkedIn/Instagram/Zoom mentions aren't stack signal); ambiguous English-word technologies (Go, React, Swift, Excel, Segment…) match case-sensitively, never at sentence start, never in hyphen compounds ("Go-to-market"), and single mentions get a confidence discount. Verified by two sample-inspection passes against prod before the full run.

July 2026 (2026-07-10) — Canonical technology taxonomy (Phase 21b-1)

Foundation for StackShare-style tech-stack intelligence (roadmap.md § Phase 21). A "technology" is now a skills row with category IS NOT NULL AND reviewed = true — the never-finished category/aliases/reviewed columns are finally in use.

  • 311 curated technologies across 17 category buckets (lib/skills/technologyCategories.ts), seeded by scripts/curate-technology-taxonomy.ts: candidates gathered from job_skills frequency + the 1,804 drafted premium_company_profiles.tech_stack arrays + Spatie company-tech-stacks tags, LLM-classified (strict: no soft skills, methodologies, protocols, or generic categories), then upserted onto canonical skills rows. Classifications cache to .cache/ so re-runs are free; script is idempotent and skips already-reviewed technologies.
  • New skills.slug + skills.logo_slug columns (docs/sql/2026-07-10-skills-technology-taxonomy.sql). Slugs are unique (will power /tech-stacks/[slug] in Phase 21c); logos resolve deterministically against the simple-icons package (154/311 matched; server-side only — see lib/skills/simpleIconMatch.ts).
  • Alias clusters folded into canonical spellings — normalized_name variants like "gcp"/"Google Cloud Platform", "Postgres"/"postgresql", and case-dupes now all group under one canonical name, with the variants preserved in aliases (these feed the Phase 21b-2 dictionary extractor).
  • /admin/technologies — admin review page grouped by category: logo, slug, aliases, job-listing usage counts across each technology's whole cluster.

July 2026 (2026-07-10) — Mercury-style app navigation: no top navbar for logged-in users

Logged-in chrome rebuilt around the sidebar (modeled on Mercury's app shell); public pages untouched.

  • Top navbar removed on desktop for authenticated users. AppLayout no longer renders LegacyNavbar. The new AppSidebar is the only desktop chrome: brand at top, grouped nav (Home + AI Chat, then EXPLORE: Search Jobs / Companies / Map / Learn, then YOUR SEARCH: Job Tracker / Saved Searches / Profile), user menu pinned to the bottom (avatar + name/email + Premium/Free plan, opening up to Your Profile / Billing-or-Upgrade / Sign out). Nav config lives in one place (components/layout/appNavLinks.ts) shared by desktop and mobile so they can't drift.
  • Saved Searches finally has a nav entry — /saved-job-searches was previously unreachable from the sidebar.
  • Active states now match nested routes (/jobs/[slug] highlights Search Jobs, /profile/* highlights Profile) instead of exact-path only.
  • Collapse state persists in localStorage across pages and sessions; collapsed rail redesigned (no more dark-hover artifacts).
  • Mobile: slim app header (logo + hamburger) replaces the marketing navbar; the hamburger and bottom-nav "More" open a new app-specific slide-over (AppMobileMenu) that mirrors the sidebar instead of showing marketing links (About/Pricing/Register). Bottom-nav Home now points at /dashboard.
  • Job tracker layout collapsed into AppLayout fullHeight — tracker no longer renders a marketing Footer under the kanban board.
  • Viewport-height fixes for the navbar-less world: /chat and the explore map size to the full viewport on desktop (100dvh) and account for the 3.5rem mobile header.

Follow-up (same PR):

  • Pinned saved searches in the sidebar (Mercury's "Bookmarks"): up to 5 saved searches render under the Saved Searches link with a new-jobs-this-week badge. New /api/auth/saved-searches/new-counts endpoint (capped at 5 COUNT queries, SWR-deduped 5 min per session).
  • Trial urgency in the user area: "Trial — N days left" replaces the plan label in sidebar + mobile menu, upgrade card copy switches to keep-your-access framing, Billing menu item hidden during trial (trial users have no Stripe subscription to manage).
  • Accent unification: indigo → tangelo/ink across all authed surfaces (chat page + panel, dashboard sections, recommendations). Indigo is now retired from app chrome per the redesign brief.
  • Tracker cards fixed: cards showed only "Created over a year ago" because board syncs hard-delete stale job_listings rows. Now: title/company/URL snapshotted into external_* columns at save time, || fallbacks tolerate legacy empty-string values, and orphaned rows render "Listing no longer available" instead of blank cards with dead links.
  • AppPageHeader standardizes the slim title + primary-action row (dashboard, saved-searches pages).

Dashboard command center (same PR):

  • Setup-first dashboard. New SetupPanel owns the top slot until the user has BOTH a profile signal (jobs-for-you profileStrength ≥ 20) and saved preferences. Step 1: resume upload (existing parse flow) or paste LinkedIn/resume text into new /api/auth/profile/import-text (reuses the MCP upload_profile_from_text pipeline, refactored into a shared applyProfileText core — platform key, no credit metering). Step 2: preferences are AI-drafted from the profile via new /api/auth/preferences/suggest (Claude call constrained to the PreferenceCard option slugs, deterministic heuristic fallback), prefilled into the preference chips for one-tap save.
  • Recommendations gated on setup. Jobs For You and Recommended Companies render only when profile + preferences exist — no more matching on an empty profile. "Skip for now" collapses setup to a resume-setup banner.
  • Mercury-style command center once set up: "Welcome back, {name}", quick-action pills (Search jobs / Ask AI / Track application / Saved searches), and a stat row — active applications, new saved-search matches this week, profile strength, watchlist size. Stats ride two new COUNTs on /api/dashboard plus the existing new-counts and jobs-for-you endpoints (shared SWR keys, no extra requests).

July 2026 (2026-07-10) — /jobs fixes for signed-in users: salary on cards, working save button, honest copy, skills deep-link

  • Salary pill on job cards. minimum_salary/maximum_salary came back from the search API but were never rendered — now a green 💵 $140K – $180K pill.
  • Save-job button fixed. It gated on isPremium with a "You must be logged in" toast (shown to logged-in users) and its optimistic state never rolled back on API failure. Now gates on authentication (the endpoint only requires a session), rolls back on error, and has an aria-label.
  • Funding pill consolidation. Three separate yellow "Latest Round" pills (name / date / amount) → one Series B · $50M · Mar 2025 pill.
  • Honest copy + dead controls. Free-user pagination said "You must login to search for jobs" to logged-in users → now an upgrade message. The no-results "Reset search" button did nothing → now links back to a clean /jobs.
  • "Add skills" CTAs now land in the skills editor. /profile?add=skills deep-link opens AddEditSkillsModal directly (query preserved through both profile redirects); wired into the /jobs For You tab (both CTAs) and the dashboard For You section. Previously these dropped users on the profile page with no hint where skills live.

July 2026 (2026-07-10) — AI Chat fixed: markdown rendering, investor filtering, no more truncated answers

Connor's screenshot of /chat surfaced four defects, all fixed:

  • Raw markdown. Assistant messages rendered as plain text (###, **, bare [text](url)). Now rendered via react-markdown + remark-gfm through a shared ChatMarkdown component (typography-plugin styling; internal links go through next/link with prefetch={false}), used by both /chat and the slide-in ChatPanel.
  • "Investors isn't a filterable field" — it is. The chat's tool schemas in lib/chat/tools.ts had drifted from the MCP definitions: no investors param, so Claude told users the database couldn't do it and padded answers from training data. Added investors (with full-firm-name guidance: "Andreessen Horowitz", not "a16z" — verified against the tags table), min/max_employees to both search tools, and min_salary + posted_within_days to search_jobs. System prompt now states investor filtering exists and forbids padding results from training data.
  • Answers cut off mid-sentence. Per-round max_tokens raised 1024 → 2048 (session cap unchanged at 15K).
  • Glued paragraphs. Multi-round answers concatenated text across tool rounds without a separator ("…specifically:Good news…"). The client now inserts a paragraph break when a tool round starts.

July 2026 (2026-07-10) — Phase 10 begins: company-side monetization + candidate/company segmentation

First slice of Phase 10 (roadmap § Phase 10, unblocked by the funnel + churn signals — see now.md investigation #7):

  • Profile field firewall formalized (lib/companies/profileFirewall.ts). The descriptive-vs-objective boundary was previously implied by route field-omission; now one module sanitizes every company-authored write. Reps lost edit access to notable_investors + funding_narrative (funding intelligence — the rep editor now explains why instead of showing the inputs). All rep writes stamp profile_source=company_submitted + profile_updated_at; the admin review queue lists company submissions alongside AI-enriched drafts.
  • Company MCP tools (server v0.8, 24 tools). get_my_company (view counts, completeness, publish state) and update_company_profile (descriptive fields, partial updates) — gated by a new requireCompanyClaim guard: active users_companies claim required, no candidate subscription needed. Candidate tools keep their premium gate; everything stays authenticated + rate-limited + audit-logged. All four docs surfaces synced (22→24).
  • Self-serve $99/mo checkout. POST /api/company-rep/companies/[id]/checkout (rep-session-gated; the existing metadata.type="company_profile" webhook branch handles fulfillment) + an upgrade card on the rep dashboard with a "Premium active" state. Previously the only path was an admin-generated payment link. New isCompanyPremium() helper mirrors isPremiumUser() on the company side.
  • Rep segmentation signal. Claiming a company now tags the user user_types.type="employer" (candidate paths already wrote "candidate").
  • Public company funnel. New /for-companies marketing page (editorial layout: how-it-works, free-vs-$99 pricing, the trust-model explainer, FAQ); "For companies" section on /pricing; "For Companies" footer link; "Hiring?" one-liner under the homepage pricing card (kept quiet deliberately — homepage stays candidate-first per positioning.md).
  • Self-serve new-company creation. A rep signing in with an unindexed work domain (e.g. octavehq.com) now lands on /companies/new: enter the company name, website pinned to the verified Google Workspace domain (the domain IS the verification), company row + email_domain + claim + employer tag created in one POST, straight to the dashboard. Guards: consumer domains rejected, existing-match race check, ambiguous-domain 409 routed to support, unique-slug generation. The claim page and company-login dead ends ("email connor@") now route here instead. Slack ping on every creation.
  • $99/mo = full MCP for up to 10 teammates. New hasCompanyPremiumSeat(): an active claim on a company with an active subscription grants the full 24-tool MCP (everything candidates get for $25) to the company's first 10 active claimers — computed in the MCP verifyToken, accepted by the candidate-tool guard alongside candidate premium. No invite system: domain-match claiming IS the seat mechanism; cancelling revokes all seats at once; claimer #11 degrades gracefully to profile tools. Dashboard + get_my_company show seat usage; /docs explains both tiers.
  • Claim-outreach export (scripts/export-claim-outreach.ts). Instantly.ai-ready CSV of high-traffic unclaimed profiles with 30-day view counts + claim URLs — the "{N} people viewed {Company} last month" hook from gtm.md § Cold email outreach. Enriched-first by default.

Phase 10 hardening (same day, PRs #367–#368) — see company-signup-flow.md:

  • Duplicate route fix (#367). Deleted stale pages/for-companies/index.tsx ($299/mo intake form). Production had been serving the wrong page alongside pages/for-companies.tsx ($99 self-serve) — next build picked one unpredictably.
  • Inline Google sign-in on /for-companies. GoogleSignInButton — reps sign in without leaving the marketing page (callbackUrl=/companies/new).
  • Async LLM signup screening. qualify-company-signup BullMQ job (Claude Haiku) on every self-created company; creation is never blocked — flagged signups go to Slack + /admin/company-signups review queue with one-click deactivate.
  • Legacy intake retired. /api/intake/company-profile (old $299 intake) → 410, redirects reps to /for-companies.
  • Ops follow-up: Railway worker redeploy required so qualify-company-signup runs in production.

July 2026 (2026-07-10) — MCP server v0.7: company comparison + saved-search email alerts

Four more tools (22 total), building on v0.6:

  • compare_companies — 2-5 slugs → one markdown table: what they do, HQ, founded, size, total raised, latest round, open roles, work model, tech stack, notable investors. Pure read over companies + premium_company_profiles; preserves the caller's column order and reports unknown slugs.
  • save_search / list_saved_searches / delete_saved_search — "watch for staff-level AI infra roles in SF and email me weekly" is now one tool call. Writes the same saved_job_searches rows (and the same query-JSON shape) the website and the notification worker already use, so MCP-created alerts ride the existing daily/weekly send-job-notifications schedule with zero new infra. Default frequency weekly; capped at 25 saved searches per user; deletes are scoped to the caller's own rows.
  • All four docs surfaces synced (18→22): /docs ToolCards + new "Saved Searches & Alerts" section + v0.7.0 history entry, /mcp catalog, /features/mcp stats.

July 2026 (2026-07-09) — MCP server v0.6: geo search + profile-from-text, landing-page copy un-stales

Two new MCP tools (the first two items of the MCP-server campaign), bringing the server to 18 tools:

  • find_companies_near_me — free-text US location (address, "City, ST", or zip) → Mapbox geocode → nearest companies by HQ via PostGIS KNN (company_locations.geo <-> point, 29K+ geocoded HQs). Returns distance in miles, one-liner, open-role count, profile link; optional radius_miles and hiring_only filters. The campaign's marketing differentiator — no other job-search MCP does geo.
  • upload_profile_from_text — paste a resume / LinkedIn About / bio → one Claude extraction call (credit-metered like summarize_company, BYOK-aware) → applies via the existing update_profile / add_work_experience / add_skills handlers so validation stays in one place. Replies with what was written and what's still missing so the client model can follow up.
  • Docs surfaces synced per the CLAUDE.md rule: /docs ToolCards + count (16→18) + v0.6.0 version-history entry; /features/mcp stats. Also fixed drift found during the audit: /mcp and lib/mcp/tools.ts still said "Seven tools" from v0.3 — the tool catalog there now lists all 18.

July 2026 (2026-07-09) — Map pin popup: anchored at the company, full company info

The /map company card used to be a fixed bottom-right overlay showing only name + "View company". Now it's a real mapboxgl.Popup anchored at the clicked pin (React card portaled into the popup via createPortal; chrome reset scoped under .company-map-popup in globals.css), and it carries the full company snapshot: logo, tagline (premium tagline/one_liner, falling back to truncated description), employee range, latest round + year, open-role count, website, and the profile link. /api/maps/feature/[id] enriched accordingly (also returns HQ lng/lat so sidebar-driven opens anchor correctly). Card extracted to components/maps/CompanyPopupCard.tsx to stay under the 500-line frontend cap.


July 2026 (2026-07-09) — Homepage funding-desk strip: screenshots of recently funded, hiring-now companies

New "Where the money just landed" section on the homepage (PR #341): top-6 venture rounds (Series*/Seed/Angel) closed in the last 12 months where the company is hiring today and has a website screenshot from the capture-company-screenshot pipeline. Each card links to the company profile. Data snapshots at build time via getStaticProps (lib/home/fundedSpecimens.ts) — no ISR; images use per-image unoptimized (no Vercel image-transformation cost); links prefetch={false}. ~223 companies qualify, ranked by round size, so the strip refreshes naturally with each deploy.


July 2026 (2026-07-08) — Diffbot credit budget corrected: 250K/month confirmed active, funding rounds back on Diffbot

A 2026-07-05 session concluded the Diffbot account had lapsed to a "250 credits/month free tier" and kicked off a provider-replacement effort (People Data Labs evaluation, Crunchbase Pro CSV import for funding rounds). Verified live against Diffbot's account API on 2026-07-08 (curl "https://api.diffbot.com/v4/account?token=$DIFFBOT_API_KEY"): that was a misread. The personal250 plan is active with 250,000 credits/month, free — usage history confirms it (254,000 credits spent across 2026-07-04/05 on 10,160 founder Person Enhance calls, i.e. ~25 credits per Enhance, before 429s began; 359,350 credits on 2026-06-17).

  • PDL replacement dropped. Frontend PR #338 and go-cli PR #3 closed unmerged. Diffbot stays the primary source for company discovery, refresh, and founder enrichment.
  • Funding rounds back on Diffbot. The Crunchbase Pro CSV import path is dropped (importer PR closed unmerged; the planned Crunchbase Pro subscription was never actually purchased, so there is nothing to cancel). sync-funding-rounds-from-diffbot is primary again, with a dedup-key fix landing in employbl-go-cli (match on amount_raised + currency via IS NOT DISTINCT FROM instead of exact round_date — Diffbot shifts round dates ±1 day between pulls) plus a one-time dedupe-funding-rounds cleanup command.
  • Budget discipline documented (data-pipeline.md § Credit budget): ~25 credits per Enhance → ~10K enhances/month total; cycle resets ~the 4th, no rollover; currently exhausted until ~2026-08-03/04. Both recent cycles burned the full 250K in 1–2 unthrottled bulk days — new rule is ~2–2.5K enhances/week, and the enrich-all-founders job now caps each run at 2,000 founders by default (payload accepts a limit override) and reports the remaining backlog in its Slack summary.

July 2026 — Funnel-tracking regression found and fixed, testing + monitoring infra added

Digging into why Phase 13f's company-surface click-through looked terrible found the real story: the company page stopped rendering <BriefCard> on 2026-07-04 (a legitimate cleanup — see the Phase 17 entry below) and the replacement, GatedContent, shipped with zero analytics. The company page — the single highest-traffic surface — had no conversion-click visibility at all for 2 days; the 8,004 "impressions" in the original Phase 13f pass were dead-code telemetry, not a live rate.

  • GatedContent now fires gated_content_impression/gated_content_cta_click with surface/tracking_id properties, wired into both call sites (company-page funding gate, FoundersSection's founders gate).
  • Closed the attribution loop. The gate's from query param (e.g. company-funding-{slug}) was generated on every register link but never read anywhere. Now threaded into register_form_submitted and user_signed_up PostHog properties.
  • New checkFunnelHealth worker job (daily, 9am UTC): compares each brief_card_impression surface's volume against its own 14-day trailing baseline and alerts Slack if a surface that normally fires goes silent, plus cross-checks Postgres signups against user_signed_up events. Would have caught this regression the same day it shipped instead of via manual investigation two days later.
  • Added a test runner. No test framework existed in this repo before now — added vitest + @testing-library/react (npm run test, folded into npm run check), with unit tests for BriefCard and GatedContent's tracking behavior so a future refactor that silently drops analytics fails CI instead of going unnoticed.

See roadmap.md § Phase 13f for the full investigation and the corrected (still directional, not final) verdict.


July 2026 — Spam filter gap patch + admin moderation tooling

Follow-on to the June 2026 signup-quality overhaul. Investigation of live signups found a concrete post-cutover escape (moviesdownload021@gmail.com, "Movies clips", via Google OAuth on 2026-07-05) that the name/business-token filter didn't catch, plus two tooling gaps that made it hard to act on spam even when spotted.

  • lib/auth/spamFilter.ts gained a spam_keyword_name check. Catches content-farm / crypto-slang "names" (download, movies, chain, web3, nft, official, etc.) that don't contain a business-name token or unusual-TLD email suffix. Documented as reactive/whack-a-mole, not exhaustive.
  • /admin/signups provider column was silently broken. authProvider was derived from google_id, which the OAuth signup path (google-sync/route.ts) never populates — every Google signup showed as "email". Now derived from password === null.
  • Deactivation now actually works. users.deleted_at (previously unused for users) is now checked in handleLogin, resolveBearerToken (covers every bearer-token API route), and the Google OAuth re-auth path in google-sync/route.ts — a deactivated account can no longer mint a new session through any path. New POST /api/admin/users/[id]/deactivate route + a one-click "Deactivate" button on /admin/signups.
  • New cleanup-unverified-signups job. Daily (7am PST), soft-deletes credential-path signups that never verified email within 14 days. Hard-floored at the 2026-06-30 verification-gate cutover date — the 4,318 pre-cutover users who never verified are historical noise, not spam, and are explicitly excluded from this job.

July 2026 — Phase 17 remainder: close the last public funding-data leaks

Audited the roadmap's stated Phase 17 remainder ("BriefCard's LAST RAISED callout and the /funding-rounds pages") and found that framing itself was stale — no BriefCard instance renders that callout anywhere, and /funding-rounds is a static page with no live data. Found two real, unflagged gaps instead.

  • Company-page StatStrip "Last raised" figure gated. /companies/[slug]'s stat strip was showing the exact dollar amount above the fold, ungated, even after the funding-rounds section below it was gated the day before. buildCompanyCallouts() now takes a teaseFunding option that swaps the amount for "Sign in to view" while keeping the round name visible.
  • /api/companies/search and /api/funding-rounds/search now require premium server-side. Both returned raw funding amounts and investor names with zero auth check at the API level — the frontend only self-gated client-side on isPremium (SWR key was null otherwise), so the routes themselves were a live, unauthenticated scrape target. Both now call isPremiumUser() and return 401 otherwise, matching the frontend's own trust boundary. No legitimate caller was affected (verified no other code calls either route).
  • Phase 18 (dashboard redesign) confirmed shipped. Git archaeology found it had already landed — bundled into PR #332 under a misleading title — so the roadmap never reflected it until now. See below.

July 2026 — Phase 16: traffic-ranked profile drafting at scale

Scaling premium company profiles from 10 toward ~100, prioritized by PostHog traffic (roadmap.md § Phase 16).

  • Traffic-ranked target query. lib/reporting/trafficRankedTargets.ts ranks /companies/[slug] pages by PostHog page views, cross-referenced against publish/claim/Diffbot-cache status in Postgres. New CLI script (scripts/rank-companies-by-traffic.ts) plus an admin "Targets" page (/admin/premium-profiles) with a per-company "queue draft" action.
  • Drafting job now uses cached Diffbot data. draftPremiumProfile.ts previously used only Firecrawl + Claude; it now also reads the already-cached diffbot_companies.diffbot_response (customers, description, categories, investments — zero additional Diffbot cost) as corroborating context, and populates notable_customers for the first time (the field existed in the schema and on the public page, but nothing wrote to it before). Falls back to Diffbot-only drafting when a site fails to scrape but a cache exists, instead of failing the whole draft.
  • New batch job, human-review gate preserved. backfillPremiumProfiles.ts fans out drafts over the traffic-ranked list — it never auto-publishes (human review required). New admin "Review" page (/admin/premium-profiles/review) lists batch-drafted candidates (profile_source = enriched, unpublished) for a human skim-and-publish pass through the existing editor.
  • Fixed a real bug found along the way: company claims were never persisted. The Google OAuth claim flow (lib/auth/nextauth.ts) recomputed token.companySlug on every JWT tick but never wrote anything to the database — a stateless per-session grant, not a durable claim. Now upserts a users_companies row on a genuine sign-in match, so "is this profile claimed?" is finally a real, queryable fact. /companies/[slug] shows a tasteful unclaimed-profile banner (copy differs for thin vs. already-enriched profiles) instead of an always-on "Claim this profile" link that ignored actual claim status.
  • PR #333.

July 2026 — Company profile fixes: broken screenshots, redundant brief, access gating

A batch of fixes to /companies/[slug], mostly found via live QA on the OpenAI profile.

  • Website screenshot URLs fixed and backfilled. captureCompanyScreenshot.ts was building virtual-hosted-style S3 URLs (bucket.s3.region.amazonaws.com/...), which silently fail to load because the bucket name (s3-images.employbl.com) contains dots — the wrong URL style for that bucket. Switched to the path-style URL used everywhere else in the codebase and backfilled all 685 existing rows via a one-off SQL rewrite. Screenshot now renders on every company profile regardless of premium-publish status (previously gated behind published_at, which meant it never showed for any of the thousands of unpublished profiles).
  • Removed the redundant "Section I · The Brief" teaser. It duplicated the masthead (title/subtitle/stat callouts) verbatim on every company page and showed a generic "locked" premium-profile table of contents even for companies with no premium profile at all.
  • Founders and capital-raised sections now blurred for signed-out visitors. Same filter: blur(5px) convention as job listings elsewhere in the app, with a "Sign up to see..." CTA. Logged-in users see everything. (First slice of Phase 17 access-control gating.)
  • Removed the Waymo sample-profile section from the homepage. The static "lead brief" demo card and its unused content/component were cut.

July 2026 — Phase 15h/i/j: screenshot capture, competitive landscape, founder deep profiles + Phase 18 dashboard redesign

Three data-side follow-ons to the June profile refresh, plus a full dashboard redesign that got bundled into the same PR under a title that didn't mention it (see the Phase 17 entry above — the roadmap only caught up to this on 2026-07-05).

  • 15h — Website screenshot capture. New capture-company-screenshot BullMQ job (ScreenshotOne → S3 → premium_company_profiles.website_screenshot_url), an admin trigger button on the premium profile editor, throttled to stay under ScreenshotOne's 20 req/min account cap (a burst of jobs tripped the limit almost immediately on first rollout). --early-only flag added to the backfill script to prioritize Pre Seed/Seed/Series A companies per city.
  • 15i — Competitive landscape section. New competitive_context Json? field on premium_company_profiles, an admin CompetitiveLandscapeSection for authoring competitor rows (name/stage/funding/differentiator), rendered as a structured table in PremiumProfile Group E.
  • 15j — Founder deep profiles. /companies/[slug]'s Leadership section now sources from Prisma founders (bio, prior companies, education pills extracted from cached diffbot_response via lib/founders/extractDiffbotSummary.ts) instead of the Go API's name-and-headshot-only data. Falls back to ceo_name when a company has zero founder rows. New admin "Enrich founders" button fans out enrich-founder-diffbot jobs.
  • Phase 18 — dashboard declutter + AI Chat promotion. pages/dashboard/index.tsx's primary-action panel is now mutually exclusive (only one of preference card / onboarding / interests signal renders at a time). The old floating "Ask AI" button is gone, replaced by a prominent promo card with a tier-aware CTA; AI Chat moved from SideNavbar slot #7 to slot #2. Three stacked CompanyListCards collapsed into one tabbed discovery card; MCP card moved below the fold. Dashboard + SideNavbar chrome swapped from indigo-gradient to the same ink/paper/tangelo tokens the public redesign runs on.
  • PR #332.

July 2026 — Fixed stale company-rep sessions on Google account switch

The jwt callback in lib/auth/nextauth.ts only recomputed the signed-in company via findCompanyForEmail inside if (user?.email), which is only true on the very first sign-in. Switching Google accounts in the same browser (e.g. signing out of an employbl.com account and back in with a personal Gmail) left the old token.companySlug in the JWT, routing the new account to the previous company's dashboard. Now recomputes the match on every JWT tick and unconditionally resets the company fields when there's no match. PR #331.


July 2026 — Beehiiv env hardening

The June auto-subscribe-at-signup feature had been silently no-oping for two months: BEEHIIV_API_KEY/BEEHIIV_PUBLICATION_ID were never set in Vercel, and subscribeToNewsletter() short-circuits on missing keys without throwing. 617 of 856 opted-in users never landed in Beehiiv as a result. Both vars are now required in production (optional in dev, same defense as the earlier NEXTAUTH_SECRET fix), and the subscribe helper warns once per process to Sentry when short-circuiting in prod so the next regression doesn't hide for months. Backfill script pacing bumped 120ms → 300ms after the first run hit Beehiiv's write rate limit. PR #328.


July 2026 — Vercel cost reduction: block preview deploys on non-main branches

Follow-on to the June cost cuts. The prior git.deploymentEnabled: { "main": true, "*": false } block in vercel.json was a misleading no-op — Vercel's object form takes literal branch names, not glob patterns, so every non-docs commit on any PR branch still burned build minutes.

  • ignoreCommand now gates on VERCEL_GIT_COMMIT_REF. Any commit not on main short-circuits with exit 0 before the diff-filter, and Vercel records the deploy as CANCELED without spinning up build resources. main commits still respect the existing docs/scripts/worker/prisma/*.md/.github exclusion.
  • Dropped the dead deploymentEnabled block. The rule lives in the ignoreCommand where it can't drift from a dashboard toggle. PR #326.

July 2026 — MCP server v0.5: profile, preferences, recommendations, similar companies

The /api/mcp server picked up 9 new tools and a public documentation page. Server bumped 0.3.0 → 0.5.0 (16 tools total).

  • Profile management (4). get_profile, update_profile, add_work_experience, add_skills — read + update basic profile, work history, and skills over MCP. Selective-section fetch; Zod-validated input.
  • Preferences (2). get_preferences, update_preferences — read + partial-update users.user_interests (seniority, industries, stages, locations, comp floor).
  • Personalized recommendations (2). get_recommended_jobs, get_recommended_companies — Typesense-backed matching against the caller's preferences, optional reasoning mode, sort by recency / relevance / recent funding. Falls back to a helpful "set preferences first" message for users with an empty user_interests.
  • Similar companies (1). find_similar_companies — look up by name or domain, return the target company plus curated premium_company_profiles.similar_company_slugs. Useful for competitive discovery.
  • New /docs page. Full public catalog of all 16 tools with example queries, install steps for Claude Desktop, auth + rate-limit notes. Indexed for SEO and used as the onboarding target from the marketing surfaces.
  • Vercel build resilience. Landing this exposed a pre-existing OOM in next build's ESLint step (recommended-requiring-type-checking runs a full TS program per file → 7m12s to lint one file locally). Two fixes: a registerTool<TInput> helper in createServer.ts that erases ShapeOutput inference across the 16 tool calls, and --no-lint on the build command so ESLint runs only in dev / manual passes. Type-check still runs during next build. PR #325.

July 2026 — Data pipeline observability + Diffbot founders backfill

Two independent workstreams landed together, both targeting the Sunday Slack pages about SLA breaches and OpenAI failures.

  • Worker Sentry wiring. New worker/lib/sentry.ts (thin wrapper over @sentry/nextjs) called from worker/index.ts at boot. worker.on("failed") / worker.on("error") capture per-queue tags; fatal boot errors flush with a 2s deadline. getLocationFromOpenAI now Sentry.captureException(err) inside its catch — the ~40% openai_failed skips are no longer silent.
  • populate-job-listings no longer fails on one flaky board. Rewrote the parent rollup to only mark the run failed when either the fatality rate exceeds 25 % or the run produced zero real work. A single Ashby 429 or a deleted board now shows up as a partial-failure with the top 5 board errors surfaced in the Slack summary, rather than flipping the whole 24 h SLA red.
  • check-pipeline-health accepts productive-but-errored runs. SLA check now matches status='success' OR (status='error' AND inserted+updated>0). Ends the "SLA page every 2 h until the next daily cron" loop.
  • Diffbot founders backfill. Revives the founders pipeline (dead since May 2024). New backfill-founders-from-cache job reads diffbot_companies.diffbot_response.founders[] and upserts founders rows keyed by (company_id, diffbot_person_id) — zero credits, pure DB fan-out over cached data. Companion enrich-founder-diffbot calls Person Enhance (kg/v3/enhance?type=Person&refreshEntity=...) at 1 credit per founder, skipping rows fresher than 90 d. Wired into the admin scheduled-jobs page and /api/admin/trigger allowlist.
  • PR #324.

July 2026 — Profile-aware AI Chat + public-page conversion refinements

New standalone product: /chat — a profile-aware AI research assistant with access to Employbl's own data through 7 MCP tools. Built as a conversion + retention lever alongside further public-page polish.

  • /chat page. Full-page chat under AppLayout. 4-column starter-prompt grid, streaming SSE responses with a tool-status pulse indicator, upgrade CTA for non-premium users, resume-upload nudge for anyone without a parsed profile.
  • Profile-aware system prompt. lib/chat/candidateContext.ts assembles seniority, industries, target locations, skills, and comp floor from users + user_interests and injects it as a context block — the agent defaults to the candidate's preferences without asking.
  • All 7 MCP tools available in-session. findCompanies, searchJobs, getCompany, summarizeCompany, personalizeSearch, getJobListing, recentFundingRounds. Shared useChatSession hook powers both /chat and the in-app ChatPanel.
  • Cost model corrected. Credit metering now bills Sonnet ($3/MTok in, $15/MTok out) instead of Haiku pricing — Sonnet is the actual model in use.
  • AI Chat in the nav. New SideNavbar entry; replaced Application Tracker in BottomMobileNavigation. Copy added to pricing feature list, register VALUE_PROPS, and the homepage AI section.
  • /companies/[slug] locked-content refinement. The black-bar redacted section is now a clean numbered section-name list + "Locked" indicator. Anon visitors see only 5 jobs with blur on jobs 4-5 and a "View all N roles →" CTA to /register.

June 2026 — Signup quality overhaul (spam floor + verification gate + LinkedIn upfront + domain-match)

The register funnel had three problems on one form: too much spam getting in, a bare experience for the real candidates who did make it, and no fork for people signing up with their work email. Shipped as one PR because the phases are load-bearing on each other (verification gates the trial that the spam accounts were consuming; LinkedIn feeds the enrichment that runs after verification; domain-match branches both the redirect and the verification-email copy). Baseline before ship: ~6% real-candidate rate on 49 signups/30d.

Spam floor

  • New blocked_registrations table. Every rejection is logged with email, name, reason, and IP so we can tune the ruleset from data instead of anecdote.
  • lib/auth/spamFilter.ts runs on both signup paths. Rejects business-name-in-name-field (SFI Insurance, Genre Sports), digits/URLs in name, role-email addresses (marketing@…, admin@…) on business domains, and .seo/.co/.aus/.us/.ltd suffix locals like nconturbines.seo@gmail.com. Runs in both handleRegister (email/password) and google-sync/route.ts (Google OAuth) — the OAuth path was letting the same spam through.

Verification-gated trial

  • Verification email actually sends now. worker/processors/sendVerificationEmail.ts — SES-based BullMQ processor on the notifications queue, both candidate and domain-matched copy variants, logged via logSentEmail. Enqueued from register + from the auth-gated resend endpoint.
  • trial_ends_at moved from register to verify-email success. Spam accounts that never verify never consume trial state, and /admin "active trials" reflects real intent. Same 7d window still applies.
  • Full-page verify wall on /dashboard. New VerifyEmailWall component replaces the whole dashboard for unverified users with a resend button. Public /jobs search stays open.
  • Diagnosis note on Google OAuth. The plan claimed "0 Google signups in 30d." Actually 7 happened in June — the regression was already resolved before this PR started. Left the audit note so future sessions don't chase the same ghost.

LinkedIn upfront + PDL enrichment

  • Optional LinkedIn URL field on the register form. linkedin.com/in/… pattern-validated in both react-hook-form and the Zod register schema, persisted to users.linkedin_url, threaded through signUp() → register() → handleRegister.
  • enrich-new-user BullMQ processor. Runs on first successful verification. Prefers LinkedIn URL as the query key (email hit-rate is much lower on the PDL free tier), best-effort — misses and gated-field responses are silent. Writes results to user_interests + candidate_skills via the shared applyEnrichment helper in lib/pdl/applyEnrichment.ts.
  • PDL wrapper bug fix. lib/pdl/enrich.ts was calling data.location_locality?.trim() — but PDL returns literal true on gated-tier fields, which threw TypeError. New pickString() guard applied to every consumed string field. All response fields now typed unknown at the API boundary so the guard is the only way through.
  • Manual PDL "enrich my profile" card removed. With enrichment now running automatically post-verify, the dashboard's ProfileEnrichCard (and its POST /api/auth/enrich-profile backing route) were the manual escape hatch nobody needs anymore. Deleted both. PreferenceCard remains as the empty-state fallback for users whose enrichment missed or who signed up via Google OAuth.

Company-email fork

  • findCompanyForEmail extracted from lib/auth/nextauth.ts into lib/companies/emailDomainMatch.ts so both NextAuth (Google reps) and handleRegister (email/password) share one implementation of the domain→company match.
  • Domain-match at register. handleRegister calls findCompanyForEmail before user create, inserts a users_companies row on match, returns companyMatch: { slug, name } in the response. Frontend reads it and redirects to /companies/[slug]/claim instead of /dashboard.
  • Verification email copy branches. Candidates get "Verify your email to start your Employbl trial." Domain-matched users get "Verify to manage {CompanyName} on Employbl" with a link to their company dashboard.
  • /api/auth/detect-company blur-detect endpoint. Register-form email onBlur pings this; if it resolves, a nudge banner appears: "Looks like you work at {CompanyName}. Signing up will link you to their company page." Non-blocking — they can still proceed with password.

Migration docs/sql/2026-06-30-blocked-registrations.sql was applied to prod via psql before this PR opened; the Prisma schema is in sync.


June 2026 — Search/filter consolidation across /jobs, /companies, and global nav

Four UX issues from the live signed-in product, fixed together.

  • /companies skeleton no longer gets stuck. RecommendedCompaniesSection was rendering a 6-cell loading skeleton forever when the /auth/recommended-companies fetch errored — SWR returns data === undefined for both loading and error states, and the component only checked the former. Now treats error as an empty result so the section disappears cleanly instead of bleeding gray boxes across the top of the page.
  • /jobs keyword search consolidated into the Filters drawer. The standalone "Search Tech Jobs" form (big orange Search button at the top of every results page) was pulling eyes away from the structured filters. Candidates come to the job board to discover roles, not to look up a known title. The keyword search is now a "Keyword" text input at the top of the Filters drawer on both desktop (JobSearchFilters) and mobile (MobileFilters), binding to query.q via the same replaceInQuery pattern other filters use (commits on blur or Enter). The existing removable "Keyword(s): … ×" pill still works.
  • Job Locations filter now shows clean USA cities only. The autocomplete was sourcing from job_listings_locations.city which contains dirty rows like "33 New Montgomery, 1100, San Francisco, CA" and "Babcock Hills Veterinary Hospital - San Antonio, TX". Regex/length filters caught some but not all of the garbage ("Bay Area", "California", "Nyc" slip through any cleaning rule). Replaced the SQL query with a curated static list of ~120 top USA cities (lib/server/us-job-cities.ts) sourced from the actual job-count ranking. The canonical search "Series A + San Francisco + Software Engineer" composes correctly: /jobs?q=software+engineer&raiseround=Series+A&job_locations=san+francisco_CA_US.
  • Global header search bar removed. <GlobalSearchAutocomplete /> was rendering in every authenticated page header — redundant with page-level filters. Removed from LegacyNavbar and deleted the orphaned component file. Each page now shows just logo + premium badge + avatar in the header chrome.

June 2026 — Homepage production cleanup + MCP positioning + locations bug fix

Three production-quality fixes to the public site, shipped together.

  • Homepage placeholders removed. The hero "PRODUCT SCREENSHOT — TO BE ADDED" box and the "DOSSIER SCROLL MOCK-UP — TO BE ADDED" box were shipping to prod as bordered empty <div>s. Both are now commented out with TODO markers so the layout intent is preserved for whoever drops the real assets in.
  • "Dossier" → "company profile" everywhere. The word "dossier" was doing too much work as the central product noun (12 visible sites). All of them now read "profile" / "company profile" — WHAT'S IN A PROFILE, INSIDE A PROFILE, Browse all 25,000+ profiles →, etc. STAT_ITEMS and INCLUDED updated to match. JSDoc cleanup in Masthead.tsx and StatStrip.tsx.
  • Hero repositioned as data platform + newsletter. Masthead kicker is now EMPLOYBL · COMPANY INTELLIGENCE PLATFORM + WEEKLY NEWSLETTER; subtitle names the web, API, and MCP surfaces plus the Saturday newsletter explicitly.
  • MCP server now featured. New HairlineSection between Geographic Discovery and the stats strip — FOR AI AGENTS AND DEVELOPERS · Bring Employbl into Claude. with the install command and a link to a new /mcp landing page.
  • /mcp landing page. New Pages-Router static page with the install command (OAuth + bearer alternative), the full 7-tool list with descriptions sourced from lib/mcp/createServer.ts, auth/rate-limit/audit notes, and CTAs to /subscribe and /profile/mcp.
  • Shared install command. Extracted MCP_OAUTH_COMMAND, MCP_URL, mcpBearerCommand into lib/mcp/install.ts so the homepage section, /mcp page, and the authenticated McpServerCard.tsx stay in sync.
  • /company-locations/[slug] zero-results bug fixed. All city-state slugs on the homepage (miami-fl, denver-co, austin-tx, seattle-wa, etc.) were rendering empty tables because the slug parser in app/api/_lib/companyCollections.ts blindly replaced dashes with spaces, turning "miami-fl" into "miami fl" which matched no rows in the DB. New locationSlugToCity() helper strips a trailing 2-letter US state code (checked against a fixed set so cities like "Santa Fe" don't get truncated) before converting remaining dashes to spaces. Miami's page now lists its 357 HQ-in-Miami companies.
  • BottomCta simplified. The "Stop guessing. Start knowing." trial-CTA block was removed (redundant with the masthead and pricing-card CTAs). The Beehiiv newsletter signup is retained.

June 2026 — Company profile refresh (Contrary-inspired) + similar-companies section

Full editorial rewrite of /companies/[slug] and its premium profile, in the visual language of Contrary's portfolio pages — quieter, more editorial, more data-dense.

  • Sticky table of contents. Long premium profiles get a right-rail TOC that highlights the active section as you scroll.
  • New founders section. Names + headshots pulled from the Go API, rendered as a proper hero block instead of an inline text mention.
  • Editorial PremiumProfile. Grouped narrative sections (product, tech & business, culture, hiring) replace the old flat card stack. Reviews removed — the signal wasn't there.
  • 15g — Similar companies. New similar_company_slugs String[] field on premium_company_profiles (migration applied); horizontal-scroll cards of logo + name at the bottom of the profile. Populated manually during profile authoring for now; auto-population via industry-tag cosine similarity is future work.
  • Phase 15h/i/j (website screenshot, competitive landscape, founder deep profiles) shipped 2026-07-03 — see the July 2026 entry above.

June 2026 — Resume-parse onboarding (Phase 9)

Prefill the candidate profile from a resume upload instead of making everyone pick pills by hand.

  • Resume upload on /profile (also surfaced inside PreferenceModal on first run).
  • Anthropic parse. Extracts { skills, seniority, cities, compMin?, summary } from PDF / DOCX text.
  • Diff-and-confirm UI. Extracted fields shown side-by-side with current values; user accepts or edits before saving.
  • Writes flow into the scoring loop. Skills persist to candidate_skills; the rest into user_interests — drops straight into jobs-for-you scoring on the next request.
  • Out of scope, by design. No resume review, grading, or AI feedback. The point is to fill the profile, not judge it.

June 2026 — Admin conversion intelligence (Phase 14)

/admin had aggregate counts but no people. Every conversion question ("who churned?", "which signups never came back?") was a one-off SQL query. Five new admin sub-pages, each answering a specific funnel question at a glance.

  • /admin/signups (14a). Last 25 users with auth provider (Google vs email), trial-status chip, subscription check, saved-jobs count. Postgres-backed.
  • /admin/funnel (14b). Live PostHog funnel — brief impressions → register submit → signed up → subscription created. 5-minute in-memory cache on /api/admin/funnel.
  • /admin/cohorts (14c). Weekly cohort retention table (W+0/1/2/4/8). "Active" = saved a job or search in that window. Color-coded cells.
  • /admin/subscriptions (14d). MRR waterfall (new / churned / net) plus a list of churned subs in the last 30d with Stripe cancel reason.
  • /admin/subscribers (14e). Sortable table of every active subscriber: email, start date, days-to-paid, MRR, cumulative spend. Joins Stripe → Postgres.
  • Housekeeping. Extracted CommandRunsTable to a component and brought pages/admin/index.tsx back under the 500-line ESLint cap.

June 2026 — MCP OAuth 2.1 + Streamable HTTP transport

The /api/mcp server got two upgrades so third-party MCP clients (Claude Desktop, Cursor, etc.) can connect via standard OAuth instead of a hand-copied bearer.

  • OAuth 2.1 PKCE server. New /api/mcp/oauth/** routes implement authorization, token, and revocation with PKCE.
  • /.well-known/oauth-protected-resource route. Standard discovery endpoint so MCP clients can auto-configure. Required a firewall bypass for .well-known/*.
  • Streamable HTTP transport. /api/mcp supports the newer Streamable HTTP flow alongside the legacy SSE transport; also required a firewall bypass.
  • UX and security follow-ups. Simplified the /profile/mcp install flow (PR #317) and patched a set of OAuth 2.1 spec-compliance gaps in the same pass.
  • /mcp marketing landing page. Public-facing page with the install command (OAuth + bearer alternative), the full 7-tool catalog with descriptions sourced from lib/mcp/createServer.ts, auth/rate-limit/audit notes, and CTAs to /subscribe and /profile/mcp.

June 2026 — Public landing redesign: "The Dossier"

We rebuilt every high-traffic anonymous landing surface to convert on the first pageview. Sessions average 1.13 pageviews — the offer has to land immediately.

  • BriefCard component. A reusable editorial-brief module that appears above the fold on every public surface. Warm paper background, Fraunces serif headline, IBM Plex Mono data callouts, redacted "Section II — Restricted" reveals for bots and AI assistants to index (labels visible to search engines, bars visible to humans), tangelo CTA.
  • City pages (/company-locations/[slug]) — previously had no above-fold CTA. BriefCard now appears above the company table with callouts for company count, open roles, top investor, and hottest employer.
  • Company pages (/companies/[slug]) — CompanyUpsellHero replaced by BriefCard with founded, headcount, open roles, and last funding round callouts.
  • Job pages (/jobs/[slug]) — 200–500 anonymous views per top job, previously no above-fold offer. BriefCard now appears above JobHeader for unauthenticated visitors, with location, company size, posted date, and ATS source callouts. Six redacted sections (comp band, equity, interview rubric, hiring manager, team context, offer timeline).
  • Company collections (/company-collections/[slug]) — BriefCard added above the company grid.
  • New editorial nav. MarketingNav replaces LegacyNavbar on public pages — a SaaS-style top nav with Companies and Tools dropdowns, no search form for anonymous users (search is a premium feature).
  • Homepage rewrite. Dead search bars removed, new Hero component, trust stats bar, "Filter by what actually matters to you" section.
  • Feature landing pages. /job-application-tracker, /profile, /funding-rounds now have proper marketing landing pages with conversion CTAs.
  • Always sidebar when logged in. MarketingLayout proxies to AppLayout for authenticated users — all 36+ public pages automatically show the sidebar once you're signed in.
  • PostHog telemetry. brief_card_impression, brief_card_cta_click, brief_reveal_hover events fire on every BriefCard surface.

June 2026 — Company logo backfill

We now have logos for 30,498 of 30,709 companies (99.3% coverage).

  • Previous coverage was incomplete — Clearbit (acquired by HubSpot) shut down its logo API and Diffbot proxy URLs had expired.
  • Google faviconV2 API (t0.gstatic.com/faviconV2) used as the primary source, with a size filter (>800 bytes) to reject generic fallback icons.
  • Direct /favicon.ico fetch added as a first-pass strategy for newer companies that Google hasn't indexed yet — picked up an additional 17 logos that the Google API missed.
  • S3 pipeline. Logos uploaded to s3-images.employbl.com/company-images/{slug}-logo.png, image_url_s3 and image_url updated in the companies table.
  • 211 companies remain without logos — all are either very new startups or sites without accessible favicons. Script is idempotent and can be re-run as coverage improves.
  • Script lives at scripts/backfill-company-logos.ts.

June 2026 — Auto-subscribe to the newsletter at signup

We wired the "subscribe to the newsletter" checkbox on /register directly into Beehiiv. Before this, the checkbox just set a flag in our database; growing the list meant manually exporting CSVs and re-importing them — which is why ~850 opted-in candidates were sitting on the wrong side of the wall.

  • New signups go straight into the publication. Opted-in registrations POST to Beehiiv's v2 subscriptions API at signup time. Fire-and-forget — registration never blocks on Beehiiv being down.
  • Backfill script for the historical opt-ins (scripts/backfill-beehiiv-subscribers.ts). Dry-runs by default; refuses to apply past the Launch plan's 2,500 cap.
  • No change for Google OAuth signups — we never captured an explicit newsletter opt-in on that path, so they're not enrolled.

June 2026 — Maps: see where AI startups are hiring

We launched a full Mapbox-powered map of where the AI startup ecosystem is hiring, end to end.

  • New /map page. A single interactive map you can pan across the US. Toggle between companies and an open-jobs heatmap, filter by metro, and click any pin for the company or role. Search inside the map to jump to a company by name.
  • City landing pages. Dedicated pages for the nine biggest tech metros — NYC, SF, LA, Seattle, Chicago, Austin, Miami, Denver, San Diego — each with live company counts, top hiring companies, and the neighborhoods they cluster in. Great for browsing, great for search engines.
  • Mini-maps on every company and job page. Premium and trial members now see an embedded map on /companies/[slug] and /jobs/[slug] showing HQ, branch offices, and on-site role locations — no more squinting at an address.
  • Search & filters synced to the URL. Send a teammate a link to a filtered view of the map and they'll see exactly what you see. (Stale between the July map rewrite and 2026-09-08, when the map kept its filters in component state; true again since the map became /companies?view=map.)
  • Backend. 29K+ company locations and 45K+ job locations now have precise lat/lng coordinates, powered by PostGIS and a US cities lookup table.
  • Retired the old Leaflet map. /companies/map and the state-level maps now redirect to the new /map.

June 2026 — Reverse trial + marketing site overhaul

We rebuilt the path from "landed on Employbl" to "paying subscriber."

  • 7-day free trial, no credit card. New accounts get full premium access for seven days with no payment up front. A trial countdown banner lives on the dashboard, with an urgency nudge in the final 48 hours.
  • Welcome email drip. A 5-day onboarding email sequence walks new candidates through the features they're most likely to convert on.
  • New homepage hero. Sharper positioning ("Get the inside track on AI startup hiring"), a showcase of premium company profiles, and a single "Start free trial" CTA.
  • Rewritten pricing page. Accurate feature list, FAQ, and a real explanation of the $25/mo value prop.
  • Redesigned register page. Two-column layout with the value props and testimonials right next to the signup form.
  • Trial-end /subscribe page. When a trial ends, the new /subscribe page recaps what the user actually built — skills added, companies watchlisted, jobs saved, applications tracked, searches saved — alongside a 7-day refund guarantee, testimonial, and FAQ.
  • Sticky conversion bars on company, job, and blog pages prompt anon visitors to register.
  • Pricing link in the footer and an upgrade CTA in the sidebar for expired-trial users.

June 2026 — Smarter onboarding and personalization

A first-time experience that actually learns what you're looking for.

  • First-run preferences modal. New users pick seniority, target compensation, and locations on day one. Those preferences feed directly into the "For You" job feed.
  • Editable preferences on your profile. Update seniority, comp expectations, target cities, and skills any time.
  • Profile prefill from your resume context. New accounts get skills and seniority prefilled from People Data Labs where possible, so the profile isn't blank from minute one.
  • Better "For You" scoring. Seniority and salary now count toward how a job is ranked, not just skills and location.
  • Cleaner dashboard. Featured companies always show a logo. The onboarding cards collapse once you've completed them. The "personalize your job feed" prompt disappears once you have at least two skills.

June 2026 — Companies: claim your profile

Recruiters and founders can now own and edit their company's Employbl profile.

  • Sign in with Google. Companies log in with their work Google account; we use the email domain to verify they belong to the company.
  • Claim flow. /companies/[slug]/claim → /companies/[slug]/dashboard → /companies/[slug]/edit.
  • Company dashboard. See PostHog page views and unique visitors for your profile over the last 30 days, your open job count, and a profile completion bar.
  • Self-serve editor. Edit your company's description, tags, locations, and other profile fields directly — no more emailing us to fix typos.
  • Candidate Google login. Job seekers can now sign in with Google too.

June 2026 — Editorial blog redesign

We rebuilt the blog as a real publication, not a knowledge-base sidebar.

  • Editorial homepage. New /blog index with hero post, secondary features, and a clean grid of recent posts.
  • Redesigned post pages. Typography, layout, and inline-CTA system rebuilt from scratch.
  • AI-generated post images. Every published post now gets a unique header image, generated via gpt-image-1.
  • Better link rendering. Inline links inside post bodies now render properly.
  • Premium company profile upgrade. The ten flagship premium profiles (Waymo, Sierra, Hightouch, Vestwell, Decagon, ElevenLabs, ClickHouse, Vanta, Ramp, Verkada) got a content and layout refresh.

June 2026 — Faster, more reliable search

A multi-week migration to Typesense for instant search across our 25K+ companies and 61K+ jobs.

  • Typesense-powered search for companies, jobs, and funding rounds with sub-100ms results.
  • In-map search. Find a company by name from inside the /map page and the camera jumps to it.
  • Funding rounds search trimmed to the most recent 5 years, dramatically faster and no more out-of-memory crashes.

June 2026 — New background job system

We migrated all of our background jobs (job board sync, company aggregates, email sends, enrichment) off Trigger.dev and onto a self-hosted BullMQ + Redis stack on Railway. End users see this as: fewer stalled syncs, faster recovery from failures, and a much shorter feedback loop on data issues.

  • New /admin/pipeline page. A live operational view of every queue, every recent run, every worker — with one-click "run now" buttons.
  • Daily job sync now chains into company aggregates. Funding totals, headcount, and other aggregates refresh automatically the moment a sync completes.
  • Hardened the data pipeline. Better handling of missing Ashby boards, smarter fan-out, automatic zombie cleanup.

June 2026 — Vercel cost reductions

Several rounds of infrastructure cleanup to keep hosting costs sustainable.

  • Killed the /jobs/search/* route that was burning a disproportionate share of the bill.
  • Tightened ISR settings on programmatic SEO pages.
  • Disabled per-branch preview deploys to save on build minutes.
  • Stopped polling /api/auth/session on anonymous traffic.
  • Per-route function execution caps.
  • Server-side auth cookies (previously set client-side, which doubled some requests).

Not user-visible, but it's why we can keep the lights on.


Earlier in 2026

For older work — Phase 1–5 (admin tools, premium profiles, candidate auth, jobs-for-you scoring, content ops) — see git history.