Suggest a page FAQ from the questions people ask
POST
/sites/{siteId}/pages/{pageId}/faq-suggest- Scope
actions:apply- ابزار MCP
run_faq_suggest
Suggest a page FAQ from the questions people ask Runs the FAQ suggestion and stores it, like "Suggest FAQ from real questions" in the app. Reuses Google results with People also ask for the keyword stored in the last 7 days (rerun: last day only, and a fresh AI judgment); otherwise uses one keyword lookup from the monthly plan, inside the spending limits. The top 5 pages are read for free and the AI step is one AI use. Nothing is written to the website.
توضیح ها از سند OpenAPI می آیند و انگلیسی اند.
پارامترها
| نام | محل | توضیح |
|---|---|---|
siteIdاجباری | path | stringWebsite id, from GET /sites. |
pageIdاجباری | path | stringPage id, from GET /pages or GET /pages/findings. |
بدنه درخواست
| فیلد | توضیح |
|---|---|
keyword | string · at most 80 characters; The search to research; default: the page's main keyword (the first of keywordChoices) |
rerun | true or false · Ask for fresh results (older than a day) and a fresh AI judgment |
language | en | de | es | fa · Language of the reasons; default en. Questions and answers stay in the page's language |
{
"keyword": "trail bike sizing",
"language": "en"
}پاسخ
200 · application/json
| فیلد | توضیح |
|---|---|
page | object · required |
page.id | string · required |
page.url | address (URL) · required |
suggestion | object · required |
suggestion.keyword | string |
suggestion.locationCode | number |
suggestion.languageCode | string |
suggestion.suggestedAt | string |
suggestion.results | object |
suggestion.results.date | string |
suggestion.results.source | string |
suggestion.results.checkUrl | string |
suggestion.results.peopleAlsoAsk | list of strings |
suggestion.results.relatedSearches | list of strings |
suggestion.results.topPagesRead | list of objects |
suggestion.results.topPagesRead[].url | string |
suggestion.results.topPagesRead[].domain | string |
suggestion.results.topPagesRead[].read | true or false |
suggestion.results.topPagesRead[].questions | number |
suggestion.pageText | string |
suggestion.questions | list of objects |
suggestion.questions[].question | string |
suggestion.questions[].askedBy | number |
suggestion.questions[].sources | list of objects |
suggestion.questions[].sources[].source | string |
suggestion.questions[].sources[].from | |
suggestion.questions[].wordings | list of strings |
suggestion.questions[].answered | string |
suggestion.questions[].answeringSentence | string |
suggestion.suggestedFaq | list of objects |
suggestion.suggestedFaq[].index | number |
suggestion.suggestedFaq[].question | string |
suggestion.suggestedFaq[].answer | string |
suggestion.suggestedFaq[].fromSentences | list of strings |
suggestion.addSection | list of objects |
suggestion.addSection[].question | string |
suggestion.addSection[].heading | string |
suggestion.addSection[].why | string |
suggestion.reasonsLanguage | string |
suggestion.model | string |
suggestion.resultsCostUsd | number |
cost | object · required |
cost.usd | number · required; What this run paid for results |
cost.lookups | integer · required; Keyword lookups used: 1, or 0 when stored results were reused |
cost.reused | true or false · required; Stored results were reused |
cost.pagesRead | integer · required; Top pages read (free) |
aiNote | string or null · required; Why questions were not grouped (the daily AI limit, the AI could not answer); run again later |
link | address (URL) · required |
خطاها
| کد | معنی |
|---|---|
400 | Bad request. Codes: missing_argument, bad_keyword, no_keyword. |
401 | Missing, unknown or revoked key. Codes: missing_key, invalid_key. |
403 | The key lacks the scope, covers another website, or its owner lost access. Codes: missing_scope, other_site, owner_left, no_owner, forbidden. |
404 | Not found. Codes: not_found. |
422 | The request cannot be carried out. Codes: unsupported_location, no_results, no_text, no_questions. |
429 | A limit is reached. rate_limited: too many requests this hour for this key. Codes: rate_limited, lookups, workspace_cap, global_cap. |
502 | An outside service did not answer. Codes: failed. |
503 | Switched off for now. Codes: no_provider. |
نمونه درخواست
curl -X POST \
-H "Authorization: Bearer mr_ws_…" \
-H "Content-Type: application/json" \
-d '{"keyword":"trail bike sizing","language":"en"}' \
"https://app.monoranks.com/api/v1/sites/SITE_ID/pages/PAGE_ID/faq-suggest"const res = await fetch("https://app.monoranks.com/api/v1/sites/SITE_ID/pages/PAGE_ID/faq-suggest", {
method: "POST",
headers: { Authorization: "Bearer mr_ws_…", "Content-Type": "application/json" },
body: JSON.stringify({
"keyword": "trail bike sizing",
"language": "en"
}),
});
if (!res.ok) throw new Error((await res.json()).error.message);
const data = await res.json();import requests
res = requests.post(
"https://app.monoranks.com/api/v1/sites/SITE_ID/pages/PAGE_ID/faq-suggest",
headers={"Authorization": "Bearer mr_ws_…"},
json={
"keyword": "trail bike sizing",
"language": "en",
},
)
res.raise_for_status()
data = res.json()<?php
$ch = curl_init("https://app.monoranks.com/api/v1/sites/SITE_ID/pages/PAGE_ID/faq-suggest");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => ["Authorization: Bearer mr_ws_…", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => '{"keyword":"trail bike sizing","language":"en"}',
CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);import axios from "axios";
const { data } = await axios.post(
"https://app.monoranks.com/api/v1/sites/SITE_ID/pages/PAGE_ID/faq-suggest",
{
"keyword": "trail bike sizing",
"language": "en"
},
{ headers: { Authorization: "Bearer mr_ws_…" } },
);نمونه پاسخ
{
"page": {
"id": "c7a9e1b3-5d7f-4b9c-8e1a-3c5e7a9b1d2f",
"url": "https://acmebikes.com/guides/trail-bike-sizing/"
},
"suggestion": {
"keyword": "trail bike sizing",
"locationCode": 2840,
"languageCode": "en",
"suggestedAt": "2026-10-09T08:12:51.000Z",
"results": {
"date": "2026-10-09",
"source": "live",
"checkUrl": "https://www.google.com/search?q=trail%20bike%20sizing&num=10&hl=en&gl=US",
"peopleAlsoAsk": [
"How do I know what size trail bike I need?",
"What size bike for 5'10?",
"Is it better to size up or down on a mountain bike?"
],
"relatedSearches": [
"trail bike size chart",
"mtb sizing calculator"
],
"topPagesRead": [
{
"url": "https://ridgecycles.example/sizing",
"domain": "ridgecycles.example",
"read": true,
"questions": 4
},
{
"url": "https://trailhub.example/fit",
"domain": "trailhub.example",
"read": false,
"questions": 0
}
]
},
"pageText": "live",
"questions": [
{
"question": "How do I know what size trail bike I need?",
"askedBy": 3,
"sources": [
{
"source": "paa",
"from": null
},
{
"source": "top_page",
"from": "ridgecycles.example"
},
{
"source": "search_console",
"from": null
}
],
"wordings": [
"How do I know what size trail bike I need?",
"How do I choose my trail bike size?",
"what size trail bike do i need"
],
"answered": "yes",
"answeringSentence": "Start from your height: riders from 170 to 180 cm usually fit a size M frame."
},
{
"question": "Is it better to size up or down on a mountain bike?",
"askedBy": 2,
"sources": [
{
"source": "paa",
"from": null
},
{
"source": "top_page",
"from": "ridgecycles.example"
}
],
"wordings": [
"Is it better to size up or down on a mountain bike?",
"Should I size up or down?"
],
"answered": "partly",
"answeringSentence": "Between two sizes, the smaller frame is easier to handle on tight trails."
},
{
"question": "How much does a trail bike weigh?",
"askedBy": 1,
"sources": [
{
"source": "answer_gap",
"from": null
}
],
"wordings": [
"How much does a trail bike weigh?"
],
"answered": "no",
"answeringSentence": null
}
],
"suggestedFaq": [
{
"index": 0,
"question": "How do I know what size trail bike I need?",
"answer": "Start from your height: riders from 170 to 180 cm usually fit a size M frame.",
"fromSentences": [
"Start from your height: riders from 170 to 180 cm usually fit a size M frame."
]
},
{
"index": 1,
"question": "Is it better to size up or down on a mountain bike?",
"answer": "Between two sizes, the smaller frame is easier to handle on tight trails.",
"fromSentences": [
"Between two sizes, the smaller frame is easier to handle on tight trails."
]
}
],
"addSection": [
{
"question": "How much does a trail bike weigh?",
"heading": "How much our trail bikes weigh",
"why": "AI answers to this question name other shops, never this one."
}
],
"reasonsLanguage": "en",
"model": "claude-sonnet-4-6",
"resultsCostUsd": 0.002
},
"cost": {
"usd": 0.002,
"lookups": 1,
"reused": false,
"pagesRead": 4
},
"aiNote": null,
"link": "https://app.monoranks.com/sites/3f6c2a1e-8b4d-4c7a-9e21-5d0b7a6f4c13/pages/c7a9e1b3-5d7f-4b9c-8e1a-3c5e7a9b1d2f#faq-suggest"
}{
"error": {
"code": "missing_argument",
"message": "page_id or url is required."
}
}{
"error": {
"code": "missing_key",
"message": "Send the key as Authorization: Bearer mr_site_…"
}
}{
"error": {
"code": "missing_scope",
"message": "This key does not have the scope this call needs."
}
}{
"error": {
"code": "not_found",
"message": "Page not found. Use a page_id from page_findings or list_pages, or the exact crawled url."
}
}{
"error": {
"code": "unsupported_location",
"message": "Google results are not available for Iran, so \"People also ask\" cannot be read there.",
"country": "Iran"
}
}{
"error": {
"code": "rate_limited",
"message": "More than 1200 requests this hour for this key."
}
}{
"error": {
"code": "failed",
"message": "Google results could not be fetched right now. Try again in a few minutes."
}
}{
"error": {
"code": "no_provider",
"message": "Google results are not available on this server yet."
}
}سرور MCP همین کار را با ابزار run_faq_suggest انجام می دهد.