API reference
Enrich Companies
Send exactly one of linkedin_urls, domains or names, with up to 25 entries. Each entry gets its own result, in the order you sent them, with a list of matches.
Each entry gives at most one company. A LinkedIn URL gives that page. A domain gives the company on exactly that domain; set exact_match to false to also accept a company the source ties to the domain on another one (confidence_score is then null). A name gives the company with exactly that name, or else the best match (confidence_score 1.0 on an exact name, null otherwise); set exact_match to true to keep only exact names. To choose between companies that share a name, use the free GET /companies/lookup and enrich the page you pick.
fields picks the groups: basic_info (the default), headcount, locations, taxonomy, followers, funding and hiring. A value we cannot fill is null, and its path is listed in unavailable, so you can tell "unknown" from "zero".
Every company found costs one credit, whatever groups you ask for; the open roles in hiring are included. Not found, invalid, capped or failed entries cost nothing, and the same company asked twice is looked up and charged once, also in two forms (a numeric LinkedIn page and its slug, or a domain and the page of the same company).
Send Authorization: Bearer gtk_…. Create the key under Connect assistant → API keys. A missing, invalid or revoked key is 401. A valid key while this API is not enabled for your organization answers 403 api_not_enabled, with what the key can do instead. Every response includes mySDR-Api-Version, mySDR-Request-Id and Cache-Control: no-store, and a response to an accepted key also X-RateLimit-* (so not a 401, a 405, an OPTIONS or a 404 for an unknown path).
Jobs
Add hiring to fields to get the open roles. company.hiring gives openings_count, the number of open roles on LinkedIn, and recent_openings: the newest roles, newest first, each with title, url, location and posted_on. The roles cost nothing extra: a company found is 1 credit, whatever groups you ask for. A value we cannot fill is null and listed in unavailable.
{
"linkedin_urls": [
"https://www.linkedin.com/company/acme-analytics"
],
"fields": [
"basic_info",
"hiring"
]
}
Authentication
Send your API key as a Bearer token: Authorization: Bearer gtk_…. Create the key under Connect assistant → API keys. A missing, invalid or revoked key is 401, including while an API is closed. On an endpoint of the Signals API or the Company API, a valid key while that API is closed for your organization answers 403 api_not_enabled, with what the key can do instead; the other endpoints work with every key. Every response includes mySDR-Api-Version, mySDR-Request-Id and Cache-Control: no-store, and a response to an accepted key also X-RateLimit-* (so not a 401, a 405, an OPTIONS or a 404 for an unknown path); every error has type, message, param and request_id.
Body parameters
linkedin_urlsstring[]— LinkedIn company pages, e.g.https://www.linkedin.com/company/acme-analytics.domainsstring[]— Company websites or domains, e.g.acme-analytics.example.namesstring[]— Company names.fieldsstring[]— Groups to return. Defaults to["basic_info"]. One of:basic_info,headcount,locations,taxonomy,followers,funding,hiring.exact_matchboolean— Domains: only a company on exactly that domain (defaults to true). Names: only a company with exactly that name (defaults to false: the best match).max_creditsinteger— Stop before the call costs more than this. An entry is looked up only while its company still fits; an entry that finds nothing costs nothing and leaves the room to the next. Entries left over arecapped. Below the cost of one company the call is402max_credits_exceeded.
Response
resultsobject[]— One entry per input, in the same order.results[].inputstring— The input as you sent it.results[].statusstring—matched,not_found,invalid(not a LinkedIn company URL, domain or name),capped(not looked up:max_creditshad no room left) orerror(lookup failed; retry later). One of:matched,not_found,invalid,capped,error.results[].match_typestring—linkedin_url,domainorname. One of:linkedin_url,domain,name.results[].matchesobject[]—confidence_scoreandcompany: one company when the status ismatched, otherwise empty.results[].matches[].confidence_scorenumber | null— 1 on a LinkedIn URL, on exactly the domain you sent or on exactly the name you sent; null otherwise (a company on another domain withexact_matchfalse, or the best match on a name).results[].matches[].companyobject— The company. See the fields below.results[].messagestring— Onnot_found,invalidandcapped: why, and what to send instead.company.linkedin_urlstring | null— The company page.company.basic_infoobject—name,linkedin_url,website,primary_domain,description,tagline,logo_url,employee_count_range,company_type,year_founded.company.headcountobject—total(employees on LinkedIn) andrange. Growth, role mix and region mix are null and listed inunavailable.company.locationsobject—headquarters,city,state,country,country_code,street_address,postal_codeandall_office_addresses.company.taxonomyobject—industryandspecialities.company.followersobject—count. Follower growth is null and listed inunavailable.company.fundingobject—last_round_type,last_round_amount_usd,last_fundraise_date,investorsandrounds(newest first), from the funding rounds we track.company.hiringobject—openings_count(open roles on LinkedIn) andrecent_openings: the newest roles, withtitle,url,locationandposted_on.company.unavailablestring[]— Paths in the requested groups that this API cannot fill for this company.credits_usedinteger— Credits this call used.truncated_bystring— Only whenmax_creditsleft entriescapped:max_credits. One of:max_credits.
Credits
1 credit per company found. 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
- 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. - 403
api_not_enabled— The key is valid, but the Signals API or the Company API is not enabled for your organization yet. The error says what this key can do. - 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). - 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.
Example
cURL
curl -X POST "https://mysdr.app/api/v1/company/enrich" \
-H "Authorization: Bearer $MYSDR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"linkedin_urls": [
"https://www.linkedin.com/company/acme-analytics"
],
"fields": [
"basic_info",
"headcount"
]
}'
JavaScript
const response = await fetch('https://mysdr.app/api/v1/company/enrich', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.MYSDR_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
"linkedin_urls": [
"https://www.linkedin.com/company/acme-analytics"
],
"fields": [
"basic_info",
"headcount"
]
})
});
const body = await response.json();
Python
import json
import os
import urllib.request
payload = {
"linkedin_urls": [
"https://www.linkedin.com/company/acme-analytics"
],
"fields": [
"basic_info",
"headcount"
]
}
request = urllib.request.Request(
"https://mysdr.app/api/v1/company/enrich",
headers={
"Authorization": f"Bearer {os.environ['MYSDR_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
{
"results": [
{
"input": "https://www.linkedin.com/company/acme-analytics",
"status": "matched",
"match_type": "linkedin_url",
"matches": [
{
"confidence_score": 1,
"company": {
"linkedin_url": "https://www.linkedin.com/company/acme-analytics",
"basic_info": {
"name": "Acme Analytics",
"linkedin_url": "https://www.linkedin.com/company/acme-analytics",
"website": "https://acme-analytics.example",
"primary_domain": "acme-analytics.example",
"description": "Analytics for finance teams.",
"tagline": null,
"logo_url": null,
"employee_count_range": "51-200",
"company_type": "Privately Held",
"year_founded": 2019
},
"headcount": {
"total": 87,
"range": "51-200",
"growth_percent": {
"1m": null,
"3m": null,
"6m": null,
"12m": null
},
"growth_absolute": {
"1m": null,
"3m": null,
"6m": null,
"12m": null
},
"by_role": null,
"by_region": null,
"largest_headcount_country": null
},
"unavailable": [
"headcount.growth_percent",
"headcount.growth_absolute",
"headcount.by_role",
"headcount.by_region",
"headcount.largest_headcount_country"
]
}
}
]
}
],
"credits_used": 1
}