Skip to content
SSalesShiftDocs
API reference

SEO

Tracked sites, keyword rank checks, site audits and the SEO overview.

13 endpoints· 5 called live· 8 not exercised here· verified against http://127.0.0.1:8741

13 endpoints

POST/api/v1/salesshift/seo/auditNot exercised hereCrawl + analyse a site on the tenant node, store the result, notify.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+custom

Request body (required) — AuditIn

FieldTypeRequiredNotes
site_idstring(uuid)?optional
urlstringoptionalDefault "".
max_pagesintegeroptionalDefault 20. min 1, max 50.

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/seo/audit' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "site_id": "<string(uuid)>", "url": "", "max_pages": 20 }'

Response · 200

Top-level keys
{
  "audit_id": "…",
  "data": "…",
  "site_id": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
400site_id or url is required
400Enter a valid URL, e.g. https://example.com
502computed at runtime: result.get('error') or 'Audit failed on the SEO engine'
#post-api-v1-salesshift-seo-auditseo_router · vxcloud_fastapiclient/app/services/salesshift/seo_router.py:616Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
GET/api/v1/salesshift/seo/auditsCalled liveAudit history — summary rows only unless ``?full=1``.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Query parameters

NameTypeRequiredNotes
site_idstring(uuid)?optional
limitintegeroptionalDefault 10. min 1. max 100.
fullintegeroptionalDefault 0. min 0. max 1.

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/seo/audits' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "success": "bool",
  "data": [
    {
      "id": "str",
      "site_id": "str",
      "url": "str",
      "health_score": "int",
      "pages_crawled": "int",
      "total_issues": "int",
      "ssl_valid": "bool",
      "robots_found": "bool",
      "sitemap_found": "bool",
      "created_at": "str"
    },
    "...x2"
  ]
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-salesshift-seo-auditsseo_router · vxcloud_fastapiclient/app/services/salesshift/seo_router.py:699Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
GET/api/v1/salesshift/seo/audits/{audit_id}Called liveOne SEO audit with its full findings.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Path parameters

NameTypeRequiredNotes
audit_idstring(uuid)required

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/seo/audits/{audit_id}' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "success": "bool",
  "data": {
    "id": "str",
    "site_id": "str",
    "url": "str",
    "health_score": "int",
    "pages_crawled": "int",
    "total_issues": "int",
    "ssl_valid": "bool",
    "robots_found": "bool",
    "sitemap_found": "bool",
    "created_at": "str",
    "result": {
      "ssl": {
        "host": "...",
        "valid": "...",
        "issuer": "...",
        "subject": "...",
        "expires_at": "...",
        "days_to_expiry": "..."
      },
      "url": "str",
      "pages": [
        "...",
        "...x20"
      ],
      "domain": "str",
      "issues": [
        "...",
        "...x47"
      ],
      "sitemap": {
        "url": "...",
        "found": "...",
        "is_index": "...",
        "url_count": "..."
      },
      "success": "bool",
      "max_pages": "int",
      "robots_txt": {
        "url": "...",
        "found": "...",
        "status": "...",
        "allows_crawl": "...",
        "sitemap_urls": "..."
      },
      "performance": {
        "slowest": "...",
        "avg_load_ms": "...",
        "max_load_ms": "...",
        "pages_analyzed": "...",
        "slow_pages_count": "..."
      },
      "generated_at": "str",
      "health_score": "int",
      "issue_counts": {
        "info": "...",
        "errors": "...",
        "warnings": "..."
      },
      "total_issues": "int",
      "pages_crawled": "int"
    }
  }
}
Observed on 2026-08-06 — keys are real, values are the types that came back.

Errors

Statusdetail
404Audit not found
#get-api-v1-salesshift-seo-audits-audit-idseo_router · vxcloud_fastapiclient/app/services/salesshift/seo_router.py:718Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
GET/api/v1/salesshift/seo/keywordsCalled liveTracked keywords, optionally narrowed to one site.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Query parameters

NameTypeRequiredNotes
site_idstring(uuid)?optional

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/seo/keywords' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "success": "bool",
  "data": [
    {
      "id": "str",
      "site_id": "str",
      "site_domain": "str",
      "keyword": "str",
      "country": "str",
      "device": "str",
      "current_rank": "null",
      "previous_rank": "null",
      "best_rank": "null",
      "delta": "null",
      "search_volume": "null",
      "difficulty": "null",
      "cpc": "null",
      "landing_url": "null",
      "last_checked_at": "null",
      "is_tracking": "bool",
      "history": [
        "<empty list>"
      ],
      "sparkline": [
        "<empty list>"
      ],
      "created_at": "str"
    },
    "...x4"
  ]
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-salesshift-seo-keywordsseo_router · vxcloud_fastapiclient/app/services/salesshift/seo_router.py:355Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
POST/api/v1/salesshift/seo/keywordsNot exercised hereBulk-add tracked keywords (deduped against what's already tracked).
Auth
get_org_user
Scope
organization
Success
201 · application/json
Envelope
success+custom

Request body (required) — KeywordsIn

FieldTypeRequiredNotes
site_idstring(uuid)?optional
keywordstringoptionalDefault "".
keywordsstring[]optional
countrystringoptionalDefault "us".
devicestringoptionalDefault "desktop".

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/seo/keywords' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "site_id": "<string(uuid)>", "keyword": "", "keywords": [ "<string>" ], "country": "us", "device": "desktop" }'

Response · 201

Top-level keys
{
  "added": "…",
  "data": "…",
  "skipped": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
400site_id is required
400No keywords provided
400Too many keywords at once ({...}) — {...} max
#post-api-v1-salesshift-seo-keywordsseo_router · vxcloud_fastapiclient/app/services/salesshift/seo_router.py:381Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
DELETE/api/v1/salesshift/seo/keywords/{keyword_id}Not exercised hereStop tracking a keyword.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+custom

Path parameters

NameTypeRequiredNotes
keyword_idstring(uuid)required

Request

curl
curl -X DELETE 'https://api.vxcloud.io/api/v1/salesshift/seo/keywords/{keyword_id}' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "success": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
404Keyword not found
#delete-api-v1-salesshift-seo-keywords-keyword-idseo_router · vxcloud_fastapiclient/app/services/salesshift/seo_router.py:446Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
POST/api/v1/salesshift/seo/keywords/{keyword_id}/checkNot exercised hereReal SERP position check through the node engine, then persist it.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+custom

Path parameters

NameTypeRequiredNotes
keyword_idstring(uuid)required

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/seo/keywords/{keyword_id}/check' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "blocked": "…",
  "data": "…",
  "engine": "…",
  "error": "…",
  "results_parsed": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
404Keyword not found
400Keyword is not attached to a site
#post-api-v1-salesshift-seo-keywords-keyword-id-checkseo_router · vxcloud_fastapiclient/app/services/salesshift/seo_router.py:562Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
POST/api/v1/salesshift/seo/keywords/check-allNot exercised hereSequentially re-check up to 25 tracked keywords (small delay between SERP fetches).

Sequentially re-check up to 25 tracked keywords (small delay between SERP fetches). Blocked checks are reported, never guessed.

Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+custom

Query parameters

NameTypeRequiredNotes
site_idstring(uuid)?optional

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/seo/keywords/check-all' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "blocked": "…",
  "checked": "…",
  "declined": "…",
  "failed": "…",
  "improved": "…",
  "remaining": "…",
  "results": "…",
  "stopped_early": "…",
  "success": "…",
  "total": "…"
}
Top-level keys read from the handler's return statements.
#post-api-v1-salesshift-seo-keywords-check-allseo_router · vxcloud_fastapiclient/app/services/salesshift/seo_router.py:464Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
GET/api/v1/salesshift/seo/overviewCalled liveRollup across the org's sites, keywords and audits.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Query parameters

NameTypeRequiredNotes
site_idstring(uuid)?optional

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/seo/overview' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "success": "bool",
  "data": {
    "sites": "int",
    "keywords_tracked": "int",
    "keywords_ranked": "int",
    "avg_position": "float",
    "top_3": "int",
    "top_10": "int",
    "top_100": "int",
    "improved": "int",
    "declined": "int",
    "improved_30d": "int",
    "declined_30d": "int",
    "last_audit": {
      "id": "str",
      "score": "int",
      "issues": "int",
      "pages_crawled": "int",
      "url": "str",
      "at": "str"
    },
    "movers_up": [
      "<empty list>"
    ],
    "movers_down": [
      "<empty list>"
    ]
  }
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-salesshift-seo-overviewseo_router · vxcloud_fastapiclient/app/services/salesshift/seo_router.py:769Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
GET/api/v1/salesshift/seo/sitesCalled liveThe organization's tracked sites with their keyword counts.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+data

Request

curl
curl 'https://api.vxcloud.io/api/v1/salesshift/seo/sites' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Observed shape
{
  "success": "bool",
  "data": [
    {
      "id": "str",
      "domain": "str",
      "name": "str",
      "health_score": "int",
      "last_audit_at": "str",
      "keywords_count": "int",
      "created_at": "str"
    },
    "...x2"
  ]
}
Observed on 2026-08-06 — keys are real, values are the types that came back.
#get-api-v1-salesshift-seo-sitesseo_router · vxcloud_fastapiclient/app/services/salesshift/seo_router.py:282Called against http://127.0.0.1:8741 on 2026-08-06 with a real JWT; the response matched the shape recorded below.
POST/api/v1/salesshift/seo/sitesNot exercised hereAdd a site to track, normalising and validating the domain.
Auth
get_org_user
Scope
organization
Success
201 · application/json
Envelope
success+custom

Request body (required) — SiteIn

FieldTypeRequiredNotes
domainstringrequired≤ 255 chars.
namestringoptionalDefault "".

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/seo/sites' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "domain": "<string>", "name": "" }'

Response · 201

Top-level keys
{
  "data": "…",
  "existing": "…",
  "success": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
400Enter a valid domain, e.g. example.com
#post-api-v1-salesshift-seo-sitesseo_router · vxcloud_fastapiclient/app/services/salesshift/seo_router.py:301Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
DELETE/api/v1/salesshift/seo/sites/{site_id}Not exercised hereRemoves the site and — via ON DELETE CASCADE — its keywords, rank history and audit history.

Removes the site and — via ON DELETE CASCADE — its keywords, rank history and audit history.

Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+custom

Path parameters

NameTypeRequiredNotes
site_idstring(uuid)required

Request

curl
curl -X DELETE 'https://api.vxcloud.io/api/v1/salesshift/seo/sites/{site_id}' \
  -H "Authorization: Bearer $SS_TOKEN"

Response · 200

Top-level keys
{
  "success": "…"
}
Top-level keys read from the handler's return statements.
#delete-api-v1-salesshift-seo-sites-site-idseo_router · vxcloud_fastapiclient/app/services/salesshift/seo_router.py:329Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.
POST/api/v1/salesshift/seo/suggestNot exercised hereReal Google autocomplete suggestions via the node — no invented ideas.
Auth
get_org_user
Scope
organization
Success
200 · application/json
Envelope
success+custom

Request body (required) — SuggestIn

FieldTypeRequiredNotes
seedstringrequired≤ 300 chars.
countrystringoptionalDefault "us".

Values in the request below are typed placeholders, not sample data.

Request

curl
curl -X POST 'https://api.vxcloud.io/api/v1/salesshift/seo/suggest' \
  -H "Authorization: Bearer $SS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{ "seed": "<string>", "country": "us" }'

Response · 200

Top-level keys
{
  "error": "…",
  "seed": "…",
  "success": "…",
  "suggestions": "…"
}
Top-level keys read from the handler's return statements.

Errors

Statusdetail
400Enter a seed keyword
#post-api-v1-salesshift-seo-suggestseo_router · vxcloud_fastapiclient/app/services/salesshift/seo_router.py:742Implemented and read in source for this inventory, but not exercised against a running server here. Treat as undemonstrated until someone calls it.