Pre-Black Friday: 20% off, for as long as you stayEARLYBFon Solo and AgencyEnds Nov 28Start free

How-to guide

How to Enrich a Candidate From Their GitHub (With a People API)

LeadOcean does not take a GitHub handle. Pull the name, company and email from GitHub's public API, then resolve the person in 2 to 4 records.

Get your free API key →Free to start. No credit card. 1,000 records to spend whenever you like.

You can turn a GitHub handle into a contactable candidate record in three calls, but not with one lookup. LeadOcean's enrich endpoint takes a LinkedIn URL, an email, a phone or a person_id. It does not take a GitHub URL. This guide shows the bridge: GitHub's public API gives you a name, a company and sometimes an email, and LeadOcean resolves the person from there.

Some APIs do take a GitHub URL directly. Crustdata's guide resolves a handle and returns a match confidence score (Crustdata blog, September 2026). If one-call handle lookup matters more to you than record cost, test that route. If you want a flat monthly plan with no per-record price, which you can script and verify yourself, read on.

TL;DR

  • Fetch the profile from GitHub's public API, then enrich by email when GitHub shows one, or search by name and company when it does not.
  • Time: about 15 minutes to wire up, under a second per candidate after that.
  • Records: 1 when GitHub exposes an email, up to 4 when you need a search first (3 search rows plus 1 enrich).

Prerequisites

  • A LeadOcean API key in $LEADOCEAN_API_KEY. The Free plan has 1,000 records, one-off, no card (sign up). Free keys get both the search and enrich scopes.
  • curl and jq.
  • A GitHub handle. Examples use the placeholder janedoe. A GitHub token is optional. Without one, GitHub allows 60 requests an hour per IP address (GitHub docs, September 2026).

Step 1: Pull the profile from GitHub

GitHub's GET /users/{username} returns the fields you need for matching: name, company, location, blog, email and bio (GitHub docs, September 2026). Each field is null when the user left it blank.

bash
curl -s https://api.github.com/users/janedoe \
  | jq '{login, name, company, location, blog, email, bio}'

The response, with placeholder values:

json
{
  "login": "janedoe",
  "name": "Jane Doe",
  "company": "@acme",
  "location": "Berlin, Germany",
  "blog": "https://janedoe.example",
  "email": null,
  "bio": "Systems engineer. Rust, Postgres."
}

Expect email to be null most of the time. GitHub also lets people commit under a noreply address (GitHub docs, September 2026), which is not an inbox. Do not enrich on it.

Step 2: Pick the route

Three cases cover almost every profile. The first one that applies wins.

GitHub gives youLeadOcean callRecords
A LinkedIn URL in blog or bioPOST /v1/people/enrich with linkedin_url1
A public emailPOST /v1/people/enrich with email1
Only name, company, locationPOST /v1/people/search, then enrich by person_idup to 4

A 404 on enrich costs nothing, so trying the cheap routes first is free when they miss.

Step 3: Enrich by LinkedIn URL or email

Send exactly one identifier. Sending two is a 400. Set reveal_email to true to get addresses and phones back. It costs no extra record.

bash
curl -s -X POST https://api.leadocean.io/v1/people/enrich \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "jane.doe@acme.com", "reveal_email": true}'

Swap the body for {"linkedin_url": "https://www.linkedin.com/in/janedoe-example", "reveal_email": true} when the blog field holds a profile link. Both bodies go to the same endpoint. A work address works best. A personal address may 404, and a 404 is free.

Step 4: No email? Search by name and company

Search takes a flat JSON body. q is free text over name, headline, title and company, and companyName is an array. Keep limit small: every row returned is a record.

bash
curl -s -X POST https://api.leadocean.io/v1/people/search \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "q": "Jane Doe",
    "companyName": ["Acme"],
    "country": ["DE"],
    "limit": 3
  }'

Search rows are a thin projection with no contact points. Read three things per row before you spend again: the name and company against GitHub, contact_data.has_email, and meta.source_ids.person_id. About a fifth of people have no LinkedIn URL, so person_id is the key that always works.

Step 5: Enrich the matching row

Send the person_id back exactly as the search returned it.

bash
curl -s -X POST https://api.leadocean.io/v1/people/enrich \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"person_id": "1234567890", "reveal_email": true}' \
  | jq '{name: .data.profile_data.full_name,
         emails: [.data.contact_data.contact_emails[] | {email, type, status}]}'

Do not trust the first row blindly. LeadOcean returns no confidence score for a GitHub match, because it never sees the handle. Check at least two signals: current company against the GitHub company field, and city against location. If two candidates fit, pick none and send a human a short list.

What you get

Sizing comes first, and it is free. Say you want Rust engineers in Germany to cross-check against your GitHub shortlist. The MCP tool leadocean_count_leads ran on 2026-10-21 with these filters and spent 0 records:

text
title: ["Software Engineer"], keywords: ["Rust"], country: ["DE"]
-> total 607, totalIsExact true, totalAll 1,860, credits 0

keywords: ["Rust"], jobFunction: ["Engineering"], country: ["DE"]
-> total 1,418, totalIsExact true, totalAll 4,669, credits 0

Both counts are mailable audiences. They count only verified, catch_all_valid and catch_all addresses, which is the tool's default. totalAll is the same filters with no email condition.

The enrich response, as documented in the API reference (response shape from the API reference, placeholder values only):

json
{
  "success": true,
  "data": {
    "profile_data": {
      "full_name": "Jane Doe"
    },
    "contact_data": {
      "has_email": true,
      "email_status": "verified",
      "email_type": "work",
      "contact_emails": [
        {
          "email": "jane.doe@acme.com",
          "type": "work",
          "status": "verified",
          "verified_batch_date": "2026-09-20"
        }
      ]
    },
    "resume_data": { "experiences": [], "educations": [], "skills": [] },
    "meta": { "schema": "leadocean.person.v1", "fetched_at": "2026-09-20" }
  },
  "meta": { "credits": 1 }
}

Since October 2026, resume_data carries career history. Past roles sit in experiences[] with title, company and dates, plus education and skills when held. Compare the past employers with the GitHub company field. Read email_type and email_status before you send. work means the address is at their current employer. work_other is a former employer and the likeliest to bounce. There is no refund for bounced emails.

Troubleshooting

ErrorCauseFix
401Missing, wrong or revoked keyCheck the x-api-key header and that $LEADOCEAN_API_KEY is set in this shell.
403The key lacks the search or enrich scopeCreate a key with both scopes in the app.
400 on enrichMore than one identifier sentSend one of linkedin_url, email, phone or person_id.
404 on enrichNobody matched, or no contact point is heldFree. Try another identifier or move to the search route.
Empty search dataA filter value is not an exact enum stringCheck values with leadocean_list_enum_values or GET /v1/enums.
429Above your plan's rate limit per account (5 a second on Free, 50 on Solo, 200 on Agency)Wait for Retry-After and retry.
402Free plan: the 1,000 records are spentThey do not reset. Move to Solo, $97 a month (pricing).

FAQ

Can LeadOcean look up a candidate by GitHub URL?

No. Enrich takes a LinkedIn URL, an email, a phone or a person_id. Use GitHub's own API to get a name, company or email first, then resolve the person here.

How many records does one candidate cost?

One if GitHub shows a LinkedIn link or a public email. Up to four if you search first: three rows at limit 3, then one enrich. A 404 on enrich costs nothing.

Is a public GitHub email enough to enrich?

Often yes, if it is a real address. A noreply address will not match anyone. A personal address may 404, which costs nothing, so fall back to the name and company search.

Can I run this from an AI agent instead of curl?

Yes. The hosted MCP server at https://api.leadocean.io/mcp signs in with OAuth and exposes search_leads and get_lead as tools. They spend records exactly as the REST calls do. For a related recipe, see web search to enrich candidates with papers, talks and posts.

Where do I compare this with other people APIs?

Start with the best people search APIs and the people data API page. More guides are on the blog.

Turn your GitHub shortlist into contactable candidates

Free to start. No credit card. 1,000 records to spend whenever you like.

Get your free API key →