Skip to content

Start building

Jump toSEO monitoring
All endpoints

SEO monitoring

Watch websites: add sites, run scans, read findings by rule and page, Google Search numbers and tracked keywords.

get/v1/seo/rules

List seo rules

Any key of this organization

Every check a scan makes, with its severity, category and three short texts: what is wrong, why it matters, and how to fix it. Errors take 25 points off a page's score, warnings 8, notices 2; a site's score is its pages' average, less 10, 4 or 1 per site-wide finding.

Response200

  • objectstring
    list
  • dataSeoRule[]
    7 fields
    • idstring
    • categorystring
      One ofcrawlindexingcontentlinkssocialstructured_dataperformancesecuritymobileai_search
    • fixstring
    • scopestring
      One ofpagesite
    • severitystring
      One oferrorwarningnotice
    • titlestring
    • whystring
  • has_moreboolean
  • next_cursorstring or null
  • facetsmap<string, map<string, integer>> or null
  • peoplemap<string, ActorRef> or null
    5 fields
    • idstring or null
    • kindstring
      One ofuserapi_keyservice_accountworkloadend_usersystem
    • namestring or null
    • avatar_versionstring or null
    • emailstring or null
  • total_countinteger or null
  • total_count_exactboolean or null

Status codes

  • 200Successful Response
  • 4XXThe request was refused: the problem says why.
  • 5XXThe API could not answer: the problem says why.
Request
curl "https://api.mydeepagents.com/v1/seo/rules" \
  -H "Authorization: Bearer $MDA_API_KEY"
Response · 200
JSON
{
  "object": "list",
  "data": [
    {
      "id": "id",
      "category": "crawl",
      "fix": "fix",
      "scope": "page",
      "severity": "error",
      "title": "Support triage",
      "why": "why"
    }
  ],
  "has_more": false,
  "next_cursor": null,
  "total_count": 1
}
get/v1/seo/search_console/properties

List search console properties

Needs seo.manage

The Search Console properties a Google Search Console connection can see, to tie a site to one: URL-prefix properties (https://www.example.com/) and domain properties (sc-domain:example.com).

Query parameters

  • connection_idstringRequired

Response200

  • objectstring
    list
  • dataSeoSearchProperty[]
    2 fields
    • permission_levelstring or null
    • site_urlstring
  • has_moreboolean
  • next_cursorstring or null

Status codes

  • 200Successful Response
  • 422The request is not valid: errors[] names each field.
  • 4XXThe request was refused: the problem says why.
  • 5XXThe API could not answer: the problem says why.
Request
curl "https://api.mydeepagents.com/v1/seo/search_console/properties" \
  -H "Authorization: Bearer $MDA_API_KEY"
Response · 200
JSON
{
  "object": "list",
  "data": [
    {
      "permission_level": "permission level",
      "site_url": "https://example.com"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
get/v1/seo/sites

List seo sites

Needs seo.view

Sorted by name by default; also score, last_scan_at, created_at, updated_at. q searches names and addresses, or finds a pasted seo_… ID. Filters, each repeatable: workspace_id, state (active, paused), schedule, created_by, updated_by. Without workspace_id, seo.view is needed across the organization.

Query parameters

  • workspace_idstring[]
  • statestring[]
  • schedulestring[]
  • created_bystring[]
  • updated_bystring[]
  • limitinteger

    Rows per page, 1 to 200.

    Default50at least 1at most 200
  • cursorstring
  • qstring

    Search: rows whose name (or the list's other searchable text) contains this, any case.

    at most 200 characters
  • orderstring

    Sort field; a leading - sorts down. Each list names the fields it sorts by.

    at most 64 charactersmatches ^-?[a-z_]+$
  • includestring[]

    total_count (counted up to 10,000) and facets (a count per filter value).

    One oftotal_countfacets
  • created_afterstring

    Only rows created at or after this time (RFC 3339).

    date-time
  • created_beforestring

    Only rows created at or before this time (RFC 3339).

    date-time
  • updated_afterstring

    Only rows last changed at or after this time (RFC 3339).

    date-time
  • updated_beforestring

    Only rows last changed at or before this time (RFC 3339).

    date-time

Response200

  • objectstring
    list
  • dataSeoSite[]
    53 fields
    • idstring
    • objectstring
      seo_site
    • active_scan_idstring or null
    • alert_clicks_drop_pctinteger
    • alert_new_errorsboolean
    • alert_score_dropinteger
    • answers_connection_idstring or null
    • brand_termsstring[]
    • check_externalboolean
    • clicks_28dinteger or null
    • clicks_prev_28dinteger or null
    • created_atstring or null
    • ctr_28dnumber or null
    • errorsinteger
    • exclude_pathsstring[]
    • impressions_28dinteger or null
    • impressions_prev_28dinteger or null
    • include_pathsstring[]
    • inspect_pagesinteger
    • last_scan_atstring or null
    • last_scan_idstring or null
    • max_pagesinteger
    • namestring
    • next_scan_atstring or null
    • next_sync_atstring or null
    • noticesinteger
    • pages_countinteger
    • position_28dnumber or null
    • previous_scoreinteger or null
    • rank_connection_idstring or null
    • rank_countrystring or null
    • rank_depthinteger
    • rank_languagestring or null
    • ranks_checked_atstring or null
    • respect_robotsboolean
    • row_versioninteger
    • schedulestring
      One ofmanualdailyweekly
    • scoreinteger or null
    • search_connection_idstring or null
    • search_errorstring or null
    • search_propertystring or null
    • search_synced_atstring or null
    • sitemap_urlsstring[]
    • statestring
      One ofactivepaused
    • track_everystring
      One ofdailyweekly
    • updated_atstring or null
    • urlstring
    • vitals_pagesinteger
    • vitals_strategystring
      One ofmobiledesktop
    • warningsinteger
    • workspace_idstring
    • created_byActorRef or null

      Who created or last changed something, resolved to a name for display. system, workload (an automation) and end_user (a widget visitor) have no ID or name: the console words them. name is null for someone the directory no longer knows. id is what the lists' created_by/updated_by filters take. avatar_version is set for a person with a photo: it is at GET /v1/members/{id}/avatar?v=<avatar_version> while they are a member.

      5 fields
      • idstring or null
      • kindstring
        One ofuserapi_keyservice_accountworkloadend_usersystem
      • namestring or null
      • avatar_versionstring or null
      • emailstring or null
    • updated_byActorRef or null

      Who created or last changed something, resolved to a name for display. system, workload (an automation) and end_user (a widget visitor) have no ID or name: the console words them. name is null for someone the directory no longer knows. id is what the lists' created_by/updated_by filters take. avatar_version is set for a person with a photo: it is at GET /v1/members/{id}/avatar?v=<avatar_version> while they are a member.

      5 fields
      • idstring or null
      • kindstring
        One ofuserapi_keyservice_accountworkloadend_usersystem
      • namestring or null
      • avatar_versionstring or null
      • emailstring or null
  • has_moreboolean
  • next_cursorstring or null
  • facetsmap<string, map<string, integer>> or null
  • peoplemap<string, ActorRef> or null
    5 fields
    • idstring or null
    • kindstring
      One ofuserapi_keyservice_accountworkloadend_usersystem
    • namestring or null
    • avatar_versionstring or null
    • emailstring or null
  • total_countinteger or null
  • total_count_exactboolean or null

Status codes

  • 200Successful Response
  • 422The request is not valid: errors[] names each field.
  • 4XXThe request was refused: the problem says why.
  • 5XXThe API could not answer: the problem says why.
Request
curl "https://api.mydeepagents.com/v1/seo/sites?limit=20" \
  -H "Authorization: Bearer $MDA_API_KEY"
Response · 200
JSON
{
  "object": "list",
  "data": [
    {
      "id": "id",
      "object": "seo_site",
      "active_scan_id": "active scan id",
      "alert_clicks_drop_pct": 2,
      "alert_new_errors": true,
      "alert_score_drop": 2,
      "answers_connection_id": "answers connection id",
      "brand_terms": [
        "brand term"
      ],
      "check_external": true,
      "clicks_28d": 2,
      "clicks_prev_28d": 2,
      "created_at": "2026-11-10T09:30:00.000Z",
      "created_by": {
        "kind": "user",
        "id": "usr_01jcf1j9wjxfrnhqda3mq7ejxn",
        "name": "Ada Lovelace",
        "email": "ada@example.com"
      },
      "ctr_28d": 0.5,
      "errors": 2,
      "exclude_paths": [
        "exclude path"
      ],
      "impressions_28d": 2,
      "impressions_prev_28d": 2,
      "include_paths": [
        "include path"
      ],
      "inspect_pages": 2,
      "last_scan_at": "2026-11-10T09:30:00.000Z",
      "last_scan_id": "last scan id",
      "max_pages": 10,
      "name": "Support triage",
      "next_scan_at": "2026-11-10T09:30:00.000Z",
      "next_sync_at": "2026-11-10T09:30:00.000Z",
      "notices": 2,
      "pages_count": 2,
      "position_28d": 0.5,
      "previous_score": 2,
      "rank_connection_id": "rank connection id",
      "rank_country": "rank country",
      "rank_depth": 2,
      "rank_language": "rank language",
      "ranks_checked_at": "2026-11-10T09:30:00.000Z",
      "respect_robots": true,
      "row_version": 4,
      "schedule": "manual",
      "score": 2,
      "search_connection_id": "search connection id",
      "search_error": null,
      "search_property": "search property",
      "search_synced_at": "2026-11-10T09:30:00.000Z",
      "sitemap_urls": [
        "https://example.com"
      ],
      "state": "active",
      "track_every": "daily",
      "updated_at": "2026-11-10T09:30:00.000Z",
      "updated_by": {
        "kind": "user",
        "id": "usr_01jcf1j9wjxfrnhqda3mq7ejxn",
        "name": "Ada Lovelace",
        "email": "ada@example.com"
      },
      "url": "https://mcp.example.com/mcp",
      "vitals_pages": 2,
      "vitals_strategy": "mobile",
      "warnings": 2,
      "workspace_id": "ws_01jccj30nr8ad7mx1yc5v9zx3h"
    }
  ],
  "has_more": false,
  "next_cursor": null,
  "total_count": 1
}
post/v1/seo/sites

Create seo site

Needs seo.manage

Watch a site. Its first scan starts at once unless scan_now is false, and a Search Console sync starts when a property is given. At most limits.seo_sites (10) per organization.

Request bodySeoSiteCreate

  • urlstringRequired
    at least 3 charactersat most 2048 characters
  • workspace_idstringRequired
  • alert_clicks_drop_pctinteger or null
    at least 0at most 100
  • alert_new_errorsboolean or null
  • alert_score_dropinteger or null
    at least 0at most 100
  • answers_connection_idstring or null
  • brand_termsstring[] or null
    at most 10 items
  • check_externalboolean or null
  • exclude_pathsstring[] or null
    at most 50 items
  • include_pathsstring[] or null
    at most 50 items
  • inspect_pagesinteger or null
    at least 0at most 100
  • max_pagesinteger or null
    at least 1at most 10000
  • namestring or null
    at most 200 characters
  • rank_connection_idstring or null
  • rank_countrystring or null
    matches ^([a-z]{2})?$
  • rank_depthinteger or null
    One of10203050100
  • rank_languagestring or null
    matches ^([a-z]{2,3}(-[a-z0-9]{2,4})?)?$
  • respect_robotsboolean or null
  • scan_nowboolean
    Defaulttrue
  • schedulestring or null
    One ofmanualdailyweekly
  • search_connection_idstring or null
  • search_propertystring or null
    at most 500 characters
  • sitemap_urlsstring[] or null
    at most 20 items
  • statestring or null
    One ofactivepaused
  • track_everystring or null
    One ofdailyweekly
  • vitals_pagesinteger or null
    at least 0at most 50
  • vitals_strategystring or null
    One ofmobiledesktop

Response201

  • idstring
  • objectstring
    seo_site
  • active_scan_idstring or null
  • alert_clicks_drop_pctinteger
  • alert_new_errorsboolean
  • alert_score_dropinteger
  • answers_connection_idstring or null
  • brand_termsstring[]
  • check_externalboolean
  • clicks_28dinteger or null
  • clicks_prev_28dinteger or null
  • created_atstring or null
  • ctr_28dnumber or null
  • errorsinteger
  • exclude_pathsstring[]
  • impressions_28dinteger or null
  • impressions_prev_28dinteger or null
  • include_pathsstring[]
  • inspect_pagesinteger
  • last_scan_atstring or null
  • last_scan_idstring or null
  • max_pagesinteger
  • namestring
  • next_scan_atstring or null
  • next_sync_atstring or null
  • noticesinteger
  • pages_countinteger
  • position_28dnumber or null
  • previous_scoreinteger or null
  • rank_connection_idstring or null
  • rank_countrystring or null
  • rank_depthinteger
  • rank_languagestring or null
  • ranks_checked_atstring or null
  • respect_robotsboolean
  • row_versioninteger
  • schedulestring
    One ofmanualdailyweekly
  • scoreinteger or null
  • search_connection_idstring or null
  • search_errorstring or null
  • search_propertystring or null
  • search_synced_atstring or null
  • sitemap_urlsstring[]
  • statestring
    One ofactivepaused
  • track_everystring
    One ofdailyweekly
  • updated_atstring or null
  • urlstring
  • vitals_pagesinteger
  • vitals_strategystring
    One ofmobiledesktop
  • warningsinteger
  • workspace_idstring
  • created_byActorRef or null

    Who created or last changed something, resolved to a name for display. system, workload (an automation) and end_user (a widget visitor) have no ID or name: the console words them. name is null for someone the directory no longer knows. id is what the lists' created_by/updated_by filters take. avatar_version is set for a person with a photo: it is at GET /v1/members/{id}/avatar?v=<avatar_version> while they are a member.

    5 fields
    • idstring or null
    • kindstring
      One ofuserapi_keyservice_accountworkloadend_usersystem
    • namestring or null
    • avatar_versionstring or null
    • emailstring or null
  • updated_byActorRef or null

    Who created or last changed something, resolved to a name for display. system, workload (an automation) and end_user (a widget visitor) have no ID or name: the console words them. name is null for someone the directory no longer knows. id is what the lists' created_by/updated_by filters take. avatar_version is set for a person with a photo: it is at GET /v1/members/{id}/avatar?v=<avatar_version> while they are a member.

    5 fields
    • idstring or null
    • kindstring
      One ofuserapi_keyservice_accountworkloadend_usersystem
    • namestring or null
    • avatar_versionstring or null
    • emailstring or null

Status codes

  • 201Successful Response
  • 422The request is not valid: errors[] names each field.
  • 4XXThe request was refused: the problem says why.
  • 5XXThe API could not answer: the problem says why.
Request
curl -X POST "https://api.mydeepagents.com/v1/seo/sites" \
  -H "Authorization: Bearer $MDA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://mcp.example.com/mcp",
    "workspace_id": "ws_01jccj30nr8ad7mx1yc5v9zx3h"
  }'
Response · 201
JSON
{
  "id": "id",
  "object": "seo_site",
  "active_scan_id": "active scan id",
  "alert_clicks_drop_pct": 2,
  "alert_new_errors": true,
  "alert_score_drop": 2,
  "answers_connection_id": "answers connection id",
  "brand_terms": [
    "brand term"
  ],
  "check_external": true,
  "clicks_28d": 2,
  "clicks_prev_28d": 2,
  "created_at": "2026-11-10T09:30:00.000Z",
  "created_by": {
    "kind": "user",
    "id": "usr_01jcf1j9wjxfrnhqda3mq7ejxn",
    "name": "Ada Lovelace",
    "email": "ada@example.com"
  },
  "ctr_28d": 0.5,
  "errors": 2,
  "exclude_paths": [
    "exclude path"
  ],
  "impressions_28d": 2,
  "impressions_prev_28d": 2,
  "include_paths": [
    "include path"
  ],
  "inspect_pages": 2,
  "last_scan_at": "2026-11-10T09:30:00.000Z",
  "last_scan_id": "last scan id",
  "max_pages": 10,
  "name": "Support triage",
  "next_scan_at": "2026-11-10T09:30:00.000Z",
  "next_sync_at": "2026-11-10T09:30:00.000Z",
  "notices": 2,
  "pages_count": 2,
  "position_28d": 0.5,
  "previous_score": 2,
  "rank_connection_id": "rank connection id",
  "rank_country": "rank country",
  "rank_depth": 2,
  "rank_language": "rank language",
  "ranks_checked_at": "2026-11-10T09:30:00.000Z",
  "respect_robots": true,
  "row_version": 4,
  "schedule": "manual",
  "score": 2,
  "search_connection_id": "search connection id",
  "search_error": null,
  "search_property": "search property",
  "search_synced_at": "2026-11-10T09:30:00.000Z",
  "sitemap_urls": [
    "https://example.com"
  ],
  "state": "active",
  "track_every": "daily",
  "updated_at": "2026-11-10T09:30:00.000Z",
  "updated_by": {
    "kind": "user",
    "id": "usr_01jcf1j9wjxfrnhqda3mq7ejxn",
    "name": "Ada Lovelace",
    "email": "ada@example.com"
  },
  "url": "https://mcp.example.com/mcp",
  "vitals_pages": 2,
  "vitals_strategy": "mobile",
  "warnings": 2,
  "workspace_id": "ws_01jccj30nr8ad7mx1yc5v9zx3h"
}
get/v1/seo/keywords/{keyword_id}

Get seo keyword

Needs seo.view

One tracked keyword: its Search Console numbers, its last Google check (the site's place and the top 10 results), its last AI answer (the answer, its sources, whether the site was cited and the brand named), and the history of both.

Path parameters

  • keyword_idstringRequired

Response200

  • idstring
  • objectstring
    seo_keyword
  • ai_checked_atstring or null
  • ai_citedboolean or null
  • ai_cited_rankinteger or null
  • ai_enginestring or null
    One ofexatavily
  • ai_mentionedboolean or null
  • answerSeoRankCheck or null

    One check. Google: position of the site, results the top 10 (position, title, url). AI answer: cited, position among the sources, mentioned, the answer and its results (sources).

    9 fields
    • answerstring or null
    • checked_atstring or null
    • citedboolean or null
    • errorstring or null
    • mentionedboolean or null
    • positioninteger or null
    • resultsobject[]
    • sourcestring
      One ofgoogleexatavily
    • urlstring or null
  • clicks_28dinteger or null
  • created_atstring or null
  • googleSeoRankCheck or null

    One check. Google: position of the site, results the top 10 (position, title, url). AI answer: cited, position among the sources, mentioned, the answer and its results (sources).

    9 fields
    • answerstring or null
    • checked_atstring or null
    • citedboolean or null
    • errorstring or null
    • mentionedboolean or null
    • positioninteger or null
    • resultsobject[]
    • sourcestring
      One ofgoogleexatavily
    • urlstring or null
  • google_checked_atstring or null
  • google_rankinteger or null
  • google_rank_previnteger or null
  • google_urlstring or null
  • historySeoRankPoint[]
    5 fields
    • checked_atstring or null
    • citedboolean or null
    • mentionedboolean or null
    • positioninteger or null
    • sourcestring
      One ofgoogleexatavily
  • impressions_28dinteger or null
  • keywordstring
  • positionnumber or null
  • position_prevnumber or null
  • site_idstring
  • synced_atstring or null
  • dailySeoKeywordDay[] or null
    4 fields
    • clicksinteger
    • datestring
    • impressionsinteger
    • positionnumber or null

Status codes

  • 200Successful Response
  • 422The request is not valid: errors[] names each field.
  • 4XXThe request was refused: the problem says why.
  • 5XXThe API could not answer: the problem says why.
Request
curl "https://api.mydeepagents.com/v1/seo/keywords/{keyword_id}" \
  -H "Authorization: Bearer $MDA_API_KEY"
Response · 200
JSON
{
  "id": "id",
  "object": "seo_keyword",
  "ai_checked_at": "2026-11-10T09:30:00.000Z",
  "ai_cited": true,
  "ai_cited_rank": 2,
  "ai_engine": "exa",
  "ai_mentioned": true,
  "answer": {
    "answer": "answer",
    "checked_at": "2026-11-10T09:30:00.000Z",
    "cited": true,
    "error": null,
    "mentioned": true,
    "position": 2,
    "results": [
      {}
    ],
    "source": "google",
    "url": "https://mcp.example.com/mcp"
  },
  "clicks_28d": 2,
  "created_at": "2026-11-10T09:30:00.000Z",
  "daily": [
    {
      "clicks": 2,
      "date": "date",
      "impressions": 2,
      "position": 0.5
    }
  ],
  "google": {
    "answer": "answer",
    "checked_at": "2026-11-10T09:30:00.000Z",
    "cited": true,
    "error": null,
    "mentioned": true,
    "position": 2,
    "results": [
      {}
    ],
    "source": "google",
    "url": "https://mcp.example.com/mcp"
  },
  "google_checked_at": "2026-11-10T09:30:00.000Z",
  "google_rank": 2,
  "google_rank_prev": 2,
  "google_url": "https://example.com",
  "history": [
    {
      "checked_at": "2026-11-10T09:30:00.000Z",
      "cited": true,
      "mentioned": true,
      "position": 2,
      "source": "google"
    }
  ],
  "impressions_28d": 2,
  "keyword": "keyword",
  "position": 0.5,
  "position_prev": 0.5,
  "site_id": "site id",
  "synced_at": "2026-11-10T09:30:00.000Z"
}
delete/v1/seo/keywords/{keyword_id}

Delete seo keyword

Needs seo.manage

Path parameters

  • keyword_idstringRequired

Response204

Answers 204 with no body.

Status codes

  • 204Successful Response
  • 422The request is not valid: errors[] names each field.
  • 4XXThe request was refused: the problem says why.
  • 5XXThe API could not answer: the problem says why.
Request
curl -X DELETE "https://api.mydeepagents.com/v1/seo/keywords/{keyword_id}" \
  -H "Authorization: Bearer $MDA_API_KEY"
get/v1/seo/pages/{page_id}

Get seo page

Needs seo.view

Path parameters

  • page_idstringRequired

Response200

  • idstring
  • objectstring
    seo_page
  • clicks_28dinteger or null
  • depthinteger or null
  • errorsinteger
  • first_seen_atstring or null
  • goneboolean
  • googleobject or null

    Any JSON object.

  • historySeoPageHistoryPoint[]
    6 fields
    • atstring or null
    • issuesinteger
    • response_msinteger or null
    • scan_idstring
    • scoreinteger or null
    • statusinteger or null
  • impressions_28dinteger or null
  • in_sitemapboolean or null
  • indexableboolean or null
  • inspected_atstring or null
  • last_scan_idstring or null
  • last_seen_atstring or null
  • linked_fromSeoIssueExample[]
    2 fields
    • page_idstring
    • urlstring
  • noticesinteger
  • position_28dnumber or null
  • response_msinteger or null
  • resultSeoPageResult or null
    23 fields
    • bytesinteger or null
    • canonicalstring or null
    • content_typestring or null
    • depthinteger or null
    • descriptionstring or null
    • encodingstring or null
    • errorstring or null
    • externalstring[]
    • factsobject

      Any JSON object.

    • final_urlstring or null
    • in_sitemapboolean
    • indexableboolean
    • issuesSeoPageIssue[]
      7 fields
      • categorystring
      • fixstring
      • rulestring
      • severitystring
        One oferrorwarningnotice
      • titlestring
      • whystring
      • detailobject or null

        Any JSON object.

    • linksstring[]
    • noindexboolean
    • redirectsobject[]
    • response_msinteger or null
    • scan_idstring
    • scoreinteger or null
    • statusinteger or null
    • titlestring or null
    • urlstring
    • vitalsobject or null

      Any JSON object.

  • scoreinteger or null
  • site_idstring
  • statusinteger or null
  • titlestring or null
  • urlstring
  • warningsinteger

Status codes

  • 200Successful Response
  • 422The request is not valid: errors[] names each field.
  • 4XXThe request was refused: the problem says why.
  • 5XXThe API could not answer: the problem says why.
Request
curl "https://api.mydeepagents.com/v1/seo/pages/{page_id}" \
  -H "Authorization: Bearer $MDA_API_KEY"
Response · 200
JSON
{
  "id": "id",
  "object": "seo_page",
  "clicks_28d": 2,
  "depth": 2,
  "errors": 2,
  "first_seen_at": "2026-11-10T09:30:00.000Z",
  "gone": true,
  "google": {},
  "history": [
    {
      "at": "at",
      "issues": 2,
      "response_ms": 840,
      "scan_id": "scan id",
      "score": 2,
      "status": 2
    }
  ],
  "impressions_28d": 2,
  "in_sitemap": true,
  "indexable": true,
  "inspected_at": "2026-11-10T09:30:00.000Z",
  "last_scan_id": "last scan id",
  "last_seen_at": "2026-11-10T09:30:00.000Z",
  "linked_from": [
    {
      "page_id": "page id",
      "url": "https://mcp.example.com/mcp"
    }
  ],
  "notices": 2,
  "position_28d": 0.5,
  "response_ms": 840,
  "result": {
    "bytes": 2,
    "canonical": "canonical",
    "content_type": "content type",
    "depth": 2,
    "description": "Reads new support email and drafts a reply.",
    "encoding": "encoding",
    "error": null,
    "external": [
      "external"
    ],
    "facts": {},
    "final_url": "https://example.com",
    "in_sitemap": true,
    "indexable": true,
    "issues": [
      {
        "category": "category",
        "detail": {},
        "fix": "fix",
        "rule": "rule",
        "severity": "error",
        "title": "Support triage",
        "why": "why"
      }
    ],
    "links": [
      "link"
    ],
    "noindex": true,
    "redirects": [
      {}
    ],
    "response_ms": 840,
    "scan_id": "scan id",
    "score": 2,
    "status": 2,
    "title": "Support triage",
    "url": "https://mcp.example.com/mcp",
    "vitals": {}
  },
  "score": 2,
  "site_id": "site id",
  "status": 2,
  "title": "Support triage",
  "url": "https://mcp.example.com/mcp",
  "warnings": 2
}
get/v1/seo/scans/{scan_id}

Get seo scan

Needs seo.view

One scan with its summary, its site-wide findings and checks (robots.txt, sitemaps, redirects, Core Web Vitals), and the settings it ran with.

Path parameters

  • scan_idstringRequired

Response200

  • idstring
  • objectstring
    seo_scan
  • cancel_requestedboolean
  • created_atstring or null
  • error_codestring or null
  • error_messagestring or null
  • errorsinteger
  • finished_atstring or null
  • fixed_issuesinteger or null
  • new_issuesinteger or null
  • noticesinteger
  • pages_crawledinteger
  • pages_failedinteger
  • pages_foundinteger
  • phasestring or null
    One ofdiscoveringcrawlinglinksvitalsfinishing
  • scoreinteger or null
  • site_idstring
  • started_atstring or null
  • statestring
    One ofqueuedrunningsucceededfailedcancelled
  • triggerstring
    One ofmanualscheduleapi
  • warningsinteger
  • workspace_idstring
  • checksobject or null

    Any JSON object.

  • settingsobject or null

    Any JSON object.

  • site_issuesSeoFinding[] or null
    3 fields
    • rulestring
    • severitystring
      One oferrorwarningnotice
    • detailobject or null

      Any JSON object.

  • summaryobject or null

    Any JSON object.

Status codes

  • 200Successful Response
  • 422The request is not valid: errors[] names each field.
  • 4XXThe request was refused: the problem says why.
  • 5XXThe API could not answer: the problem says why.
Request
curl "https://api.mydeepagents.com/v1/seo/scans/{scan_id}" \
  -H "Authorization: Bearer $MDA_API_KEY"
Response · 200
JSON
{
  "id": "id",
  "object": "seo_scan",
  "cancel_requested": true,
  "checks": {},
  "created_at": "2026-11-10T09:30:00.000Z",
  "error_code": null,
  "error_message": "error message",
  "errors": 2,
  "finished_at": "2026-11-10T09:30:00.000Z",
  "fixed_issues": 2,
  "new_issues": 2,
  "notices": 2,
  "pages_crawled": 2,
  "pages_failed": 2,
  "pages_found": 2,
  "phase": "discovering",
  "score": 2,
  "settings": {},
  "site_id": "site id",
  "site_issues": [
    {
      "detail": {},
      "rule": "rule",
      "severity": "error"
    }
  ],
  "started_at": "2026-11-10T09:30:00.000Z",
  "state": "queued",
  "summary": {},
  "trigger": "api",
  "warnings": 2,
  "workspace_id": "ws_01jccj30nr8ad7mx1yc5v9zx3h"
}
post/v1/seo/scans/{scan_id}/cancel

Cancel seo scan

Needs seo.manage

Stop the scan at its next batch of pages. A finished scan is answered as it is.

Path parameters

  • scan_idstringRequired

Response200

  • idstring
  • objectstring
    seo_scan
  • cancel_requestedboolean
  • created_atstring or null
  • error_codestring or null
  • error_messagestring or null
  • errorsinteger
  • finished_atstring or null
  • fixed_issuesinteger or null
  • new_issuesinteger or null
  • noticesinteger
  • pages_crawledinteger
  • pages_failedinteger
  • pages_foundinteger
  • phasestring or null
    One ofdiscoveringcrawlinglinksvitalsfinishing
  • scoreinteger or null
  • site_idstring
  • started_atstring or null
  • statestring
    One ofqueuedrunningsucceededfailedcancelled
  • triggerstring
    One ofmanualscheduleapi
  • warningsinteger
  • workspace_idstring
  • checksobject or null

    Any JSON object.

  • settingsobject or null

    Any JSON object.

  • site_issuesSeoFinding[] or null
    3 fields
    • rulestring
    • severitystring
      One oferrorwarningnotice
    • detailobject or null

      Any JSON object.

  • summaryobject or null

    Any JSON object.

Status codes

  • 200Successful Response
  • 422The request is not valid: errors[] names each field.
  • 4XXThe request was refused: the problem says why.
  • 5XXThe API could not answer: the problem says why.
Request
curl -X POST "https://api.mydeepagents.com/v1/seo/scans/{scan_id}/cancel" \
  -H "Authorization: Bearer $MDA_API_KEY"
Response · 200
JSON
{
  "id": "id",
  "object": "seo_scan",
  "cancel_requested": true,
  "checks": {},
  "created_at": "2026-11-10T09:30:00.000Z",
  "error_code": null,
  "error_message": "error message",
  "errors": 2,
  "finished_at": "2026-11-10T09:30:00.000Z",
  "fixed_issues": 2,
  "new_issues": 2,
  "notices": 2,
  "pages_crawled": 2,
  "pages_failed": 2,
  "pages_found": 2,
  "phase": "discovering",
  "score": 2,
  "settings": {},
  "site_id": "site id",
  "site_issues": [
    {
      "detail": {},
      "rule": "rule",
      "severity": "error"
    }
  ],
  "started_at": "2026-11-10T09:30:00.000Z",
  "state": "queued",
  "summary": {},
  "trigger": "api",
  "warnings": 2,
  "workspace_id": "ws_01jccj30nr8ad7mx1yc5v9zx3h"
}
get/v1/seo/sites/{site_id}

Get seo site

Needs seo.view

Path parameters

  • site_idstringRequired

Response200

  • idstring
  • objectstring
    seo_site
  • active_scan_idstring or null
  • alert_clicks_drop_pctinteger
  • alert_new_errorsboolean
  • alert_score_dropinteger
  • answers_connection_idstring or null
  • brand_termsstring[]
  • check_externalboolean
  • clicks_28dinteger or null
  • clicks_prev_28dinteger or null
  • created_atstring or null
  • ctr_28dnumber or null
  • errorsinteger
  • exclude_pathsstring[]
  • impressions_28dinteger or null
  • impressions_prev_28dinteger or null
  • include_pathsstring[]
  • inspect_pagesinteger
  • last_scan_atstring or null
  • last_scan_idstring or null
  • max_pagesinteger
  • namestring
  • next_scan_atstring or null
  • next_sync_atstring or null
  • noticesinteger
  • pages_countinteger
  • position_28dnumber or null
  • previous_scoreinteger or null
  • rank_connection_idstring or null
  • rank_countrystring or null
  • rank_depthinteger
  • rank_languagestring or null
  • ranks_checked_atstring or null
  • respect_robotsboolean
  • row_versioninteger
  • schedulestring
    One ofmanualdailyweekly
  • scoreinteger or null
  • search_connection_idstring or null
  • search_errorstring or null
  • search_propertystring or null
  • search_synced_atstring or null
  • sitemap_urlsstring[]
  • statestring
    One ofactivepaused
  • track_everystring
    One ofdailyweekly
  • updated_atstring or null
  • urlstring
  • vitals_pagesinteger
  • vitals_strategystring
    One ofmobiledesktop
  • warningsinteger
  • workspace_idstring
  • created_byActorRef or null

    Who created or last changed something, resolved to a name for display. system, workload (an automation) and end_user (a widget visitor) have no ID or name: the console words them. name is null for someone the directory no longer knows. id is what the lists' created_by/updated_by filters take. avatar_version is set for a person with a photo: it is at GET /v1/members/{id}/avatar?v=<avatar_version> while they are a member.

    5 fields
    • idstring or null
    • kindstring
      One ofuserapi_keyservice_accountworkloadend_usersystem
    • namestring or null
    • avatar_versionstring or null
    • emailstring or null
  • updated_byActorRef or null

    Who created or last changed something, resolved to a name for display. system, workload (an automation) and end_user (a widget visitor) have no ID or name: the console words them. name is null for someone the directory no longer knows. id is what the lists' created_by/updated_by filters take. avatar_version is set for a person with a photo: it is at GET /v1/members/{id}/avatar?v=<avatar_version> while they are a member.

    5 fields
    • idstring or null
    • kindstring
      One ofuserapi_keyservice_accountworkloadend_usersystem
    • namestring or null
    • avatar_versionstring or null
    • emailstring or null

Status codes

  • 200Successful Response
  • 422The request is not valid: errors[] names each field.
  • 4XXThe request was refused: the problem says why.
  • 5XXThe API could not answer: the problem says why.
Request
curl "https://api.mydeepagents.com/v1/seo/sites/{site_id}" \
  -H "Authorization: Bearer $MDA_API_KEY"
Response · 200
JSON
{
  "id": "id",
  "object": "seo_site",
  "active_scan_id": "active scan id",
  "alert_clicks_drop_pct": 2,
  "alert_new_errors": true,
  "alert_score_drop": 2,
  "answers_connection_id": "answers connection id",
  "brand_terms": [
    "brand term"
  ],
  "check_external": true,
  "clicks_28d": 2,
  "clicks_prev_28d": 2,
  "created_at": "2026-11-10T09:30:00.000Z",
  "created_by": {
    "kind": "user",
    "id": "usr_01jcf1j9wjxfrnhqda3mq7ejxn",
    "name": "Ada Lovelace",
    "email": "ada@example.com"
  },
  "ctr_28d": 0.5,
  "errors": 2,
  "exclude_paths": [
    "exclude path"
  ],
  "impressions_28d": 2,
  "impressions_prev_28d": 2,
  "include_paths": [
    "include path"
  ],
  "inspect_pages": 2,
  "last_scan_at": "2026-11-10T09:30:00.000Z",
  "last_scan_id": "last scan id",
  "max_pages": 10,
  "name": "Support triage",
  "next_scan_at": "2026-11-10T09:30:00.000Z",
  "next_sync_at": "2026-11-10T09:30:00.000Z",
  "notices": 2,
  "pages_count": 2,
  "position_28d": 0.5,
  "previous_score": 2,
  "rank_connection_id": "rank connection id",
  "rank_country": "rank country",
  "rank_depth": 2,
  "rank_language": "rank language",
  "ranks_checked_at": "2026-11-10T09:30:00.000Z",
  "respect_robots": true,
  "row_version": 4,
  "schedule": "manual",
  "score": 2,
  "search_connection_id": "search connection id",
  "search_error": null,
  "search_property": "search property",
  "search_synced_at": "2026-11-10T09:30:00.000Z",
  "sitemap_urls": [
    "https://example.com"
  ],
  "state": "active",
  "track_every": "daily",
  "updated_at": "2026-11-10T09:30:00.000Z",
  "updated_by": {
    "kind": "user",
    "id": "usr_01jcf1j9wjxfrnhqda3mq7ejxn",
    "name": "Ada Lovelace",
    "email": "ada@example.com"
  },
  "url": "https://mcp.example.com/mcp",
  "vitals_pages": 2,
  "vitals_strategy": "mobile",
  "warnings": 2,
  "workspace_id": "ws_01jccj30nr8ad7mx1yc5v9zx3h"
}
patch/v1/seo/sites/{site_id}

Update seo site

Needs seo.manage

Change any setting. Tying the site to a (different) Search Console property starts a sync.

Path parameters

  • site_idstringRequired

Request bodySeoSitePatch

  • alert_clicks_drop_pctinteger or null
    at least 0at most 100
  • alert_new_errorsboolean or null
  • alert_score_dropinteger or null
    at least 0at most 100
  • answers_connection_idstring or null
  • brand_termsstring[] or null
    at most 10 items
  • check_externalboolean or null
  • clear_answersboolean
    Defaultfalse
  • clear_rankboolean
    Defaultfalse
  • clear_searchboolean
    Defaultfalse
  • exclude_pathsstring[] or null
    at most 50 items
  • include_pathsstring[] or null
    at most 50 items
  • inspect_pagesinteger or null
    at least 0at most 100
  • max_pagesinteger or null
    at least 1at most 10000
  • namestring or null
    at most 200 characters
  • rank_connection_idstring or null
  • rank_countrystring or null
    matches ^([a-z]{2})?$
  • rank_depthinteger or null
    One of10203050100
  • rank_languagestring or null
    matches ^([a-z]{2,3}(-[a-z0-9]{2,4})?)?$
  • respect_robotsboolean or null
  • row_versioninteger or null
  • schedulestring or null
    One ofmanualdailyweekly
  • search_connection_idstring or null
  • search_propertystring or null
    at most 500 characters
  • sitemap_urlsstring[] or null
    at most 20 items
  • statestring or null
    One ofactivepaused
  • track_everystring or null
    One ofdailyweekly
  • urlstring or null
    at least 3 charactersat most 2048 characters
  • vitals_pagesinteger or null
    at least 0at most 50
  • vitals_strategystring or null
    One ofmobiledesktop

Response200

  • idstring
  • objectstring
    seo_site
  • active_scan_idstring or null
  • alert_clicks_drop_pctinteger
  • alert_new_errorsboolean
  • alert_score_dropinteger
  • answers_connection_idstring or null
  • brand_termsstring[]
  • check_externalboolean
  • clicks_28dinteger or null
  • clicks_prev_28dinteger or null
  • created_atstring or null
  • ctr_28dnumber or null
  • errorsinteger
  • exclude_pathsstring[]
  • impressions_28dinteger or null
  • impressions_prev_28dinteger or null
  • include_pathsstring[]
  • inspect_pagesinteger
  • last_scan_atstring or null
  • last_scan_idstring or null
  • max_pagesinteger
  • namestring
  • next_scan_atstring or null
  • next_sync_atstring or null
  • noticesinteger
  • pages_countinteger
  • position_28dnumber or null
  • previous_scoreinteger or null
  • rank_connection_idstring or null
  • rank_countrystring or null
  • rank_depthinteger
  • rank_languagestring or null
  • ranks_checked_atstring or null
  • respect_robotsboolean
  • row_versioninteger
  • schedulestring
    One ofmanualdailyweekly
  • scoreinteger or null
  • search_connection_idstring or null
  • search_errorstring or null
  • search_propertystring or null
  • search_synced_atstring or null
  • sitemap_urlsstring[]
  • statestring
    One ofactivepaused
  • track_everystring
    One ofdailyweekly
  • updated_atstring or null
  • urlstring
  • vitals_pagesinteger
  • vitals_strategystring
    One ofmobiledesktop
  • warningsinteger
  • workspace_idstring
  • created_byActorRef or null

    Who created or last changed something, resolved to a name for display. system, workload (an automation) and end_user (a widget visitor) have no ID or name: the console words them. name is null for someone the directory no longer knows. id is what the lists' created_by/updated_by filters take. avatar_version is set for a person with a photo: it is at GET /v1/members/{id}/avatar?v=<avatar_version> while they are a member.

    5 fields
    • idstring or null
    • kindstring
      One ofuserapi_keyservice_accountworkloadend_usersystem
    • namestring or null
    • avatar_versionstring or null
    • emailstring or null
  • updated_byActorRef or null

    Who created or last changed something, resolved to a name for display. system, workload (an automation) and end_user (a widget visitor) have no ID or name: the console words them. name is null for someone the directory no longer knows. id is what the lists' created_by/updated_by filters take. avatar_version is set for a person with a photo: it is at GET /v1/members/{id}/avatar?v=<avatar_version> while they are a member.

    5 fields
    • idstring or null
    • kindstring
      One ofuserapi_keyservice_accountworkloadend_usersystem
    • namestring or null
    • avatar_versionstring or null
    • emailstring or null

Status codes

  • 200Successful Response
  • 422The request is not valid: errors[] names each field.
  • 4XXThe request was refused: the problem says why.
  • 5XXThe API could not answer: the problem says why.
Request
curl -X PATCH "https://api.mydeepagents.com/v1/seo/sites/{site_id}" \
  -H "Authorization: Bearer $MDA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
Response · 200
JSON
{
  "id": "id",
  "object": "seo_site",
  "active_scan_id": "active scan id",
  "alert_clicks_drop_pct": 2,
  "alert_new_errors": true,
  "alert_score_drop": 2,
  "answers_connection_id": "answers connection id",
  "brand_terms": [
    "brand term"
  ],
  "check_external": true,
  "clicks_28d": 2,
  "clicks_prev_28d": 2,
  "created_at": "2026-11-10T09:30:00.000Z",
  "created_by": {
    "kind": "user",
    "id": "usr_01jcf1j9wjxfrnhqda3mq7ejxn",
    "name": "Ada Lovelace",
    "email": "ada@example.com"
  },
  "ctr_28d": 0.5,
  "errors": 2,
  "exclude_paths": [
    "exclude path"
  ],
  "impressions_28d": 2,
  "impressions_prev_28d": 2,
  "include_paths": [
    "include path"
  ],
  "inspect_pages": 2,
  "last_scan_at": "2026-11-10T09:30:00.000Z",
  "last_scan_id": "last scan id",
  "max_pages": 10,
  "name": "Support triage",
  "next_scan_at": "2026-11-10T09:30:00.000Z",
  "next_sync_at": "2026-11-10T09:30:00.000Z",
  "notices": 2,
  "pages_count": 2,
  "position_28d": 0.5,
  "previous_score": 2,
  "rank_connection_id": "rank connection id",
  "rank_country": "rank country",
  "rank_depth": 2,
  "rank_language": "rank language",
  "ranks_checked_at": "2026-11-10T09:30:00.000Z",
  "respect_robots": true,
  "row_version": 4,
  "schedule": "manual",
  "score": 2,
  "search_connection_id": "search connection id",
  "search_error": null,
  "search_property": "search property",
  "search_synced_at": "2026-11-10T09:30:00.000Z",
  "sitemap_urls": [
    "https://example.com"
  ],
  "state": "active",
  "track_every": "daily",
  "updated_at": "2026-11-10T09:30:00.000Z",
  "updated_by": {
    "kind": "user",
    "id": "usr_01jcf1j9wjxfrnhqda3mq7ejxn",
    "name": "Ada Lovelace",
    "email": "ada@example.com"
  },
  "url": "https://mcp.example.com/mcp",
  "vitals_pages": 2,
  "vitals_strategy": "mobile",
  "warnings": 2,
  "workspace_id": "ws_01jccj30nr8ad7mx1yc5v9zx3h"
}
delete/v1/seo/sites/{site_id}

Delete seo site

Needs seo.manage

Stop watching the site. A scan in progress stops at its next batch; its pages, results and search numbers are removed 30 days later.

Path parameters

  • site_idstringRequired

Response204

Answers 204 with no body.

Status codes

  • 204Successful Response
  • 422The request is not valid: errors[] names each field.
  • 4XXThe request was refused: the problem says why.
  • 5XXThe API could not answer: the problem says why.
Request
curl -X DELETE "https://api.mydeepagents.com/v1/seo/sites/{site_id}" \
  -H "Authorization: Bearer $MDA_API_KEY"
get/v1/seo/sites/{site_id}/history

Seo score history

Needs seo.view

The score and counts after each finished scan, oldest first.

Path parameters

  • site_idstringRequired

Query parameters

  • limitinteger
    Default60at least 1at most 200

Response200

  • objectstring
    seo_score_history
  • dataSeoScorePoint[]
    7 fields
    • atstring or null
    • errorsinteger
    • noticesinteger
    • pagesinteger
    • scan_idstring
    • scoreinteger or null
    • warningsinteger

Status codes

  • 200Successful Response
  • 422The request is not valid: errors[] names each field.
  • 4XXThe request was refused: the problem says why.
  • 5XXThe API could not answer: the problem says why.
Request
curl "https://api.mydeepagents.com/v1/seo/sites/{site_id}/history?limit=20" \
  -H "Authorization: Bearer $MDA_API_KEY"
Response · 200
JSON
{
  "object": "seo_score_history",
  "data": [
    {
      "at": "at",
      "errors": 2,
      "notices": 2,
      "pages": 2,
      "scan_id": "scan id",
      "score": 2,
      "warnings": 2
    }
  ]
}
get/v1/seo/sites/{site_id}/issues

List seo issues

Needs seo.view

What a scan found (the latest finished one unless scan_id names another), one entry per rule: errors first, then by how many pages it hit. new_pages counts the pages that didn't have it in the scan before.

Path parameters

  • site_idstringRequired

Query parameters

  • scan_idstring

Response200

  • objectstring
    seo_issue_list
  • dataSeoIssue[]
    11 fields
    • idstring
    • categorystring
      One ofcrawlindexingcontentlinkssocialstructured_dataperformancesecuritymobileai_search
    • examplesSeoIssueExample[]
      2 fields
      • page_idstring
      • urlstring
    • fixstring
    • new_pagesinteger or null
    • pagesinteger
    • scopestring
      One ofpagesite
    • severitystring
      One oferrorwarningnotice
    • titlestring
    • whystring
    • detailobject or null

      Any JSON object.

  • scan_idstring or null

Status codes

  • 200Successful Response
  • 422The request is not valid: errors[] names each field.
  • 4XXThe request was refused: the problem says why.
  • 5XXThe API could not answer: the problem says why.
Request
curl "https://api.mydeepagents.com/v1/seo/sites/{site_id}/issues" \
  -H "Authorization: Bearer $MDA_API_KEY"
Response · 200
JSON
{
  "object": "seo_issue_list",
  "data": [
    {
      "id": "id",
      "category": "crawl",
      "detail": {},
      "examples": [
        {
          "page_id": "page id",
          "url": "https://mcp.example.com/mcp"
        }
      ],
      "fix": "fix",
      "new_pages": 2,
      "pages": 2,
      "scope": "page",
      "severity": "error",
      "title": "Support triage",
      "why": "why"
    }
  ],
  "scan_id": "scan id"
}
get/v1/seo/sites/{site_id}/keywords

List seo keywords

Needs seo.view

Tracked keywords, A to Z, each with its last 90 days.

Path parameters

  • site_idstringRequired

Response200

  • objectstring
    list
  • dataSeoKeyword[]
    20 fields
    • idstring
    • objectstring
      seo_keyword
    • ai_checked_atstring or null
    • ai_citedboolean or null
    • ai_cited_rankinteger or null
    • ai_enginestring or null
      One ofexatavily
    • ai_mentionedboolean or null
    • clicks_28dinteger or null
    • created_atstring or null
    • google_checked_atstring or null
    • google_rankinteger or null
    • google_rank_previnteger or null
    • google_urlstring or null
    • impressions_28dinteger or null
    • keywordstring
    • positionnumber or null
    • position_prevnumber or null
    • site_idstring
    • synced_atstring or null
    • dailySeoKeywordDay[] or null
      4 fields
      • clicksinteger
      • datestring
      • impressionsinteger
      • positionnumber or null
  • has_moreboolean
  • next_cursorstring or null

Status codes

  • 200Successful Response
  • 422The request is not valid: errors[] names each field.
  • 4XXThe request was refused: the problem says why.
  • 5XXThe API could not answer: the problem says why.
Request
curl "https://api.mydeepagents.com/v1/seo/sites/{site_id}/keywords" \
  -H "Authorization: Bearer $MDA_API_KEY"
Response · 200
JSON
{
  "object": "list",
  "data": [
    {
      "id": "id",
      "object": "seo_keyword",
      "ai_checked_at": "2026-11-10T09:30:00.000Z",
      "ai_cited": true,
      "ai_cited_rank": 2,
      "ai_engine": "exa",
      "ai_mentioned": true,
      "clicks_28d": 2,
      "created_at": "2026-11-10T09:30:00.000Z",
      "daily": [
        {
          "clicks": 2,
          "date": "date",
          "impressions": 2,
          "position": 0.5
        }
      ],
      "google_checked_at": "2026-11-10T09:30:00.000Z",
      "google_rank": 2,
      "google_rank_prev": 2,
      "google_url": "https://example.com",
      "impressions_28d": 2,
      "keyword": "keyword",
      "position": 0.5,
      "position_prev": 0.5,
      "site_id": "site id",
      "synced_at": "2026-11-10T09:30:00.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
post/v1/seo/sites/{site_id}/keywords

Add seo keywords

Needs seo.manage

Track search terms (case is ignored; a term already tracked is skipped). Their numbers arrive with the next Search Console sync. At most limits.seo_keywords (50) per site.

Path parameters

  • site_idstringRequired

Request bodySeoKeywordsAdd

  • keywordsstring[]Required
    at least 1 itemsat most 100 items

Response201

  • objectstring
    list
  • dataSeoKeyword[]
    20 fields
    • idstring
    • objectstring
      seo_keyword
    • ai_checked_atstring or null
    • ai_citedboolean or null
    • ai_cited_rankinteger or null
    • ai_enginestring or null
      One ofexatavily
    • ai_mentionedboolean or null
    • clicks_28dinteger or null
    • created_atstring or null
    • google_checked_atstring or null
    • google_rankinteger or null
    • google_rank_previnteger or null
    • google_urlstring or null
    • impressions_28dinteger or null
    • keywordstring
    • positionnumber or null
    • position_prevnumber or null
    • site_idstring
    • synced_atstring or null
    • dailySeoKeywordDay[] or null
      4 fields
      • clicksinteger
      • datestring
      • impressionsinteger
      • positionnumber or null
  • has_moreboolean
  • next_cursorstring or null

Status codes

  • 201Successful Response
  • 422The request is not valid: errors[] names each field.
  • 4XXThe request was refused: the problem says why.
  • 5XXThe API could not answer: the problem says why.
Request
curl -X POST "https://api.mydeepagents.com/v1/seo/sites/{site_id}/keywords" \
  -H "Authorization: Bearer $MDA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "keywords": [
      "keyword"
    ]
  }'
Response · 201
JSON
{
  "object": "list",
  "data": [
    {
      "id": "id",
      "object": "seo_keyword",
      "ai_checked_at": "2026-11-10T09:30:00.000Z",
      "ai_cited": true,
      "ai_cited_rank": 2,
      "ai_engine": "exa",
      "ai_mentioned": true,
      "clicks_28d": 2,
      "created_at": "2026-11-10T09:30:00.000Z",
      "daily": [
        {
          "clicks": 2,
          "date": "date",
          "impressions": 2,
          "position": 0.5
        }
      ],
      "google_checked_at": "2026-11-10T09:30:00.000Z",
      "google_rank": 2,
      "google_rank_prev": 2,
      "google_url": "https://example.com",
      "impressions_28d": 2,
      "keyword": "keyword",
      "position": 0.5,
      "position_prev": 0.5,
      "site_id": "site id",
      "synced_at": "2026-11-10T09:30:00.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
get/v1/seo/sites/{site_id}/pages

List seo pages

Needs seo.view

Worst score first by default; also url, status, response_ms, errors, clicks, last_seen_at. q searches addresses and titles. Filters: rule (pages the latest scan found it on), status_class (2xx, 3xx, 4xx, 5xx, failed), severity (worst finding: error, warning, notice, none), indexable, in_sitemap, gone (true/false).

Path parameters

  • site_idstringRequired

Query parameters

  • rulestring
  • status_classstring[]
  • severitystring[]
  • indexablestring[]
  • in_sitemapstring[]
  • gonestring[]
  • limitinteger

    Rows per page, 1 to 200.

    Default50at least 1at most 200
  • cursorstring
  • qstring

    Search: rows whose name (or the list's other searchable text) contains this, any case.

    at most 200 characters
  • orderstring

    Sort field; a leading - sorts down. Each list names the fields it sorts by.

    at most 64 charactersmatches ^-?[a-z_]+$
  • includestring[]

    total_count (counted up to 10,000) and facets (a count per filter value).

    One oftotal_countfacets
  • created_afterstring

    Only rows created at or after this time (RFC 3339).

    date-time
  • created_beforestring

    Only rows created at or before this time (RFC 3339).

    date-time
  • updated_afterstring

    Only rows last changed at or after this time (RFC 3339).

    date-time
  • updated_beforestring

    Only rows last changed at or before this time (RFC 3339).

    date-time

Response200

  • objectstring
    list
  • dataSeoPage[]
    23 fields
    • idstring
    • objectstring
      seo_page
    • clicks_28dinteger or null
    • depthinteger or null
    • errorsinteger
    • first_seen_atstring or null
    • goneboolean
    • googleobject or null

      Any JSON object.

    • impressions_28dinteger or null
    • in_sitemapboolean or null
    • indexableboolean or null
    • inspected_atstring or null
    • last_scan_idstring or null
    • last_seen_atstring or null
    • noticesinteger
    • position_28dnumber or null
    • response_msinteger or null
    • scoreinteger or null
    • site_idstring
    • statusinteger or null
    • titlestring or null
    • urlstring
    • warningsinteger
  • has_moreboolean
  • next_cursorstring or null
  • facetsmap<string, map<string, integer>> or null
  • peoplemap<string, ActorRef> or null
    5 fields
    • idstring or null
    • kindstring
      One ofuserapi_keyservice_accountworkloadend_usersystem
    • namestring or null
    • avatar_versionstring or null
    • emailstring or null
  • total_countinteger or null
  • total_count_exactboolean or null

Status codes

  • 200Successful Response
  • 422The request is not valid: errors[] names each field.
  • 4XXThe request was refused: the problem says why.
  • 5XXThe API could not answer: the problem says why.
Request
curl "https://api.mydeepagents.com/v1/seo/sites/{site_id}/pages?limit=20" \
  -H "Authorization: Bearer $MDA_API_KEY"
Response · 200
JSON
{
  "object": "list",
  "data": [
    {
      "id": "id",
      "object": "seo_page",
      "clicks_28d": 2,
      "depth": 2,
      "errors": 2,
      "first_seen_at": "2026-11-10T09:30:00.000Z",
      "gone": true,
      "google": {},
      "impressions_28d": 2,
      "in_sitemap": true,
      "indexable": true,
      "inspected_at": "2026-11-10T09:30:00.000Z",
      "last_scan_id": "last scan id",
      "last_seen_at": "2026-11-10T09:30:00.000Z",
      "notices": 2,
      "position_28d": 0.5,
      "response_ms": 840,
      "score": 2,
      "site_id": "site id",
      "status": 2,
      "title": "Support triage",
      "url": "https://mcp.example.com/mcp",
      "warnings": 2
    }
  ],
  "has_more": false,
  "next_cursor": null,
  "total_count": 1
}
get/v1/seo/sites/{site_id}/scans

List seo scans

Needs seo.view

Newest first. Filters: state, trigger (manual, schedule, api).

Path parameters

  • site_idstringRequired

Query parameters

  • statestring[]
  • triggerstring[]
  • limitinteger

    Rows per page, 1 to 200.

    Default50at least 1at most 200
  • cursorstring
  • qstring

    Search: rows whose name (or the list's other searchable text) contains this, any case.

    at most 200 characters
  • orderstring

    Sort field; a leading - sorts down. Each list names the fields it sorts by.

    at most 64 charactersmatches ^-?[a-z_]+$
  • includestring[]

    total_count (counted up to 10,000) and facets (a count per filter value).

    One oftotal_countfacets
  • created_afterstring

    Only rows created at or after this time (RFC 3339).

    date-time
  • created_beforestring

    Only rows created at or before this time (RFC 3339).

    date-time
  • updated_afterstring

    Only rows last changed at or after this time (RFC 3339).

    date-time
  • updated_beforestring

    Only rows last changed at or before this time (RFC 3339).

    date-time

Response200

  • objectstring
    list
  • dataSeoScan[]
    26 fields
    • idstring
    • objectstring
      seo_scan
    • cancel_requestedboolean
    • created_atstring or null
    • error_codestring or null
    • error_messagestring or null
    • errorsinteger
    • finished_atstring or null
    • fixed_issuesinteger or null
    • new_issuesinteger or null
    • noticesinteger
    • pages_crawledinteger
    • pages_failedinteger
    • pages_foundinteger
    • phasestring or null
      One ofdiscoveringcrawlinglinksvitalsfinishing
    • scoreinteger or null
    • site_idstring
    • started_atstring or null
    • statestring
      One ofqueuedrunningsucceededfailedcancelled
    • triggerstring
      One ofmanualscheduleapi
    • warningsinteger
    • workspace_idstring
    • checksobject or null

      Any JSON object.

    • settingsobject or null

      Any JSON object.

    • site_issuesSeoFinding[] or null
      3 fields
      • rulestring
      • severitystring
        One oferrorwarningnotice
      • detailobject or null

        Any JSON object.

    • summaryobject or null

      Any JSON object.

  • has_moreboolean
  • next_cursorstring or null
  • facetsmap<string, map<string, integer>> or null
  • peoplemap<string, ActorRef> or null
    5 fields
    • idstring or null
    • kindstring
      One ofuserapi_keyservice_accountworkloadend_usersystem
    • namestring or null
    • avatar_versionstring or null
    • emailstring or null
  • total_countinteger or null
  • total_count_exactboolean or null

Status codes

  • 200Successful Response
  • 422The request is not valid: errors[] names each field.
  • 4XXThe request was refused: the problem says why.
  • 5XXThe API could not answer: the problem says why.
Request
curl "https://api.mydeepagents.com/v1/seo/sites/{site_id}/scans?limit=20" \
  -H "Authorization: Bearer $MDA_API_KEY"
Response · 200
JSON
{
  "object": "list",
  "data": [
    {
      "id": "id",
      "object": "seo_scan",
      "cancel_requested": true,
      "checks": {},
      "created_at": "2026-11-10T09:30:00.000Z",
      "error_code": null,
      "error_message": "error message",
      "errors": 2,
      "finished_at": "2026-11-10T09:30:00.000Z",
      "fixed_issues": 2,
      "new_issues": 2,
      "notices": 2,
      "pages_crawled": 2,
      "pages_failed": 2,
      "pages_found": 2,
      "phase": "discovering",
      "score": 2,
      "settings": {},
      "site_id": "site id",
      "site_issues": [
        {
          "detail": {},
          "rule": "rule",
          "severity": "error"
        }
      ],
      "started_at": "2026-11-10T09:30:00.000Z",
      "state": "queued",
      "summary": {},
      "trigger": "api",
      "warnings": 2,
      "workspace_id": "ws_01jccj30nr8ad7mx1yc5v9zx3h"
    }
  ],
  "has_more": false,
  "next_cursor": null,
  "total_count": 1
}
post/v1/seo/sites/{site_id}/scans

Start seo scan

Needs seo.manage

Scan now. A site already being scanned answers with that scan (created false) instead of starting a second one.

Path parameters

  • site_idstringRequired

Response202

  • objectstring
    seo_scan_started
  • createdboolean
  • scan_idstring

Status codes

  • 202Successful Response
  • 422The request is not valid: errors[] names each field.
  • 4XXThe request was refused: the problem says why.
  • 5XXThe API could not answer: the problem says why.
Request
curl -X POST "https://api.mydeepagents.com/v1/seo/sites/{site_id}/scans" \
  -H "Authorization: Bearer $MDA_API_KEY"
Response · 202
JSON
{
  "object": "seo_scan_started",
  "created": true,
  "scan_id": "scan id"
}

Build with us

Ready for your first call?

Early access is open. Tell us what you want your agents to do, and we will help you get your first key.