PEOPLECOMPANYAI API MCP READY

Xing Profile API

Xing is the professional network of German-speaking Europe, and it holds people who never joined any other one. That is the whole point of this source: a Munich Softwareentwicklerin or a Vienna Prokurist can have a full Xing profile and no presence anywhere else, so for DACH recruiting and market research this is a distinct source rather than a substitute. Send profile URLs or bare handles, get back name, job title, city, country, employment history, education, skills in German and English, and languages, one row per person. It enriches profiles you already have. It does not search for people.

MEDIAN LAGon demand
FIELDS24

Input parameters

PARAMETERTYPEREQDEFAULTDESCRIPTION
profileUrls string[] yes Xing member profile URLs, for example https://www.xing.com/profile/Jane_Doe. A bare handle such as Jane_Doe works as shorthand. Up to 1000 per run, de-duplicated before anything is fetched, and billed once per profile actually returned. Anything that is not a xing.com/profile URL or a bare handle is rejected before the run starts and logged as a warning rather than sent upstream. This is the only parameter, and it is the only thing that moves your bill. — drives your bill

Output schema

FIELDTYPEDESCRIPTIONNULLABLE
result_type string profile or error. On every row, so filter on it rather than counting rows. no
profileId string Stable identifier for the member on the source network. Use it as your join key: the handle in the profile URL can change, this does not. yes
fullName string Full name as published, falling back to prefix plus given plus family name. yes
givenName string First name. yes
familyName string Surname. yes
honorificPrefix string Academic or honorific prefix such as Dr. or Prof., common on German profiles. Present only when the member published one, and absent on both profiles in the last verification run. yes
profileUrl string The profile page this record was collected from. yes
jobTitle string Current job title, in whatever language the member wrote it. German titles come back in German and are not translated. yes
city string City the member lists. Mostly DACH cities, but members list locations worldwide and the field returns whatever the profile holds. yes
countryCode string Two-letter country code the member lists, for example DE, AT or CH. yes
membership string Membership level on the network, for example BASIC or PREMIUM. yes
imageUrl string Profile photo URL, served from the source network's image host. yes
skills string[] Listed professional skills, verbatim. A single profile routinely mixes German and English, and nothing is translated or normalised. yes
languages string[] Languages the member lists, flattened to readable names rather than the source's level objects. yes
interests string[] Personal and professional interests. Frequently absent: neither profile in the last verification run carried this field. yes
groups string[] Professional groups the member belongs to. Also frequently absent, for the same reason. yes
experience object[] Employment history. Every entry carries company. Title, startDate, endDate and description appear only when the member published them, and in the last verification run none of the eleven roles across two profiles carried a date. Do not build a tenure calculation that assumes startDate exists. yes
education object[] Education history with institution, qualification, startDate and endDate. In practice this is often just qualification. yes
similarProfiles string[] Profile URLs the source considers comparable, around twenty per profile. The member's own URL is included, usually twice. yes
summary string One-line plain-language description of the row, built from name, title, city, role count and skill count so an agent can read a record without a parsing layer. yes
fetched_at string ISO 8601 UTC timestamp for when the row was collected. On every row. no
sourceUrl string Error rows only. The input URL the error relates to. yes
error_message string Error rows only. Plain-language reason, for example that the profile no longer exists or that the page could not be parsed. yes
error_type string Error rows only. Machine-readable category such as CollectionError or MissingRequiredParameter. yes

Worked examples

One profile — the Actor's own prefill, and the cheapest way to see the row shape
{
  "profileUrls": [
    "https://www.xing.com/profile/Babureddy_C"
  ]
}
Bare handles — the shorthand form, expanded to full URLs before collection
{
  "profileUrls": [
    "Babureddy_C",
    "Chuck_Coulson"
  ]
}
Mixed batch — URLs and handles in one list, duplicates collapsed before anything is billed
{
  "profileUrls": [
    "https://www.xing.com/profile/Jane_Doe",
    "Max_Mustermann",
    "https://www.xing.com/profile/Jane_Doe"
  ]
}
Watchlist — save as a task, schedule it, and diff jobTitle and city between runs
{
  "profileUrls": [
    "Jane_Doe",
    "Max_Mustermann",
    "Anna_Schmidt",
    "Thomas_Bauer"
  ]
}
Team map — profiles you already hold for one employer, joined on the company names in experience
{
  "profileUrls": [
    "https://www.xing.com/profile/Jane_Doe",
    "https://www.xing.com/profile/Max_Mustermann",
    "https://www.xing.com/profile/Anna_Schmidt"
  ]
}
POWER-USER TIP
similarProfiles includes the member itself — The array runs to roughly twenty URLs and the subject's own profile appears inside it, in the last verification run both first and last. Treat it as a lead list only after de-duplicating and dropping the input URL, or your next run pays to collect a profile you already have.
POWER-USER TIP
experience is company-first, not date-first — Company is the one key you can count on. Title, dates and description are published at the member's discretion, and a profile with seven roles can return seven objects that each contain nothing but a company name. Compute tenure only on rows that actually carry startDate, and treat the length of the array as a role count rather than a career timeline.
POWER-USER TIP
profileId is the join key, not the URL — Members can rename their handle, which changes the profile URL and turns a stored URL into an error row on the next run. profileId stays put. Store it on first collection and key your own table on it, then refresh the URL from whatever the latest row returns.
POWER-USER TIP
the run budget silently shortens the batch — Before fetching anything the Actor reads the run's maximum total charge and trims the URL list to what that budget can pay for, because the upstream bills per delivered record. A 500-URL list under a one-dollar cap collects the first 200 and logs a warning for the rest. If a run returns fewer rows than you sent URLs, check the cap before you suspect the profiles.
POWER-USER TIP
errors arrive as rows, and they are nearly free — A deleted, renamed or unparseable profile returns result_type error with an explanation instead of failing the run, and the per-profile fee is not charged. The per-row dataset fraction still is, so a thousand dead URLs cost about a cent rather than nothing. Nothing disappears silently either way.

Coverage

1,000
profile URLs per run — de-duplicated · collected 20 at a time
21
fields on a profile row — identity · role · history · skills · languages
2
ready-made dataset views — profile overview · career history
2
row types — profile · error

Tasks

Saved runs with the inputs already filled in — each one a standalone page and a working configuration example.

Request a task →

Written about this source

Walkthroughs, worked examples and posts about this source.

Code

curl

curl -X POST "https://api.apify.com/v2/acts/johnvc~xing-profile-api/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"profileUrls": ["https://www.xing.com/profile/Babureddy_C", "Chuck_Coulson"]}'

Python

from apify_client import ApifyClient

client = ApifyClient("APIFY_TOKEN")
run = client.actor("johnvc/xing-profile-api").call(
    run_input={"profileUrls": ["Babureddy_C", "Chuck_Coulson"]}
)

for item in client.dataset(run.default_dataset_id).iterate_items():
    if item.get("result_type") != "profile":
        print("skipped:", item.get("sourceUrl"), item.get("error_message"))
        continue
    roles = [e.get("company") for e in item.get("experience", [])]
    print(item["profileId"], item.get("fullName"), "|", item.get("jobTitle"))
    print("   ", item.get("city"), item.get("countryCode"), "|", ", ".join(roles))

MCP

claude mcp add --transport http xing \
  "https://mcp.apify.com/?tools=actors,docs,johnvc/xing-profile-api"

Changelog

2026-08-06 Pay per profile returned, tiered from FREE through GOLD. Initial pricing at launch.
2026-08-07 Published to the Store with six worked example pages and a monthly keep-alive run.
2026-08-08 0.0.8 Rebuilt after a fleet-wide fix to dataset value coercion, then re-verified end to end over the hosted MCP server.

What people use it for

Alternatives

LinkedIn Profile API — the same row shape from the global network, and the better choice for anyone outside German-speaking Europeours LinkedIn Company API — firmographics for the employers named in the experience arrayours Workday Careers API — the employer's open roles rather than the person behind a profileours
Xing Scraper (jobs, companies and profiles) on the same marketplace — genuinely better when you have no URLs. It searches Xing by keyword, location, discipline and radius, covers job postings and company pages as well as profiles, and costs roughly a quarter as much per row. This API is narrower on purpose: one documented person schema, one charge per profile returned, and no discovery step to configurecompeting