{"openapi": "3.1.0", "info": {"title": "Demand Forecast API", "version": "1.0.0", "description": "Demand forecast and season calendar. From category seed keywords it collects related queries, groups them into segments, forecasts the next 3 or 6 months and the change versus last year from 48 months of monthly search volume, and derives prep, campaign, launch and peak months. Product planners, merchandisers and campaign owners use it to set season timing. Data comes from the ListeningMind Data API (intent_finder, keyword_info). Markets: Korea, Japan, US. Workflow: get_config → suggest_seeds → estimate_credits → start_run → get_run → get_report_markdown → download_timing_ics → download_forecast_csv", "contact": {"email": "m-support@listeningmind.com"}}, "servers": [{"url": "https://daas-forecast.listeningmind.ai"}], "paths": {"/api/config": {"get": {"operationId": "get_config", "summary": "Settings and options", "description": "Returns markets, example seed topics per category for the market, the timing rules (ramp, prep lead, launch window, peak thresholds), the default credit cap, whether the LLM is available and the account credit balance. Free. 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": "lang", "in": "query", "required": false, "description": "Language of generated text: ko, ja or en.", "schema": {"type": "string", "enum": ["ko", "ja", "en"], "default": "ko"}}, {"name": "gl", "in": "query", "required": false, "description": "Search market: kr (Korea), jp (Japan) or us (United States).", "schema": {"type": "string", "enum": ["kr", "jp", "us"], "default": "kr"}}]}}, "/api/suggest_seeds": {"post": {"operationId": "suggest_seeds", "summary": "Suggest seeds", "description": "Proposes companion seed keywords for one category keyword: related queries from intent_finder, ranked by 12-month volume from keyword_info, then picked by an LLM. Returns {seeds, credits}. Up to 600 Data API credits (usually about 200-300), 10-30 seconds. 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: up to 600 Data API credits (usually about 200-300) plus 1 LLM call. Time: 10-30 seconds. Usually followed by: estimate_credits.", "tags": ["run"], "x-lm-kind": "run", "x-lm-cost": "up to 600 Data API credits (usually about 200-300) plus 1 LLM call", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"keyword": {"type": "string", "description": "One category keyword (the UI sends the first typed seed)."}, "gl": {"type": "string", "description": "Search market: kr (Korea), jp (Japan) or us (United States).", "enum": ["kr", "jp", "us"], "default": "kr"}, "lang": {"type": "string", "description": "Language of generated text: ko, ja or en.", "enum": ["ko", "ja", "en"], "default": "ko"}}, "required": ["keyword"]}}}}}}, "/api/estimate": {"post": {"operationId": "estimate_credits", "summary": "Estimate credits", "description": "Returns the expected Data API credits for the inputs: {harvest, series, demography, total, pool}. Computed locally, no API calls; cached calls in the real run are free. Read only, free. Usually followed by: start_run.", "tags": ["read"], "x-lm-kind": "read", "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": {"seeds": {"type": "string", "description": "Category seed keywords, comma or newline separated; duplicates removed, up to 5 used. Each seed adds its related keywords to the universe, so seeds define what the category forecast covers. Example: '선크림, 자외선차단제'. get_config.topics lists examples per market.", "minLength": 1}, "gl": {"type": "string", "description": "Search market: kr (Korea), jp (Japan) or us (United States).", "enum": ["kr", "jp", "us"], "default": "kr"}, "lang": {"type": "string", "description": "Language of generated text: ko, ja or en.", "enum": ["ko", "ja", "en"], "default": "ko"}, "horizon": {"type": "integer", "description": "Forecast horizon in months: 3 or 6 (values of 6 or more mean 6, anything lower means 3). Changes the forecast months, the horizon totals and year-over-year figures, and which timing windows fall inside the horizon.", "enum": [3, 6], "default": 6}, "scope": {"type": "string", "description": "Keyword universe size: standard (100 related keywords by volume plus 40 rising per seed) or wide (200 plus 40, more credits). Wider universes add long-tail keywords to segments; total pool capped at 700.", "enum": ["standard", "wide"], "default": "standard"}, "segment_mode": {"type": "string", "description": "How keywords are grouped into segments: auto (LLM groups by need), seed (one segment per seed) or custom (your own segments in custom_segments).", "enum": ["auto", "seed", "custom"], "default": "auto"}, "custom_segments": {"type": "string", "description": "Only for segment_mode=custom. One segment per line as 'Name: keyword1, keyword2'. Up to 12 segments. Example: '선스틱: 선스틱, 톤업 선스틱'.", "default": ""}, "demography": {"type": "boolean", "description": "Add gender and age share per segment from the top 5 keywords of each segment (Korea only; ignored for jp and us). Adds about 400 credits at most. The web form shows this only for Korea.", "default": false}, "credit_cap": {"type": "integer", "description": "Hard Data API credit cap for this run; the run stops with an error when it is reached. Default is the server cap (5,000 at the time of writing; get_config.credit_cap_default). The server does not clamp a higher value, so do not raise it without the person's consent.", "minimum": 1}}, "required": ["seeds"]}}}}}}, "/api/runs": {"post": {"operationId": "start_run", "summary": "Start a forecast", "description": "Starts a background run: builds a keyword universe from the seeds, filters off-topic keywords with an LLM, pulls 48 months of volume, groups keywords into segments, forecasts the next 3 or 6 months per segment and for the category, and derives prep, campaign, launch and peak months. Returns {run_id}. Poll get_run. About 400-1,800 Data API credits with defaults, 1-3 minutes. 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 400-1,800 Data API credits with defaults (cap 5,000) plus LLM calls for filtering, segments and the brief. Time: 1-3 minutes. Usually followed by: get_run.", "tags": ["run"], "x-lm-kind": "run", "x-lm-cost": "about 400-1,800 Data API credits with defaults (cap 5,000) plus LLM calls for filtering, segments and the brief", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object", "properties": {"seeds": {"type": "string", "description": "Category seed keywords, comma or newline separated; duplicates removed, up to 5 used. Each seed adds its related keywords to the universe, so seeds define what the category forecast covers. Example: '선크림, 자외선차단제'. get_config.topics lists examples per market.", "minLength": 1}, "gl": {"type": "string", "description": "Search market: kr (Korea), jp (Japan) or us (United States).", "enum": ["kr", "jp", "us"], "default": "kr"}, "lang": {"type": "string", "description": "Language of generated text: ko, ja or en.", "enum": ["ko", "ja", "en"], "default": "ko"}, "horizon": {"type": "integer", "description": "Forecast horizon in months: 3 or 6 (values of 6 or more mean 6, anything lower means 3). Changes the forecast months, the horizon totals and year-over-year figures, and which timing windows fall inside the horizon.", "enum": [3, 6], "default": 6}, "scope": {"type": "string", "description": "Keyword universe size: standard (100 related keywords by volume plus 40 rising per seed) or wide (200 plus 40, more credits). Wider universes add long-tail keywords to segments; total pool capped at 700.", "enum": ["standard", "wide"], "default": "standard"}, "segment_mode": {"type": "string", "description": "How keywords are grouped into segments: auto (LLM groups by need), seed (one segment per seed) or custom (your own segments in custom_segments).", "enum": ["auto", "seed", "custom"], "default": "auto"}, "custom_segments": {"type": "string", "description": "Only for segment_mode=custom. One segment per line as 'Name: keyword1, keyword2'. Up to 12 segments. Example: '선스틱: 선스틱, 톤업 선스틱'.", "default": ""}, "demography": {"type": "boolean", "description": "Add gender and age share per segment from the top 5 keywords of each segment (Korea only; ignored for jp and us). Adds about 400 credits at most. The web form shows this only for Korea.", "default": false}, "credit_cap": {"type": "integer", "description": "Hard Data API credit cap for this run; the run stops with an error when it is reached. Default is the server cap (5,000 at the time of writing; get_config.credit_cap_default). The server does not clamp a higher value, so do not raise it without the person's consent.", "minimum": 1}}, "required": ["seeds"]}}}}}, "get": {"operationId": "list_runs", "summary": "Run history", "description": "Lists recent runs with run_id, status, params, credits, created_at, updated_at, error and, for finished runs, a summary {segments, keywords, latest_month}. 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": "limit", "in": "query", "required": false, "description": "Maximum runs to return.", "schema": {"type": "integer", "default": 40}}]}}, "/api/runs/{run_id}": {"get": {"operationId": "get_run", "summary": "Run status and result", "description": "Returns one run: status (running, done, error), progress {stage, pct, steps}, credits, params, error and, when done, the result (meta, stats, months, category forecast and plan, segments, keywords, excluded, rules, brief, evidence). Repeat until status is done or error. Read only, free. Waits up to about 45 s for 'status' to reach done, error; call again if not done. Usually followed by: get_report_markdown, download_timing_ics.", "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": "run_id", "in": "path", "required": true, "description": "Run id returned by start_run or list_runs (shown in the result URL /r/{run_id}).", "schema": {"type": "string"}}]}, "delete": {"operationId": "delete_run", "summary": "Delete run", "description": "Deletes a run and its result. Cannot be undone. 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": "run_id", "in": "path", "required": true, "description": "Run id returned by start_run or list_runs (shown in the result URL /r/{run_id}).", "schema": {"type": "string"}}]}}, "/api/runs/{run_id}/report.md": {"get": {"operationId": "get_report_markdown", "summary": "Report (Markdown)", "description": "Returns the full forecast report as Markdown text (category outlook, segment plans, timing, keywords). Free. 404 until the run is done. 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": "run_id", "in": "path", "required": true, "description": "Run id returned by start_run or list_runs (shown in the result URL /r/{run_id}).", "schema": {"type": "string"}}]}}, "/runs/{run_id}/report.html": {"get": {"operationId": "get_report_html", "summary": "Report HTML", "description": "Returns the full report as a self-contained HTML page. download=1 (default) sends it as a file, 0 shows it inline. Free. 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": "run_id", "in": "path", "required": true, "description": "Run id returned by start_run or list_runs (shown in the result URL /r/{run_id}).", "schema": {"type": "string"}}, {"name": "download", "in": "query", "required": false, "description": "1 to send as a file download, 0 to view inline.", "schema": {"type": "integer", "enum": [0, 1], "default": 1}}]}}, "/runs/{run_id}/forecast.csv": {"get": {"operationId": "download_forecast_csv", "summary": "Forecast CSV", "description": "Downloads monthly actual and forecast values (with lo/hi range, model and regime) per segment and for the whole category as CSV. Free. 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": "run_id", "in": "path", "required": true, "description": "Run id returned by start_run or list_runs (shown in the result URL /r/{run_id}).", "schema": {"type": "string"}}]}}, "/runs/{run_id}/keywords.csv": {"get": {"operationId": "download_keywords_csv", "summary": "Keywords CSV", "description": "Downloads the keyword list with segment, volume and forecast as CSV. Free. 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": "run_id", "in": "path", "required": true, "description": "Run id returned by start_run or list_runs (shown in the result URL /r/{run_id}).", "schema": {"type": "string"}}]}}, "/runs/{run_id}/timing.ics": {"get": {"operationId": "download_timing_ics", "summary": "Timing calendar (ICS)", "description": "Downloads the prep, campaign, launch and peak windows as an iCalendar (.ics) file to import into a calendar. Free. 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": "run_id", "in": "path", "required": true, "description": "Run id returned by start_run or list_runs (shown in the result URL /r/{run_id}).", "schema": {"type": "string"}}]}}, "/runs/{run_id}/run.json": {"get": {"operationId": "download_run_json", "summary": "Result JSON", "description": "Returns the raw result object of a finished run as JSON. Free. 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": "run_id", "in": "path", "required": true, "description": "Run id returned by start_run or list_runs (shown in the result URL /r/{run_id}).", "schema": {"type": "string"}}]}}, "/api/runs/{run_id}/rerun": {"post": {"operationId": "rerun_run", "summary": "Re-run with same inputs", "description": "Starts a new run with the same parameters as an earlier run. Returns {run_id}. Same cost as start_run minus cached calls. 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: same as start_run (cached calls are free). Time: 1-3 minutes. Usually followed by: get_run.", "tags": ["run"], "x-lm-kind": "run", "x-lm-cost": "same as start_run (cached calls are free)", "responses": {"200": {"description": "Success"}, "default": {"description": "Error (application/problem+json or JSON with detail)"}}, "parameters": [{"name": "run_id", "in": "path", "required": true, "description": "Run id returned by start_run or list_runs (shown in the result URL /r/{run_id}).", "schema": {"type": "string"}}]}}, "/_lm/report-robots/{run_id}": {"get": {"operationId": "get_report_robots", "summary": "Report search visibility", "description": "Returns whether search engines may index this report page (index or noindex), and why: a company member's run or one set by hand is index; a customer's run, and any run that is still going, failed or came back empty, is noindex. Read only; no credits. 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": "run_id", "in": "path", "required": true, "description": "The report's run id: the id in the report address (for ACO the project id, or project~step).", "schema": {"type": "string"}}]}}}, "externalDocs": {"url": "https://daas-forecast.listeningmind.ai/agents.md", "description": "Agent guide"}}