> ## Documentation Index
> Fetch the complete documentation index at: https://docs.keplerinsights.us/llms.txt
> Use this file to discover all available pages before exploring further.

# GET /v1/company/{domain}/cohort

> Sector + geo + business-profile-matched peer comparison.

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

```json theme={null}
{
  "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.


## OpenAPI

````yaml GET /v1/company/{domain}/cohort
openapi: 3.1.0
info:
  title: Kepler Insights API
  version: 1.0.0
  summary: Curated company-scoring intelligence over a 67-signal engine.
  description: >
    The Kepler Insights API exposes a curated subset of the Kepler scoring
    engine

    over a stable REST surface. Every score is a composite over 67 signals
    organized

    into 4 buckets (Team & Structure, Market Position, Momentum & Tailwinds,

    Financial Health), with a separate scale premium that lifts established

    companies whose underlying fundamentals justify a higher tier.


    **Authentication.** All requests require a single header: `X-API-Key`.

    Keys are issued from the developer console at
    `https://console.keplerinsights.us`.


    **Sandbox.** Test keys prefixed `ki_test_` accept only the four canned

    domains (`acme.test`, `unicorn.test`, `struggling.test`, `cohort.test`),

    never invoke fetchers, and return deterministic responses tagged with

    `mode: sandbox`. Live keys prefixed `ki_live_` reject test domains and

    run against the real engine.


    **Cold vs cached.** `GET /v1/score/{domain}` is always cached (404 if no

    recent record exists). `POST /v1/score` decides per-call based on your

    tier's freshness window: a fresh record returns inline (`200`), a stale

    or missing one queues a cold pipeline run and returns `202` with a

    `job_id` to poll. Cold spend is bounded by per-tier monthly caps +

    circuit breakers.
  contact:
    name: Kepler Insights API support
    email: noah@keplerinsights.us
  license:
    name: Proprietary
servers:
  - url: https://api.keplerinsights.us
    description: Production
security:
  - apiKey: []
tags:
  - name: scoring
    description: Score a company and retrieve the latest result.
  - name: history
    description: Time-series of past scoring runs for a single company.
  - name: company
    description: Per-company analytics (cohort, confidence).
  - name: universe
    description: Distribution + movers across the full scored universe.
  - name: meta
    description: Signal manifest + caller usage + async job tracking.
paths:
  /v1/company/{domain}/cohort:
    get:
      tags:
        - company
      summary: Sector + geo + business-profile-matched cohort comparison.
      description: |
        Returns where the target ranks against companies sharing its sector,
        geo scope, and growth/established profile. Drawn from the scoring
        event store; refresh interval depends on universe size (typically <10s).
      operationId: getCohort
      parameters:
        - $ref: '#/components/parameters/DomainPath'
      responses:
        '200':
          description: Cohort stats + member list (capped at 200).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CohortResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: Target has no scored record yet.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  parameters:
    DomainPath:
      in: path
      name: domain
      required: true
      schema:
        type: string
      example: stripe.com
      description: Bare hostname. Strips a leading `www.` and any URL scheme automatically.
  schemas:
    CohortResponse:
      type: object
      properties:
        mode:
          type: string
        target:
          type: object
          properties:
            domain:
              type: string
            company_name:
              type: string
            composite_score:
              type: number
            ki_rating:
              type: string
            business_profile:
              type: string
              enum:
                - growth
                - established
            context:
              type: object
              properties:
                sector:
                  type: string
                geo_scope:
                  type: string
        cohort:
          type: object
          description: >-
            Aggregate stats over the cohort (target excluded for percentile
            math).
          properties:
            count:
              type: integer
            mean:
              type: number
            p50:
              type: number
            p90:
              type: number
            stddev:
              type: number
            min:
              type: number
            max:
              type: number
            rank:
              type: integer
              description: 1-indexed position of target inside the cohort (1 = top).
            percentile:
              type: integer
              minimum: 0
              maximum: 100
        bucket_means:
          type: object
          description: Per-bucket comparison vs cohort mean.
          additionalProperties:
            type: object
            properties:
              target:
                type: number
              cohort:
                type: number
              delta:
                type: number
        members:
          type: array
          maxItems: 200
          description: Cohort members, sorted DESC by composite_score.
          items:
            type: object
            properties:
              domain:
                type: string
              company_name:
                type: string
              composite_score:
                type: number
              ki_rating:
                type: string
              business_profile:
                type: string
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
          example: unauthorized
        message:
          type: string
        reason:
          type: string
          description: Additional context for rate-limit responses.
  responses:
    Unauthorized:
      description: Missing or invalid `X-API-Key`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: >
        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.

````