Company lookup
POST /v1/company turns a LinkedIn company URL, slug, numeric id or URN into a structured company profile.
POST https://api.happyfetch.net/v1/company
Request#
| Field | Type | Required | Meaning |
|---|---|---|---|
url |
string | yes | The company reference, in any of the forms below. |
max_age |
integer, seconds | no | The oldest cached answer you accept. 0 forces a fresh fetch. Defaults to 7 days. See Caching. |
Every form of the same company leads to the same profile and the same cache entry:
| You send | Read as |
|---|---|
https://www.linkedin.com/company/stripe/ |
the slug stripe. The scheme and subdomain don't matter, and /about/, query strings and fragments are ignored. |
company/stripe or stripe |
the slug stripe |
https://www.linkedin.com/company/2135371/ or 2135371 |
the numeric id 2135371 |
urn:li:organization:2135371 |
the numeric id 2135371 (also urn:li:company: and urn:li:fsd_company:) |
Profile (/in/), school, showcase and job URLs are rejected with
invalid_company_reference and aren't charged.
Example#
curl https://api.happyfetch.net/v1/company --max-time 120 \
-H "Authorization: Bearer $HAPPYFETCH_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"url":"https://www.linkedin.com/company/stripe"}'const res = await fetch("https://api.happyfetch.net/v1/company", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.HAPPYFETCH_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(), // send the same key when you retry this call
},
body: JSON.stringify({
"url": "https://www.linkedin.com/company/stripe"
}),
signal: AbortSignal.timeout(120_000),
});
const { data, meta, error } = await res.json();
if (!res.ok) throw new Error(`${error.code}: ${error.message}`);
console.log(meta.request_id, meta.cache.status, data);import os, uuid, requests
res = requests.post(
"https://api.happyfetch.net/v1/company",
headers={
"Authorization": f"Bearer {os.environ['HAPPYFETCH_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()), # send the same key when you retry this call
},
json={
"url": "https://www.linkedin.com/company/stripe"
},
timeout=120,
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
print(body["meta"]["request_id"], body["meta"]["cache"]["status"])Response#
data has 18 fields. Every key is always present; a value is null when it isn't available.
| Field | Type | Meaning |
|---|---|---|
name |
string or null | Company name. |
tagline |
string or null | The one-line tagline. |
description |
string or null | The About text. |
industry |
string or null | Industry label. |
websiteUrl |
string or null | Company website. |
phone |
string or null | Phone number, when public. |
logo |
string or null | Logo image URL. |
backgroundUrl |
string or null | Cover image URL. |
followerCount |
integer or null | Followers on the company page. |
employeeCount |
integer or null | The employee count the company page shows, when it shows one. |
employeeCountRange |
{start, end} or null | Size band; end is null for open-ended bands. |
foundedOn |
{year} or null | Founding year. |
headquarter |
address or null | Headquarters address. |
locations |
array of addresses | Office addresses. |
specialities |
array of strings | Specialties. |
universalName |
string or null | The canonical slug. It changes when the company is renamed. |
linkedInUrl |
string or null | The canonical LinkedIn company page URL. |
linkedInId |
string or null | Numeric organization id, as a string. Use it as your stable key: it never changes. |
An address, in headquarter and in each entry of locations, has city, country, postalCode,
street1, street2, and geographicArea (headquarters) or state (locations). Any of them can be null.
The complete response for Stripe, exactly as the API returns it:
{
"data": {
"name": "Stripe",
"tagline": "Help increase the GDP of the internet.",
"description": "Stripe builds programmable financial services. Millions of companies—from the world’s largest enterprises to the most ambitious startups—use Stripe to accept payments, grow their revenue, and accelerate new business opportunities. Headquartered in San Francisco and Dublin, the company aims to increase the GDP of the internet.",
"industry": "Technology, Information and Internet",
"websiteUrl": "https://stripe.com",
"phone": null,
"logo": "https://media.licdn.com/dms/image/v2/D560BAQE2ZfJyfn-VCg/company-logo_200_200/B56ZlyKwpUKIAI-/0/1758557047806/stripe_logo?e=2147483647&v=beta&t=En4Hm6NDGbDTYCoOQ0Ko5Ne2gylx0WRb0yL2GlOeXBQ",
"backgroundUrl": "https://media.licdn.com/dms/image/v2/D563DAQFt98MykXcktg/image-scale_191_1128/B56Z352EMMKIAY-/0/1778013193531/stripe_cover?e=2147483647&v=beta&t=UwiZWbPrYkD77DpQmZIjVuuqKMCfyZ-e-YcHE336MlY",
"followerCount": 1721407,
"employeeCount": 16594,
"employeeCountRange": {
"start": 5001,
"end": 10000
},
"foundedOn": {
"year": 2010
},
"headquarter": {
"city": "South San Francisco",
"country": "US",
"geographicArea": "California",
"postalCode": "94080",
"street1": "354 Oyster Point Blvd",
"street2": null
},
"locations": [
{
"city": "South San Francisco",
"country": "US",
"postalCode": "94080",
"state": "California",
"street1": "354 Oyster Point Blvd",
"street2": null
}
],
"specialities": [],
"universalName": "stripe",
"linkedInUrl": "https://www.linkedin.com/company/stripe",
"linkedInId": "2135371"
},
"meta": {
"request_id": "85fcc6e9-767a-44b1-876e-4099e3542ef9",
"endpoint": "company",
"credits_charged": 2,
"credits_remaining": 198,
"cache": {
"status": "miss",
"age_seconds": 0,
"fetched_at": "2026-09-22T17:40:00.000Z",
"max_age_seconds": 604800
},
"content_hash": "sha256:5da96e23d8f77cc3b21e33ef47ed3f0086328e61fdf427f2941e351f56af9554",
"canonical": {
"slug": "stripe",
"id": "2135371"
}
}
}meta.canonical holds the canonical slug and numeric id. Use canonical.id (the same as
data.linkedInId) as your stable key: a renamed company gets a new slug but keeps its id, and old slugs
and ids lead back to the same record. When the id is null, fall back to canonical.slug.
Price#
A lookup by LinkedIn company URL costs 2 credits fetched now and 1 credit from our cache. A confirmed not-found costs 1 credit, and nothing from our cache. A confirmed not-found is the error not_found or
unresolvable_id. Calls we can't complete are refunded automatically. See
Credits, billing and refunds.