Public API v1
Read and manage account websites, analytics organization, campaign keywords, and indexing through a stable, AI-friendly HTTP API.
Developer access
Get your Semalt API key
Create a free Semalt account to access the Public API and connect AI tools through MCP.
Quick start
Base URL: https://semalt.com/api/v1
Authenticate every request with the API key from your Semalt account:
Authorization: Bearer YOUR_API_KEYStart with /me to identify the API key owner, then /accounts to discover available account contexts:
curl 'https://semalt.com/api/v1/me' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Accept: application/json'Alternatively, pass the key as token in the query string. Header authentication is recommended because URLs can appear in logs and browser history:
curl 'https://semalt.com/api/v1/me?token=YOUR_API_KEY' \
-H 'Accept: application/json'Account context
One API key can read and manage the accounts available to it. Use /me to identify the API key owner and /accounts to discover account contexts available for selection.
- Call
GET /api/v1/me.data.account_ididentifies the API key owner. - Call
GET /api/v1/accountsto discover accounts available for selection with names and emails. The collection supportssearch,limit, and cursor pagination. - Use
/api/v1/accounts/{account_id}/...for every account operation while keeping the same API key.GET /accounts/{account_id}reads its details.
/me always identifies the token owner. There is no persistent account selection. Do not pass account_id in query parameters or JSON bodies. Account responses include meta.actor_account_id and meta.account_id so clients can distinguish the key owner from the selected account. Account identifiers, including owner_account.account_id, are returned as strings. linked_account_ids in /me and account details describes the linked group of the account returned by that endpoint and includes the account itself. It is relationship metadata, not the list of all accounts available to the API key; use /accounts to determine which account IDs are selectable.
- Sites and analytics use the selected account’s own, linked and explicitly shared sites.
access_type=ownrestricts the list to its own records. - New websites, site tags and keyword groups belong to the selected account.
- Site Tags retain individual owners; the selected account and active linked accounts can view and fully edit them. Editing preserves the owner. Names are unique per owner, so linked accounts may have separate namesake tags. Responses include
owner_account,is_ownandcan_editto distinguish them. Inactive linked owners' tags are hidden until the owners are restored. Account linking preserves tag identifiers and assignments. - Keyword Groups retain individual owners; linked accounts can view and edit them. Groups are domain-scoped, even when accessed through a physical site id.
- My SEO campaigns belong to the selected account. List them at
/accounts/{account_id}/my-seo/campaignsand use the returnedcampaign_idfor/accounts/{account_id}/my-seo/campaigns/{campaign_id}/keywordsand/accounts/{account_id}/my-seo/campaigns/{campaign_id}/backlinks. Campaigns for the same domain in different accounts remain separate. Backlinksearchmatches the start of the donor domain, case-insensitively:blogmatchesblog.example.com;exampledoes not matchblog.example.com. Type and domain-rating filters remain available. - Indexing history and balance belong to the selected account. URL submissions consume that account’s balance. Linked balances are not pooled.
Access is checked for every request. Explicit sharing of one website does not grant access to its owner’s account context. Product limits and campaign requirements apply to every selected account. The authenticated global ranking endpoints /google-serp/rankings and /ai-analytics/rankings are account-independent.
MCP uses the same rules: call semalt_get_me or semalt_list_accounts, then pass the required integer account_id to each account tool. Use semalt_list_my_seo_campaigns for campaign_id. No switch-account tool or connection change is needed.
Site identity
Site collections preserve separate accessible website records without domain or Search Console property deduplication. Hidden and removed records are excluded. access_type is own, linked, or shared relative to the selected account. Use the site record’s id as site_id in that same account context. Selecting a linked site does not automatically switch to its owner.
Pagination
Site collections use stable cursor pagination:
GET /api/v1/accounts/ACCOUNT_ID/sites?limit=50&cursor=12345Use meta.next_cursor for the next request while meta.has_more is true. The maximum limit is 200.
Use descriptive query parameters such as search, search_engine_id, sort_direction, and url_contains. AI Analytics accepts model with gpt-4.1-nano or gpt-5-nano; implementation-specific model identifiers are not part of the public contract. The OpenAPI files below define the filters, allowed values, defaults, and pagination style for each endpoint.
Every site response contains tags owned by the selected account or its active linked accounts. Filter site collections with comma-separated tag_ids, combine them with tag_match=any|all, and exclude tags with exclude_tag_ids. Reusable keyword groups are managed under /accounts/{account_id}/sites/{site_id}/keyword-groups and can filter My SEO keywords, Google SERP keywords, and Google SERP best pages through keyword_group_id.
Write requests
Write endpoints accept one JSON object and require Content-Type: application/json. Actions without fields still expect an empty JSON object {}. They add sites, manage site tags and keyword groups, add manual FullSEO campaign keywords, and submit URLs for indexing. The maximum JSON body size is 2 MB; product limits such as 10,000 URLs or keywords per request still apply.
curl --request POST \
--url 'https://semalt.com/api/v1/accounts/ACCOUNT_ID/sites' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{"domain":"example.com"}'Replace ACCOUNT_ID with an account_id returned by /me or /accounts.
Adding the same site, site-tag assignment, or keyword-group keyword again is safe: the API returns the existing record or skips the duplicate. Delete and membership-removal operations use explicit POST action URLs so an AI client can request user confirmation before invoking them.
My SEO keyword controls
The My SEO keyword endpoints use public snake_case fields, including target_url, backlink_weight, backlink_share, and sort_direction.
POST /accounts/{account_id}/my-seo/campaigns/{campaign_id}/keyword-modechanges a launched FullSEO campaign betweenautoandmanualmode.POST .../keywords/statusupdates keyword review statuses. Auto mode allows rejecting keywords and restoring rejected keywords topending; manual mode also allowsapproved.POST .../keywords/backlink-weightschanges integer weights from 1 to 10000 for approved keywords in manual mode.POST .../keywords/backlink-allocationapplies the dashboard’s one-shot percentage allocation to approved keywords in manual mode. Supplied keyword percentages are fixed for that request and omitted approved keywords share the remainder equally. The fixed percentages are not persisted as a separate configuration; call the keyword list endpoint afterwards to inspect the resulting weights and shares.
Keyword ids are the id values returned by the campaign keyword list. The allocation request accepts decimal percentages from 0.01 to 100 with at most two decimal places. All four control endpoints return the selected public campaign and a snake_case result summary.
POST /accounts/{account_id}/indexing/urls consumes indexing balance and does not currently accept an idempotency key. If a client loses the response after sending the request, it should check GET /accounts/{account_id}/indexing/urls before retrying instead of retrying automatically.
Request example
curl --request GET \
--url 'https://semalt.com/api/v1/accounts/ACCOUNT_ID/search-console/sites?limit=25' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Accept: application/json'Machine-readable contracts:
Human-readable documentation is published at https://semalt.com/api-docs.
Account
Discover accounts available for selection, then use account_id for each account operation with the same token.
GET /me Get the token owner
/meAlways returns the API key owner as account_id. linked_account_ids contains that account and the other members of its linked group. Use GET /accounts to discover account contexts available for selection, then pass a returned account_id in account endpoint paths.
GET /accounts List available accounts
/accountsList account contexts available for selection with this API key. Each record identifies the account using account_id, email and name. A shared website alone does not grant access to its owner’s account context. Follow next_cursor while has_more is true.
limit query · optional · integer · default: 50 Maximum number of records to return in this cursor page. The API may return fewer records; use has_more and next_cursor to continue.
cursor query · optional · string Continuation cursor from the previous response meta.next_cursor. Omit it for the first page and treat its value as opaque.
search query · optional · string Case-insensitive text matched against available account names and emails.
GET /accounts/{account_id} Get a selected account
/accounts/{account_id}Returns the selected account’s account_id, email, name, verification state and linked_account_ids. The linked ids describe the selected account’s linked group and include the selected account itself. This does not change the token owner or select an account for later requests. Use GET /accounts to determine which account IDs are selectable with the current API key.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
Sites
Website records available to the selected account.
GET /accounts/{account_id}/sites List accessible sites
/accounts/{account_id}/sitesReturns website records available to the selected account. Records are not grouped, so the same domain can appear more than once when it is available through different accounts or properties.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
limit query · optional · integer · default: 50 Maximum number of records to return in this cursor page. The API may return fewer records; use has_more and next_cursor to continue.
cursor query · optional · string Continuation cursor from the previous response meta.next_cursor. Omit it for the first page and treat its value as opaque.
search query · optional · string Case-insensitive substring matched against the website domain and, when present, its Search Console property URL.
tag_ids query · optional · array<integer> Comma-separated site tag ids from GET /accounts/{account_id}/site-tags. By default a site may match any supplied tag; use tag_match=all to require every tag.
tag_match query · optional · string · any | all · default: any How tag_ids are combined: any returns a site with at least one selected tag; all requires every selected tag.
exclude_tag_ids query · optional · array<integer> Comma-separated site tag ids. Sites carrying any excluded tag are omitted.
site_type query · optional · string · gsc | manual Return only Search Console-connected records (gsc) or manually added records (manual).
access_type query · optional · string · own | linked | shared Filter by the relationship between the selected account and the site record: direct ownership, linked-group ownership, or explicit sharing.
has_search_console query · optional · boolean When true, return only records connected to a usable Search Console property; when false, return records without one.
POST /accounts/{account_id}/sites Add a website
/accounts/{account_id}/sitesCreates or restores a manual website for the selected account. The operation is idempotent by normalized domain: adding the same domain again returns its existing site record.
application/json one JSON objectWebsite to add. A complete URL is accepted and normalized to its domain.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
domain body · required · string Public domain or HTTP/HTTPS URL.
{
"domain": "example.com"
}GET /accounts/{account_id}/sites/{site_id} Get one site
/accounts/{account_id}/sites/{site_id}Use an id returned by a site collection. The request returns 404 when the site is hidden, removed, unknown, or not accessible to the current account.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
Keyword Groups
Reusable, site-specific keyword collections used as analytics filters.
GET /accounts/{account_id}/sites/{site_id}/keyword-groups List keyword groups
/accounts/{account_id}/sites/{site_id}/keyword-groupsReturns reusable keyword groups owned by the selected account or its linked accounts for the selected site. Explicit site sharing does not expose another owner's groups.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
POST /accounts/{account_id}/sites/{site_id}/keyword-groups Create a keyword group
/accounts/{account_id}/sites/{site_id}/keyword-groupsCreates a personal reusable keyword group for the domain represented by site_id.
application/json one JSON objectName for the new group.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
name body · required · string {
"name": "Commercial keywords"
}POST /accounts/{account_id}/sites/{site_id}/keyword-groups/{group_id} Rename a keyword group
/accounts/{account_id}/sites/{site_id}/keyword-groups/{group_id}Renames an editable non-default keyword group.
application/json one JSON objectNew group name.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
group_id path · required · integer Keyword group identifier returned for the selected site.
name body · required · string {
"name": "High-intent keywords"
}POST /accounts/{account_id}/sites/{site_id}/keyword-groups/{group_id}/delete Delete a keyword group
/accounts/{account_id}/sites/{site_id}/keyword-groups/{group_id}/deletePermanently deletes an editable non-default group and its keyword membership. Confirm this destructive action before calling it.
application/json one JSON objectSend an empty JSON object to confirm the request shape.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
group_id path · required · integer Keyword group identifier returned for the selected site.
{}GET /accounts/{account_id}/sites/{site_id}/keyword-groups/{group_id}/keywords List group keywords
/accounts/{account_id}/sites/{site_id}/keyword-groups/{group_id}/keywordsReturns keyword rows stored in one reusable group. search is a case-insensitive keyword substring.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
group_id path · required · integer Keyword group identifier returned for the selected site.
page query · optional · integer · default: 1 One-based result page number. Use 1 for the first page.
page_size query · optional · integer · default: 50 Maximum number of items in one page. Public API responses cap this value at 200; some product datasets may apply a lower internal cap.
search query · optional · string Text used to narrow keyword or query results. For Google SERP token search, provide at least four characters.
POST /accounts/{account_id}/sites/{site_id}/keyword-groups/{group_id}/keywords Add keywords to a group
/accounts/{account_id}/sites/{site_id}/keyword-groups/{group_id}/keywordsAdds normalized keywords to an editable group. Exact duplicates are skipped and reported, so retrying the same payload is safe.
application/json one JSON objectKeyword text values to add.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
group_id path · required · integer Keyword group identifier returned for the selected site.
keywords body · required · array<string> {
"keywords": [
"technical seo audit",
"managed seo services"
]
}POST /accounts/{account_id}/sites/{site_id}/keyword-groups/{group_id}/keywords/remove Remove keywords from a group
/accounts/{account_id}/sites/{site_id}/keyword-groups/{group_id}/keywords/removeRemoves keyword rows by ids returned by the group keyword list. Confirm the affected rows before calling it.
application/json one JSON objectKeyword row ids to remove.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
group_id path · required · integer Keyword group identifier returned for the selected site.
keyword_ids body · required · array<integer> {
"keyword_ids": [
123,
124
]
}Search Console
Google Search Console properties and their analytics.
GET /accounts/{account_id}/search-console/sites List Search Console properties
/accounts/{account_id}/search-console/sitesReturns accessible Search Console properties with current and previous metrics for each record on this cursor page. By default, the current period ends yesterday and covers the preceding 29 inclusive calendar dates.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
limit query · optional · integer · default: 50 Maximum number of records to return in this cursor page. The API may return fewer records; use has_more and next_cursor to continue.
cursor query · optional · string Continuation cursor from the previous response meta.next_cursor. Omit it for the first page and treat its value as opaque.
search query · optional · string Case-insensitive substring matched against the website domain and, when present, its Search Console property URL.
tag_ids query · optional · array<integer> Comma-separated site tag ids from GET /accounts/{account_id}/site-tags. By default a site may match any supplied tag; use tag_match=all to require every tag.
tag_match query · optional · string · any | all · default: any How tag_ids are combined: any returns a site with at least one selected tag; all requires every selected tag.
exclude_tag_ids query · optional · array<integer> Comma-separated site tag ids. Sites carrying any excluded tag are omitted.
access_type query · optional · string · own | linked | shared Filter by the relationship between the selected account and the site record: direct ownership, linked-group ownership, or explicit sharing.
date_from query · optional · string Inclusive first calendar date of the requested analytics period in YYYY-MM-DD format. If omitted, the endpoint selects a recent default period.
date_to query · optional · string Inclusive last calendar date of the requested analytics period in YYYY-MM-DD format. If both dates are supplied in reverse order, site summaries normalize their order.
GET /accounts/{account_id}/search-console/sites/{site_id}/overview Get Search Console overview
/accounts/{account_id}/search-console/sites/{site_id}/overviewReturns summary cards and daily charts for the exact Search Console property associated with site_id.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
date_from query · optional · string Inclusive first calendar date of the requested analytics period in YYYY-MM-DD format. If omitted, the endpoint selects a recent default period.
date_to query · optional · string Inclusive last calendar date of the requested analytics period in YYYY-MM-DD format. If both dates are supplied in reverse order, site summaries normalize their order.
GET /accounts/{account_id}/search-console/sites/{site_id}/traffic Get a Search Console traffic series
/accounts/{account_id}/search-console/sites/{site_id}/trafficReturns one daily series for a selected query, page, device, or country. metric chooses which measurement is copied into each item.value; every item also contains clicks, impressions, CTR, and average position for context. Use value to select the exact dimension value.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
date_from query · optional · string Inclusive first calendar date of the requested analytics period in YYYY-MM-DD format. If omitted, the endpoint selects a recent default period.
date_to query · optional · string Inclusive last calendar date of the requested analytics period in YYYY-MM-DD format. If both dates are supplied in reverse order, site summaries normalize their order.
metric query · optional · string · clicks | impressions | ctr | position · default: position Selects the measurement written to each traffic-series item.value: clicks is Google result visits, impressions is result appearances, ctr is clicks divided by impressions as a percentage, and position is average Google result position. Each item still includes all four measurements. Default: position.
dimension query · optional · string · query | page | device | country · default: query Entity represented by value in the traffic series. Use query for a search phrase, page for a page URL, device for desktop/mobile/tablet, or country for a Search Console country code.
value query · optional · string Exact query text, page URL, device name, or country code whose daily series should be returned. Its meaning is determined by dimension.
device query · optional · string · desktop | mobile | tablet Restrict Search Console data to one device category.
country query · optional · string Restrict Search Console data to a canonical country code returned by Search Console, usually a three-character code.
GET /accounts/{account_id}/search-console/sites/{site_id}/keywords List Search Console keywords
/accounts/{account_id}/search-console/sites/{site_id}/keywordsReturns aggregated search queries. search matches query text; metric ranges are inclusive and apply before pagination.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
search query · optional · string Case-insensitive substring matched against Search Console query text.
date_from query · optional · string Inclusive first calendar date of the requested analytics period in YYYY-MM-DD format. If omitted, the endpoint selects a recent default period.
date_to query · optional · string Inclusive last calendar date of the requested analytics period in YYYY-MM-DD format. If both dates are supplied in reverse order, site summaries normalize their order.
page query · optional · integer · default: 1 One-based result page number. Use 1 for the first page.
page_size query · optional · integer · default: 50 Maximum number of items in one page. Public API responses cap this value at 200; some product datasets may apply a lower internal cap.
device query · optional · string · desktop | mobile | tablet Restrict Search Console data to one device category.
country query · optional · string Restrict Search Console data to a canonical country code returned by Search Console, usually a three-character code.
sort_by query · optional · string · value | keywords | pages | clicks | impressions | ctr | first_time | position · default: impressions Column used to order aggregated Search Console rows.
sort_direction query · optional · string · ASC | DESC Sort in ascending (ASC) or descending (DESC) order using sort_by. Defaults are endpoint-specific when omitted.
clicks_min query · optional · number Keep rows with at least this many clicks.
clicks_max query · optional · number Keep rows with no more than this many clicks.
impressions_min query · optional · number Keep rows with at least this many impressions.
impressions_max query · optional · number Keep rows with no more than this many impressions.
ctr_min query · optional · number Keep rows with CTR at or above this percentage.
ctr_max query · optional · number Keep rows with CTR at or below this percentage.
position_min query · optional · number Keep rows whose average position is at least this numeric value.
position_max query · optional · number Keep rows whose average position is no greater than this numeric value; useful for TOP 10-style filtering.
GET /accounts/{account_id}/search-console/sites/{site_id}/pages List Search Console pages
/accounts/{account_id}/search-console/sites/{site_id}/pagesReturns aggregated pages. search matches a page URL or path; metric ranges are inclusive and apply before pagination.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
search query · optional · string Case-insensitive substring matched against a Search Console page URL or path.
date_from query · optional · string Inclusive first calendar date of the requested analytics period in YYYY-MM-DD format. If omitted, the endpoint selects a recent default period.
date_to query · optional · string Inclusive last calendar date of the requested analytics period in YYYY-MM-DD format. If both dates are supplied in reverse order, site summaries normalize their order.
page query · optional · integer · default: 1 One-based result page number. Use 1 for the first page.
page_size query · optional · integer · default: 50 Maximum number of items in one page. Public API responses cap this value at 200; some product datasets may apply a lower internal cap.
device query · optional · string · desktop | mobile | tablet Restrict Search Console data to one device category.
country query · optional · string Restrict Search Console data to a canonical country code returned by Search Console, usually a three-character code.
sort_by query · optional · string · value | keywords | pages | clicks | impressions | ctr | first_time | position · default: impressions Column used to order aggregated Search Console rows.
sort_direction query · optional · string · ASC | DESC Sort in ascending (ASC) or descending (DESC) order using sort_by. Defaults are endpoint-specific when omitted.
clicks_min query · optional · number Keep rows with at least this many clicks.
clicks_max query · optional · number Keep rows with no more than this many clicks.
impressions_min query · optional · number Keep rows with at least this many impressions.
impressions_max query · optional · number Keep rows with no more than this many impressions.
ctr_min query · optional · number Keep rows with CTR at or above this percentage.
ctr_max query · optional · number Keep rows with CTR at or below this percentage.
position_min query · optional · number Keep rows whose average position is at least this numeric value.
position_max query · optional · number Keep rows whose average position is no greater than this numeric value; useful for TOP 10-style filtering.
GET /accounts/{account_id}/search-console/sites/{site_id}/devices List Search Console devices
/accounts/{account_id}/search-console/sites/{site_id}/devicesReturns aggregated desktop, mobile, and tablet performance. country can narrow the rows before aggregation.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
date_from query · optional · string Inclusive first calendar date of the requested analytics period in YYYY-MM-DD format. If omitted, the endpoint selects a recent default period.
date_to query · optional · string Inclusive last calendar date of the requested analytics period in YYYY-MM-DD format. If both dates are supplied in reverse order, site summaries normalize their order.
page query · optional · integer · default: 1 One-based result page number. Use 1 for the first page.
page_size query · optional · integer · default: 50 Maximum number of items in one page. Public API responses cap this value at 200; some product datasets may apply a lower internal cap.
device query · optional · string · desktop | mobile | tablet Restrict Search Console data to one device category.
country query · optional · string Restrict Search Console data to a canonical country code returned by Search Console, usually a three-character code.
sort_by query · optional · string · value | keywords | pages | clicks | impressions | ctr | first_time | position · default: impressions Column used to order aggregated Search Console rows.
sort_direction query · optional · string · ASC | DESC Sort in ascending (ASC) or descending (DESC) order using sort_by. Defaults are endpoint-specific when omitted.
clicks_min query · optional · number Keep rows with at least this many clicks.
clicks_max query · optional · number Keep rows with no more than this many clicks.
impressions_min query · optional · number Keep rows with at least this many impressions.
impressions_max query · optional · number Keep rows with no more than this many impressions.
ctr_min query · optional · number Keep rows with CTR at or above this percentage.
ctr_max query · optional · number Keep rows with CTR at or below this percentage.
position_min query · optional · number Keep rows whose average position is at least this numeric value.
position_max query · optional · number Keep rows whose average position is no greater than this numeric value; useful for TOP 10-style filtering.
GET /accounts/{account_id}/search-console/sites/{site_id}/countries List Search Console countries
/accounts/{account_id}/search-console/sites/{site_id}/countriesReturns performance grouped by canonical Google Search Console country code. device can narrow the rows before aggregation.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
date_from query · optional · string Inclusive first calendar date of the requested analytics period in YYYY-MM-DD format. If omitted, the endpoint selects a recent default period.
date_to query · optional · string Inclusive last calendar date of the requested analytics period in YYYY-MM-DD format. If both dates are supplied in reverse order, site summaries normalize their order.
page query · optional · integer · default: 1 One-based result page number. Use 1 for the first page.
page_size query · optional · integer · default: 50 Maximum number of items in one page. Public API responses cap this value at 200; some product datasets may apply a lower internal cap.
device query · optional · string · desktop | mobile | tablet Restrict Search Console data to one device category.
country query · optional · string Restrict Search Console data to a canonical country code returned by Search Console, usually a three-character code.
sort_by query · optional · string · value | keywords | pages | clicks | impressions | ctr | first_time | position · default: impressions Column used to order aggregated Search Console rows.
sort_direction query · optional · string · ASC | DESC Sort in ascending (ASC) or descending (DESC) order using sort_by. Defaults are endpoint-specific when omitted.
clicks_min query · optional · number Keep rows with at least this many clicks.
clicks_max query · optional · number Keep rows with no more than this many clicks.
impressions_min query · optional · number Keep rows with at least this many impressions.
impressions_max query · optional · number Keep rows with no more than this many impressions.
ctr_min query · optional · number Keep rows with CTR at or above this percentage.
ctr_max query · optional · number Keep rows with CTR at or below this percentage.
position_min query · optional · number Keep rows whose average position is at least this numeric value.
position_max query · optional · number Keep rows whose average position is no greater than this numeric value; useful for TOP 10-style filtering.
Google SERP
Google ranking analytics resolved from an accessible website.
GET /accounts/{account_id}/google-serp/sites List sites with Google SERP metrics
/accounts/{account_id}/google-serp/sitesReturns accessible site records with ranking statistics joined by normalized domain. The same domain remains separate when it is accessible through more than one account record. The default date range ends today.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
limit query · optional · integer · default: 50 Maximum number of records to return in this cursor page. The API may return fewer records; use has_more and next_cursor to continue.
cursor query · optional · string Continuation cursor from the previous response meta.next_cursor. Omit it for the first page and treat its value as opaque.
search query · optional · string Case-insensitive substring matched against the website domain and, when present, its Search Console property URL.
tag_ids query · optional · array<integer> Comma-separated site tag ids from GET /accounts/{account_id}/site-tags. By default a site may match any supplied tag; use tag_match=all to require every tag.
tag_match query · optional · string · any | all · default: any How tag_ids are combined: any returns a site with at least one selected tag; all requires every selected tag.
exclude_tag_ids query · optional · array<integer> Comma-separated site tag ids. Sites carrying any excluded tag are omitted.
date_from query · optional · string Inclusive first calendar date of the requested analytics period in YYYY-MM-DD format. If omitted, the endpoint selects a recent default period.
date_to query · optional · string Inclusive last calendar date of the requested analytics period in YYYY-MM-DD format. If both dates are supplied in reverse order, site summaries normalize their order.
search_engine_id query · optional · integer · default: 1 Numeric search-engine/location identifier returned by Semalt analytics. The default value 1 is the standard engine.
site_type query · optional · string · gsc | manual Return only Search Console-connected records (gsc) or manually added records (manual).
access_type query · optional · string · own | linked | shared Filter by the relationship between the selected account and the site record: direct ownership, linked-group ownership, or explicit sharing.
GET /accounts/{account_id}/google-serp/sites/{site_id}/overview Get Google SERP overview
/accounts/{account_id}/google-serp/sites/{site_id}/overviewReturns site statistics for the selected search engine and date range. If an exact snapshot is unavailable, the analytics source may use the nearest earlier snapshot.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
date_from query · optional · string Inclusive first calendar date of the requested analytics period in YYYY-MM-DD format. If omitted, the endpoint selects a recent default period.
date_to query · optional · string Inclusive last calendar date of the requested analytics period in YYYY-MM-DD format. If both dates are supplied in reverse order, site summaries normalize their order.
search_engine_id query · optional · integer · default: 1 Numeric search-engine/location identifier returned by Semalt analytics. The default value 1 is the standard engine.
GET /accounts/{account_id}/google-serp/sites/{site_id}/keywords List Google SERP keyword positions
/accounts/{account_id}/google-serp/sites/{site_id}/keywordsReturns keyword positions and movement for the domain resolved from site_id. search is a keyword token search and should contain at least four characters. keyword_group_id restricts results to a reusable group visible for this site. Continue cursor pagination with next_token from the result as page_token.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
search_engine_id query · optional · integer · default: 1 Numeric search-engine/location identifier returned by Semalt analytics. The default value 1 is the standard engine.
date query · optional · string Requested snapshot date in YYYY-MM-DD format. When the exact snapshot is unavailable, Google SERP data may come from the nearest earlier snapshot.
search query · optional · string Text used to narrow keyword or query results. For Google SERP token search, provide at least four characters.
keyword_group_id query · optional · integer Restrict results to keywords in this reusable group. Obtain the id from GET /accounts/{account_id}/sites/{site_id}/keyword-groups; an empty group returns no matching rows.
page_url query · optional · string Exact page URL or path previously returned by Google SERP analytics.
position_group query · optional · string · top1 | top3 | top10 | quick_wins Convenience filter for position sets: top1 is position 1, top3 is 1–3, top10 is 1–10, and quick_wins is 4–10.
position_change query · optional · string · dynamics | moved_up | moved_down | changed | not_changed | entered | dropped Filter keywords by movement between snapshots. dynamics means no movement filter.
primary_only query · optional · boolean When true, return only primary Google SERP position records.
sort_by query · optional · string · key_val | pos | searches | popularity · default: popularity Column used to order Google SERP keyword rows.
sort_direction query · optional · string · ASC | DESC Sort in ascending (ASC) or descending (DESC) order using sort_by. Defaults are endpoint-specific when omitted.
page_size query · optional · integer · default: 50 Maximum number of items in one page. Public API responses cap this value at 200; some product datasets may apply a lower internal cap.
page_token query · optional · string Opaque Google SERP keyword cursor from the previous result next_token. Omit it for the first page.
GET /accounts/{account_id}/google-serp/sites/{site_id}/pages List best Google SERP pages
/accounts/{account_id}/google-serp/sites/{site_id}/pagesReturns best-performing pages for the resolved domain. keyword_group_id calculates page metrics only from keywords in a reusable group. page_url and keyword are exact upstream values; numeric minimum and maximum filters are inclusive.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
search_engine_id query · optional · integer · default: 1 Numeric search-engine/location identifier returned by Semalt analytics. The default value 1 is the standard engine.
date query · optional · string Requested snapshot date in YYYY-MM-DD format. When the exact snapshot is unavailable, Google SERP data may come from the nearest earlier snapshot.
keyword_group_id query · optional · integer Restrict results to keywords in this reusable group. Obtain the id from GET /accounts/{account_id}/sites/{site_id}/keyword-groups; an empty group returns no matching rows.
page_url query · optional · string Exact page URL or path previously returned by Google SERP analytics.
keyword query · optional · string Exact keyword value previously returned by Google SERP analytics.
queries_min query · optional · number Keep pages with at least this many tracked queries.
queries_max query · optional · number Keep pages with no more than this many tracked queries.
average_position_min query · optional · number Keep pages whose average position is at least this value.
average_position_max query · optional · number Keep pages whose average position is no greater than this value.
share_percent_min query · optional · number Keep pages whose visibility share is at least this percentage.
share_percent_max query · optional · number Keep pages whose visibility share is no greater than this percentage.
rating_min query · optional · number Keep pages whose rating is at least this value.
rating_max query · optional · number Keep pages whose rating is no greater than this value.
sort_by query · optional · string · total_queries | keywords | avg_pos | share_percent | rating · default: total_queries Column used to order Google SERP page rows.
sort_direction query · optional · string · ASC | DESC Sort in ascending (ASC) or descending (DESC) order using sort_by. Defaults are endpoint-specific when omitted.
page query · optional · integer · default: 1 One-based result page number. Use 1 for the first page.
page_size query · optional · integer · default: 50 Maximum number of items in one page. Public API responses cap this value at 200; some product datasets may apply a lower internal cap.
GET /accounts/{account_id}/google-serp/sites/{site_id}/competitors List Google SERP competitors
/accounts/{account_id}/google-serp/sites/{site_id}/competitorsReturns the top competitors by shared keywords for the resolved domain.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
search_engine_id query · optional · integer · default: 1 Numeric search-engine/location identifier returned by Semalt analytics. The default value 1 is the standard engine.
date query · optional · string Requested snapshot date in YYYY-MM-DD format. When the exact snapshot is unavailable, Google SERP data may come from the nearest earlier snapshot.
GET /google-serp/rankings List global Google SERP rankings
/google-serp/rankingsReturns a page of global domain rankings for one search engine and snapshot date.
search_engine_id query · optional · integer · default: 1 Numeric search-engine/location identifier returned by Semalt analytics. The default value 1 is the standard engine.
date query · optional · string Requested snapshot date in YYYY-MM-DD format. When the exact snapshot is unavailable, Google SERP data may come from the nearest earlier snapshot.
sort_by query · optional · string · rank | authority_linear | authority_percentile | authority_commercial | total_queries | total_pages · default: rank Column used to order global Google SERP rankings.
sort_direction query · optional · string · ASC | DESC Sort in ascending (ASC) or descending (DESC) order using sort_by. Defaults are endpoint-specific when omitted.
page query · optional · integer · default: 1 One-based result page number. Use 1 for the first page.
page_size query · optional · integer · default: 50 Maximum number of items in one page. Public API responses cap this value at 200; some product datasets may apply a lower internal cap.
AI Analytics
AI visibility analytics for GPT-4.1 nano and GPT-5 nano.
GET /accounts/{account_id}/ai-analytics/sites List sites with AI visibility metrics
/accounts/{account_id}/ai-analytics/sitesReturns accessible site records with visibility metrics for the selected public model name. The default model is gpt-5-nano.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
limit query · optional · integer · default: 50 Maximum number of records to return in this cursor page. The API may return fewer records; use has_more and next_cursor to continue.
cursor query · optional · string Continuation cursor from the previous response meta.next_cursor. Omit it for the first page and treat its value as opaque.
search query · optional · string Case-insensitive substring matched against the website domain and, when present, its Search Console property URL.
tag_ids query · optional · array<integer> Comma-separated site tag ids from GET /accounts/{account_id}/site-tags. By default a site may match any supplied tag; use tag_match=all to require every tag.
tag_match query · optional · string · any | all · default: any How tag_ids are combined: any returns a site with at least one selected tag; all requires every selected tag.
exclude_tag_ids query · optional · array<integer> Comma-separated site tag ids. Sites carrying any excluded tag are omitted.
model query · optional · string · gpt-4.1-nano | gpt-5-nano · default: gpt-5-nano AI model dataset to query. gpt-4.1-nano selects GPT-4.1 nano analytics; gpt-5-nano selects GPT-5 nano analytics.
site_type query · optional · string · gsc | manual Return only Search Console-connected records (gsc) or manually added records (manual).
access_type query · optional · string · own | linked | shared Filter by the relationship between the selected account and the site record: direct ownership, linked-group ownership, or explicit sharing.
GET /accounts/{account_id}/ai-analytics/sites/{site_id}/overview Get AI Analytics overview
/accounts/{account_id}/ai-analytics/sites/{site_id}/overviewReturns AI visibility statistics for the domain resolved from site_id and the selected model.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
model query · optional · string · gpt-4.1-nano | gpt-5-nano · default: gpt-5-nano AI model dataset to query. gpt-4.1-nano selects GPT-4.1 nano analytics; gpt-5-nano selects GPT-5 nano analytics.
GET /accounts/{account_id}/ai-analytics/sites/{site_id}/queries List AI query positions
/accounts/{account_id}/ai-analytics/sites/{site_id}/queriesReturns query, page, position, and category data. query_id and page_id are exact ids returned by this endpoint; position_group provides common TOP filters without constructing arrays.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
model query · optional · string · gpt-4.1-nano | gpt-5-nano · default: gpt-5-nano AI model dataset to query. gpt-4.1-nano selects GPT-4.1 nano analytics; gpt-5-nano selects GPT-5 nano analytics.
position_group query · optional · string · top1 | top3 | top10 | quick_wins Convenience filter for position sets: top1 is position 1, top3 is 1–3, top10 is 1–10, and quick_wins is 4–10.
query_id query · optional · integer Exact AI Analytics query id returned by a previous query result.
page_id query · optional · integer Exact AI Analytics page id returned by a previous result.
sort_by query · optional · string · key_val | page_val | pos | ts · default: pos Column used to order AI query-position rows.
sort_direction query · optional · string · ASC | DESC Sort in ascending (ASC) or descending (DESC) order using sort_by. Defaults are endpoint-specific when omitted.
page query · optional · integer · default: 1 One-based result page number. Use 1 for the first page.
page_size query · optional · integer · default: 50 Maximum number of items in one page. Public API responses cap this value at 200; some product datasets may apply a lower internal cap.
GET /accounts/{account_id}/ai-analytics/sites/{site_id}/pages List best AI Analytics pages
/accounts/{account_id}/ai-analytics/sites/{site_id}/pagesReturns best-performing pages for the resolved domain and selected model.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
model query · optional · string · gpt-4.1-nano | gpt-5-nano · default: gpt-5-nano AI model dataset to query. gpt-4.1-nano selects GPT-4.1 nano analytics; gpt-5-nano selects GPT-5 nano analytics.
sort_by query · optional · string · total_queries | avg_pos | share_percent | rating · default: total_queries Column used to order AI Analytics page rows.
sort_direction query · optional · string · ASC | DESC Sort in ascending (ASC) or descending (DESC) order using sort_by. Defaults are endpoint-specific when omitted.
page query · optional · integer · default: 1 One-based result page number. Use 1 for the first page.
page_size query · optional · integer · default: 50 Maximum number of items in one page. Public API responses cap this value at 200; some product datasets may apply a lower internal cap.
GET /accounts/{account_id}/ai-analytics/sites/{site_id}/competitors List AI competitors
/accounts/{account_id}/ai-analytics/sites/{site_id}/competitorsReturns the leading AI visibility competitors for the resolved domain and selected model.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
site_id path · required · integer Stable site identifier returned by a site collection endpoint.
model query · optional · string · gpt-4.1-nano | gpt-5-nano · default: gpt-5-nano AI model dataset to query. gpt-4.1-nano selects GPT-4.1 nano analytics; gpt-5-nano selects GPT-5 nano analytics.
GET /ai-analytics/rankings List global AI visibility rankings
/ai-analytics/rankingsReturns a page of global domain rankings for the selected AI model.
model query · optional · string · gpt-4.1-nano | gpt-5-nano · default: gpt-5-nano AI model dataset to query. gpt-4.1-nano selects GPT-4.1 nano analytics; gpt-5-nano selects GPT-5 nano analytics.
page query · optional · integer · default: 1 One-based result page number. Use 1 for the first page.
page_size query · optional · integer · default: 50 Maximum number of items in one page. Public API responses cap this value at 200; some product datasets may apply a lower internal cap.
My SEO
Campaigns owned by the selected account, addressed by campaign_id. Select another available account to manage its campaigns.
GET /accounts/{account_id}/my-seo/campaigns List account campaigns
/accounts/{account_id}/my-seo/campaignsReturns campaigns owned by account_id for accessible, visible domains. Each record contains campaign_id, account_id and domain. Campaigns on the same domain in different accounts remain separate. Use campaign_id for keyword and backlink endpoints.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
limit query · optional · integer · default: 50 Maximum number of records to return in this cursor page. The API may return fewer records; use has_more and next_cursor to continue.
cursor query · optional · string Continuation cursor from the previous response meta.next_cursor. Omit it for the first page and treat its value as opaque.
search query · optional · string Case-insensitive substring matched against assigned domains.
campaign_status query · optional · string · draft | launched | paused | cancelled Return only campaigns in this lifecycle state.
campaign_plan query · optional · string · autoseo | fullseo Return only campaigns using this plan.
GET /accounts/{account_id}/my-seo/campaigns/{campaign_id}/keywords List campaign keywords
/accounts/{account_id}/my-seo/campaigns/{campaign_id}/keywordsThe campaign_id must belong to account_id. search matches keyword text; target_url is an exact normalized target URL; keyword_group_id restricts results to a reusable group visible for this site. Response fields use the public snake_case contract.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
campaign_id path · required · integer Campaign identifier returned by the selected account’s campaign list. It must belong to account_id.
page query · optional · integer · default: 1 One-based result page number. Use 1 for the first page.
page_size query · optional · integer · default: 50 Maximum number of items in one page. Public API responses cap this value at 200; some product datasets may apply a lower internal cap.
search query · optional · string Text used to narrow keyword or query results. For Google SERP token search, provide at least four characters.
keyword_group_id query · optional · integer Restrict results to keywords in this reusable group. Obtain the id from GET /accounts/{account_id}/sites/{site_id}/keyword-groups; an empty group returns no matching rows.
source query · optional · string · gsc | serp | manual Filter campaign keywords by their source.
status query · optional · string · pending | approved | rejected Filter campaign keywords by review status.
target_url query · optional · string Exact normalized target URL assigned to a campaign keyword.
sort_by query · optional · string · keyword | source | url | position | popularity | status | updated_at · default: popularity Column used to order campaign keywords.
sort_direction query · optional · string · ASC | DESC Sort in ascending (ASC) or descending (DESC) order using sort_by. Defaults are endpoint-specific when omitted.
POST /accounts/{account_id}/my-seo/campaigns/{campaign_id}/keywords Add manual campaign keywords
/accounts/{account_id}/my-seo/campaigns/{campaign_id}/keywordsAdds keyword and target URL pairs to the campaign_id owned by account_id when it is a launched FullSEO campaign. Duplicate pairs update the existing manual records. Target URLs must belong to the campaign domain.
application/json one JSON objectManual keyword rows and their initial review state.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
campaign_id path · required · integer Campaign identifier returned by the selected account’s campaign list. It must belong to account_id.
items body · required · array<object> approved body · optional · boolean · default: true true saves as Approved; false saves as Recommended.
{
"items": [
{
"keyword": "technical seo audit",
"url": "https://example.com/seo-audit"
}
],
"approved": true
}POST /accounts/{account_id}/my-seo/campaigns/{campaign_id}/keyword-mode Set campaign keyword mode
/accounts/{account_id}/my-seo/campaigns/{campaign_id}/keyword-modeChanges keyword mode for a launched FullSEO campaign. auto keeps keyword review read-only except that rejected keywords can be restored to pending; manual enables approval, rejection, backlink weights, and allocation controls.
application/json one JSON objectKeyword mode to use for the campaign.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
campaign_id path · required · integer Campaign identifier returned by the selected account’s campaign list. It must belong to account_id.
keyword_mode body · required · string · auto | manual {
"keyword_mode": "manual"
}POST /accounts/{account_id}/my-seo/campaigns/{campaign_id}/keywords/status Update campaign keyword statuses
/accounts/{account_id}/my-seo/campaigns/{campaign_id}/keywords/statusUpdates the selected campaign keyword ids. In auto mode only rejected keywords may be restored to pending. In manual FullSEO mode, pending, approved, and rejected are supported.
application/json one JSON objectKeyword ids and the requested review status.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
campaign_id path · required · integer Campaign identifier returned by the selected account’s campaign list. It must belong to account_id.
keyword_ids body · required · array<string> status body · required · string · pending | approved | rejected {
"keyword_ids": [
"campaign-keyword-id"
],
"status": "approved"
}POST /accounts/{account_id}/my-seo/campaigns/{campaign_id}/keywords/backlink-weights Set keyword backlink weights
/accounts/{account_id}/my-seo/campaigns/{campaign_id}/keywords/backlink-weightsSets integer backlink weights for approved keywords in a launched FullSEO campaign using manual keyword mode. Weight values are from 1 to 10000; the resulting backlink share is derived from the total approved weight.
application/json one JSON objectApproved keyword ids and their backlink weights.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
campaign_id path · required · integer Campaign identifier returned by the selected account’s campaign list. It must belong to account_id.
items body · required · array<object> {
"items": [
{
"id": "campaign-keyword-id",
"backlink_weight": 5
}
]
}POST /accounts/{account_id}/my-seo/campaigns/{campaign_id}/keywords/backlink-allocation Apply one-shot backlink allocation
/accounts/{account_id}/my-seo/campaigns/{campaign_id}/keywords/backlink-allocationApplies the current UI allocation behavior once to all approved keywords in a launched FullSEO campaign using manual keyword mode. Supplied percentages are fixed for this operation; omitted approved keywords share the remainder equally. The allocation is not stored as a persistent fixed-percentage configuration. Call the keyword list endpoint afterwards to inspect the resulting weights and shares.
application/json one JSON objectKeyword ids and their one-shot percentage assignments.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
campaign_id path · required · integer Campaign identifier returned by the selected account’s campaign list. It must belong to account_id.
items body · required · array<object> {
"items": [
{
"id": "campaign-keyword-id",
"percentage": 25.5
}
]
}GET /accounts/{account_id}/my-seo/campaigns/{campaign_id}/backlinks List campaign backlinks
/accounts/{account_id}/my-seo/campaigns/{campaign_id}/backlinksThe campaign_id must belong to account_id. search matches the start of the donor domain, case-insensitively. Response fields use the public snake_case contract.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
campaign_id path · required · integer Campaign identifier returned by the selected account’s campaign list. It must belong to account_id.
page query · optional · integer · default: 1 One-based result page number. Use 1 for the first page.
page_size query · optional · integer · default: 50 Maximum number of items in one page. Public API responses cap this value at 200; some product datasets may apply a lower internal cap.
search query · optional · string Case-insensitive prefix matched against the donor domain. For example, blog matches blog.example.com, but example does not match blog.example.com. Wildcard characters are treated literally.
link_type query · optional · string · discussion | article | wiki Filter backlinks by placement type.
domain_rating query · optional · string · under40 | 40_70 | 70plus Filter donor domain rating into a simple range: under40, 40_70 (40 inclusive, 70 exclusive), or 70plus.
sort_by query · optional · string · placed | donor | dr | referring_domains | backlinks | rank | top100 · default: placed Column used to order campaign backlinks.
sort_direction query · optional · string · ASC | DESC Sort in ascending (ASC) or descending (DESC) order using sort_by. Defaults are endpoint-specific when omitted.
Indexing
URLs and indexing balance owned by the selected account. Submissions consume that account’s balance; balances are not pooled.
GET /accounts/{account_id}/indexing/urls List indexing URLs
/accounts/{account_id}/indexing/urlsReturns indexing URLs and their current crawler status for the selected account. url_contains and domain are independent, case-insensitive substring filters.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
page query · optional · integer · default: 1 One-based result page number. Use 1 for the first page.
page_size query · optional · integer · default: 50 Maximum number of items in one page. Public API responses cap this value at 200; some product datasets may apply a lower internal cap.
url_contains query · optional · string Case-insensitive substring matched against the complete submitted URL.
domain query · optional · string Domain or hostname substring. A supplied URL is normalized to its domain before filtering.
status query · optional · string · queued | processing | visited | failed Filter by readable indexing state.
bot query · optional · string · google | openai | bing Filter by crawler that processes the URL.
sort_by query · optional · string · url | domain | bot | status | created · default: created Column used to order indexing records.
sort_direction query · optional · string · ASC | DESC Sort in ascending (ASC) or descending (DESC) order using sort_by. Defaults are endpoint-specific when omitted.
POST /accounts/{account_id}/indexing/urls Add URLs to indexing
/accounts/{account_id}/indexing/urlsSubmits each unique URL for every selected bot and debits the account indexing balance only for persisted requests. google is the default bot; bing is also supported. This operation does not accept an idempotency key: after an ambiguous network failure, inspect GET /accounts/{account_id}/indexing/urls for the same account before retrying.
application/json one JSON objectComplete URLs and supported crawler names.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
urls body · required · array<string> bots body · optional · array<string> · default: google {
"urls": [
"https://example.com/",
"https://example.com/page"
],
"bots": [
"google"
]
}Report Center
Synchronous PDFs, generation history, and public links. Saved definitions, schedules, and email delivery are not exposed yet.
GET /accounts/{account_id}/report-center/catalog Discover PDF reports
/accounts/{account_id}/report-center/catalogReturns ready-to-fill definition_template objects. Replace the null ID in each template’s scope with a site_id or campaign_id, then add only fields advertised by that item. For custom PDF branding, also call the white-label endpoint and add its white_label_id to the definition. The response includes comparison modes, PDF row caps, effective actor quotas, and timeout_seconds. Every actor is subject to global capacity limits.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
GET /accounts/{account_id}/report-center/white-labels Find white labels for PDF branding
/accounts/{account_id}/report-center/white-labelsReturns up to 50 active white labels with uploaded logos available to the selected linked account group. Take data[].white_label_id and pass it as definition.white_label_id when generating a PDF. Omit white_label_id to use Semalt branding. Use search to narrow results.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
search query · optional · string GET /accounts/{account_id}/report-center/runs List report runs
/accounts/{account_id}/report-center/runsReturns owned and linked-account history, newest first, including browser runs. meta includes limit, has_more and next_cursor. Listing does not issue public links.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
limit query · optional · integer · default: 25 cursor query · optional · string status query · optional · string · queued | processing | ready | failed | expired POST /accounts/{account_id}/report-center/runs Generate a PDF synchronously
/accounts/{account_id}/report-center/runsWaits for PDF generation and stores the result for 90 days. To use a custom brand, put a white_label_id returned by the white-label endpoint inside definition; the PDF embeds the selected label snapshot. A ready result includes public view_url and download_url: anyone holding a link can read the file. No email is sent. Reuse the same idempotency_key and definition after a lost response; it returns the same run without consuming another generation quota. An in-progress duplicate returns processing. Failed runs return status=failed and error_code; use a new key for another attempt. Replayed ready runs receive new links without extending expiry. Changed definitions with the same key conflict. Standard defaults: 1 concurrent, 3/minute, 50/rolling day. Authorized staff receive higher configured quotas, determined by the key owner. Account and global caps always apply.
application/json one JSON objectaccount_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
definition body · required · object Start with the report catalog and copy the selected item’s definition_template. Replace its null scope ID, then add only optional fields listed for that item. For custom PDF branding, add white_label_id obtained from GET /accounts/{account_id}/report-center/white-labels. Fixed dates must be ordered and span at most 367 days. latest_snapshot uses source snapshot semantics and a default 28-day reporting window.
execution body · optional · string · default: sync disposition body · optional · string · inline | attachment · default: inline idempotency_key body · required · string {
"definition": {
"kind": "report",
"key": "search_console.site_overview",
"scope": {
"site_id": "123"
},
"period": {
"type": "fixed",
"date_from": "2026-08-01",
"date_to": "2026-08-31"
},
"comparison": {
"type": "previous_period"
},
"white_label_id": "42"
},
"execution": "sync",
"disposition": "inline",
"idempotency_key": "gsc-123-2026-08"
}GET /accounts/{account_id}/report-center/runs/{run_id} Get a report run
/accounts/{account_id}/report-center/runs/{run_id}Returns status and metadata without creating a public link.
account_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
run_id path · required · integer POST /accounts/{account_id}/report-center/runs/{run_id}/links Create public PDF links
/accounts/{account_id}/report-center/runs/{run_id}/linksCreates new links to a ready PDF. Links expire with the original artifact, at most 90 days after generation. Site access changes do not automatically revoke these capability links.
application/json one JSON objectaccount_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
run_id path · required · integer disposition body · optional · string · inline | attachment · default: inline {
"disposition": "inline"
}POST /accounts/{account_id}/report-center/runs/{run_id}/links/revoke Revoke public PDF links
/accounts/{account_id}/report-center/runs/{run_id}/links/revokeIdempotently revokes all currently issued public links to this run. The private artifact remains available in history; authorized callers may explicitly issue new links.
application/json one JSON objectaccount_id path · required · integer Account context returned by /me or /accounts. Selects the account for this request. Site operations may return records owned by the selected account, its linked group, or explicitly shared with it. New sites, site tags and keyword groups belong to this account, and indexing uses its balance. Repeat account_id in every account request.
run_id path · required · integer {}GET /report-files/{report_token} Open or download a public PDF
/report-files/{report_token}Requires only the unguessable token from an issued URL, not an API key. Invalid, expired, or revoked links return 404. Browser settings may override inline display.
report_token path · required · string download query · optional · string · 1 Use 1 for attachment; omit for inline display.
Errors
Errors use application/problem+json and include a stable code plus a request_id. Send the request id to support when investigating an error.
Common statuses are 401 for a missing or invalid API key, 403 for a product scope restriction, 404 for an inaccessible site id, and 502 when an analytics data source is temporarily unavailable.
PDF reports
Call GET /accounts/{account_id}/report-center/catalog first. Each item contains a ready-to-fill definition_template. Copy it into the run request and replace the null value in scope with an ID returned by /sites or /my-seo/campaigns. The template's scope.id_field is the exact field name (site_id, campaign_id, or no field for account/global items). Add only filters, columns, and comparison modes listed by that item. For custom PDF branding, call GET .../white-labels?search=..., take the returned white_label_id, and add it to the report definition. Omit white_label_id to use Semalt branding. All paths below are relative to /api/v1.
For campaign backlinks, choose kind: "report" and key: "my_seo.backlinks" with scope: { "campaign_id": "…" }. Its PDF contains Total backlinks, Discussions, Articles, Average DR, and the placement table. Summary cards cover all placements in the selected period; search, type, and dr filters apply to the table. Use period: { "type": "latest_snapshot" } for all recorded placements, or period: { "type": "fixed", "date_from": "2026-09-01", "date_to": "2026-09-30" } to select placement dates. Both dates are inclusive in UTC. The same period applies to summary cards and table rows. The corresponding kind: "table" export remains available without summary cards.
For example, a catalog item for a site report provides a structure like this:
{
"scope": { "type": "site", "id_field": "site_id", "required": true },
"definition_template": {
"kind": "report",
"key": "search_console.site_overview",
"scope": { "site_id": null },
"period": { "type": "latest_snapshot" },
"filters": {}
}
}To find a custom brand, use the same account_id as the report run:
GET /api/v1/accounts/20/report-center/white-labels?search=AcmeThe endpoint returns active white labels with uploaded logos. Use the exact data[].white_label_id value in definition.white_label_id; do not send the logo URL or company name in the run request:
{
"data": [
{
"white_label_id": "42",
"name": "Acme Reports",
"company_name": "Acme Ltd"
}
],
"meta": {
"limit": 50,
"has_more": false
}
}curl --request POST 'https://semalt.com/api/v1/accounts/20/report-center/runs' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"definition": {
"kind": "report",
"key": "search_console.site_overview",
"scope": { "site_id": "123" },
"period": {
"type": "fixed",
"date_from": "2026-08-01",
"date_to": "2026-08-31"
},
"comparison": { "type": "previous_period" },
"white_label_id": "42"
},
"execution": "sync",
"disposition": "inline",
"idempotency_key": "gsc-123-2026-08"
}'The request waits for generation and returns JSON. Inspect data.status:
ready:view_urlopens the PDF,download_urlrequests an attachment, andurlselects the requested disposition. Browser preferences can override inline display.processing: an identical request is already running; useGET .../runs/{run_id}.failed: inspecterror_code; use a new idempotency key for another attempt.expired: the original artifact has expired; use a new key to generate another.
The required idempotency key is scoped to the actor and selected account, shared across REST/MCP, and retained with the run. A changed definition with the same key returns 409. Replays do not consume another generation quota. Replayed ready runs receive new links to the same artifact; old links remain valid until revoked or expired. GET status/history never creates public links.
PDF links grant anyone holding the URL access without an API key until 90 days after generation or explicit revocation. Site-access changes do not automatically revoke an already shared copy. POST .../runs/{run_id}/links issues another link; POST .../runs/{run_id}/links/revoke with {} revokes all current links. Issuing a link never extends artifact retention. Revocation does not delete the private PDF or prevent an authorized user from explicitly issuing a new link.
GET .../runs lists owned/linked Report Center history, including browser runs, using descending ID cursors. API-created runs have no saved report definition and appear in dashboard history. No schedule, saved definition, or email is created. Public link issuance currently supports PDF only.
Generation defaults: 1 concurrent / 3 per minute / 50 per rolling 24 hours for a standard actor; authorized staff have higher configured quotas. Account and global concurrency caps always apply, including to staff. 429 and capacity 503 errors include Retry-After when applicable; MCP errors include errors.retry_after. The default generation budget is 50 seconds. Allow a longer transport timeout to receive the completed response and accommodate admission and response overhead.
Use fixed dates for an exact period. The template uses latest_snapshot by default; time-series sources resolve that to the latest available 28-day window. When the catalog item lists previous_period, add "comparison": {"type":"previous_period"} to put the immediately preceding period of the same length into the same PDF with comparison charts and deltas. Arbitrary internal params, account overrides, HTML, logo URLs, and export-source overrides are rejected.