curl --request POST \
--url https://api.datalegion.ai/company/search \
--header 'API-Key: <api-key>' \
--header 'Content-Type: application/json' \
--data @- <<EOF
{
"query": "SELECT * FROM companies WHERE industry ILIKE '%software%' AND size='1001-5000'",
"limit": 10
}
EOFimport requests
url = "https://api.datalegion.ai/company/search"
payload = {
"query": "SELECT * FROM companies WHERE industry ILIKE '%software%' AND size='1001-5000'",
"limit": 10
}
headers = {
"API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
query: 'SELECT * FROM companies WHERE industry ILIKE \'%software%\' AND size=\'1001-5000\'',
limit: 10
})
};
fetch('https://api.datalegion.ai/company/search', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.datalegion.ai/company/search",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'query' => 'SELECT * FROM companies WHERE industry ILIKE \'%software%\' AND size=\'1001-5000\'',
'limit' => 10
]),
CURLOPT_HTTPHEADER => [
"API-Key: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.datalegion.ai/company/search"
payload := strings.NewReader("{\n \"query\": \"SELECT * FROM companies WHERE industry ILIKE '%software%' AND size='1001-5000'\",\n \"limit\": 10\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.datalegion.ai/company/search")
.header("API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"query\": \"SELECT * FROM companies WHERE industry ILIKE '%software%' AND size='1001-5000'\",\n \"limit\": 10\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.datalegion.ai/company/search")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"query\": \"SELECT * FROM companies WHERE industry ILIKE '%software%' AND size='1001-5000'\",\n \"limit\": 10\n}"
response = http.request(request)
puts response.read_body{
"matches": [
{
"company": {
"legion_id": "c8a1b2c3-d4e5-6f7a-8b9c-0d1e2f3a4b5c",
"name": {
"cleaned": "stripe inc",
"display": "Stripe",
"raw": [
"Stripe, Inc."
]
},
"domain": "stripe.com",
"industry": "financial services",
"type": "private",
"size": "5001-10000",
"founded": 2010,
"linkedin_url": "https://www.linkedin.com/company/stripe",
"linkedin_id": "2135371",
"legion_employee_count": 8500,
"legion_average_tenure": 28.4,
"legion_employee_growth_rate": {
"1m": 0.012,
"3m": 0.035,
"6m": 0.068,
"12m": 0.125
},
"last_seen": "2026-01",
"num_sources": 5
}
}
],
"total": 3417
}{
"error": "<string>",
"message": "<string>",
"details": {}
}{
"error": "<string>",
"message": "<string>",
"details": {}
}{
"error": "<string>",
"message": "<string>",
"details": {}
}{
"error": "<string>",
"message": "<string>",
"details": {}
}{
"error": "<string>",
"message": "<string>",
"details": {}
}{
"error": "<string>",
"message": "<string>",
"details": {}
}{
"error": "<string>",
"message": "<string>",
"details": {}
}{
"error": "<string>",
"message": "<string>",
"details": {}
}{
"error": "<string>",
"message": "<string>",
"details": {}
}{
"error": "<string>",
"message": "<string>",
"details": {}
}Company Search (Beta)
Company Search API endpoint: query company profiles using SQL-like syntax with flexible filtering across 50+ data fields.
curl --request POST \
--url https://api.datalegion.ai/company/search \
--header 'API-Key: <api-key>' \
--header 'Content-Type: application/json' \
--data @- <<EOF
{
"query": "SELECT * FROM companies WHERE industry ILIKE '%software%' AND size='1001-5000'",
"limit": 10
}
EOFimport requests
url = "https://api.datalegion.ai/company/search"
payload = {
"query": "SELECT * FROM companies WHERE industry ILIKE '%software%' AND size='1001-5000'",
"limit": 10
}
headers = {
"API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
query: 'SELECT * FROM companies WHERE industry ILIKE \'%software%\' AND size=\'1001-5000\'',
limit: 10
})
};
fetch('https://api.datalegion.ai/company/search', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.datalegion.ai/company/search",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'query' => 'SELECT * FROM companies WHERE industry ILIKE \'%software%\' AND size=\'1001-5000\'',
'limit' => 10
]),
CURLOPT_HTTPHEADER => [
"API-Key: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.datalegion.ai/company/search"
payload := strings.NewReader("{\n \"query\": \"SELECT * FROM companies WHERE industry ILIKE '%software%' AND size='1001-5000'\",\n \"limit\": 10\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.datalegion.ai/company/search")
.header("API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"query\": \"SELECT * FROM companies WHERE industry ILIKE '%software%' AND size='1001-5000'\",\n \"limit\": 10\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.datalegion.ai/company/search")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"query\": \"SELECT * FROM companies WHERE industry ILIKE '%software%' AND size='1001-5000'\",\n \"limit\": 10\n}"
response = http.request(request)
puts response.read_body{
"matches": [
{
"company": {
"legion_id": "c8a1b2c3-d4e5-6f7a-8b9c-0d1e2f3a4b5c",
"name": {
"cleaned": "stripe inc",
"display": "Stripe",
"raw": [
"Stripe, Inc."
]
},
"domain": "stripe.com",
"industry": "financial services",
"type": "private",
"size": "5001-10000",
"founded": 2010,
"linkedin_url": "https://www.linkedin.com/company/stripe",
"linkedin_id": "2135371",
"legion_employee_count": 8500,
"legion_average_tenure": 28.4,
"legion_employee_growth_rate": {
"1m": 0.012,
"3m": 0.035,
"6m": 0.068,
"12m": 0.125
},
"last_seen": "2026-01",
"num_sources": 5
}
}
],
"total": 3417
}{
"error": "<string>",
"message": "<string>",
"details": {}
}{
"error": "<string>",
"message": "<string>",
"details": {}
}{
"error": "<string>",
"message": "<string>",
"details": {}
}{
"error": "<string>",
"message": "<string>",
"details": {}
}{
"error": "<string>",
"message": "<string>",
"details": {}
}{
"error": "<string>",
"message": "<string>",
"details": {}
}{
"error": "<string>",
"message": "<string>",
"details": {}
}{
"error": "<string>",
"message": "<string>",
"details": {}
}{
"error": "<string>",
"message": "<string>",
"details": {}
}{
"error": "<string>",
"message": "<string>",
"details": {}
}Query Format
Write aSELECT * FROM companies WHERE ... query. Do not include LIMIT or OFFSET clauses in the SQL; use the limit and offset parameters instead.
{
"query": "SELECT * FROM companies WHERE industry ILIKE '%software%' AND legion_employee_count > 100",
"limit": 5
}
Response Shape
{
"matches": [ { "company": { "..." : "..." } } ],
"total": 3417
}
-
matches: capped at the request’slimit(max 100). -
total: the full row count matching your WHERE clause across the database, not just the returned page. Useful for account-sizing: query for “fintech companies founded after 2018” withlimit: 1andtotaltells you how many accounts exist. The companionTotal-Count-Statusresponse header tells you howtotalwas derived:exact(the true count, for selective queries like the one above),estimate(on broad, low-selectivity queries the exact count exceeds its time budget, sototalbecomes the query planner’s row estimate; treat it as a magnitude, not a precise number), orpage(neither available;totalis just the returned page size). Search responses do not includematch_metadata(that field is only populated by/company/enrich). A broad query returns the same response shape with an approximate total, flagged by the header:Total-Count-Status: estimate{ "matches": [ { "company": { "..." : "..." } } ], "total": 62000 } -
Industry filters:
industryholds the LinkedIn industry names listed in Enums, lowercased. A filter no stored value can satisfy, such as an older LinkedIn name inindustry ILIKE '%information technology%', returns an empty page at once, free of charge, with aSearch-Warningresponse header naming the filter and the closest stored values.
Pagination
To page through results beyond the first 100, setoffset to the number of rows to skip. Maximum offset is 10,000.
{
"query": "SELECT * FROM companies WHERE industry ILIKE '%software%' AND legion_employee_count > 100",
"limit": 100,
"offset": 100
}
Available Columns
Text Columns
| Column | Description |
|---|---|
name_cleaned | Normalized company name (lowercased) |
name_display | Display-ready company name (original casing preserved) |
domain | Primary website domain |
industry | Industry, a LinkedIn industry name (see Enums) |
headline_cleaned | LinkedIn headline |
description_cleaned | Company description |
Numeric Columns
| Column | Description |
|---|---|
founded | Year founded |
linkedin_followers | LinkedIn follower count |
linkedin_employee_count | Employee count from LinkedIn |
legion_employee_count | Employee count from Data Legion |
legion_average_tenure | Average employee tenure (months) |
Enum Columns
| Column | Values |
|---|---|
type | private, public, nonprofit, government_agency, educational |
size | 1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+ |
Workforce Analytics Columns
| Column | Description |
|---|---|
legion_new_hire_count_1m / 3m / 6m / 12m | New hires in the 1/3/6/12 months ending at the as-of month |
legion_attrition_count_1m / 3m / 6m / 12m | Departures in the 1/3/6/12 months ending at the as-of month |
legion_employee_growth_rate_1m / 3m / 6m / 12m | Growth rate as a decimal fraction (0.05 = 5%) |
legion_turnover_rate_1m / 3m / 6m / 12m | Turnover rate as a decimal fraction (0.1 = 10%) |
Cross-Table Columns
These columns search across related tables and are automatically rewritten to subqueries:| Column | Description |
|---|---|
ticker_symbol / ticker | Stock ticker symbol |
exchange | Stock exchange |
social_url | Social media URLs |
alt_domain | Alternative domains |
ILIKE patterns with % as the wildcard (ticker ILIKE 'MS%' matches tickers starting with MS) and = for an exact match that ignores case (ticker_symbol = 'aapl', alt_domain = 'google.com'). To exclude, wrap the filter: NOT (exchange = 'nasdaq'). Other operators on these columns, such as ~*, NOT ILIKE or IN (...), return a 400 that lists the supported forms.
Example Queries
-- Software companies with 100+ employees
SELECT * FROM companies WHERE industry ILIKE '%software%' AND legion_employee_count > 100
-- Public companies in healthcare
SELECT * FROM companies WHERE type = 'public' AND industry ILIKE '%health%'
-- Fast-growing companies (20%+ growth over the 6 months to the as-of month)
SELECT * FROM companies WHERE legion_employee_growth_rate_6m > 0.2
-- Companies with high turnover (30%+ over the 12 months to the as-of month)
SELECT * FROM companies WHERE legion_turnover_rate_12m > 0.3 AND legion_employee_count > 50
Authorizations
Body
Request model for SQL query-based company search.
SQL query against company data (must not contain LIMIT)
1 - 10000Maximum results to return
1 <= x <= 100Number of results to skip for pagination (0-10000). Stable within a build; ordering may change across builds.
0 <= x <= 10000If true, format text fields in title case (names, company names, locations). Raw fields, IDs, URLs, codes, and confidence fields are excluded.
Comma-separated list of fields to include in response. If omitted, all fields are returned.
Comma-separated list of fields to exclude from response. Applied after include_fields filter.
If true, pretty-print JSON response with indentation.
Response
Success - query executed and results returned
List of matches sorted by confidence (descending). Capped at the request's limit.
Show child attributes
Show child attributes
For /company/search and /company/discover, the total number of rows matching the query's WHERE clause across the database (not just this page). For /company/enrich, the number of matches found for the input identifier. On search/discover, if the exact count exceeds its time budget (broad, low-selectivity queries) it falls back to the query planner's row estimate, and if that is unavailable, to the size of the returned page; the response header Total-Count-Status reports which (exact, estimate, or page).