Skip to main content
POST
/
v1
/
score
Score a company. Cached returns inline, cold returns a job.
curl --request POST \
  --url https://api.keplerinsights.us/v1/score \
  --header 'Content-Type: application/json' \
  --header 'X-API-Key: <api-key>' \
  --data '
{
  "domain": "stripe.com",
  "force_fresh": false,
  "wait": true
}
'
{
  "domain": "<string>",
  "scored_at": "2023-11-07T05:31:56Z",
  "ki_rating": "KI-1+",
  "composite_score": 50,
  "buckets": {
    "team_structure": 50,
    "market_position": 50,
    "momentum_tailwinds": 50,
    "financial_health": 50
  },
  "mode": "<string>",
  "scale_premium": 6,
  "rank": {
    "percentile": 50,
    "cohort_size": 1
  },
  "x_kepler": {
    "tier": "free",
    "cache_status": "cached",
    "freshness_window_hours": 123
  }
}

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.

The primary scoring entry point. Returns the latest score for domain from cache when a stored record is within your tier’s freshness window, or starts a cold scoring job when no fresh record exists.

Two response shapes

  • HTTP 200 — a cached score is available. Returned inline; ready to use.
  • HTTP 202 — no fresh record. The server has started a cold scoring run and returned a job_id. Poll GET /v1/jobs/{job_id} until status: "complete".
Cold scoring runs typically take 25–90 seconds end-to-end. They are billed when the job starts, not when you finish polling — abandoning a poll loop does not get you a refund.

When you’ll see each path

  • Cached (200) — the dominant path. Most calls hit it; tier-determined freshness windows are designed so that customer traffic mostly reuses recent work.
  • Cold (202) — first time you’ve ever asked for domain, or the most recent record is older than your tier’s window.
Your tier’s freshness window:
TierWindow
Free7 days (sandbox only — Free can’t run live cold)
Starter24 hours
Growth6 hours
Scale1 hour
Enterprise15 minutes

Example (Python SDK)

The official SDK handles both shapes transparently. score() blocks until the score is ready, polling internally on the cold path.
from kepler_insights import Kepler

k = Kepler(api_key="ki_live_...")

score = k.score("stripe.com")               # blocks up to 180s on cold
print(f"{score.domain}: {score.ki_rating} ({score.composite_score:.1f})")

# Non-blocking — get the Job and poll yourself:
job = k.start_score("acme-co.com")
print(job.id)
score = job.wait(timeout=240)

Example (curl, manual polling)

# 1. Submit
curl -X POST https://api.keplerinsights.us/v1/score \
  -H "X-API-Key: ki_live_..." \
  -H "Content-Type: application/json" \
  -d '{"domain":"stripe.com"}'

# Cached response (200):
# { "domain": "stripe.com", "ki_rating": "KI-1", "composite_score": 73.65, ... }

# Cold response (202):
# { "job_id": "679a9e32-...", "status": "pending",
#   "domain": "stripe.com", "poll_url": "/v1/jobs/679a9e32-..." }

# 2. Poll until terminal (cold only)
curl https://api.keplerinsights.us/v1/jobs/679a9e32-... \
  -H "X-API-Key: ki_live_..."
Branch on the response: if the body has composite_score, you have the score inline. If it has job_id, queue a poll loop on the poll_url.

Field notes

  • composite_score is 0–100, not 0–10. Easy mistake when reading.
  • scale_premium is a separate additive bonus (up to ~12 pts). It’s already applied to composite_score; the field is broken out so you can show “47.0 composite + 4.1 scale premium” if you want.
  • rank is computed against the full universe Kepler has ever scored, not just the active cohort. Use /v1/company/{domain}/cohort for sector-matched comparison.
  • x_kepler.cache_status is "cached" on the 200 path. On the 202 path, the eventual GET /v1/jobs/{job_id}score_url response carries cache_status: "cold".
  • wait parameter is accepted but ignored. Cold = async, always. The parameter is preserved so older client code doesn’t break.

Sandbox behavior

ki_test_ keys against the 4 canned domains (acme.test, unicorn.test, struggling.test, cohort.test) always return inline 200. Sandbox has no cold path — there’s nothing to queue. This means production code paths that branch on 202 won’t be exercised in the sandbox. Test the polling path against a fresh live domain in staging before relying on it.

Authorizations

X-API-Key
string
header
required

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

Query Parameters

wait
enum<string>
default:true

Accepted for backwards compatibility, ignored. Cold is always async.

Available options:
true,
false

Body

application/json
domain
string
required
Example:

"stripe.com"

force_fresh
boolean
default:false

Enterprise-only. Forces a cold run even if a fresh record exists.

wait
boolean
default:true
deprecated

Accepted for backwards compatibility, ignored. Cold is always async.

Response

Cached score (fresh under your tier's window).

domain
string
required
scored_at
string<date-time>
required
ki_rating
enum<string>
required
Available options:
KI-1+,
KI-1,
KI-2+,
KI-2,
KI-3,
KI-4,
KI-5
composite_score
number<float>
required
Required range: 0 <= x <= 100
buckets
object
required

The 4 KI buckets. Each is 0–100.

mode
string

Present and = sandbox only with a ki_test_ key.

scale_premium
number<float>

Up to ~12 pts for established mega-caps; up to ~6 pts for growth profile.

Required range: 0 <= x <= 12
rank
object
x_kepler
object

Caller-facing metadata. Stable across versions.