Enrich profiles

The profile record for each target. One request, one credit.

POSThttps://api.easydata.win/v1/profiles/enrich
1  per targetone profile fetch

Returns the Profile record for every identifier you send.

Four identifier forms all reach the same record: a profile URL, a public identifier, a member URN, and the base64 slug out of a Sales Navigator lead URL. Which one you hold is an accident of where your data came from and should not change what you get back - which is also why there is no separate Sales Navigator profile endpoint. That slug is an input format, not a product.

One request to LinkedIn, one credit. Follower and connection counts and the detail under each role are on other parts of the profile and cost a request each, so they are not here - Enrich profiles, detailed is this record plus whichever of those you ask for, at +0.5 each.

Set find_emails: true and each record also carries an emails object with a work email address in it, for a flat +4 per person we reach a verdict about. See Finding email addresses.

Need it in the response?POST https://api.easydata.win/v1/profiles/enrich/sync runs the same operation inside your request and hands back the record, for 2per target - twice the price above, because it outranks every queued batch for a worker and holds one open while you wait. It takes target, one entity, never a targets array. See Synchronous requests.

Request #

FieldTypeNotes
targetsrequiredarrayWhat to look up. Each entry is a bare string - read as a URL or a public identifier - or an object. At most 50,000 per submission; splitting a larger job into several batches costs nothing.
find_emailsbooleanLook up a work email address for every person this returns, and fold it in under emails. Adds a flat +4 per person we reach a verdict about - an address, an address on a catch-all domain, or an honest "this domain has no mailbox for them". A person we could not look up at all comes back with emails.status: "unresolved" and a reason, and is not charged. Flat whatever it took: the price does not move with how much work it was.
targets[].domainstringOptional, per target: the company mail domain this person's address lives on, as { "url": "...", "domain": "acme.com" }. Only read when find_emails is set. It skips resolving their employer, which makes the lookup faster and more accurate when your own data already knows the answer, and it changes nothing about the price.
external_idstringYour own correlation handle. It comes back on the batch, on the completion webhook and in the usage rollup, so spend can be attributed to your pipeline rather than only to ours.
callback_urlstringWhere to deliver batch.completed. Optional - polling is a first-class path, not a fallback. Validated when you send it and again when we dial it. Mutually exclusive with webhook_tag.
webhook_tagstringRoute the completion to the endpoints carrying this tag instead of to the untagged ones, so you can name a destination without knowing its URL. A tag matching no enabled endpoint is refused here rather than discovered as a webhook that never fired.

Call it #

cURL
curl -X POST "https://api.easydata.win/v1/profiles/enrich" \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"targets":["https://linkedin.com/in/satyanadella",{"urn":"ACoAAA8BYqEBCGLg"}],"find_emails":true,"external_id":"crm-sync-2026-09-01"}'

Response #

JSON
{
  "data": {
    "batch_id": "afec9131-080b-4b96-b3bb-726249e4bbf8",
    "operation": "profiles.enrich",
    "status": "queued",
    "total": 2,
    "succeeded": 0,
    "failed": 0,
    "pending": 2,
    "results_available": 0,
    "credits_used": 0,
    "external_id": "crm-sync-2026-09-01",
    "created_at": "2026-09-01T10:00:00Z",
    "completed_at": null,
    "recommended_poll_ms": 2000
  },
  "meta": { "requestId": "req_8f2ka91x", "recommendedPollMs": 2000 }
}

A result entry #

Once the batch has drained, this is what reading its results gives you.

JSON
{
  "item_index": 0,
  "input": "https://linkedin.com/in/satyanadella",
  "status": "succeeded",
  "credits_used": 1,
  "data": {
    "public_identifier": "satyanadella",
    "urn": "ACoAAA8BYqEBCGLg_vT9kbxlBWbLnLGVsBWc_pI",
    "member_id": 19186432,
    "url": "https://www.linkedin.com/in/satyanadella",
    "first_name": "Satya",
    "last_name": "Nadella",
    "full_name": "Satya Nadella",
    "headline": "Chairman and CEO at Microsoft",
    "avatar_url": "https://media.licdn.com/dms/image/...",
    "premium": false,
    "influencer": true,
    "creator": false,
    "top_voice": false,
    "summary": "Chairman and CEO of Microsoft. Focused on ...",
    "location": "Redmond, Washington, United States",
    "open_to_work": false,
    "birth_date": { "month": 8, "day": 19 },
    "locale_country": "US",
    "locale_language": "en",
    "skills": ["Cloud Computing", "Enterprise Software", "Business Strategy"],
    "positions": [
      {
        "title": "Chairman and CEO",
        "current": true,
        "company_name": "Microsoft",
        "company_id": 1035,
        "company_url": "https://www.linkedin.com/company/1035",
        "company_industry": "Software Development",
        "company_employee_range": "10001+",
        "company_logo_url": "https://media.licdn.com/dms/image/...",
        "started_on": { "year": 2014, "month": 2 }
      },
      { "...": "Position" }
    ],
    "educations": [
      {
        "school": "University of Wisconsin-Milwaukee",
        "degree": "MS",
        "field_of_study": "Computer Science",
        "started_on": { "year": 1988 },
        "ended_on": { "year": 1990 }
      }
    ],
    "certifications": [ { "...": "Certification" } ],
    "languages": [
      { "name": "English", "proficiency": "NATIVE_OR_BILINGUAL" }
    ],
    "scraped_at": "2026-09-01T10:00:04Z"
  },
  "created_at": "2026-09-01T10:00:04Z"
}

The arrays above are abridged to keep the sample readable: one measured record came back with 20 skills, 5 positions, 1 education, 3 certifications and 2 languages. The Profile glossary page lists every field the record can carry, and an optional one is absent rather than blank when LinkedIn does not carry it for that member.

follower_count, connection_count and the six per-role fields - description, location, workplace_type, employment_type, skills and tenure_months - are absent here by design. Each of them costs a further request to LinkedIn, so they are sold by the section on Enrich profiles, detailed rather than folded into this price.

Errors #

StatusTypeWhen
400invalid_requestThe body could not be accepted as sent. `error.field` names what was wrong. A field this reference does not list is one of these: an unknown key is refused rather than accepted and ignored, because a typo that is silently dropped is indistinguishable from one that worked.
401invalid_api_keyMissing, malformed, revoked or expired key. Never metered.
403quota_exhaustedThis month's allowance cannot cover the submission. Nothing is reserved and nothing is charged.
403email_unverifiedNobody on the account has confirmed their email address, and the account is on the default allowance rather than an agreed one. Open the link sent when the account was created, or request a new one from the console.
429rate_limitedToo fast: the request budget for your key, too many batches in flight, too many synchronous requests (per minute or at once), or an agreed hourly spend already met. `message` says which. Carries `Retry-After`. Never metered.
422unprocessable_targetPer item, on the result entry: the profile is private, deleted or unreachable. credits_used is 0 and the batch carries on.
422capacity_unavailablePer item: we had no capacity able to run it right now. The message narrows it - Sales Navigator capacity on a search, general capacity elsewhere. credits_used is 0, so retrying later costs you only the wait.

Every failure uses the same envelope, and none of them is metered - see Errors.