GitHub
Match a GitHub username to a LinkedIn profile and work emails, or go the other way from a LinkedIn URL or a name to a GitHub account.
GitHub
View API reference · Tag GitHub
We built GitHub matching so a username — a contributor, a stargazer, a username on a résumé — becomes a LinkedIn profile URL, and optionally the work emails attached to that developer's commit history. It also runs the other way: give it a LinkedIn URL or a name and it finds the GitHub account.
Developers are the hardest audience to reach from a conventional B2B dataset. Their LinkedIn is often stale and their work email is rarely listed, but their code is public and current. This is the bridge between the two.
Once you have a LinkedIn URL, the person is an ordinary Fiber profile. Email and phone beyond what GitHub exposes come from Contact Reveal.
Which direction do you need
| You have | You want | Use |
|---|---|---|
| One GitHub username | LinkedIn and/or emails | githubToLinkedinSingle — synchronous, answer in the response |
| Up to 1,000 GitHub usernames | LinkedIn and/or emails | githubToLinkedInTrigger → githubToLinkedInPolling — background job |
| LinkedIn URLs, user IDs, or names | GitHub profiles | githubLookupTrigger → githubLookupPoll — background job, no synchronous version |
Anything described as a background job follows the same shape: you call the trigger, it returns a run ID, and you either poll for results or subscribe to the completion webhook. The first poll is normally still running — that is expected, not a failure.
GitHub → LinkedIn
What you send
| Field | Where | Notes |
|---|---|---|
githubUsername | single | The username on its own, not a profile URL |
people[] | batch | Up to 1,000 entries, each a githubUsername plus an optional customerProvidedId |
outputType | both | linkedin, email, or both. Defaults to both on the single route and linkedin on the batch route — set it explicitly so you are not surprised by the bill. |
context / overallContext | single / batch | Optional free text describing who these people are. Worth sending on common names. |
customerProvidedId | both | Your own ID, echoed back so you can join results to your rows |
What you get back
| Field | Meaning |
|---|---|
linkedInUrl | The matched profile URL, or null when there is no confident match |
linkedInSlug | The slug from that URL |
confidenceOutOf10 | 0–10. Use it to decide what to work and what to review. |
rationale | A short explanation of why this profile was selected |
extractedEmails | Work emails found for the developer. Empty unless you asked for email or both. |
githubProfile | Name, company, location, and bio as GitHub has them |
customerProvidedId | Echoed straight back from your request |
Single request — POST /v1/github-to-linkedin/single:
{
"apiKey": "YOUR_API_KEY",
"githubUsername": "torvalds",
"outputType": "both",
"context": "maintainers of large open-source infrastructure projects"
}An unknown username returns 404, and so do bot accounts and organization
accounts — the route resolves people, not orgs. Those calls are refunded in
full. A username that exists but has no confident LinkedIn match returns
200 with linkedInUrl null, and you are billed only for the parts that
actually resolved.
Polling the batch
githubToLinkedInPolling takes the githubAgentRunId from the trigger.
Page through results with cursor, sending back the nextCursor from the
previous response; pageSize runs 1–100 and defaults to 10. The run-level
status moves NOT_STARTED → STARTED → DONE (or FAILED), and each row
carries its own status. You have everything when the run is DONE and
hasMore is false. The github_to_linkedin.completed webhook fires at the
same point.
LinkedIn or a name → GitHub
This direction is a background job only.
githubLookupTrigger takes people[] (up to 1,000) and — unlike the other
routes — requires overallContext: one sentence describing what the list
has in common, such as "backend engineers at Series B fintechs in NYC". Each
person is identified one of three ways:
inputType: "linkedinUrl"— a LinkedIn URL, slug, or entity URNinputType: "linkedinUserId"— the numeric LinkedIn user IDinputType: "manual"—fullNameplus optionalcompany,jobTitle,schoolName,workEmail, andlinkedinUrl
Pass externalId on each row to join the results back to your data.
githubLookupPoll takes the githubAgentRunId and returns the whole result
set in one response — there is no paging on this route. You get:
| Field | Meaning |
|---|---|
overallStatus | NOT_STARTED, STARTED, DONE, or FAILED |
counts | total, found, notFound, invalidInput, failed, pending — these sum to total |
people[] | One entry per person, each with an outcome of found or notFound; a found entry carries username, githubUrl, and confidenceOutOf10 |
Treat counts.pending reaching 0 as the finish line, or subscribe to
github_lookup.completed and skip polling entirely.
Using it effectively
Batch is not just faster, it is several times cheaper. The single route is priced for interactive, one-off lookups at 5 credits for a LinkedIn match. The batch route is 1 credit per person for the same thing. Anything that is genuinely a list — a repo's contributors, a stargazer export, a conference attendee sheet — belongs on the trigger even when you are not in a hurry.
Ask only for the output you will use. outputType: "both" on the single
route costs 5 credits for the LinkedIn match plus 3 more for email extraction.
If you are going to run Contact Reveal anyway,
linkedin alone is the cheaper path to the same place.
Send context, especially on batches. overallContext is required on the
LinkedIn → GitHub direction for a reason: matching a name to a GitHub account
is much easier when the system knows the list is all Rust compiler
contributors rather than all people called Chen. The optional context on the
GitHub → LinkedIn side pays off the same way.
Use confidenceOutOf10 as a routing decision, not decoration. Pick a
threshold, send everything above it straight into outreach, and put the middle
band in front of a human. A null linkedInUrl and a 3-out-of-10 match are
very different problems.
Filter developers by what they build. The githubProfile on a result
gives you company, location, and bio as the developer maintains them, which
tends to be fresher than a self-reported LinkedIn headline for this audience.
Prefer the webhook to a poll loop. Both directions fire a completion event. Polling is free but it is still code you have to write, back off, and monitor.
Use cases
Turn a competitor's contributor list into a recruiting pipeline. Export
the usernames who have committed to a relevant open-source project, send them
to githubToLinkedInTrigger in one call with outputType: "linkedin" and an
overallContext describing the project, take the
github_to_linkedin.completed webhook, then run
Contact Reveal on the LinkedIn URLs above your
confidence threshold. At 1 credit per person the discovery step is cheap
enough to run on the full list rather than a sample.
Reach developers already using an adjacent technology. Stargazers of a
complementary library are the warmest developer-tool audience there is.
Batch-resolve them the same way, then segment on the company field from
githubProfile so you are not pitching to people at your own customers.
Qualify one candidate mid-conversation. A recruiter looking at a résumé
with a GitHub username on it wants an answer now, not a job. That is what
githubToLinkedinSingle is for — one call, outputType: "both", LinkedIn and
any commit emails in the response.
Find the GitHub account behind a LinkedIn list. When your list starts on
LinkedIn (a saved search, a target account's engineering team), run
githubLookupTrigger with a tight overallContext and read
counts.found to see how technical the list really is. The GitHub URLs give
you something concrete to reference in a first message.
Credits
Costs depend on direction and on whether you batch:
| Operation | Cost |
|---|---|
githubToLinkedinSingle | 5 credits per person for the LinkedIn match, plus 3 credits per person for email extraction. You are billed only for what resolves. |
githubToLinkedInTrigger | 1 credit per person for LinkedIn or email, 2 credits when outputType is both |
githubLookupTrigger | 3 credits per person |
| All polling routes | Free |
Batch triggers charge when the job starts, which shows up as
charged-for-async-process. Rate limits differ per route: the single lookup
allows 120 requests per minute, the triggers 30, and githubToLinkedInPolling
60. chargeInfo on the response is the authoritative amount — see
Billing.
Related: Social media APIs · X → LinkedIn · Contact Reveal · Webhooks