GenRank API v2
This document is the whole reference for the GenRank API. It is written for people and for agents alike: hand over this URL and a key, nothing else. Plain text: https://www.genrank.com/api/v2/docs.md. The same text as a page: https://www.genrank.com/en-us/data/api. OpenAPI 3.1: https://www.genrank.com/api/v2/docs.
Quick start
-
Get a key. Apply at https://www.genrank.com/en-us/data. A key is a string starting with
grk_, shown once. Keep it on a server; never put it in a browser. -
Send
Authorization: Bearer <key>and alanguagequery with every request.language=kois the Korean index,language=enthe English one. The two never mix. -
First call:
curl -H "Authorization: Bearer $GENRANK_API_KEY" \ "https://www.genrank.com/api/v2/categories?language=ko&q=dental" -
To look at one brand, find its id with
/entities/search?q=<brand>&language=ko, then call/entities/{id}/overview?language=ko. One answer carries its category ranks, top questions, the brands named alongside it, the sources cited, its regional ranks, a four-week trend and the run status. -
Read again weekly. A Korean week starts Sunday 00:00 KST; a week's numbers are final once
/runs?language=koreports that run ascompleted. -
Quote the edition (
week_start) and themethodology_versionwith every number. A ranking without them is not a GenRank ranking. -
Matching. To start from a website instead of a name, call
/entities/resolve?url=<site>&language=ko, adding&name=<the site's own name>when you know it. To place a brand GenRank does not have, POST its name and what it sells to/classify, then POST it to/categories/{key}/competitors. To check your own AI answers the way GenRank reads its own, POST them to/extract: the response says which of your brands each answer named, where, and what kind of source each citation is.
Response shapes are defined by the reference below and by the OpenAPI document. Errors are always { "error": "...", "code": "..." }.
Endpoints
Base URL: https://www.genrank.com/api/v2. Index routes are GET; the matching routes that compute from what you send are POST with a JSON body. Columns: the parameter, where it goes, whether it is required, what it means.
Categories
GET /categories
The category tree as a flat list with question and brand counts and the top three of each; with q, the categories matching a name, key or question texts
| Parameter | In | Required | Meaning |
|---|---|---|---|
language | query | yes | ko or en. Entities and questions are separate per language. |
q | query | no | 2 to 100 characters: a key, a name, or words that appear in question texts |
limit | query | no | 1 to 1000, default 1000 |
offset | query | no | Default 0 |
Response CategoriesResponse:
meta: objecttotal: integercategories: array of objectkey: stringname_ko: stringname_en: stringlevel: integergeo_mode:city|metro|countryparent_key: stringquestions: integer (Active national questions in the subtree)regional_questions: integerbrands: integer (Entities ranked in this category)leaders: array of object (Top three of the current ranking)id: stringslug: stringname: stringscore: number
match: objectkind:exact|name|question(What matched q: the key or a name exactly, a name partially, or question texts)score: number
Statuses: 200, 304, 400, 401, 403, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/categories?language=ko"
POST /categories/{key}/competitors
The category's ranked entities by relevance to one brand: nearest by meaning first, then a judge model's probability that the brand's customers compare the two
| Parameter | In | Required | Meaning |
|---|---|---|---|
key | path | yes | Category key (slug) |
Body CompetitorsRequest:
language:ko|enentity_id: stringname: stringhomepage: stringoffering: string (What the brand sells and to whom, one or two sentences)limit: integer
Response CompetitorsResponse:
meta: objectrelevance_version: stringjudged_by:model|vectorwindow: object (The 4-week window of mentions and trials)from_week: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)to_week: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)
competitors: array of objectentity: objectid: stringslug: stringname: string
rank: integer (Current rank in the category)relevance: number (Probability that this brand's customers compare the two)similarity: numberco_mentions: integer (Answers inwindowthat named both this brand and the entity_id brand, over the category's own questions (2.6.0: the same four weeks as mentions and trials). null without entity_id (no brand to count with) and in a category above the leaves (co-mentions are kept per leaf): show no number then)mentions: integer (Answers in this category that named it, over the window, on the current panel: thetotal.mentionsof its /categories/{key}/matrix row)trials: integer (Answers measured for this category over the same window and panel: thetotal.trialsof its matrix row)
Statuses: 200, 400, 401, 403, 404, 413, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" -H "Content-Type: application/json" -d '{"language":"ko","name":"Lemonbase","offering":"Performance reviews, 1:1s and OKRs for HR teams","limit":12}' "https://www.genrank.com/api/v2/categories/software-hr-hris/competitors"
GET /categories/{key}
One category: node, ancestors, children, and how many weekly editions it has
| Parameter | In | Required | Meaning |
|---|---|---|---|
key | path | yes | Category key (slug) |
language | query | yes | ko or en. Entities and questions are separate per language. |
Response CategoryDetailResponse:
meta: objectcategory: objectkey: stringname_ko: stringname_en: stringlevel: integergeo_mode:city|metro|countryparent_key: stringquestions: integer (Active national questions in the subtree)regional_questions: integerbrands: integer (Entities ranked in this category)leaders: array of object (Top three of the current ranking)id: stringslug: stringname: stringscore: number
match: objectkind:exact|name|question(What matched q: the key or a name exactly, a name partially, or question texts)score: number
ancestors: array of object (Root first)key: stringname_ko: stringname_en: stringlevel: integergeo_mode:city|metro|country
children: array of objectkey: stringname_ko: stringname_en: stringlevel: integergeo_mode:city|metro|countryparent_key: stringquestions: integer (Active national questions in the subtree)regional_questions: integerbrands: integer (Entities ranked in this category)leaders: array of object (Top three of the current ranking)id: stringslug: stringname: stringscore: number
match: objectkind:exact|name|question(What matched q: the key or a name exactly, a name partially, or question texts)score: number
rollup: objectweeks_measured: integerlatest_week: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)methodology_version: string
Statuses: 200, 304, 400, 401, 403, 404, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/categories/services-health-dental?language=ko"
GET /categories/{key}/rankings
The ranking of a category in one kept week (default: the latest), with each entity's previous rank. National only.
| Parameter | In | Required | Meaning |
|---|---|---|---|
key | path | yes | Category key (slug) |
language | query | yes | ko or en. Entities and questions are separate per language. |
week | query | no | Week start (Sunday, YYYY-MM-DD). Default: the latest kept week. |
limit | query | no | 1 to 100, default 50 |
offset | query | no | 0 to 10000, default 0 |
Response CategoryRankingsResponse:
meta: objectcategory: objectkey: stringname_ko: stringname_en: stringlevel: integergeo_mode:city|metro|country
week_start: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)previous_week: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)methodology_version: stringtotal: integeroffset: integerrankings: array of objectid: stringslug: stringname: stringrank: integerscore: number (GenRank score: the unbounded weighted sum behind the rank)previous_rank: integer (Rank in the previous kept week; NULL when new or not comparable)
Statuses: 200, 304, 400, 401, 403, 404, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/categories/services-health-dental/rankings?language=ko"
GET /categories/{key}/history
Top N of a category per kept week with the methodology version of each week; one entity's rows added with entity. National only.
| Parameter | In | Required | Meaning |
|---|---|---|---|
key | path | yes | Category key (slug) |
language | query | yes | ko or en. Entities and questions are separate per language. |
weeks | query | no | 1 to 104, default 26 |
top | query | no | 1 to 50, default 10 |
entity | query | no | Entity id or slug to include regardless of rank |
Response CategoryHistoryResponse:
meta: objectcategory: objectkey: stringname_ko: stringname_en: stringlevel: integergeo_mode:city|metro|country
weeks: array of object (Kept weeks, oldest first; a change of major methodology version is a break)week_start: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)methodology_version: string
entities: array of objectid: stringslug: stringname: stringcurrent_rank: integer
points: array of objectweek_start: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)entity_id: stringrank: integerscore: number
Statuses: 200, 304, 400, 401, 403, 404, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/categories/services-health-dental/history?language=ko"
GET /categories/{key}/graph
Co-mention graph of the top entities and the domain-to-entity source flow over the last four weeks. National only.
| Parameter | In | Required | Meaning |
|---|---|---|---|
key | path | yes | Category key (slug) |
language | query | yes | ko or en. Entities and questions are separate per language. |
nodes | query | no | 5 to 100, default 50 |
min_answers | query | no | Edges below this many shared answers are dropped; 1 to 50, default 2 |
domains | query | no | 1 to 30, default 10 |
Response CategoryGraphResponse:
meta: objectcategory: objectkey: stringname_ko: stringname_en: stringlevel: integergeo_mode:city|metro|country
window: objectfrom_week: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)to_week: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)weeks:4
nodes: array of objectid: stringslug: stringname: stringrank: integeranswers: integer (Answers naming the entity in the window)
edges: array of objecta: stringb: stringanswers: integer (Answers naming both)questions: integersurfaces: integer
sources: objectdomains: array of objectdomain: stringtype: stringanswers: integer
entities: array of objectid: stringslug: stringname: stringrank: integer
links: array of objectdomain: stringentity_id: stringanswers: integer
Statuses: 200, 304, 400, 401, 403, 404, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/categories/services-health-dental/graph?language=ko"
GET /categories/{key}/matrix
Mentions and trials per surface for the top entities of a category over the 4-week window; counts only. National only.
| Parameter | In | Required | Meaning |
|---|---|---|---|
key | path | yes | Category key (slug) |
language | query | yes | ko or en. Entities and questions are separate per language. |
limit | query | no | Entities, 1 to 50, default 15 |
pin | query | no | An entity id or slug to keep as a row whatever its rank, marked pinned; repeat for more, up to 5. A merged entity's old id leads to the entity that holds it now; an unknown one is ignored. A pinned entity within limit is not repeated; one not ranked in the category comes last with rank null, its cells the category's trials and its mentions there (2.6.0) |
Response CategoryMatrixResponse:
meta: objectcategory: objectkey: stringname_ko: stringname_en: stringlevel: integergeo_mode:city|metro|country
window: objectfrom_week: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)to_week: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)
surfaces: array of objectmodel_id: stringname: stringrole:scored|observedweight: number
rows: array of objectid: stringslug: stringname: stringrank: integer (Rank in the category; null for a pinned entity not ranked in it (2.6.0))pinned: boolean (Asked for with pin= (2.6.0); a pinned entity ranked within limit is not repeated)cells: array of object (One cell per surface, insurfacesorder. trials is the category's answers measured on the surface, the same for every row)model_id: stringtrials: integermentions: integer
total: objecttrials: integermentions: integer
Statuses: 200, 304, 400, 401, 403, 404, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/categories/services-health-dental/matrix?language=ko"
GET /categories/{key}/questions
Questions of a category and its descendants; with region_id, that region's questions and their publish gates
| Parameter | In | Required | Meaning |
|---|---|---|---|
key | path | yes | Category key (slug) |
language | query | yes | ko or en. Entities and questions are separate per language. |
region_id | query | no | A regions.id from /regions. Scopes the call to that region of the regional index; omit for the national index. An unknown id answers 400 UNKNOWN_REGION. |
limit | query | no | 1 to 200, default 100 |
offset | query | no | Default 0 |
Response CategoryQuestionsResponse:
meta: objectcategory: objectkey: stringname_ko: stringname_en: stringlevel: integergeo_mode:city|metro|countrypriority: stringt: string
questions: array of objectid: stringslug: stringtext: stringintent:best|compare|choose|transactionaltopic: stringregion_id: stringstatus:active|retiredretired_at: stringreplaced_by: string (Slug of the follow-up question when retired)rank: objectscore: numbersearch_component: numberestimate_component: numberbasis:none|search_only|estimate_only|combinedcomputed_at: string
signals: objectnaver_pc: integernaver_mobile: integergoogle: integerfetched_at: string
estimates: array of objectmodel_id: stringrank: integer
first_measured_week: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)weeks_measured: integergate: objectpublished: booleanentities: integermodels_agreeing: integerweeks: integer
total: integer
Statuses: 200, 304, 400, 401, 403, 404, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/categories/services-health-dental/questions?language=ko"
GET /categories/{key}/citations
Sources the answers of a category (and its descendants) cited in one week: domains with distinct answer, question and model counts, and each domain's most cited pages
| Parameter | In | Required | Meaning |
|---|---|---|---|
key | path | yes | Category key (slug) |
language | query | yes | ko or en. Entities and questions are separate per language. |
week | query | no | Week start (Sunday, YYYY-MM-DD). Default: the latest week with citations for this category. |
limit | query | no | Domains, 1 to 50, default 20 |
urls | query | no | Pages per domain, 0 to 10, default 3 |
Response CategoryCitationsResponse:
meta: objectcategory: objectkey: stringname_ko: stringname_en: stringlevel: integergeo_mode:city|metro|country
week_start: string (The week shown; NULL when the category has no citations yet)weeks: array of string (Weeks with citation data for this category, newest first)answers: array of object (Per surface of the panel, by weight as in /models, then any other surface measured that week (2.6.0). Empty for weeks kept before 18 October 2026)model_id: stringasked: integer (Cells measured: every question asked on this surface, including those where the surface showed no AI answer or the call failed (the denominator of the public sources page))answers: integer (Cells with an AI answer)cited_answers: integer (Answers citing at least one source)
types: array of object (Every domain of the week folded by type, not cut bylimit: all nine types, each with every surface (2.6.0))type:portal|social|community|directory|shopping|media|reference|public|otherby_model: array of object (One entry per surface, zeros included. responses counts an answer once however many sites of the type it cites, so it can be less than the sum of the type's domains)model_id: stringresponses: integer (Distinct answers of this surface that cited it in the week)questions: integer (Questions those answers belong to)answers: integer (Answers this surface gave in the week (an AI answer was there): the denominator of the share)
domains: array of objectdomain: stringtype:portal|social|community|directory|shopping|media|reference|public|otherresponses: integer (Distinct answers that cited this domain)questions: integermodels: integerby_model: array of object (One entry per surface, inanswersorder, zeros included (2.6.0))model_id: stringresponses: integer (Distinct answers of this surface that cited it in the week)questions: integer (Questions those answers belong to)answers: integer (Answers this surface gave in the week (an AI answer was there): the denominator of the share)
urls: array of object (The most cited pages of this domain)url: stringtitle: stringresponses: integer (Distinct answers that cited this URL)
Statuses: 200, 304, 400, 401, 403, 404, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/categories/services-health-dental/citations?language=ko"
Entities
GET /entities/search
Find entities by name or alias (q) or website domain; with region_id, that region's entities join the national ones
| Parameter | In | Required | Meaning |
|---|---|---|---|
q | query | no | Name or alias, 2 to 100 characters. q or domain is required. |
domain | query | no | Website host, e.g. example.com |
language | query | yes | ko or en. Entities and questions are separate per language. |
region_id | query | no | A regions.id from /regions. Scopes the call to that region of the regional index; omit for the national index. An unknown id answers 400 UNKNOWN_REGION. |
limit | query | no | 1 to 20, default 10 |
Response EntitySearchResponse:
meta: objectentities: array of objectid: stringslug: stringname: stringtype: stringaliases: array of stringwebsite: stringregion_id: stringparent_entity_id: stringcategories: array of objectkey: stringname_ko: stringname_en: stringlevel: integergeo_mode:city|metro|country
score_summary: objectinclusion_rate_4w: numbertrials_4w: integermentions_4w: integerquestions: integer
match: object (How the entity was found (2.2.0): sound is the same Hangul/Latin sound skeleton, semantic is vector similarity)kind:exact|name|alias|sound|semantic|website|domainscore: number
Statuses: 200, 304, 400, 401, 403, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/entities/search?language=ko"
GET /entities/resolve
Which entity a website belongs to: a stored website, else entities named in answers that cited the site, ranked with how much the site name sounds like theirs
| Parameter | In | Required | Meaning |
|---|---|---|---|
url | query | yes | A website address or host, e.g. https://www.example.com/about |
name | query | no | A name the site gives itself (its title, the brand it names), up to 100 characters; repeat for other names, up to 5, the main one first. When exactly one entity named in answers that cited the site has one of them as its name or alias, match is likely and that entity comes first; when several do, match is candidates. A national entity wins over regional entities of the same name. On a platform's own address (naver.com) the candidates stay the entities named like the platform, and name only picks among them (2.5.0). When no cited entity has one of the names and the site alone gives no likely owner, brands and businesses with one of them as name or alias are looked up in the whole index (not products, people, works, places or branches) and join the candidates with match sound and name_similarity 1. One of them is likely when the address is written in its names (starbucks.co.kr and the alias Starbucks), or else when GenRank's judge model reads the site as its official site; two businesses can share a name, so the others stay candidates (2.7.0) |
language | query | yes | ko or en. Entities and questions are separate per language. |
limit | query | no | 1 to 20, default 5 |
Response EntityResolveResponse:
meta: objectsite: objecthost: stringlabel: string (The registrable name, e.g. "lemonbase" for www.lemonbase.com)platform: string (Citation type when the host is a portal, store, map, social or media site; its citations say nothing about ownership)account: string (Account or place id on a platform URL)title: string (The page title as AI answers cited it; for a place, its own name (2.2.1))
match:website|likely|candidates|none|platformcandidates: array of objectentity: objectid: stringslug: stringname: stringtype: stringregion_id: string
match:website|cited|sound(website: the stored website is this host; cited: answers that named the entity cited the site or page; sound: no answer cited it, but the name sounds like the site name (2.2.1), or one of the names sent is its name or alias (name_match true, name_similarity 1; 2.7.0))cited_answers: integer (Answers in the latest measured week that named the entity and cited the site)name_similarity: number (How much the site name sounds like the entity name (Hangul and Latin compared by sound); 1 for a cited entity whose name or alias is one of the names sent (2.5.0), and for an entity found by one of them in the whole index (2.7.0))confidence: numbername_match: boolean (One of the names sent (name=) is the entity's name or alias, compared without case, spaces or punctuation; false when no name was sent (2.5.0))
Statuses: 200, 304, 400, 401, 403, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/entities/resolve?url=…&language=ko"
POST /entities/suggest
Record a brand GenRank does not have. It never adds the brand to a ranking: GenRank asks questions, and an entity appears only when AI answers name it
Body SuggestRequest:
language:ko|enname: stringhomepage: stringoffering: string (What the brand sells and to whom, one or two sentences)category_key: stringsource: string
Response SuggestResponse:
status:recorded|existssuggestion_id: stringtimes: integer (How many times this site or name has been suggested)entity: object (The entity this site already belongs to, when status is exists)id: stringslug: stringname: string
Statuses: 200, 202, 400, 401, 403, 413, 429, 503.
- 200: Suggested before (
status: recorded,timescounts up), or the site already belongs to a GenRank entity (status: existswithentity) - 202: First suggestion of this site or name:
status: recorded,times: 1
curl -H "Authorization: Bearer $GENRANK_API_KEY" -H "Content-Type: application/json" -d '{"language":"ko","name":"…","homepage":"https://…","offering":"…"}' "https://www.genrank.com/api/v2/entities/suggest"
GET /entities/{id}
Entity detail: categories, per-question and per-model 4-week numbers, peers, region and parent when regional
| Parameter | In | Required | Meaning |
|---|---|---|---|
id | path | yes | Entity id or slug |
language | query | yes | ko or en. Entities and questions are separate per language. |
Response EntityDetailResponse:
meta: objectentity: objectid: stringslug: stringname: stringtype: stringaliases: array of stringwebsite: stringregion_id: stringparent_entity_id: stringcategories: array of objectkey: stringname_ko: stringname_en: stringlevel: integergeo_mode:city|metro|country
description: stringregion: object (The region of a regional entity; NULL for the national index (widened from null in 2.1.0))id: stringslug: stringlevel:sido|sigungu|districtparent_id: stringname_ko: stringname_en: string
parent: object (The national entity a regional one belongs to, when known (widened from null in 2.1.0))id: stringslug: stringname: string
score_summary: objectinclusion_rate_4w: numbertrials_4w: integermentions_4w: integerquestions: integer
questions: array of objectslug: stringtext: stringstatus:active|retiredfrom_week: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)to_week: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)inclusion_rate_4w: numbermean_rank: numbermodels: array of objectmodel_id: stringtrials: integermentions: integermean_rank: numbercited: integer (Trials in which the entity's own site was cited. NULL until citations are linked to entities.)
peers: array of objectid: stringslug: stringname: stringcategory_key: stringrank: integerinclusion_rate_4w: number
Statuses: 200, 301, 304, 400, 401, 403, 404, 410, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/entities/dental-a?language=ko"
GET /entities/{id}/history
Category rank per kept week, best current rank first
| Parameter | In | Required | Meaning |
|---|---|---|---|
id | path | yes | Entity id or slug |
language | query | yes | ko or en. Entities and questions are separate per language. |
weeks | query | no | 1 to 104, default 26 |
categories | query | no | 1 to 30, default 8 |
Response EntityHistoryResponse:
meta: objectentity: objectid: stringslug: stringname: string
categories: array of object (Best current rank first)category: objectkey: stringname_ko: stringname_en: stringlevel: integergeo_mode:city|metro|country
points: array of objectweek_start: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)methodology_version: stringrank: integertotal: integer
Statuses: 200, 304, 400, 401, 403, 404, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/entities/dental-a/history?language=ko"
GET /entities/{id}/graph
Entities named alongside this one and the sources those answers cite, over the last four weeks
| Parameter | In | Required | Meaning |
|---|---|---|---|
id | path | yes | Entity id or slug |
language | query | yes | ko or en. Entities and questions are separate per language. |
scope | query | no | national (default) or regional |
limit | query | no | 1 to 100, default 30 |
Response EntityGraphResponse:
meta: objectentity: objectid: stringslug: stringname: string
scope:national|regionalwindow: objectto_week: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)weeks:4
co_mentions: array of object (Entities named in the same answers, most often first)id: stringslug: stringname: stringanswers: integerquestions: integersurfaces: integer
sources: array of object (Domains cited by answers naming the entity)domain: stringtype: stringanswers: integerquestions: integersurfaces: integer
Statuses: 200, 304, 400, 401, 403, 404, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/entities/dental-a/graph?language=ko"
GET /entities/{id}/overview
One call for an onboarding screen: detail, category ranks, top questions, co-mentions, sources, regions, 4-week trend, run status. Parts that fail are named in partial.
| Parameter | In | Required | Meaning |
|---|---|---|---|
id | path | yes | Entity id or slug |
language | query | yes | ko or en. Entities and questions are separate per language. |
region_id | query | no | A regions.id from /regions. Scopes the call to that region of the regional index; omit for the national index. An unknown id answers 400 UNKNOWN_REGION. |
Response EntityOverviewResponse:
meta: objectentity: objectid: stringslug: stringname: stringtype: stringaliases: array of stringwebsite: stringregion_id: stringparent_entity_id: stringcategories: array of objectkey: stringname_ko: stringname_en: stringlevel: integergeo_mode:city|metro|country
description: stringregion: object (The region of a regional entity; NULL for the national index (widened from null in 2.1.0))id: stringslug: stringlevel:sido|sigungu|districtparent_id: stringname_ko: stringname_en: string
parent: object (The national entity a regional one belongs to, when known (widened from null in 2.1.0))id: stringslug: stringname: string
score_summary: objectinclusion_rate_4w: numbertrials_4w: integermentions_4w: integerquestions: integer
categories: array of objectkey: stringname_ko: stringname_en: stringlevel: integergeo_mode:city|metro|countryrank: integertotal: integerscore: number
questions: array of object (Top ten by 4-week inclusion)slug: stringtext: stringstatus:active|retiredfrom_week: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)to_week: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)inclusion_rate_4w: numbermean_rank: numbermodels: array of objectmodel_id: stringtrials: integermentions: integermean_rank: numbercited: integer (Trials in which the entity's own site was cited. NULL until citations are linked to entities.)
co_mentions: array of objectid: stringslug: stringname: stringanswers: integerquestions: integersurfaces: integer
sources: array of objectdomain: stringtype: stringanswers: integerquestions: integersurfaces: integer
regions: array of objectregion_id: stringregion_slug: stringcategory_key: stringquestion_id: stringrank: integerscore: numberweek_start: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)
trend: array of object (Last four kept weeks in up to three categories)category: objectkey: stringname_ko: stringname_en: stringlevel: integergeo_mode:city|metro|country
points: array of objectweek_start: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)methodology_version: stringrank: integertotal: integer
runs: array of objectid: stringweek_start: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)scope:national|regionallanguage:ko|en(NULL for runs that covered every language (all runs before v4.0))trigger_type: stringstatus:running|completed|failedquestions_total: integerquestions_completed: integerstarted_at: stringcompleted_at: stringroutes: objectbatch: integerdirect: integeropenrouter: integer
partial: array of string (Parts that could not be read this time; they are empty, not absent)
Statuses: 200, 301, 304, 400, 401, 403, 404, 410, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/entities/dental-a/overview?language=ko"
Questions
GET /questions/{slug}/results
One question: raw answers per model, entities, citations, 4-week cells. A regional slug carries its region; region_id, when given, must match.
| Parameter | In | Required | Meaning |
|---|---|---|---|
slug | path | yes | Question slug |
language | query | yes | ko or en. Entities and questions are separate per language. |
region_id | query | no | A regions.id from /regions. Scopes the call to that region of the regional index; omit for the national index. An unknown id answers 400 UNKNOWN_REGION. |
week | query | no | Week start (Sunday, YYYY-MM-DD). Default: latest completed week. |
Response QuestionResultsResponse:
question: objectid: stringslug: stringtext: stringstatus:active|retiredreplaced_by: stringregion_id: stringintent: stringtopic: stringcategories: array of string
week_start: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)methodology_version: stringmodels: array of objectmodel_id: stringname: stringprovider: stringweight: numberweb_search: booleancollection:api|serp
responses: array of objectmodel_id: stringmeasured_at: stringweek_start: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)route:direct|openrouter|batchsearch_location:nullresponse_text: stringentities: array of objectid: stringslug: stringname: stringrank: integerrole:answer
citations: array of objecturl: stringdomain: stringtitle: stringtype: string (Source type. NULL until classification ships (REVAMP 6.3).)
status:ok|empty|failed
cells_4w: objectfrom_week: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)to_week: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)cells: array of objectmodel_id: stringtrials: integermentions: integermean_rank: numbercited: integer (Trials in which the entity's own site was cited. NULL until citations are linked to entities.)entity_id: string
entities: array of objectid: stringslug: stringname: string
meta: object
Statuses: 200, 304, 400, 401, 403, 404, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/questions/dental-network-brands-affordable/results?language=ko"
GET /questions/{slug}/history
Weekly history of a question for one entity or its top 10
| Parameter | In | Required | Meaning |
|---|---|---|---|
slug | path | yes | Question slug |
language | query | yes | ko or en. Entities and questions are separate per language. |
region_id | query | no | A regions.id from /regions. Scopes the call to that region of the regional index; omit for the national index. An unknown id answers 400 UNKNOWN_REGION. |
entity | query | no | Entity id or slug |
weeks | query | no | 1 to 104, default 26 |
Response QuestionHistoryResponse:
meta: objectquestion: objectslug: stringstatus:active|retired
entities: array of objectid: stringslug: stringname: string
points: array of objectweek_start: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)entity_id: stringmodel_id: string (NULL when the point is the cross-model rank (runs before per-model cells were stored))mentioned: booleanrank: integer
Statuses: 200, 304, 400, 401, 403, 404, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/questions/dental-network-brands-affordable/history?language=ko"
GET /questions/results
Latest results for up to 50 questions
| Parameter | In | Required | Meaning |
|---|---|---|---|
slugs | query | yes | Comma-separated question slugs, at most 50 |
language | query | yes | ko or en. Entities and questions are separate per language. |
region_id | query | no | A regions.id from /regions. Scopes the call to that region of the regional index; omit for the national index. An unknown id answers 400 UNKNOWN_REGION. |
updated_since | query | no | ISO 8601 time. Questions not measured after it are listed in unchanged. |
Response BulkResultsResponse:
meta: objectresults: array of objectquestion: objectid: stringslug: stringtext: stringstatus:active|retiredreplaced_by: stringregion_id: stringintent: stringtopic: stringcategories: array of string
week_start: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)methodology_version: stringmodels: array of objectmodel_id: stringname: stringprovider: stringweight: numberweb_search: booleancollection:api|serp
responses: array of objectmodel_id: stringmeasured_at: stringweek_start: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)route:direct|openrouter|batchsearch_location:nullresponse_text: stringentities: array of objectcitations: array of objectstatus:ok|empty|failed
cells_4w: objectfrom_week: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)to_week: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)cells: array of object
entities: array of objectid: stringslug: stringname: string
missing: array of stringunchanged: array of string (Slugs skipped because nothing was measured after updated_since)
Statuses: 200, 304, 400, 401, 403, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/questions/results?slugs=a,b&language=ko"
Matching
POST /classify
Which GenRank categories a brand competes in: nearest categories by meaning and categories named by its words, then a judge model chooses among them, with the probability that none fits
Body ClassifyRequest:
language:ko|enname: stringhomepage: stringoffering: string (What the brand sells and to whom, one or two sentences)site_text: string (Text of the brand site; the first 1,500 characters are used)limit: integer
Response ClassifyResponse:
meta: objectclassifier_version: stringjudged_by:model|vector(vector when the judge model did not answer and the order is by similarity only)none_probability: number (Probability that no GenRank category fits; null when judged_by is vector)categories: array of objectkey: stringname_ko: stringname_en: stringlevel: integergeo_mode:city|metro|countrypath: array of stringprobability: numbersimilarity: number (Cosine similarity of the brand and category vectors)source:vector|name(How the category reached the judge: among the nearest by meaning, or because its name holds a word of offering or site_text)
Statuses: 200, 400, 401, 403, 413, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" -H "Content-Type: application/json" -d '{"language":"ko","name":"Lemonbase","homepage":"https://lemonbase.com","offering":"Performance reviews, 1:1s and OKRs for HR teams"}' "https://www.genrank.com/api/v2/classify"
POST /extract
Check AI answers for mentions of your brands with GenRank's own extractor, and type each citation, in the request. 503 when any answer could not be read: nothing is judged then, retry after Retry-After
Body ExtractRequest, one of:
-
Up to 20 answers in
items:language:ko|enitems: array of objectquestion: stringanswer: stringcitations: array of objecturl: stringtitle: string
tracked: array of objectentity_id: stringname: stringaliases: array of stringhomepage: string (The brand's site or platform page; cited pages on it count as the brand's own)
-
One answer:
question: stringanswer: stringcitations: array of objecturl: stringtitle: string
tracked: array of objectentity_id: stringname: stringaliases: array of stringhomepage: string (The brand's site or platform page; cited pages on it count as the brand's own)
language:ko|en
Response ExtractResponse:
meta: objectextractor_version: stringresults: array of objectindex: integerentities: array of object (What the answer recommends, in its order; sources and generic terms are left out)entity_id: stringname: stringrank: numbertracked_index: integer
tracked: array of objectindex: integermentioned: booleanrank: number
citations: array of object (One per citation sent, in order)index: integer (Position in the citations you sent)domain: string (Host of the page cited, without www. Google's redirects (google.com/goto, Gemini grounding links) are opened and translated pages (translate.google.com, translate.goog) count as the page; Google Maps and Shopping pages on google.com count as maps.google.com and shopping.google.com. NULL when the URL is not one, or a Google redirect could not be opened)type:portal|social|community|directory|shopping|media|reference|public|othertracked_index: integer (The tracked brand whose own site or platform page this is)
Statuses: 200, 400, 401, 403, 413, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" -H "Content-Type: application/json" -d '{"language":"ko","question":"Recommend a performance review tool","answer":"1. flex 2. Lemonbase 3. Others","citations":[{"url":"https://lemonbase.com/blog","title":"Lemonbase blog"}],"tracked":[{"name":"Lemonbase","homepage":"https://lemonbase.com"}]}' "https://www.genrank.com/api/v2/extract"
Index
GET /sources
Sources across the whole index in one week, the figures of the public sources page: per surface the cells asked, answers and citing answers, every source type with the answers citing it per surface, and the most cited domains per surface (2.6.0)
| Parameter | In | Required | Meaning |
|---|---|---|---|
language | query | yes | ko or en. Entities and questions are separate per language. |
week | query | no | Week start (Sunday, YYYY-MM-DD). Default: the latest week with per-surface counts; a week without them falls back to it. |
scope | query | no | all (default, national and regional questions added up, as the public page shows them), national or regional |
limit | query | no | Domains, 1 to 100, default 50 |
Response SourcesResponse:
meta: objectscope:national|regional|allweek_start: string (The week shown; NULL before the first week with per-surface counts)weeks: array of string (Weeks available, newest first)surfaces: array of object (Per surface of the panel, by weight as in /models, then any other surface measured that week)model_id: stringasked: integer (Cells measured: every question asked on this surface, including those where the surface showed no AI answer or the call failed (the denominator of the public sources page))answers: integer (Cells with an AI answer)cited_answers: integer (Answers citing at least one source)
types: array of object (Every domain of the week folded by type: all nine types, each with every surface)type:portal|social|community|directory|shopping|media|reference|public|otherby_model: array of object (One entry per surface, zeros included. responses counts an answer once however many sites of the type it cites, so it can be less than the sum of the type's domains)model_id: stringresponses: integer (Distinct answers of this surface that cited it in the week)questions: integer (Questions those answers belong to)answers: integer (Answers this surface gave in the week (an AI answer was there): the denominator of the share)
domains: array of object (Most cited first,limitof them)domain: stringtype:portal|social|community|directory|shopping|media|reference|public|otherresponses: integer (Distinct answers that cited this domain)questions: integerby_model: array of object (One entry per surface, insurfacesorder, zeros included)model_id: stringresponses: integer (Distinct answers of this surface that cited it in the week)questions: integer (Questions those answers belong to)answers: integer (Answers this surface gave in the week (an AI answer was there): the denominator of the share)
Statuses: 200, 304, 400, 401, 403, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/sources?language=ko"
GET /models
The panel in effect for an index: each surface's weight (0 to 1) and since when it has held it, then the surfaces that left
| Parameter | In | Required | Meaning |
|---|---|---|---|
language | query | yes | ko or en. Entities and questions are separate per language. |
scope | query | no | national (default) or regional (Korean only) |
Response ModelsResponse:
meta: objectmodels: array of objectmodel_id: stringname: stringprovider: stringweight: numbereffective_from: stringweb_search: booleancollection:api|serp
retired: array of objectmodel_id: stringname: stringprovider: stringretired_at: string
Statuses: 200, 304, 400, 401, 403, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/models?language=ko"
GET /methodology
Current and next methodology version
| Parameter | In | Required | Meaning |
|---|---|---|---|
language | query | no | Default ko |
Response MethodologyResponse:
meta: objectcurrent: objectversion: stringeffective_from: string
next: objectversion: stringeffective_from: stringannounced: string
changelog: array of objectversion: stringdate: stringsummary: string
question_rank_formula: stringpublish_gate: stringurl: string
Statuses: 200, 304, 400, 401, 403, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/methodology?language=ko"
GET /regions
Regions and the (leaf, region) pairs measured in each, with the publish gate of each pair
| Parameter | In | Required | Meaning |
|---|---|---|---|
language | query | yes | ko or en. Entities and questions are separate per language. |
Response RegionsResponse:
meta: objectregions: array of objectid: stringslug: stringlevel:sido|sigungu|districtparent_id: stringname_ko: stringname_en: stringaliases: array of stringleaves: array of objectkey: stringpublished: booleanweeks_measured: integer
Statuses: 200, 304, 400, 401, 403, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/regions?language=ko"
GET /runs
Run status per week
| Parameter | In | Required | Meaning |
|---|---|---|---|
language | query | yes | ko or en. Entities and questions are separate per language. |
scope | query | no | national (default) or regional |
weeks | query | no | 1 to 26, default 4 |
Response RunsResponse:
meta: objectruns: array of objectid: stringweek_start: string (Sunday (KST) that starts a GenRank week, YYYY-MM-DD)scope:national|regionallanguage:ko|en(NULL for runs that covered every language (all runs before v4.0))trigger_type: stringstatus:running|completed|failedquestions_total: integerquestions_completed: integerstarted_at: stringcompleted_at: stringroutes: objectbatch: integerdirect: integeropenrouter: integer
Statuses: 200, 304, 400, 401, 403, 429, 503.
curl -H "Authorization: Bearer $GENRANK_API_KEY" "https://www.genrank.com/api/v2/runs?language=ko"
Authentication
Every route needs Authorization: Bearer grk_…. Keys are issued by GenRank staff on application (https://www.genrank.com/en-us/data) and shown once. A key may carry an expiry date and an allowlist of addresses; a revoked, expired or disallowed key answers 401 or 403 within 60 seconds on every server. Keys are rotated from the admin side: the new key inherits every setting and the old one keeps working for 7 days.
Call the API from a server. There are no CORS headers, so a browser cannot call it directly, and a key placed in a page would be public.
Limits and quotas
Each key has a per-minute limit and, optionally, a daily quota (the day is the KST calendar day). Every response carries:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests allowed per minute for this key |
X-RateLimit-Remaining | Requests left in the current minute |
X-RateLimit-Reset | Unix time (seconds) when the minute window rolls over |
X-Quota-Limit, X-Quota-Remaining | Daily quota and what is left of it today (only when a quota is set and the counter answered) |
X-RateLimit-Approx | 1 when the shared counter store could not be reached; the request was served and counted locally only |
Retry-After | On 429 and 503: seconds to wait |
The counters are shared across servers. Requests refused with 429 count towards the minute; refusals by a server's own first-stage limiter may not count towards the daily quota. A burst above the limit returns 429 RATE_LIMITED; an exhausted quota returns 429 QUOTA_EXCEEDED with Retry-After counting down to midnight KST.
Caching and freshness
Responses are Cache-Control: private, max-age=60 with Vary: Authorization and a strong ETag. Send If-None-Match with the last ETag to receive 304 when nothing changed; the ETag ignores meta.generated_at, so it is stable between runs.
The server caches each answer for 5 minutes (/runs: 60 seconds) and drops its cache when a run completes. To follow the index: poll /runs?language=ko and refetch what you show when a week flips to completed. The Korean index is measured weekly (national and regional runs), the English index monthly.
Errors
The body is always { "error": "<message>", "code": "<CODE>" }.
| Status | Code | Meaning |
|---|---|---|
| 400 | VALIDATION_ERROR | A parameter is missing or malformed; the message says which |
| 400 | UNKNOWN_REGION | region_id is well formed but is not an active region (see /regions) |
| 401 | UNAUTHORIZED | No key, an unknown key, or a revoked or expired key |
| 403 | FORBIDDEN | The key lacks the scope this route needs |
| 403 | IP_NOT_ALLOWED | The key is pinned to other addresses |
| 404 | NOT_FOUND | No such entity, question or category in this language |
| 404 | WEEK_NOT_MEASURED | Nothing was measured for that week |
| 410 | GONE | The entity was removed from the index |
| 413 | PAYLOAD_TOO_LARGE | A POST body over 256 KB |
| 429 | RATE_LIMITED | Over the per-minute limit; wait Retry-After seconds |
| 429 | QUOTA_EXCEEDED | Over the daily quota; Retry-After counts to midnight KST |
| 500 | INTERNAL_ERROR | A bug on our side; the request was fine |
| 503 | UNAVAILABLE | The index or the key store did not answer in time; retry after Retry-After |
A 301 on an entity route means the entity was merged: the body carries redirected_to: { id, slug } and Location points at the keeper. Store the new id.
Conventions
- One language per index.
languageis required on every data route (/methodologydefaults toko). Entities, questions and rankings never mix across languages. - Weeks. A GenRank week starts Sunday 00:00 KST.
weekparameters andweek_startfields are that Sunday asYYYY-MM-DD. - Methodology version. Every ranking row and every
metacarriesmethodology_version. Rows of different major versions (3.x and 4.x) are not comparable; minor versions are. History responses give the version per week so a chart can break the line where the major version changes. - Scores and ranks.
rankis the integer position.scoreis the unbounded weighted sum behind it; compare it within one category and one week only. The API publishes counts (answers, mentions, trials), never derived shares. - Identifiers. Entities and questions have a stable
slugand anid; categories have akey.model_idis the provider's model identifier (for exampleopenai/gpt-5.6-luna), listed by/models. Merged entity ids answer 301, removed ones 410; a retired question keeps answering withstatus: retiredandreplaced_by. - Regional index (Korean).
/regionslists regions and the (leaf, region) pairs measured in each, with their publish gate. Regional questions have their own slugs ({leaf}--{region}) and regional entities their own ids withregion_idand, when known,parent_entity_id(the national brand). Passregion_idto scope a question or entity route to that region; category rankings, history, graph and matrix are national and refuse it. - Windows.
cells_4w, the matrix, the graph and co-mentions cover the last four kept weeks;windowin the response says which. - Pagination. List routes take
limitandoffsetand returntotal. Bounds are in the parameter tables below.
Licence and attribution
GenRank Data (published rankings, scores and API responses) is free for lookup, research, journalism, education and internal business analysis under the Terms of Service, section 3 (https://www.genrank.com/en-us/terms#data-license): cite "GenRank (www.genrank.com)" with the edition date and methodology version; do not present altered, re-weighted, partial or out-of-date data as GenRank's findings, and do not imply that GenRank endorses a brand; wholesale copying, resale or embedding in a paid product needs a written licence. Attribution line: "Source: GenRank, {category} AI Visibility Index, edition {date}" with a link to the page.
Matching endpoints
- How they decide.
/classifyand/categories/{key}/competitorsnarrow by meaning first (vectors of GenRank's categories and ranked entities), then a judge model chooses among the few left and gives probabilities./classifyalso gives the judge up to ten categories whose name holds a word ofofferingorsite_text(the closest of them by meaning, leaving out parents and children of the nearest), so a business that sells to another industry, such as marketing for clinics, still meets its own category;categories[].sourcesays which way each one came. If the judge does not answer in time the order is by similarity only andjudged_byisvector.classifier_versionandrelevance_versionname the models; store them with what you keep. The same input gives the same answer for 24 hours. - Website lookup. Most entities have no stored website.
/entities/resolvethen ranks the entities named in answers that cited the site by how much the site name sounds like theirs (match: likelywhen one clearly fits). A platform page (a Naver Place, a Kakao Map place, an Instagram account, a Naver blog) is matched as a page: the entities named in answers that cited that page, ranked by how well the page title matches them (for a place the title is its own name, so most places resolve). The platform's own address, or a page no answer cited, answersmatch: platform; short links are not followed. A site no answer cited falls back to names that sound like it (match: sound, neverlikelyunless the names are nearly identical). Send the names the site gives itself asname(repeatable, up to 5): a site name that sounds like nothing (amc.seoul.kr) still resolves when one entity cited with it carries one of those names (name_match: true), and a name two such entities share leavesmatch: candidates. When no cited entity carries one, brands and businesses with one of those names are looked up in the whole index (match: sound,name_similarity: 1); one islikelywhen the address is written in its names (starbucks.co.kr and Starbucks) or a judge model reads the site as its official site, since two businesses can share a name. Sites that are looked up are judged daily, and a confirmed website is stored, after which the lookup answersmatch: website. - Mention checks.
POST /extracttakes one answer (question,answer,citations,tracked) or up to 20 initems, all read at once, and answers in the request: one answer usually takes 2 to 4 seconds, and a call that cannot be judged within 20 seconds answers 503. Each answer is read by the extractor GenRank uses on its own answers (extractor_version); the result gives, per answer, the recommended names in order, per tracked brand whether and where it was named, and per citation its source type and the tracked brand it belongs to, if any. A brand named only as a source or in a refusal does not count.rankis the position in the answer as GenRank's weekly data records it: an integer from 1; items the answer puts at the same position share it, and an item left out (a source, a generic term) leaves its gap. A cited page is a tracked brand's when it is on thehomepageyou send, on the website GenRank stored for itsentity_id, or when the website lookup gives the page to that entity (a Naver blog of the brand istype: portalwith itstracked_index). A call identical to one the same key sent before (language, question, answer, citations and tracked brands) gets the stored result back, for as long as the record is kept; the same answer with other tracked brands is not read again. A newextractor_versionis announced in this changelog; judge stored answers again when it changes. If any answer of a call cannot be read the whole call answers 503 withRetry-Afterand nothing is judged; never store a guess in its place. Keys are capped at 2,000 answers per KST day unless issued without a cap (429QUOTA_EXCEEDEDbeyond). - Competitors. For each ranked entity of the category, the judge model asks whether customers in the index's market (Korea for
language=ko) compare it with the brand when buying: the same buyers and use, including a broader product that covers the use; a product not sold in that market or not offered in its language does not count.mentionsandtrialsare the totals of the entity's/categories/{key}/matrixrow overwindow.co_mentionscounts the answers over the samewindowthat named both the entity and theentity_idbrand; it is null withoutentity_idand in a category above the leaves (co-mentions are kept per leaf), and there is no number to show then. - Sources per surface.
/categories/{key}/citationsand/sourcesgive counts per surface:answers(the surface's answers that week) beside the answers citing each domain and each source type, so a share isresponses / answers. A type counts an answer once however many of its sites the answer cites.askedalso counts the cells where the surface showed no AI answer or the call failed; the public sources page divides by it./sourcesadds national and regional questions together unlessscopesays otherwise. - Suggestions.
POST /entities/suggestrecords a brand GenRank lacks and answersexistswith the entity when the site already belongs to one. A suggestion never adds a brand to a ranking: GenRank asks questions, and an entity appears only when AI answers name it. - Nothing you send changes the index. Results go back to you; no score, ranking or entity is changed by what an API user sends.
Request records
Every request made with a key is recorded: the path, the query parameters and the JSON body, with the key, the time and a daily-salted hash of the address. GenRank uses the records to run and improve the API and to find categories and questions the index does not cover; they never enter a score or a ranking, are not passed to anyone, and are deleted after 12 months, together with suggestions and the answers sent to /extract with their judgments (https://www.genrank.com/en-us/governance#operator, https://www.genrank.com/en-us/privacy).
Changelog
- 2026-11-10, 2.7.0. GET /entities/resolve looks a name up in the whole index. When name is sent, no entity named in answers that cited the site has one of the names, and the site alone gives no likely owner, the brands and businesses with one of the names as their name or alias (compared as in 2.5.0) join the candidates with match sound, name_similarity 1 and confidence 0.8. Products, people, works, places, kinds of thing and branches are not looked up. One of them is likely when the site address is written in its names: the registrable name is a Latin name of the entity (starbucks.co.kr and Starbucks) or the host is one of its aliases (wtable.co.kr). Failing that, a judge model reads whether the site is the official site of each one found (from the address and the entity, not the names sent), and one it accepts is likely. Two businesses can share a name (a meat processor and a Bible app share one Korean name), so a name with neither tie stays a candidate, as it does when the judge is unavailable; one national entity still wins over regional ones of the same name. Large brands are named in answers that cite news and shops, rarely their own site, so they used to answer none or a sub-brand. Nothing changes without name, on a platform's address, or when the site already resolves; a name sent never stores a website.
- 2026-11-08, 2.6.0. Sources per surface. GET /categories/{key}/citations adds answers (per surface: cells asked, answers, answers citing a source), types (all nine source types folded over every domain of the week, not cut by limit, each with every surface) and by_model on each domain (answers and questions per surface, zeros included); type is now one of the nine types. New GET /sources gives the same for the whole index, the figures of the public sources page, with scope all (default), national or regional. A share is responses / answers; a type counts an answer once however many of its sites the answer cites. Weeks kept before 18 October 2026 have no per-surface counts. GET /categories/{key}/matrix takes pin (repeatable, up to 5): those entities are rows whatever their rank, marked pinned, with rank null when not ranked in the category. Competitors: co_mentions counts the same four weeks as mentions and trials; it is null without entity_id and in a category above the leaves, where it used to read 0.
- 2026-11-07, 2.5.0. GET /entities/resolve takes name: the name the site gives itself, repeatable up to 5 times, 100 characters each, the main one first. When exactly one entity named in answers that cited the site has one of them as its name or alias (compared without case, spaces or punctuation), match is likely and that entity comes first with name_similarity 1; when several do, match is candidates. One national entity wins over regional entities of the same name, since a website belongs to no region. On a platform's own address the candidates stay the entities named like the platform, and name only picks among them (musinsa.com with the name of the store, not of its own label). Without name the answer is unchanged. A site name that sounds like no entity (amc.seoul.kr for Asan Medical Center) used to answer candidates with an unrelated entity first. Each candidate adds name_match. A stored website now stays the first candidate when another entity also reaches confidence 1.
- 2026-11-05, 2.4.0. From 15 November 2026 00:00 KST, POST /extract reads answers with the extractor of methodology 4.3: GPT-6 Luna at reasoning effort low instead of Gemini 2.5 Flash, which Google retires on 1 December 2026. extractor_version becomes genrank-extract/openai/gpt-6-luna/2026-11-15.1; results stored under 2026-10-28.3 are read again, not reused. Names come back as the answer writes them (a Korean answer gives Korean names; translations go to aliases), and generic phrases the old extractor returned as recommendations (a type of clinic, a kind of photo) now come back with role generic or not at all. A reading takes about 3 seconds for one answer (median of 20, slowest 9). The judge behind the GenRank index changes the same day (GPT-6.1 Sol); /classify, /competitors and /entities/resolve keep their models.
- 2026-11-02, 2.3.2. POST /classify also gives the judge up to ten categories whose name holds a word of offering or site_text, besides the twelve nearest by meaning (not a parent or child of one of them). A business that sells to another industry (marketing for clinics, tax services for academies) had its meaning pulled toward its customers' industry, so its own category was never among the choices and none_probability came out high. Each of categories[] adds source: vector or name. classifier_version is 2026-11-02.1; answers stored under 2026-10-28.2 may differ.
- 2026-10-28, 2.3.1. Cited links are read as the pages they stand for. Google AI Mode writes the links in its answers as google.com/goto redirects, and Google cites English pages through Google Translate; both were counted as google.com. Redirects are now opened before an answer is stored, translated pages count as the page, Google Maps and Shopping pages on google.com count as maps.google.com (directory) and shopping.google.com (shopping), and Google place cards, which list the businesses an answer names, are not counted as citations under any address. The stored answers of the weeks of 18 and 25 October and their source statistics were corrected. POST /extract does the same with the citations you send (citations[].domain is the page cited; a redirect it cannot open gives domain null and type other); extractor_version is genrank-extract/google/gemini-2.5-flash/2026-10-28.3, so results stored under 2026-10-28.2 are judged again.
- 2026-10-28, 2.3.0. POST /extract answers in the request: 200 with the judgment of every answer, or 503 with Retry-After when any answer could not be read within 20 seconds (nothing is judged then). Up to 20 answers per call, read at once. The 202 response, job_id and GET /extract/{id} are removed. extractor_version is genrank-extract/google/gemini-2.5-flash/2026-10-28.2. Each result adds citations[]: per citation sent, its GenRank source type and, when the page is a tracked brand's own site or platform page, tracked_index; tracked[] takes an optional homepage. A call identical to an earlier one from the same key gets the stored result. /categories/{key}/competitors judges whether customers in the index's market compare the two (for ko, Korean buyers; a product not sold there is not a competitor), and each competitor adds mentions and trials, the totals of its /categories/{key}/matrix row, with window. /entities/search no longer times out on common names (a query of two characters matches names and aliases that start with it), and a slow meaning lookup is skipped instead of failing the search.
- 2026-10-28, 2.2.1. /entities/resolve reads platform pages: a Naver Place (map.naver.com and m.place.naver.com forms alike), a Kakao Map place, an Instagram account, a Naver blog or a smartstore resolves to the entities named in answers that cited that page, ranked by how well the page title (for a place, its own name) matches them; site.title carries that title. A site no answer cited falls back to names that sound like it (match: sound). Short links (naver.me, bit.ly ...) answer platform. candidates[].match adds sound.
- 2026-10-28, 2.2.0. Matching endpoints that compute from what you send: GET /entities/resolve (which entity a website belongs to), POST /classify (which categories a brand competes in), POST /categories/{key}/competitors (a category ranked by relevance to one brand), POST /extract and GET /extract/{id} (mention checks with GenRank's extractor, judged in batches), POST /entities/suggest (record a brand GenRank lacks). /entities/search adds sound matches across Hangul and Latin spellings and meaning matches, and each result carries match { kind, score }; alias matches work again (the alias filter used a column that was never filled), and domain search no longer times out. Every keyed request is now recorded with its parameters and body for 12 months (see Request records).
- 2026-10-28, 2.1.2. citations[].type is classified with the current source rules for every week (it was the reading stored at collection time). Review, listing and booking platforms such as place.naver.com, hwahae.co.kr and glowpick.com are now directory instead of other, and the most specific host wins (play.google.com is directory, not portal). The set of values is unchanged.
- 2026-10-28, 2.1.1. /models reads the panel each index is scored with: language=ko lists the eight Korean surfaces with their weights (it listed the English panel's weights and 0 for the Korean surfaces); effective_from is when the surface took its current weight; collection is serp for search-page surfaces; scope=regional lists the Korean regional panel; retired lists the surfaces the index stopped measuring.
- 2026-10-28, 2.1.0. Category endpoints (/categories, /categories/{key}, rankings, history, graph, matrix); entity history, graph and overview; /regions and /runs?scope=regional populated; region_id honoured on question and entity routes, with 400 UNKNOWN_REGION for an unknown id; entity.region and entity.parent widened from null to objects; daily quotas, X-Quota-* headers and 503 UNAVAILABLE; keys with expiry, rotation and IP allowlists. The v1 routes under /api answer 410.
- 2026-10-20, 2.0.0. First release of the read API v2.
Contact
hello@genrank.com. Corrections are free and published (https://www.genrank.com/en-us/governance#corrections).
API version 2.7.0.