FounderMCPDocs

API reference

Find people at companies

People who work at up to 25 companies, filtered on role, seniority, department and country. One call reads one page and returns at most 25 people. Each person costs 5 credits. A company that cannot be matched, and a page with nobody on it, cost nothing.

POSThttps://foundermcp.dev/api/v1/leads
View Markdown

People who work at up to 25 companies, filtered on role, seniority, department and country. One call reads one page and returns at most 25 people. Each person costs 5 credits. A company that cannot be matched, and a page with nobody on it, cost nothing.

Name a company by id (cmp_… from an earlier row), domain, or linkedin_url. Send next_cursor back as cursor with the same companies and filters. No profile is fetched: use POST /person/enrich with person_ids for the full profile and a work email.

This is not a buying signal. signal_type on each row is null. The person did not do anything; they hold a role at a company you named.

Authentication

Send Authorization: Bearer gtk_…. Create the key under API Access → API Keys. A missing, invalid or revoked key is 401, including while this API is closed. A valid key while the API is closed for your organization answers 404, the same body as an unknown path. Every response includes FounderMCP-Api-Version and FounderMCP-Request-Id.

Body parameters

  • companies object[] · required — 1 to 25 companies. Each object has exactly one of id, domain or linkedin_url.
  • filters object · required — At least one of roles (job titles, up to 10), seniority (c_level, vp, director, manager) or departments (the same department keys as a buyer profile). countries is ISO alpha-2, up to 20. Titles rank people but do not exclude them. Seniority and countries do.
  • limit integer — At most this many people, 1 to 100. One call still returns at most 25. Defaults to 25.
  • cursor string | null — next_cursor of the previous response, with the same companies and filters.
  • max_credits integer | null — Stop before the next person would pass this.

Response

  • object string · required — Always list.
  • data object[] · required — People. id is per_… (send it to POST /person/enrich as person_ids). from_company_id is the company they were found at. signals is the current role.
  • companies object[] · required — One entry per company you sent, in order: status matched, not_found or invalid, company_id, rows, message.
  • next_cursor string | null · required — The next page.
  • credits_used integer · required — People delivered times 5.
  • truncated_by string | null · required — max_credits when the cap left people out.

Credits

5 credits per person delivered. Misses are free. Errors and empty lookups are free. A call that spent credits puts that number in credits_used, in X-Credits-Used and in X-Credits-Charged. When the wallet can be read, the response also sends X-Credits-Remaining.

Errors

  • 503 service_unavailable — A company could not be looked up just now. param names companies[i]. Nothing was charged.
  • 400 invalid_request — The body is not valid JSON, a field is unknown or has the wrong type, or a value is not allowed.
  • 401 authentication_error — The Authorization header is missing, or the key is unknown or revoked.
  • 403 permission_error — API access is not part of your plan, or your account is suspended.
  • 404 not_found — The endpoint does not exist.
  • 429 rate_limit_error — More than 60 requests per minute, or more than 3 at the same time, on one key. Wait for the Retry-After header.
  • 429 daily_limit_reached — The request could take your organization over its daily credit limit. The limit resets at midnight (Europe/Brussels).
  • 402 insufficient_credits — The credit balance is lower than this request could cost. Nothing was charged. Add credits, or send a smaller request. The error includes code, fix and a link to the credits docs.
  • 502 upstream_error — The data source did not answer. Retry later.
  • 503 service_unavailable — The API is temporarily unavailable. Retry later.
  • 500 internal_error — Something went wrong on our side.
  • 402 max_credits_exceeded — max_credits is lower than the credits of the first row, so nothing could be returned. Nothing was charged; raise max_credits or ask for fewer rows.

Example

cURL

curl -X POST "https://foundermcp.dev/api/v1/leads" \
  -H "Authorization: Bearer $FOUNDERMCP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "companies": [
      {
        "linkedin_url": "https://www.linkedin.com/company/acme-analytics"
      }
    ],
    "filters": {
      "roles": [
        "CFO",
        "Head of Finance"
      ],
      "seniority": [
        "c_level",
        "vp"
      ],
      "countries": [
        "BE"
      ]
    },
    "limit": 3,
    "max_credits": 15
  }'

JavaScript

const response = await fetch('https://foundermcp.dev/api/v1/leads', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.FOUNDERMCP_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    "companies": [
      {
        "linkedin_url": "https://www.linkedin.com/company/acme-analytics"
      }
    ],
    "filters": {
      "roles": [
        "CFO",
        "Head of Finance"
      ],
      "seniority": [
        "c_level",
        "vp"
      ],
      "countries": [
        "BE"
      ]
    },
    "limit": 3,
    "max_credits": 15
  })
});
const body = await response.json();

Python

import json
import os
import urllib.request

payload = {
  "companies": [
    {
      "linkedin_url": "https://www.linkedin.com/company/acme-analytics"
    }
  ],
  "filters": {
    "roles": [
      "CFO",
      "Head of Finance"
    ],
    "seniority": [
      "c_level",
      "vp"
    ],
    "countries": [
      "BE"
    ]
  },
  "limit": 3,
  "max_credits": 15
}

request = urllib.request.Request(
    "https://foundermcp.dev/api/v1/leads",
    headers={
    "Authorization": f"Bearer {os.environ['FOUNDERMCP_API_KEY']}",
    "Content-Type": "application/json"
    },
    data=json.dumps(payload).encode(),
    method="POST",
)
with urllib.request.urlopen(request) as response:
    body = json.load(response)

Example response

{
  "object": "list",
  "data": [
    {
      "id": "per_01J9Z6P8C8V0K3W6T2N8R5M1XK",
      "object": "person",
      "signal_type": null,
      "from_company_id": "cmp_01J9Z6P8C8V0K3W6T2N8R5M1XB",
      "credits_charged": 5,
      "person": {
        "full_name": "Jane Example",
        "title": "Chief Financial Officer",
        "linkedin_url": "https://www.linkedin.com/in/jane-example"
      }
    }
  ],
  "companies": [
    {
      "input": {
        "linkedin_url": "https://www.linkedin.com/company/acme-analytics"
      },
      "status": "matched",
      "rows": 1,
      "message": null
    }
  ],
  "next_cursor": null,
  "credits_used": 5,
  "truncated_by": null,
  "sources": [
    "linkedin"
  ],
  "notes": []
}