For developers
Match verified company emails to Y Combinator listings. Get a company name, domain, and sourced founding year at sign-in.
Authentication is through TrustedRouter, including Google sign-in. This integration is not operated or endorsed by Y Combinator.
- 01
Your appContinue with TrustedRouter
- 02
TrustedRouter sign-inVerified company email + user consent
- 03
Company contextY Combinator, domain, founding year
Add it with your agent
Paste this into Claude Code, Codex, or your preferred coding agent.
Integration prompt
Add "Sign in with Y Combinator" to this app using TrustedRouter. Follow the guide and use its button image: https://trustedrouter.com/sign-in-as-ycombinator
One sign-in flow. Extra company context.
Register your app
Sign in to TrustedRouter and register your app through
OAuth registration and protocol referencePOST /v1/oauth/appswith its name, app ID, and exact callback URL. Registration uses your console session, not a provider API key.Request profile access
Use the authorization-code flow with PKCE S256 and state validation. Request
profile; addinferenceonly if your app also calls models. The user approves access.Read the current identity
Exchange the code and fetch
/v1/auth/userinfoserver-side with the returned access token. Usedata.subas the stable user ID. Do not trust profile JSON sent by the browser.Match the organization
Require a verified email and an exact
funding_organizationmatch. Show the company and its source. Recheck current claims before granting company-only benefits.
Read company context JavaScript / server
// Server-side, after the OAuth code exchange.
// accessToken comes from TrustedRouter, not a browser claim.
const response = await fetch(
"https://trustedrouter.com/v1/auth/userinfo",
{
headers: { Authorization: `Bearer ${accessToken}` },
cache: "no-store",
},
);
if (!response.ok) throw new Error("TrustedRouter profile unavailable");
const { data } = await response.json();
const company = data.email_verified === true
&& Array.isArray(data.company_affiliations)
? data.company_affiliations.find((claim) =>
claim.funding_organization === "Y Combinator"
&& claim.match_method === "verified_email_domain")
: undefined;
// No match does not prevent ordinary sign-in.
const userId = data.sub;
const companyContext = company ?? null;
This runs after your OAuth callback. A missing match is null, not a failed login.
What your app receives
- Company + domain
- The listed company name and exact verified email domain.
- Organization
funding_organization: "Y Combinator", with the directory relationship.- Founding year
- A sourced year when known.
nullmeans unknown, not zero. - Evidence
- A source listing, check timestamp, and
verified_email_domainmatch method.
View the response shape
Illustrative values below, not a real company record. Userinfo wraps the identity in data; the OAuth token exchange includes profile metadata under trustedrouter.
Example response JSON
{
"data": {
"sub": "usr_example",
"email": "person@example.com",
"email_verified": true,
"company_affiliations": [
{
"company_name": "Example Company",
"funding_organization": "Y Combinator",
"relationship": "accelerator",
"domain": "example.com",
"founding_year": null,
"source_url": "https://www.ycombinator.com/companies",
"checked_at": "2026-09-12T00:00:00+00:00",
"match_method": "verified_email_domain"
}
]
}
}
A useful signal, not an employment check.
A match means the verified email domain matches a reviewed company listing. It does not prove employment, investor endorsement, funding eligibility, or ownership of the company.
Personal email, an unlisted domain, or stale or unavailable evidence can produce no match. Keep ordinary sign-in working. Offer retry or manual review for company-only benefits rather than treating missing data as proof that someone is ineligible.
The Sign in with Y Combinator artwork identifies a company-affiliation sign-in flow, not official authentication operated by Y Combinator. Keep the backing line visible and explain that TrustedRouter checks the company email domain.