Guides

Org chart

Size an account: count one company's people by department and seniority, break a department into its sub-functions, and see where its people are.

Org chart shows the shape of a company rather than a list of its people. Give POST /v1/org-chart a company and it returns a department × seniority grid: how many people sit in each function at each level, with totals on both axes. Two drill-downs break a department into its sub-functions and show where the people are located.

Use Org chart when the question is "how big is this team, and how senior is it?" If you want the people themselves, use Search with category: "person". If you want to know who you already know there, use Relationships.

Use cases#

Three situations cover most uses of the org chart.

Size an account

You are deciding whether an account is worth pursuing. You get its headcount by function and level, so the team you would sell to is a number rather than a guess.

Break a department down

One function matters more than the rest. You get its sub-functions, each with a headcount and a seniority split.

See where the people are

Territory and timezone matter. You get the company's people by country, state and city, and the exact place names the grid accepts as filters.

Each tab shows the request to send and the outcome you hold when it returns.

Send the company's domain:

curl -X POST https://api.sproutsdata.ai/v1/org-chart \
  -H "X-API-Key: $SPROUTS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain": "stripe.com"}'

Outcome: the grid. departments and seniorities name the rows and columns, cells holds a count for each department and seniority pair that has people, and department_totals and seniority_totals sum each axis. total is the company's headcount.

{
  "company": { "domain": "stripe.com", "linkedin_url": null },
  "total": 8214,
  "departments": ["Engineering / Software", "Sales"],
  "seniorities": ["C-Suite", "VP", "Director / Head", "IC"],
  "cells": [
    { "department": "Engineering / Software", "seniority": "VP", "count": 38 },
    { "department": "Sales", "seniority": "Director / Head", "count": 94 }
  ],
  "department_totals": { "Engineering / Software": 2801, "Sales": 1329 },
  "seniority_totals": { "C-Suite": 4, "VP": 64, "Director / Head": 215, "IC": 3791 },
  "meta": { "request_id": "...", "environment": "live", "as_of": "...", "credential": "api_key", "credits_charged": 1 }
}

How it works#

  • Scope: all three routes require dsp.search.read.
  • Billing: all three are billed under dsp.org_chart at 1 credit flat per call. A call that returns nothing (no cells, no departments, no locations) is not charged and reports meta.credits_charged: 0. See Credits & usage.
  • Retries: all three routes honour an Idempotency-Key header.

Identify the company

Send a domain or a linkedin_url, exactly one. Sending both or neither is refused, because the two could name different companies.

  • A pasted URL is reduced to its host, so https://www.stripe.com/about and stripe.com are the same request.
  • Many companies in the index have no domain. For those, send the company's LinkedIn page: {"linkedin_url": "linkedin.com/company/stripe"}. A personal profile or a school page is refused.
  • A company name is not accepted. Find the company with Search first, then send its domain or LinkedIn URL.

Filters change the counts

Filters narrow the population before it is grouped, so "country": ["Netherlands"] returns the Dutch org chart, not the global one with cells hidden. The grid and /departments accept:

FilterValues
country, state, cityPlace names, case-insensitive. Take them from /locations. __unknown__ matches people with no value recorded at that level
employment_typeFull Time, Part Time, Freelancer, Contractor, Consultant (External)
governance_levelFounder, Co Founder, Owner, Partner, Board Member, Investor, Advisor
has_direct_access_to_c_suitetrue or false. Omit it to filter on neither

Values within one filter are combined with OR, and different filters with AND.

total is not the sum of the cells

total is everyone at the company who matches the filters. The cells can add up to less or more than that:

  • Less, because a person whose function could not be inferred is counted in total but in no cell.
  • More, because a person with several departments or seniorities is counted once in total and once in each of their cells.

Show total as the headcount and the cells as its classified breakdown. Send include_others: true to see the unclassified people as their own Others row and column.

Departments are ordered by headcount, and seniorities always run C-Suite, VP, Director / Head, Manager, IC, Entry, In Training. A pair with nobody in it is absent from cells rather than listed as zero.

The people behind a cell

The grid holds counts, not people. A cell's two labels are valid search filters, so send them to POST /v1/search to list the people:

curl -X POST https://api.sproutsdata.ai/v1/search \
  -H "X-API-Key: $SPROUTS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "category": "person",
        "include_domains": ["stripe.com"],
        "filters": {
          "department": {"include": ["Engineering / Software"]},
          "seniority": {"include": ["VP"]}
        },
        "limit": 10
      }'

For a company you reached by linkedin_url, replace include_domains with the company filter: "company": {"include": [{"value": "linkedin.com/company/stripe", "by": "li"}]}. Either way it is a separate search, billed as one. A cell labelled Others names the absence of a value, so there is nothing to search for.

Two vocabularies, deliberately

/departments returns the corpus's own sub-function labels, which are finer than the grid's departments. People with no sub-function are labelled Uncategorized there, where the grid says Others. /departments also has no total, because summing departments would leave out everyone the corpus could not place.

Errors

Everything in the errors guide applies. Two are worth handling on their own:

StatusCodeMeaning
422request.invalidThe company is unknown (the detail names the identifier you sent), or the request broke a rule such as sending both domain and linkedin_url. An unknown company is a 422, not a 404
501not_implementedOrg charts are not enabled in this deployment. It is never charged, and retrying will not change it

Best practices#

  • Prefer linkedin_url when a company has no domain. It is the only way to reach those companies, and it is exact.
  • Read total as the headcount. Never present the sum of the cells as the size of the company.
  • Fill location filters from /locations. The labels it returns are the exact values the grid accepts, so you never guess at place names.
  • Chain a cell to Search only when someone asks for the people. The org chart costs 1 credit; listing everyone behind every cell would cost far more.

For every field and parameter, see the Org chart API reference.