Skip to main content
GET
/
v1
/
company
/
{domain}
/
cohort
Sector + geo + business-profile-matched cohort comparison.
curl --request GET \
  --url https://api.keplerinsights.us/v1/company/{domain}/cohort \
  --header 'X-API-Key: <api-key>'
import requests

url = "https://api.keplerinsights.us/v1/company/{domain}/cohort"

headers = {"X-API-Key": "<api-key>"}

response = requests.get(url, headers=headers)

print(response.text)
const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};

fetch('https://api.keplerinsights.us/v1/company/{domain}/cohort', 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.keplerinsights.us/v1/company/{domain}/cohort",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

import (
"fmt"
"net/http"
"io"
)

func main() {

url := "https://api.keplerinsights.us/v1/company/{domain}/cohort"

req, _ := http.NewRequest("GET", url, nil)

req.Header.Add("X-API-Key", "<api-key>")

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.get("https://api.keplerinsights.us/v1/company/{domain}/cohort")
.header("X-API-Key", "<api-key>")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.keplerinsights.us/v1/company/{domain}/cohort")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'

response = http.request(request)
puts response.read_body
{
  "mode": "<string>",
  "target": {
    "domain": "<string>",
    "company_name": "<string>",
    "composite_score": 123,
    "ki_rating": "<string>",
    "context": {
      "sector": "<string>",
      "geo_scope": "<string>"
    }
  },
  "cohort": {
    "count": 123,
    "mean": 123,
    "p50": 123,
    "p90": 123,
    "stddev": 123,
    "min": 123,
    "max": 123,
    "rank": 123,
    "percentile": 50
  },
  "bucket_means": {},
  "members": [
    {
      "domain": "<string>",
      "company_name": "<string>",
      "composite_score": 123,
      "ki_rating": "<string>",
      "business_profile": "<string>"
    }
  ]
}
{
"error": "unauthorized",
"message": "<string>",
"reason": "<string>"
}
{
"error": "unauthorized",
"message": "<string>",
"reason": "<string>"
}
Where does this company rank against companies that are actually like it — same sector, same geographic scope, same growth-or-established profile? /v1/distribution gives universe context; this endpoint gives matched-peer context, which is usually what an analyst actually wants.

When to use it

  • “Is composite_score = 67 actually good for a B2B SaaS in growth stage?”
  • “Show me where this company ranks against its competitive set.”
  • Building a comp table next to a profile page.

Matching rules

The cohort filter uses three fields from the target’s stored record:
  1. sector (e.g. saas, fintech, healthcare, …)
  2. geo_scope (e.g. us, eu, global, …)
  3. business_profile (growth or established)
A company is in the cohort if all three match the target’s. The target itself is excluded for percentile / rank math.

Response highlights

{
  "target": {
    "domain": "stripe.com",
    "ki_rating": "KI-1+",
    "composite_score": 78.2,
    "business_profile": "growth",
    "context": { "sector": "fintech", "geo_scope": "global" }
  },
  "cohort": {
    "count": 47,
    "mean": 51.3, "p50": 50.8, "p90": 68.4,
    "stddev": 11.2,
    "rank": 1, "percentile": 100
  },
  "bucket_means": {
    "team_structure":     { "target": 82.0, "cohort": 54.2, "delta": 27.8 },
    "market_position":    { "target": 81.5, "cohort": 53.7, "delta": 27.8 },
    "momentum_tailwinds": { "target": 76.0, "cohort": 50.1, "delta": 25.9 },
    "financial_health":   { "target": 73.5, "cohort": 47.0, "delta": 26.5 }
  },
  "members": [
    { "domain": "...", "composite_score": 68.4, "ki_rating": "KI-1" },
    ...
  ]
}
members is capped at 200 and sorted DESC by composite score. bucket_means.{bucket}.delta is target − cohort.mean — positive = target outperforms cohort on that bucket.

What 404 means

If the target has never been scored, you get 404 { error: "no_history" }. Trigger a score with POST /v1/score first. If the target exists but has no peers (rare — usually a very narrow sector / geo combination), the response is 200 with cohort.count: 0. Render gracefully.

Refresh cadence

The cohort is computed over the latest record per domain from the Kepler event stream. Refresh interval matches the platform’s scoring cadence — most cohorts are at most ~24 hours stale.

Authorizations

X-API-Key
string
header
required

Live keys are prefixed ki_live_, test keys ki_test_. Issue + revoke keys at https://console.keplerinsights.us. Never embed a key in client-side code — every endpoint is backend-to-API only.

Path Parameters

domain
string
required

Bare hostname. Strips a leading www. and any URL scheme automatically.

Response

Cohort stats + member list (capped at 200).

mode
string
target
object
cohort
object

Aggregate stats over the cohort (target excluded for percentile math).

bucket_means
object

Per-bucket comparison vs cohort mean.

members
object[]

Cohort members, sorted DESC by composite_score.

Maximum array length: 200