{"openapi": "3.1.0", "info": {"title": "Brand Wiki API", "version": "1.0.0", "description": "Crawls a brand website to build an entity map, brand wiki, evidence claims and schema, then links them to ListeningMind search demand to produce an action plan, entity gaps, coverage and page signals. GEO/AEO teams use it to fix content so AI answers describe the brand correctly. Demand data exists for Korea, Japan and the US; demand and category context can also be imported from Intent KG runs. Workflow: create_project → discover_urls → update_crawl_settings → crawl_pages → start_entity_analysis → get_analysis_status → get_analysis → get_kg_link → import_demand_from_ontology → fetch_demand_live → import_category_context → start_action_plan → get_action_plan_status → start_entity_gap → get_entity_gap_status → start_coverage → get_coverage → start_page_signals → get_page_signals → generate_entity_page → get_project → export_project", "contact": {"email": "m-support@listeningmind.com"}}, "servers": [{"url": "https://daas-wiki.listeningmind.ai"}], "paths": {"/api/projects": {"get": {"operationId": "list_projects", "summary": "List projects", "description": "Lists all brand wiki projects: {projects:[{projectId, brandName, domain, seedUrl, language, country, industry, crawlSettings, status, createdAt, updatedAt}]}. status moves created -> discovered -> crawling -> crawled -> analyzed. Read only, free. Usually followed by: get_project.", "tags": ["read"], "x-lm-kind": "read", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}}, "post": {"operationId": "create_project", "summary": "Create a project", "description": "Creates a project for one brand website. Only seedUrl is required; brandName defaults to the host name, language and country are normalized (empty language is detected from content later). Returns {project} with projectId (HTTP 201). Changes saved data in the app; no credits. Usually followed by: discover_urls.", "tags": ["action"], "x-lm-kind": "action", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"seedUrl": {"type": "string", "description": "Brand site URL to start from, e.g. https://www.example.com/."}, "brandName": {"type": "string", "description": "Brand name used in analysis prompts, wiki titles and the brand MCP; defaults to the host name."}, "country": {"type": "string", "description": "Market. Decides which ListeningMind market demand data comes from (only KR, JP, US have data; others are refused for demand) and the default language. Empty = guessed from domain TLD and language. Names like 한국 or kr are normalized.", "enum": ["", "KR", "JP", "US", "GB", "CA", "AU", "SG", "CN", "TW", "HK", "DE", "FR", "ES", "IT", "NL", "PL", "TR", "RU", "BR", "MX", "PT", "VN", "TH", "ID", "IN", "AE", "SA"], "default": ""}, "language": {"type": "string", "description": "Preferred report language. Empty = market default or detected. Note: the analysis decides the output language from the crawled pages first (html lang majority, then script), and uses this setting only when pages give no clear signal.", "enum": ["", "ko", "ja", "zh-Hans", "zh-Hant", "en", "es", "fr", "de", "pt", "it", "nl", "ru", "pl", "tr", "vi", "th", "id", "ar", "hi"], "default": ""}, "industry": {"type": "string", "description": "Industry text given to the analysis as context, e.g. B2B SaaS."}, "maxPages": {"type": "integer", "description": "Max pages to crawl. More pages give more entities and claims and longer analysis. Default from settings (80 unless changed).", "minimum": 1, "maximum": 1000}, "maxDepth": {"type": "integer", "description": "Max link depth for discovery (default from settings, 3).", "minimum": 1, "maximum": 10}, "competitors": {"type": "array", "description": "Competitor names.", "items": {"type": "string"}}, "priorityCategories": {"type": "array", "description": "Priority categories.", "items": {"type": "string"}}, "includePaths": {"type": "array", "description": "Only crawl these path prefixes.", "items": {"type": "string"}}, "excludePaths": {"type": "array", "description": "Skip these path prefixes (default from settings).", "items": {"type": "string"}}, "respectRobots": {"type": "boolean", "description": "Respect robots.txt (default true).", "default": true}, "includeNoindex": {"type": "boolean", "description": "Also keep noindex pages (default false).", "default": false}}, "required": ["seedUrl"]}}}}}}, "/api/projects/{project_id}": {"get": {"operationId": "get_project", "summary": "Get project bundle", "description": "Returns everything stored for a project: {project, discovery, pages, analysis (entities, wiki pages, claims, schema), connector (demand keywords), actionPlan, entityGap, generatedPages, pageSignals, categoryContext}. Can be large. Read only, free.", "tags": ["read"], "x-lm-kind": "read", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}]}, "patch": {"operationId": "update_crawl_settings", "summary": "Change crawl settings", "description": "Updates crawl settings of a project before crawling. maxPages is clamped to 1-1000 and maxDepth to 1-10. Returns {project}. Changes saved data in the app; no credits.", "tags": ["action"], "x-lm-kind": "action", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"crawlSettings": {"type": "object", "description": "{maxPages 1-1000, maxDepth 1-10, includePaths: [string], excludePaths: [string]}; send only what changes. The UI sends maxPages right before crawling.", "properties": {"maxPages": {"type": "integer", "minimum": 1, "maximum": 1000}, "maxDepth": {"type": "integer", "minimum": 1, "maximum": 10}, "includePaths": {"type": "array", "items": {"type": "string"}}, "excludePaths": {"type": "array", "items": {"type": "string"}}}}}, "required": ["crawlSettings"]}}}}}, "delete": {"operationId": "delete_project", "summary": "Delete a project", "description": "Deletes a project and all its data. Returns {ok:true}. Deletes data. A person approves it first.", "tags": ["delete"], "x-lm-kind": "delete", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}]}}, "/api/projects/{project_id}/discover": {"post": {"operationId": "discover_urls", "summary": "Discover URLs", "description": "Collects candidate URLs from the site's sitemaps and links and reads robots.txt to judge AI crawler access. Pass robotsOnly='1' to only re-read robots.txt for an existing discovery. Returns {discovery:{urls:[{url, included, ...}], ...}}. Changes saved data in the app; no credits. Time: 10 seconds to a few minutes. Usually followed by: crawl_pages.", "tags": ["action"], "x-lm-kind": "action", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}, {"name": "robotsOnly", "in": "query", "required": false, "description": "'1' = only refresh robots.txt access, keep the URL list.", "schema": {"type": "string", "enum": ["1"]}}]}}, "/api/projects/{project_id}/crawl": {"post": {"operationId": "crawl_pages", "summary": "Crawl pages", "description": "Crawls pages and stores their text. With no urls it crawls every discovered URL marked included (capped by maxPages). Waits until done (up to 5 minutes). Returns {crawled, successful, failed}. Spends ListeningMind Data API credits or paid model calls. Over MCP a person approves it first (you get a confirm link); in the browser the page asks the person. Cost: free (no credits); fetches the brand's site. Time: up to 5 minutes. Usually followed by: start_entity_analysis.", "tags": ["run"], "x-lm-kind": "run", "x-lm-cost": "free (no credits); fetches the brand's site", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}], "requestBody": {"required": false, "content": {"application/json": {"schema": {"type": "object", "properties": {"urls": {"type": "array", "description": "Specific URLs to crawl; omit to crawl the included discovered URLs.", "items": {"type": "string"}}}, "required": []}}}}}}, "/api/projects/{project_id}/analyze": {"post": {"operationId": "start_entity_analysis", "summary": "Start entity analysis", "description": "Starts the AI analysis of the crawled pages: entity map (core, supporting, context), brand wiki pages, evidence claims and schema. Runs in the background; returns {started:true} or 409 {reason:'already-running'}. Poll get_analysis_status. Spends ListeningMind Data API credits or paid model calls. Over MCP a person approves it first (you get a confirm link); in the browser the page asks the person. Cost: paid LLM calls on the server (Gemini, OpenAI, Anthropic or MiniMax, whichever key is set); no Data API credits. Time: 1-10 minutes depending on page count. Usually followed by: get_analysis_status.", "tags": ["run"], "x-lm-kind": "run", "x-lm-cost": "paid LLM calls on the server (Gemini, OpenAI, Anthropic or MiniMax, whichever key is set); no Data API credits", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}]}, "get": {"operationId": "get_analysis_status", "summary": "Check analysis status", "description": "Returns {status:{state (idle, running, done, error), startedAt, finishedAt, message, progress:{pagesCited, totalPages, entities, elapsedSec}}, claudeAvailable}. Repeat until state is done or error. Read only, free. Waits up to about 45 s for 'status.state' to reach done, error, idle; call again if not done. Usually followed by: get_analysis.", "tags": ["read"], "x-lm-kind": "read", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}]}}, "/api/projects/{project_id}/analysis": {"get": {"operationId": "get_analysis", "summary": "Get analysis", "description": "Returns {analysis}: entities with types, layers, descriptions, CEPs, attributes and evidence; brand wiki pages; claims with source URLs; review status. null before analysis. Read only, free.", "tags": ["read"], "x-lm-kind": "read", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}]}, "put": {"operationId": "save_analysis", "summary": "Save edited analysis", "description": "Replaces the whole analysis object, as the in-app editor does when you edit an entity or wiki page or change review status. Send the full analysis from get_analysis with your edits. Returns {ok:true}. Changes saved data in the app; no credits.", "tags": ["action"], "x-lm-kind": "action", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"analysis": {"type": "object", "description": "Full analysis object (same shape as get_analysis.analysis)."}}, "required": ["analysis"]}}}}}}, "/api/projects/{project_id}/connector": {"get": {"operationId": "get_demand_data", "summary": "Get demand data", "description": "Returns the project's demand connector: {connector:{source, importedAt, items:[{keyword, intent, cep, monthlyVolume, trend, relatedEntity, note}]}} or null. Read only, free.", "tags": ["read"], "x-lm-kind": "read", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}]}, "put": {"operationId": "import_demand_data", "summary": "Import demand data", "description": "Saves demand keywords you already have. Send exactly one of items, csv (header keyword,volume,intent,cep,trend,note; Korean headers also work) or json (a JSON string of an array or {items}). Replaces the current connector. Returns {connector}. Changes saved data in the app; no credits.", "tags": ["action"], "x-lm-kind": "action", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}], "requestBody": {"required": false, "content": {"application/json": {"schema": {"type": "object", "properties": {"items": {"type": "array", "description": "Demand items [{keyword, monthlyVolume, intent, cep, trend, relatedEntity, note}].", "items": {"type": "object"}}, "csv": {"type": "string", "description": "CSV text with a header row."}, "json": {"type": "string", "description": "JSON text: an array of items or {items:[...]}."}, "source": {"type": "string", "description": "Source label (default listeningmind)."}}, "required": []}}}}}}, "/api/projects/{project_id}/connector/fetch-direct": {"get": {"operationId": "check_live_demand_fetch", "summary": "Check automatic demand fetch", "description": "Tells whether the server can fetch demand directly from ListeningMind for this project: {available, market:{code, name, gl}, marketSupported, message}. Only KR, JP and US markets have data. Read only, free. Usually followed by: fetch_demand_live.", "tags": ["read"], "x-lm-kind": "read", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}]}, "post": {"operationId": "fetch_demand_live", "summary": "Fetch demand from ListeningMind", "description": "Server calls the ListeningMind Data API: expands related keywords from up to 5 seed keywords (cluster_finder rels), then gets volume and trend for up to about 120 candidates (keyword_info), keeps those with volume, and saves them as the demand connector. Returns {imported, source}; 409 no-credentials or unsupported-market. Spends ListeningMind Data API credits or paid model calls. Over MCP a person approves it first (you get a confirm link); in the browser the page asks the person. Cost: ListeningMind Data API credits: up to 5 cluster_finder calls plus keyword_info for up to about 120 keywords. Time: up to 2 minutes. Usually followed by: start_action_plan.", "tags": ["run"], "x-lm-kind": "run", "x-lm-cost": "ListeningMind Data API credits: up to 5 cluster_finder calls plus keyword_info for up to about 120 keywords", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}]}}, "/api/projects/{project_id}/connector/fetch": {"post": {"operationId": "prepare_demand_handoff", "summary": "Prepare Claude Code demand hand-off", "description": "Writes a FETCH-LM.md instruction file into the project folder and returns {command, gl, market, marketSupported, seeds} so a Claude Code session with the ListeningMind MCP can collect demand and write connector.json. No credits by itself. Changes saved data in the app; no credits.", "tags": ["action"], "x-lm-kind": "action", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}]}}, "/api/projects/{project_id}/connector/fetch-ontology": {"get": {"operationId": "list_ontology_runs_for_demand", "summary": "List KG runs for demand", "description": "Lists existing Intent KG (topic ontology) runs that can be imported as demand data, optionally filtered by topic text and market. Returns {runs:[{runId, topic, gl, ...}]}. Never builds. Read only, free.", "tags": ["read"], "x-lm-kind": "read", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}, {"name": "q", "in": "query", "required": false, "description": "Topic text filter.", "schema": {"type": "string"}}, {"name": "gl", "in": "query", "required": false, "description": "Market code.", "schema": {"type": "string", "enum": ["kr", "jp", "us"]}}]}, "post": {"operationId": "import_demand_from_ontology", "summary": "Import demand from a KG run", "description": "Imports the decision layer of one existing Intent KG run as the project's demand connector. Give runId, or topic (+gl) to match a run. Never builds a new run. Returns {imported, connector, stats}; 404 no-match when no run exists. Changes saved data in the app; no credits. Usually followed by: start_action_plan.", "tags": ["action"], "x-lm-kind": "action", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}], "requestBody": {"required": false, "content": {"application/json": {"schema": {"type": "object", "properties": {"runId": {"type": "string", "description": "KG run id."}, "topic": {"type": "string", "description": "Topic to match when runId is not given."}, "gl": {"type": "string", "description": "Market code for topic matching.", "enum": ["kr", "jp", "us"], "default": "kr"}, "cap": {"type": "integer", "description": "Max demand items to import (server default when omitted).", "minimum": 1}}, "required": []}}}}}}, "/api/projects/{project_id}/actionplan": {"post": {"operationId": "start_action_plan", "summary": "Generate action plan", "description": "Builds the action plan that maps demand keywords to entities and content actions. Needs an analysis and demand data. Runs in the background; returns {started:true}. Poll get_action_plan_status, then read actionPlan from get_project. Spends ListeningMind Data API credits or paid model calls. Over MCP a person approves it first (you get a confirm link); in the browser the page asks the person. Cost: paid LLM calls on the server (Gemini, OpenAI, Anthropic or MiniMax, whichever key is set); no Data API credits. Time: 1-5 minutes. Usually followed by: get_action_plan_status.", "tags": ["run"], "x-lm-kind": "run", "x-lm-cost": "paid LLM calls on the server (Gemini, OpenAI, Anthropic or MiniMax, whichever key is set); no Data API credits", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}]}, "get": {"operationId": "get_action_plan_status", "summary": "Check action plan status", "description": "Returns {status:{state, message, ...}, claudeAvailable}. Repeat until done or error; the plan itself is in get_project.actionPlan. Read only, free. Waits up to about 45 s for 'status.state' to reach done, error, idle; call again if not done. Usually followed by: get_project.", "tags": ["read"], "x-lm-kind": "read", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}]}, "put": {"operationId": "save_action_plan", "summary": "Save action plan edits", "description": "Saves the full action plan after edits such as changing an action item's status. Send the full actionPlan object. Returns {ok:true}. Changes saved data in the app; no credits.", "tags": ["action"], "x-lm-kind": "action", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"actionPlan": {"type": "object", "description": "Full actionPlan object (from get_project)."}}, "required": ["actionPlan"]}}}}}}, "/api/projects/{project_id}/entitygap": {"post": {"operationId": "start_entity_gap", "summary": "Start entity gap analysis", "description": "Finds entities and facts the brand should cover but does not (uses demand data as a hint if present). Needs an analysis. Background job; returns {started:true}. Poll get_entity_gap_status, then read entityGap from get_project. Spends ListeningMind Data API credits or paid model calls. Over MCP a person approves it first (you get a confirm link); in the browser the page asks the person. Cost: paid LLM calls on the server (Gemini, OpenAI, Anthropic or MiniMax, whichever key is set); no Data API credits. Time: 1-5 minutes. Usually followed by: get_entity_gap_status.", "tags": ["run"], "x-lm-kind": "run", "x-lm-cost": "paid LLM calls on the server (Gemini, OpenAI, Anthropic or MiniMax, whichever key is set); no Data API credits", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}]}, "get": {"operationId": "get_entity_gap_status", "summary": "Check entity gap status", "description": "Returns {status:{state, message, ...}, claudeAvailable}. Repeat until done or error. Read only, free. Waits up to about 45 s for 'status.state' to reach done, error, idle; call again if not done. Usually followed by: get_project.", "tags": ["read"], "x-lm-kind": "read", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}]}, "put": {"operationId": "save_entity_gap", "summary": "Save entity gap edits", "description": "Saves the full entity gap report after edits such as a gap status toggle. Returns {ok:true}. Changes saved data in the app; no credits.", "tags": ["action"], "x-lm-kind": "action", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"entityGap": {"type": "object", "description": "Full entityGap report (from get_project)."}}, "required": ["entityGap"]}}}}}}, "/api/projects/{project_id}/coverage": {"post": {"operationId": "start_coverage", "summary": "Start coverage analysis", "description": "Checks how well the site covers the entities and demand (questions AI assistants would ask). Needs an analysis. Background job; returns {started:true}. Poll get_coverage. Spends ListeningMind Data API credits or paid model calls. Over MCP a person approves it first (you get a confirm link); in the browser the page asks the person. Cost: paid LLM calls on the server (Gemini, OpenAI, Anthropic or MiniMax, whichever key is set); no Data API credits. Time: 1-5 minutes. Usually followed by: get_coverage.", "tags": ["run"], "x-lm-kind": "run", "x-lm-cost": "paid LLM calls on the server (Gemini, OpenAI, Anthropic or MiniMax, whichever key is set); no Data API credits", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}]}, "get": {"operationId": "get_coverage", "summary": "Get coverage report", "description": "Returns {status:{state, message}, report, claudeAvailable}. Repeat until state is done or error; report holds the coverage result. Read only, free. Waits up to about 45 s for 'status.state' to reach done, error, idle; call again if not done.", "tags": ["read"], "x-lm-kind": "read", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}]}}, "/api/projects/{project_id}/page-signals": {"post": {"operationId": "start_page_signals", "summary": "Start page signal analysis", "description": "Scores crawled pages for AI-readability signals (structure, schema, entity clarity, demand fit). Needs analysis and crawled pages. Background job; returns {started:true}. Poll get_page_signals. Spends ListeningMind Data API credits or paid model calls. Over MCP a person approves it first (you get a confirm link); in the browser the page asks the person. Cost: paid LLM calls on the server (Gemini, OpenAI, Anthropic or MiniMax, whichever key is set); no Data API credits. Time: 1-5 minutes. Usually followed by: get_page_signals.", "tags": ["run"], "x-lm-kind": "run", "x-lm-cost": "paid LLM calls on the server (Gemini, OpenAI, Anthropic or MiniMax, whichever key is set); no Data API credits", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}]}, "get": {"operationId": "get_page_signals", "summary": "Get page signals", "description": "Returns {status:{state, message}, report, claudeAvailable}. Repeat until state is done or error. Read only, free. Waits up to about 45 s for 'status.state' to reach done, error, idle; call again if not done.", "tags": ["read"], "x-lm-kind": "read", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}]}}, "/api/projects/{project_id}/generate-page": {"post": {"operationId": "generate_entity_page", "summary": "Generate entity page", "description": "Generates a draft canonical page (text and schema) for one entity of the analysis. Background job; returns {started:true}. Poll get_page_generation_status; the result appears in get_project.generatedPages. Spends ListeningMind Data API credits or paid model calls. Over MCP a person approves it first (you get a confirm link); in the browser the page asks the person. Cost: paid LLM calls on the server (Gemini, OpenAI, Anthropic or MiniMax, whichever key is set); no Data API credits. Time: about 1-3 minutes. Usually followed by: get_page_generation_status.", "tags": ["run"], "x-lm-kind": "run", "x-lm-cost": "paid LLM calls on the server (Gemini, OpenAI, Anthropic or MiniMax, whichever key is set); no Data API credits", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"entityId": {"type": "string", "description": "Entity id from the analysis."}}, "required": ["entityId"]}}}}}, "get": {"operationId": "get_page_generation_status", "summary": "Check page generation", "description": "Returns {status, aiAvailable}. status describes the current or last page generation job (state, entityId, message). Repeat until done or error. Read only, free. Waits up to about 45 s for 'status.state' to reach done, error, idle; call again if not done. Usually followed by: get_project.", "tags": ["read"], "x-lm-kind": "read", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}]}}, "/api/projects/{project_id}/wiki/fetch-ontology-context": {"get": {"operationId": "list_ontology_runs_for_context", "summary": "List KG runs for category context", "description": "Lists existing Intent KG runs whose knowledge layer can be imported as category context for the wiki. Returns {runs}. Never builds. Read only, free.", "tags": ["read"], "x-lm-kind": "read", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}, {"name": "q", "in": "query", "required": false, "description": "Topic text filter.", "schema": {"type": "string"}}, {"name": "gl", "in": "query", "required": false, "description": "Market code.", "schema": {"type": "string", "enum": ["kr", "jp", "us"]}}]}, "post": {"operationId": "import_category_context", "summary": "Import category context", "description": "Imports one KG run's knowledge layer (conventions, heuristics, trade-offs, benchmarks, pitfalls) as the project's category context, cited at the bottom of wiki pages. Give runId, or topic (+gl). Returns {imported, context, stats}. Changes saved data in the app; no credits.", "tags": ["action"], "x-lm-kind": "action", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}], "requestBody": {"required": false, "content": {"application/json": {"schema": {"type": "object", "properties": {"runId": {"type": "string", "description": "KG run id."}, "topic": {"type": "string", "description": "Topic to match when runId is not given."}, "gl": {"type": "string", "description": "Market code for topic matching.", "enum": ["kr", "jp", "us"], "default": "kr"}, "cap": {"type": "integer", "description": "Max context items to import (server default when omitted).", "minimum": 1}}, "required": []}}}}}}, "/api/projects/{project_id}/kg": {"get": {"operationId": "get_kg_build", "summary": "Check KG build", "description": "Returns {job:{status, ...}, link}. When status is done the link is refreshed to the new run. Repeat until done or error. Read only, free. Waits up to about 45 s for 'job.status' to reach done, error; call again if not done.", "tags": ["read"], "x-lm-kind": "read", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}, {"name": "poll", "in": "query", "required": true, "description": "Build job id from request_kg_build (link.building.jobId).", "schema": {"type": "string"}}]}, "post": {"operationId": "request_kg_build", "summary": "Request a new KG build", "description": "Asks the Intent KG app to build a new topic graph for this project (sends build:true and confirm:true). Returns {link} with link.building.jobId; poll get_kg_build. Spends ListeningMind Data API credits or paid model calls. Over MCP a person approves it first (you get a confirm link); in the browser the page asks the person. Cost: about 20,000-50,000 Data API credits per build. Time: several minutes. Usually followed by: get_kg_build.", "tags": ["run"], "x-lm-kind": "run", "x-lm-cost": "about 20,000-50,000 Data API credits per build", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"topic": {"type": "string", "description": "Topic to build."}, "gl": {"type": "string", "description": "Market code.", "enum": ["kr", "jp", "us"]}}, "required": ["topic"]}}}}}}, "/api/projects/{project_id}/mcp-demo": {"post": {"operationId": "ask_dual_demo", "summary": "Ask the dual-knowledge demo", "description": "Answers one question twice: from internal brand knowledge only, and from brand knowledge plus live ListeningMind search demand for the most related entity. Returns {internal, combined, evidence:{wiki, market}}. Spends ListeningMind Data API credits or paid model calls. Over MCP a person approves it first (you get a confirm link); in the browser the page asks the person. Cost: 2 paid LLM calls plus ListeningMind Data API credits (cluster_finder rels and keyword_info for up to 40 keywords). Time: 10-60 seconds.", "tags": ["run"], "x-lm-kind": "run", "x-lm-cost": "2 paid LLM calls plus ListeningMind Data API credits (cluster_finder rels and keyword_info for up to 40 keywords)", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}], "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"question": {"type": "string", "description": "Question about the brand."}}, "required": ["question"]}}}}}}, "/api/projects/{project_id}/mcp": {"get": {"operationId": "get_brand_mcp_info", "summary": "Get brand MCP server info", "description": "Describes the per-project brand knowledge MCP server (JSON-RPC 2.0 over POST to the same path): service name, transport, endpoint and tool names (search_wiki, list_entities, read_entity, search_market, gap_report, category_kg). Read only, free.", "tags": ["read"], "x-lm-kind": "read", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}]}}, "/api/projects/{project_id}/export": {"get": {"operationId": "export_project", "summary": "Export", "description": "Downloads project data. format: markdown (wiki), json (whole bundle), entities-csv, claims-csv, jsonld (schema.org), llms-txt, connector (demand JSON), connector-csv. Sent as an attachment. Read only, free.", "tags": ["read"], "x-lm-kind": "read", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "project_id", "in": "path", "required": true, "description": "Project id (12 hex chars) from list_projects or create_project.", "schema": {"type": "string"}}, {"name": "format", "in": "query", "required": false, "description": "Export format.", "schema": {"type": "string", "enum": ["markdown", "json", "entities-csv", "claims-csv", "jsonld", "llms-txt", "connector", "connector-csv"], "default": "markdown"}}]}}, "/api/settings": {"get": {"operationId": "get_settings", "summary": "Get default settings", "description": "Returns {settings:{defaultMaxPages, defaultMaxDepth, defaultExcludePaths, respectRobots}} applied to new projects. Read only, free.", "tags": ["read"], "x-lm-kind": "read", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}}, "put": {"operationId": "update_settings", "summary": "Update default settings", "description": "Updates defaults for new projects. defaultMaxPages is clamped to 1-1000 and defaultMaxDepth to 1-10. Returns {settings}. Changes saved data in the app; no credits.", "tags": ["action"], "x-lm-kind": "action", "x-lm-cost": "free", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "requestBody": {"required": false, "content": {"application/json": {"schema": {"type": "object", "properties": {"defaultMaxPages": {"type": "integer", "description": "Default max pages."}, "defaultMaxDepth": {"type": "integer", "description": "Default max depth."}, "defaultExcludePaths": {"type": "array", "description": "Default excluded path prefixes.", "items": {"type": "string"}}, "respectRobots": {"type": "boolean", "description": "Respect robots.txt by default."}}, "required": []}}}}}}}, "externalDocs": {"url": "https://daas-wiki.listeningmind.ai/agents.md", "description": "Agent guide"}}