Platform API v1
Legit Scores in your product
For campaign platforms that pay creators per view, agencies and brand tools: start a check of a TikTok or Instagram account, read the result when it’s ready, or look up a recent score before you approve a payout or a deal.
What it does
The API runs the same LEGIT Engine as legitscore.io: it samples the account’s public audience and engagement and returns a 0–100 confidence opinion on how real and responsive that audience is, with a confidence band, a tier, the five pillar scores, the audience cohort mix and the top reasons. Only audience behaviour counts: a creator’s format (on camera or faceless, human or AI) is never an input. How it works: methodology.
Authentication
Keys are issued by Legit Score per partner; email hello@legitscore.io to request one. Send it on every request:
Authorization: Bearer ls_live_3f9a1c2b7d4e_…A key is shown once, when we create it, and sent to you privately; we store only a hash of it, so we can’t send it again. If it’s lost or leaks, we rotate it (the old key stops working at once) or revoke it. Call the API from your servers only: keys must never reach a browser or an app, and the API sends no CORS headers.
Endpoints
Base URL https://legitscore.io. Requests and responses are JSON; the version is in the path and in the X-Legit-API-Version header.
POST/api/v1/checks
Start a check of a TikTok or Instagram account. Body: {"platform": "tiktok" | "instagram", "handle": "name, @name or a profile URL"}. Returns 202 with the queued check. If your key already has a check of that account queued or running, you get that one back (200).
Billing: 1 lookup when a new check is queued. Getting back a check already in progress is free.
GET/api/v1/checks/{id}
A check your key started: status (queued, running, done, failed), progress 0–100, and when done the result with the engine version and the standard notice. A check takes a few minutes; poll every 10–30 seconds.
Billing: Free (counts towards the rate limit only).
GET/api/v1/score?platform=&handle=[&max_age_days=]
The latest score for the account if it is at most max_age_days old (default 30, up to 90): from a check your key ran, or the account's public Legit Verified score. Otherwise 404 no_recent_score with a hint to POST a check.
Billing: 1 lookup when a score is returned. A 404 is free.
Examples
Start a check
curl -X POST https://legitscore.io/api/v1/checks \
-H "Authorization: Bearer $LEGIT_SCORE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"platform": "tiktok", "handle": "@creatorname"}'202 Accepted:
{
"object": "check",
"id": "7b2c0e4a-5f1d-4c3e-9a8b-2d6f0e1c3b5a",
"platform": "tiktok",
"handle": "creatorname",
"status": "queued",
"progress": 0,
"stage": "Waiting to start",
"createdAt": "2026-10-27T12:00:00.000Z",
"finishedAt": null,
"result": null,
"message": null,
"engineVersion": null,
"notice": "A Legit Score is an automated, evaluative opinion about audience characteristics, based on statistical sampling and proprietary models. It is not a statement of fact or an accusation of wrongdoing. Subscription status never influences a score."
}Poll the check
curl https://legitscore.io/api/v1/checks/7b2c0e4a-5f1d-4c3e-9a8b-2d6f0e1c3b5a \
-H "Authorization: Bearer $LEGIT_SCORE_API_KEY"200 OK, once done:
{
"object": "check",
"id": "7b2c0e4a-5f1d-4c3e-9a8b-2d6f0e1c3b5a",
"platform": "tiktok",
"handle": "creatorname",
"status": "done",
"progress": 100,
"stage": "Done",
"createdAt": "2026-10-27T12:00:00.000Z",
"finishedAt": "2026-10-27T12:03:10.000Z",
"result": {
"score": 74,
"band": {
"low": 68,
"high": 80
},
"tier": "VERIFIED_COMMERCIAL",
"tierLabel": "Verified Commercial",
"dataDepth": "PUBLIC_SAMPLE",
"pillars": {
"L": {
"score": 71,
"note": null
},
"E": {
"score": 78,
"note": null
},
"G": {
"score": null,
"note": null
},
"I": {
"score": 69,
"note": null
},
"T": {
"score": 80,
"note": null
}
},
"audience": {
"sampleSize": 385,
"shares": {
"C1_ACTIVE_REAL": 0.31,
"C2_PASSIVE_REAL": 0.33,
"C3_MASS_FOLLOWER": 0.18,
"C4_NOTABLE": 0.02,
"C5_SUSPICIOUS": 0.11,
"C6_AUTOMATED": 0.05
}
},
"reasons": [
{
"code": "LA-01",
"pillar": "L",
"label": "Elevated share of mass followers"
}
],
"modifiers": [],
"realReachEstimate": 41200,
"computedAt": "2026-10-27T12:03:09.000Z"
},
"message": null,
"engineVersion": "1.1.0-dev",
"notice": "A Legit Score is an automated, evaluative opinion about audience characteristics, based on statistical sampling and proprietary models. It is not a statement of fact or an accusation of wrongdoing. Subscription status never influences a score."
}Look up a recent score
curl "https://legitscore.io/api/v1/score?platform=instagram&handle=creatorname&max_age_days=14" \
-H "Authorization: Bearer $LEGIT_SCORE_API_KEY"200 OK:
{
"object": "score",
"platform": "instagram",
"handle": "creatorname",
"source": "api_check",
"checkId": "7b2c0e4a-5f1d-4c3e-9a8b-2d6f0e1c3b5a",
"checkedAt": "2026-10-20T09:14:00.000Z",
"ageDays": 7,
"score": 74,
"band": {
"low": 68,
"high": 80
},
"tier": "VERIFIED_COMMERCIAL",
"tierLabel": "Verified Commercial",
"result": {
"…": "same shape as a finished check's result"
},
"engineVersion": "1.1.0-dev",
"notice": "A Legit Score is an automated, evaluative opinion about audience characteristics, based on statistical sampling and proprietary models. It is not a statement of fact or an accusation of wrongdoing. Subscription status never influences a score."
}JavaScript
// Server-side only (Node 18+, Workers, Deno). Never ship your key to a browser.
const API = "https://legitscore.io/api/v1";
const headers = { Authorization: `Bearer ${process.env.LEGIT_SCORE_API_KEY}` };
async function legitScore(platform, handle) {
// 1. Use a recent score if there is one.
const recent = await fetch(`${API}/score?${new URLSearchParams({ platform, handle })}`, { headers });
if (recent.ok) return recent.json();
const { error } = await recent.json();
if (error.code !== "no_recent_score") throw new Error(`${error.code}: ${error.message}`);
// 2. Otherwise start a check (or get back the one already running) and poll it.
const started = await fetch(`${API}/checks`, {
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify({ platform, handle }),
});
let check = await started.json();
if (!started.ok) throw new Error(`${check.error.code}: ${check.error.message}`);
while (check.status === "queued" || check.status === "running") {
await new Promise((r) => setTimeout(r, 15_000));
check = await (await fetch(`${API}/checks/${check.id}`, { headers })).json();
}
return check; // status "done" (check.result) or "failed" (check.message)
}Limits and billing
- Rate limit: 60 requests per minute per key by default. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (seconds); a 429 rate_limited carries Retry-After.
- Monthly quota: an agreed number of lookups (checks started + scores returned) per calendar month, UTC. Past it, billable calls return 429 quota_exceeded until the 1st; polling still works.
- Capacity: while we are in early access, checks from every source share a site-wide daily capacity (currently 20 new checks a day). When it is used up, POST /api/v1/checks returns 503 capacity_reached with Retry-After, and nothing is billed.
- Pricing: usage is counted per key per month and invoiced at $0.50–$2 per lookup depending on volume. Paying for the API never changes a score.
- Platforms: TikTok and Instagram. Accounts that have opted out are refused with 403 account_opted_out, and their earlier results are no longer returned.
Errors
Every error has the same shape. Branch on code; the message is plain English.
{
"error": {
"code": "no_recent_score",
"message": "There is no score for this account from the last 30 days.",
"status": 404,
"hint": "Start a check with POST /api/v1/checks, then poll GET /api/v1/checks/{id}.",
"docs": "https://legitscore.io/developers#errors"
}
}| Code | Status | Meaning |
|---|---|---|
| missing_api_key | 401 | Send your API key as `Authorization: Bearer ls_live_…`. |
| invalid_api_key | 401 | This API key isn't valid. |
| revoked_api_key | 401 | This API key has been revoked. Ask Legit Score for a new one. |
| rate_limited | 429 | Too many requests for this key. Wait for the next minute and retry. |
| quota_exceeded | 429 | This key's monthly quota is used up. It resets on the 1st (UTC). |
| capacity_reached | 503 | Today's check capacity is used up. Retry after midnight UTC. |
| invalid_request | 400 | The request isn't valid. |
| payload_too_large | 413 | The request body is too large. |
| account_opted_out | 403 | This account has opted out of Legit Score, so it can't be checked or shown. |
| not_found | 404 | Not found. |
| no_recent_score | 404 | There is no recent score for this account. |
| unavailable | 503 | The API isn't available right now. Please retry later. |
Acceptable use
Using the API means agreeing to these rules and to our terms:
- No consumer-reporting uses. Never use a Legit Score, or anything from this API, as a factor in decisions about a person's eligibility for employment, credit, housing, insurance or tenancy, or any other purpose covered by the US Fair Credit Reporting Act or similar laws. Legit Score is not a consumer reporting agency and scores are not consumer reports.
- Present scores as opinions. Show the score with its confidence band, tier, date and the standard notice. Don't describe an account or its holder as dishonest, and don't present a score as proof of wrongdoing; use pattern language such as "shows patterns common to automated accounts" or "low confidence".
- Use it for brand-safety, campaign and payout review, with a person able to review the outcome. Give creators a way to ask questions, and point disputes to legitscore.io/disputes.
- Respect opt-outs and freshness. Don't keep showing a score after we return 403 account_opted_out for that account, and re-check rather than reuse old scores indefinitely.
- No bulk republishing, resale or competing datasets without a written agreement, and no attempts to identify individual followers or commenters or to reverse engineer the models.
- Keep keys secret and server-side. One key per integration; we rotate or revoke keys that leak or break these rules.
Questions
Keys, quotas, pricing and support: hello@legitscore.io. Account holders can dispute a score or opt out at /disputes.