REST API Reference

The Better Search Console REST API allows you to programmatically manage your websites, URLs, sitemaps, and indexation. All endpoints require authentication.

Authentication

Authenticate requests using the X-API-TOKEN header with your 64-character hex API token (available in your account settings).

curl -H "X-API-TOKEN: your_token_here" \
     https://<your-host>/api/dashboards

Base URL

https://<your-host>/api

Response Envelope

List endpoints return a paginated envelope:

{
  "data": [...],
  "page": 1,
  "per_page": 20,
  "total": 42,
  "total_pages": 3
}

Single-resource endpoints return the object directly. Errors return { "error": "..." } with status 400 (bad params), 401 (no auth), or 404 (not found / not owned).

Error Format

All errors return a JSON object:

{
  "error": "Description of what went wrong"
}

Validation errors (400) include a fieldErrors object with per-field messages.

Rate Limits

API endpoints share rate limits with the MCP server. See the MCP documentation for tier details. When rate-limited, the API returns 429 Too Many Requests.

Account

MethodPathDescriptionBodyResponseStatuses
GET/api/meGet the authenticated user's profile.-{ id, email, nickname, subscriptionType, newsletterEmail, hasPreviouslyBeenPremium }200, 401

Websites

MethodPathDescriptionBodyResponseStatuses
GET/api/websitesList all websites owned by the caller.-{ data: [...] }200, 401
GET/api/websites/[id]Get a single website (404 if not owned).-Website object200, 400, 401, 404

Indexation

MethodPathDescriptionBodyResponseStatuses
POST/api/indexation/googleSubmit a URL to Google for indexing.{ website_id, url_id }{ success, result }200, 400, 401, 404
POST/api/indexation/bingSubmit a URL to Bing for indexing.{ website_id, url_id }{ success, result }200, 400, 401, 404
POST/api/indexation/bulkSubmit multiple URLs for indexing.{ website_id, url_ids }{ success, results }200, 400, 401
POST/api/indexation/checkCheck indexation status of a URL.{ website_id, url_id }{ success, status }200, 400, 401, 404
POST/api/indexation/check/bulkCheck indexation status of multiple URLs.{ website_id, url_ids }{ success, results }200, 400, 401
PUT/api/indexation/coverage-stateGet coverage state summary for a website.{ website_id }{ states }200, 401, 404
POST/api/indexation/disable/bulkDisable indexation for multiple URLs.{ website_id, url_ids }{ success, count }200, 400, 401
POST/api/indexation/reenable/bulkRe-enable indexation for multiple URLs.{ website_id, url_ids }{ success, count }200, 400, 401

Sitemaps

MethodPathDescriptionBodyResponseStatuses
GET/api/sitemapsList sitemaps for a website.None (query: ?website_id=){ data: [...] }200, 400, 401, 404
GET/api/sitemaps/[id]Get a single sitemap (404 if not owned).-Sitemap object200, 400, 401, 404
POST/api/sitemaps/addAdd a new sitemap to a website.{ website_id, sitemap_url }{ success, sitemap }201, 400, 401, 404
DELETE/api/sitemaps/[id]Delete a sitemap.None{ success }200, 401, 404
POST/api/sitemaps/[id]/processProcess/crawl a sitemap to discover URLs.None{ success, urls_found }200, 401, 404
POST/api/sitemaps/process-allProcess all sitemaps for a website.{ website_id }{ success, processed }200, 401, 404

URLs

MethodPathDescriptionBodyResponseStatuses
GET/api/urlsPaginated list. Query: website_id (required), page, per_page (max 100), search, sitemap, coverage_state, indexation (indexed|not-indexed|unknown), fields=url (returns string[]).None{ data, page, per_page, total, total_pages }200, 400, 401, 404
GET/api/urls/[id]Get a single URL with sitemap and urlData.-Url object200, 400, 401, 404
DELETE/api/urls/[id]Delete a single URL.None{ success }200, 401, 404
POST/api/urls/delete/bulkDelete multiple URLs.{ website_id, url_ids }{ success, deleted }200, 400, 401

URL Data (PageSpeed)

MethodPathDescriptionBodyResponseStatuses
GET/api/url-dataPaginated list of PageSpeed data for owned URLs. Query: website_id (required), page, per_page.None{ data, page, per_page, total, total_pages }200, 400, 401, 404
GET/api/url-data/[id]Get a single URL data record (404 if not owned).-UrlData object200, 400, 401, 404

Dashboards

MethodPathDescriptionBodyResponseStatuses
GET/api/dashboardsList custom dashboards for the authenticated user.None{ dashboards }200, 401
POST/api/dashboardsCreate a new custom dashboard.{ website_id, name }{ success, dashboard }201, 400, 401
GET/api/dashboards/[id]Get a dashboard with its widgets.None{ dashboard, widgets }200, 401, 404
PUT/api/dashboards/[id]Update a dashboard.{ name, is_default }{ success, dashboard }200, 400, 401, 404
DELETE/api/dashboards/[id]Delete a dashboard.None{ success }200, 401, 404
GET/api/dashboards/[id]/dataGet data for all widgets in a dashboard.None{ data }200, 401, 404
POST/api/dashboards/[id]/widgetsAdd a widget to a dashboard.{ type, title, position, span, config }{ success, widget }201, 400, 401, 404

Dashboard Chart Data

MethodPathDescriptionBodyResponseStatuses
GET/api/dashboard/chart-dataFetch GSC performance chart data for the overview dashboard.{ website_id, start_date, end_date, dimensions? }{ rows }200, 400, 401

Prompt Analyses

MethodPathDescriptionBodyResponseStatuses
GET/api/prompt-analysesPaginated list of prompt analyses. Query: website_id (required), page, per_page. PHP-serialized fields are decoded.None{ data, page, per_page, total, total_pages }200, 400, 401, 404
GET/api/prompt-analyses/[id]Get a single prompt analysis (decoded). 404 if not owned.-PromptAnalysis object200, 400, 401, 404
POST/api/prompt-analyses/createCreate a new prompt analysis.{ website_id, prompt, models, targeted_keywords? }{ success, analysis }201, 400, 401
PUT/api/prompt-analyses/[id]/keywordsGet keyword mentions for a prompt analysis.None{ keywords }200, 401, 404

Settings

MethodPathDescriptionBodyResponseStatuses
PUT/api/settings/website/[id]Update website settings.{ name, auto_indexing, auto_sitemap_refresh, ... }{ success, website }200, 400, 401, 404
GET/api/bing/statusBing Webmaster Tools connection state and URL submission quota for a website.?website_id={ configured, ok, reason, sites, quota }200, 400, 401, 404
GET/api/bing/feedsSitemaps Bing has for a website.?website_id={ feeds }200, 400, 401, 404, 502
POST/api/bing/feedsSubmit a sitemap to Bing Webmaster Tools.{ website_id, feed_url }{ success, feed_url }201, 400, 401, 404, 502
POST/api/bing/oauth/disconnectForget the stored Bing OAuth tokens for the signed-in user.{ success }200, 401
POST/api/settings/website/[id]/service-accountUpload a Google service account JSON key.FormData with file{ success }200, 400, 401, 404

Tools

MethodPathDescriptionBodyResponseStatuses
POST/api/tools/generate-robotsGenerate a robots.txt file for a website.{ website_id, rules? }{ content }200, 400, 401
POST/api/tools/generate-sitemapGenerate an XML sitemap for a website.{ website_id, urls? }{ xml }200, 400, 401

Filters

MethodPathDescriptionBodyResponseStatuses
GET/api/filtersList saved filters for a website.None (query: ?website_id=){ filters }200, 401
DELETE/api/filters/[id]Delete a saved filter.None{ success }200, 401, 404

Reports

MethodPathDescriptionBodyResponseStatuses
POST/api/reports/generateGenerate a PDF report for a website.{ website_id, date_range?, branding? }PDF binary or { url }200, 400, 401, 404

Blog

MethodPathDescriptionBodyResponseStatuses
GET/api/blog-postsPaginated list of published blog posts (id, title, slug, image, createdAt, meta fields). Query: page, per_page.None{ data, page, per_page, total, total_pages }200, 401
GET/api/blog-posts/[slug]Get a single blog post by slug.-BlogPost object200, 401, 404
POST/api/blogCreate a new blog post.{ title, slug, content, image?, metaTitle?, metaDescription?, ogTitle, ogDescription, keywords, articleSection }{ success, post }201, 400, 401, 409
PUT/api/blog/[slug]Update a blog post (author only).Same as create{ success, post }200, 400, 401, 404, 409
DELETE/api/blog/[slug]Delete a blog post (author only).None{ success }200, 401, 404

Models (Reference Data)

MethodPathDescriptionBodyResponseStatuses
GET/api/modelsList all available AI models (id, name, price). Requires auth but not user-scoped.-{ data: [...] }200, 401

Admin

MethodPathDescriptionBodyResponseStatuses
PATCH/api/admin/users/[id]Change user subscription type (admin only).{ subscriptionType }{ success, old, new }200, 400, 401, 403, 404