Documentation Index
Fetch the complete documentation index at: https://docs.crustdata.com/llms.txt
Use this file to discover all available pages before exploring further.
This page lists every behavioral and contract change between the legacy
company-enrich endpoint and the current one. Use it as a side-by-side
reference when porting an integration; each section gives the old shape,
the new shape, and the smallest edit that closes the gap.
| Topic | Legacy | Current |
|---|
| Path | GET /screener/company | POST /company/enrich |
| Method | GET with query parameters | POST with a JSON body |
| Auth | Authorization: Token <key> | Authorization: Bearer <key> |
| Version | (not required) | x-api-version: 2025-11-01 (required) |
| Base URL | https://api.crustdata.com | https://api.crustdata.com |
Three header / shape changes are required. The HTTP method moved from
GET to POST, the authorization scheme moved from Token <key> to
Bearer <key>, and the x-api-version: 2025-11-01 header is now
required on every call. Calls missing any of these are rejected.
1. Request — top-level keys
Identifiers moved from comma-separated query parameters to JSON arrays in
the request body. Submit exactly one identifier type per request (up to 25
values).
| Legacy query parameter | Current body key | Notes |
|---|
?company_domain=stripe.com,google.com | { "domains": ["stripe.com", "google.com"] } | Comma-separated string → JSON array. |
?company_name=Stripe,Google | { "names": ["Stripe", "Google"] } | Comma-separated string → JSON array. |
?company_id=12345,67890 | { "crustdata_company_ids": [12345, 67890] } | Strings of digits → JSON array of integers. |
?company_linkedin_url=https://... | { "professional_network_profile_urls": ["https://..."] } | Key renamed. |
?fields=name,headcount | { "fields": ["basic_info.name", "headcount"] } | Comma-separated string → JSON array. Section names changed — see Field-name mapping. |
?exact_match=true | { "exact_match": true } | Moved into the body. Default is now null (auto-detect) rather than false. |
?enrich_realtime=true | (removed) | No direct replacement on this endpoint — see Removed features. |
Submit exactly one identifier type per request. Mixing domains,
names, crustdata_company_ids, and professional_network_profile_urls in
the same call returns 400. Maximum 25 values per identifier array.
fields is no longer optional in practice. When omitted, the response
contains only crustdata_company_id and basic_info. Sections such as
headcount, funding, people, hiring, web_traffic, seo,
competitors, employee_reviews, software_reviews, news,
social_profiles, taxonomy, and followers must be listed explicitly.
2. Identifier behavior
| Topic | Legacy | Current |
|---|
| Identifier shape | Comma-separated string in a query parameter | JSON array in the body |
| Max values per request | 25 | 25 |
| Mutual exclusion | Pass one identifier parameter | Pass one identifier array |
| Mixed-identifier error | 400 with "Please provide only one type of input" | 400 with { error: { type: "invalid_request", message: "..." } } |
| Over-limit error | 400 with provided_count / max_allowed fields | 400 with the new error envelope |
3. Field-name mapping
The legacy response was a flat object with linkedin_*, glassdoor, g2,
crunchbase_*, producthunt, and gartner sections at the top level. The
current response groups fields under basic_info, headcount, funding,
taxonomy, revenue, locations, competitors, followers,
social_profiles, hiring, web_traffic, seo, employee_reviews,
software_reviews, public_launches, and market_intel.
Identity and profile
| Legacy field | Current field |
|---|
company_id | crustdata_company_id (top-level) / basic_info.crustdata_company_id |
company_name | basic_info.name |
company_website_domain | basic_info.primary_domain |
company_website | basic_info.website |
domains | basic_info.all_domains |
linkedin_profile_url | basic_info.professional_network_url |
linkedin_id | basic_info.professional_network_id |
linkedin_profile_name | basic_info.profile_name |
linkedin_company_description | basic_info.description |
linkedin_logo_url / linkedin_logo_permalink | basic_info.logo_permalink |
linkedin_industries | basic_info.industries[] |
company_type | basic_info.company_type |
year_founded | basic_info.year_founded (now an integer; see Type changes) |
employee_count_range | basic_info.employee_count_range |
markets | basic_info.markets |
last_updated | updated_at (top-level) |
Taxonomy
| Legacy field | Current field |
|---|
linkedin_industry | taxonomy.professional_network_industry |
taxonomy.linkedin_industry | taxonomy.professional_network_industry |
taxonomy.linkedin_industries | taxonomy.professional_network_industries |
taxonomy.linkedin_specialities | taxonomy.professional_network_specialities |
crunchbase_categories / taxonomy.crunchbase_categories | taxonomy.categories |
taxonomy.primary_naics_detail | taxonomy.primary_naics_detail |
taxonomy.sic_detail_list | taxonomy.sic_detail_list |
Headcount
| Legacy field | Current field |
|---|
headcount.linkedin_headcount | headcount.total |
headcount.linkedin_headcount_total_growth_percent | headcount.growth_percent |
headcount.linkedin_headcount_by_role_absolute | headcount.by_role_absolute |
headcount.linkedin_headcount_by_role_percent | headcount.by_role_percent |
headcount.linkedin_headcount_by_region_absolute | headcount.by_region_absolute |
headcount.linkedin_headcount_timeseries | (available via the broader timeseries response on enrich) |
largest_headcount_country | headcount.largest_headcount_country |
Followers
| Legacy field | Current field |
|---|
linkedin_followers.linkedin_followers | followers.count |
linkedin_followers.linkedin_followers_mom_percent | followers.mom_percent |
linkedin_followers.linkedin_followers_qoq_percent | followers.qoq_percent |
linkedin_followers.linkedin_followers_six_months_growth_percent | followers.six_months_growth_percent |
linkedin_followers.linkedin_followers_yoy_percent | followers.yoy_percent |
Funding and investors
| Legacy field | Current field |
|---|
funding_and_investment.crunchbase_total_investment_usd | funding.total_investment_usd |
funding_and_investment.last_funding_round_investment_usd | funding.last_round_amount_usd |
funding_and_investment.last_funding_round_type | funding.last_round_type |
funding_and_investment.crunchbase_investors | funding.investors |
funding_and_investment.crunchbase_investors_info_list | funding.investors_detail |
funding_and_investment.funding_milestones_timeseries | funding.funding_rounds[] (renamed; same one-row-per-round shape) |
funding_and_investment.acquisitions | funding.acquisitions[] (see Acquisitions schema) |
funding_and_investment.acquired_by | funding.acquired_by[] |
crunchbase_valuation_usd / crunchbase_valuation_date | funding.valuation_usd / funding.valuation_date |
Acquisitions schema
The acquisitions object keeps the same fields but the field names are
consistently prefixed by acquirer_* / acquiree_* in the new endpoint.
| Legacy field | Current field |
|---|
acquirer_company_id | acquirer_company_id |
acquirer_company_name | acquirer_company_name |
acquiree_company_id | acquiree_company_id |
acquiree_company_name | acquiree_company_name |
announced_on_date | announced_on_date |
price_usd | price_usd |
transaction_text | transaction_text |
Revenue and public-market data
| Legacy field | Current field |
|---|
estimated_revenue_lower_bound_usd | revenue.estimated.lower_bound_usd |
estimated_revenue_higher_bound_usd | revenue.estimated.upper_bound_usd |
estimated_revenue_timeseries | revenue.estimated.timeseries |
acquisition_status | revenue.acquisition_status |
stock_symbols | revenue.public_markets.stock_symbols |
fiscal_year_end | revenue.public_markets.fiscal_year_end |
ipo_date | revenue.public_markets.ipo_date |
Locations
| Legacy field | Current field |
|---|
hq_country | locations.country |
hq_state | locations.state |
headquarters | locations.headquarters |
hq_street_address | locations.street_address |
all_office_addresses | locations.all_office_addresses |
hq_city | (removed from response; available via the location parser) |
Competitors
| Legacy field | Current field |
|---|
competitors.competitor_website_domains | competitors.all_domains |
competitors.paid_seo_competitors_website_domains | competitors.paid_seo |
competitors.organic_seo_competitors_website_domains | competitors.organic_seo |
Job openings → hiring
The legacy job_openings section is now hiring.
| Legacy field | Current field |
|---|
job_openings.recent_job_openings_title | hiring.recent_titles_csv |
job_openings.job_openings_count | hiring.openings_count |
job_openings.job_openings_count_growth_percent | hiring.openings_growth_percent |
job_openings.open_jobs_timeseries | hiring.openings_timeseries |
job_openings.recent_job_openings[] | hiring.recent_openings[] |
Web traffic and SEO
Field paths are unchanged in shape — they remain under web_traffic and
seo — but the response is keyed by domain under web_traffic (so you can
distinguish traffic across multiple owned domains).
Social profiles
The legacy spec exposed brand-specific keys (company_twitter_url,
crunchbase_profile_url). These are consolidated under social_profiles:
| Legacy field | Current field |
|---|
company_twitter_url | social_profiles.twitter_url |
crunchbase_profile_url | social_profiles.crunchbase.url |
crunchbase_profile_uuid | social_profiles.crunchbase.uuid |
| (new — see Added features) | social_profiles.professional_network |
Employee reviews
Brand-specific keys (glassdoor.glassdoor_*) are replaced by neutral keys
under employee_reviews:
| Legacy field | Current field |
|---|
glassdoor.glassdoor_overall_rating | employee_reviews.overall_rating |
glassdoor.glassdoor_review_count | employee_reviews.review_count |
glassdoor.glassdoor_culture_rating | employee_reviews.culture_and_values_rating |
glassdoor.glassdoor_work_life_balance_rating | employee_reviews.work_life_balance_rating |
glassdoor.glassdoor_compensation_rating | employee_reviews.compensation_and_benefits_rating |
glassdoor.glassdoor_career_opportunities_rating | employee_reviews.career_opportunities_rating |
glassdoor.glassdoor_senior_management_rating | employee_reviews.senior_management_rating |
glassdoor.glassdoor_diversity_rating | employee_reviews.diversity_and_inclusion_rating |
glassdoor.glassdoor_recommend_to_friend_pct | employee_reviews.recommend_to_friend_rating |
glassdoor.glassdoor_business_outlook_pct | employee_reviews.business_outlook_rating |
glassdoor.glassdoor_ceo_approval_pct | (now surfaced via Employee Review Enrich — company_ceo.ceo_rating) |
Software reviews
Brand-specific g2.* keys are replaced by neutral keys under
software_reviews:
| Legacy field | Current field |
|---|
g2.g2_review_count | software_reviews.review_count |
g2.g2_average_rating | software_reviews.average_rating |
Product launches
Brand-specific producthunt.* keys are replaced by neutral keys under
public_launches:
| Legacy field | Current field |
|---|
producthunt.rating | public_launches.rating |
producthunt.num_upvotes | public_launches.num_upvotes |
producthunt.num_reviews | public_launches.num_reviews |
producthunt.num_followers | public_launches.num_followers |
producthunt.categories | public_launches.categories |
producthunt.makers[] | public_launches.makers[] |
producthunt.reviews[] | public_launches.reviews[] |
producthunt.launches[] | public_launches.launches[] |
producthunt.last_updated | public_launches.last_updated |
Market intelligence
Brand-specific gartner.* keys are replaced by neutral keys under
market_intel:
| Legacy field | Current field |
|---|
gartner.year_founded | market_intel.year_founded (integer) |
gartner.head_office_city | market_intel.head_office_city |
gartner.head_office_country | market_intel.head_office_country |
gartner.num_employees_min / _max | market_intel.num_employees_min / _max |
gartner.products[] | market_intel.products[] |
gartner.reviews[] | market_intel.reviews[] |
People
| Legacy field | Current field |
|---|
decision_makers[] | people.decision_makers[] |
founders.profiles[] | people.founders[] |
cxos[] | people.cxos[] |
ceo_location | (available inside people.cxos[]) |
News
| Legacy field | Current field |
|---|
news_articles[].article_url | news[].article_url |
news_articles[].article_title | news[].article_title |
news_articles[].article_publish_date | news[].article_publish_date |
news_articles[].article_publisher_name | news[].article_publisher_name |
For the full enrich-response field catalog, see
Company Enrich reference.
4. Type changes
| Field | Legacy type | Current type | Notes |
|---|
year_founded | string | integer | Past responses returned "2017"; current responses return 2017. |
exact_match default | false | null (auto-detect) | The new endpoint treats null as “let the backend decide”. Pass true for strict domain matching. |
year_founded is now an integer. Update any parsing logic that expected
a quoted string ("2017") — values are now bare numbers (2017).
5. Removed features
enrich_realtime query parameter
The legacy endpoint used enrich_realtime=true to fall back to live
retrieval when a company was not in the indexed dataset. This flag has been
removed and has no direct replacement on the current endpoint —
/company/enrich serves the indexed dataset only. If a company is not
present, the request returns an entry with empty matches: [] rather than
attempting a live fetch. Contact
support@crustdata.co if you need on-demand
live company enrichment for an account.
Brand-named response sections
Top-level glassdoor, g2, producthunt, gartner sections are removed.
Their values are returned under the neutralized employee_reviews,
software_reviews, public_launches, and market_intel sections — see
the mapping tables above.
status: "enriching" | "not_found" field
The legacy response included a status field with values "enriching" and
"not_found", and an accompanying companies_to_be_enriched array. The
current endpoint represents no-match as an entry with an empty matches
array instead — see Response shape.
Comma-separated query parameter style
The endpoint moved from GET with query parameters to POST with a JSON
body. All identifiers must be sent as JSON arrays.
6. Added features
| Feature | Description |
|---|
| Match-result envelope | The response wraps each result in { matched_on, match_type, matches: [{ confidence_score, company_data }] }, making batch matching unambiguous. |
confidence_score | Numeric score on each match candidate. Higher is better; 1.0 is common for direct identifier lookups. |
updated_at, indexed_at | Top-level timestamps marking the most recent profile refresh and indexing. |
social_profiles.professional_network | Professional-network profile URL surfaced alongside legacy social links. |
public_launches, market_intel | Neutralized replacements for the legacy producthunt / gartner blocks. |
| Stable error envelope | All 4xx/5xx errors return { "error": { "type", "message", "metadata" } }. |
7. Response shape
The envelope shape changed. The legacy endpoint returned a top-level array
of company records. The current endpoint returns a top-level array of
match-result envelopes, each containing one or more company_data
candidates.
Envelope
[
{
"company_id": 633593,
"company_name": "Retool",
"company_website_domain": "retool.com",
"year_founded": "2017",
"linkedin_industry": "Software Development",
"headcount": { "linkedin_headcount": 443 }
}
]
Match-result fields
| Field | Description |
|---|
matched_on | The input value you submitted (a domain, name, ID, or profile URL). |
match_type | One of domain, name, crustdata_company_id, professional_network_profile_url. |
matches | Array of candidate matches. Empty when nothing matched. |
matches[].confidence_score | Number. Higher is better. 1.0 is common for direct identifier lookups. |
matches[].company_data | Full enriched company profile — see Field-name mapping for section paths. |
No-match behavior
Each entry corresponds to one input identifier. When nothing matches, the
entry’s matches array is empty:
[
{
"matched_on": "thisdomaindoesnotexist12345xyz.com",
"match_type": "domain",
"matches": []
}
]
The legacy endpoint returned 404 when no companies matched. The current
endpoint returns 200 with empty matches: [] for unmatched identifiers.
The OpenAPI contract still defines 404 for completeness — handle both.
8. Error responses
The error envelope changed shape. Status codes are unchanged (400, 401,
403, 500).
{
"error": "Please provide only one type of input: company_name, company_domain, company_linkedin_url, or company_id"
}
401 continues to use a flat { "message": "Invalid API key in request" }
shape — parse based on HTTP status.
9. End-to-end example
Enriching two companies by domain — written against both endpoints.
curl --request GET \
--url 'https://api.crustdata.com/screener/company?company_domain=retool.com,serverobotics.com&fields=company_name,headcount.linkedin_headcount,funding_and_investment.crunchbase_total_investment_usd' \
--header 'authorization: Token YOUR_API_KEY'
Migration checklist
See also