SoftSolzSoftSolz
HomeAPI GuideAPI ReferenceWidget Tester

Change the notes, source, research figures or target page of a tracked keyword.

Send only the fields to change; null clears one. Pass expected_updated_at from the last read so a change made elsewhere answers 409 STALE_VERSION instead of being overwritten. The Google position history is never changed by this call.

PATCHhttps://app.softsolz.uk/api/v1/services/seo/sites/{site_id}/keywords/{keyword_id}

Recent Requests

Kept only in this browser
TimeStatusTook
Send a request with Try it to see it here.

Path Params

site_idstringrequired
keyword_idstringrequired

Headers

Authorizationstringrequired

Bearer token: `Bearer sk_live_...` (or `sk_test_...` for sandbox). A login token will not work here.

Idempotency-Keystring

Optional idempotency key for safe retries.

Body Params

notesstring | null

Your notes about the keyword, up to 1000 characters.

source_labelstring | null

Where the research came from, up to 80 characters. Shown as "From <source>".

their_monthly_searchesinteger | null

Monthly searches as estimated by your research tool, 0 or more. Stored and shown as that tool estimate, never as a Google figure.

their_difficultyinteger | null

Difficulty from 0 to 100 as scored by your research tool. Stored and shown as that tool estimate.

target_urlstring | null

The page that should rank for the keyword: a full address on the website domain (with or without www) or a path starting with /. Anything else is refused with 400 target_url_not_on_site.

expected_updated_atstring

updated_at from your last read of the keyword.

Response

Response Body

idstringTracked keyword id. Use it as keyword_id.
site_idstringThe website it belongs to.
query_textstringNormalised search text.
notesstring | nullYour notes about the keyword, up to 1000 characters.
source_labelstring | nullWhere the research came from, up to 80 characters. Shown as "From <source>".
their_monthly_searchesinteger | nullMonthly searches as estimated by your research tool, 0 or more. Stored and shown as that tool estimate, never as a Google figure.
their_difficultyinteger | nullDifficulty from 0 to 100 as scored by your research tool. Stored and shown as that tool estimate.
target_urlstring | nullThe page that should rank, as a full address.
added_viastringHow it was added: dashboard, api or connected_app.
added_by_labelstring | nullThe app or key that added it.
created_atstringWhen tracking started.
updated_atstringSend it back as expected_updated_at when you change the keyword.

Request

curl --request PATCH \
--url https://app.softsolz.uk/api/v1/services/seo/sites/{site_id}/keywords/{keyword_id} \
--header 'Authorization: Bearer sk_live_your_key' \
--header 'Content-Type: application/json' \
--data '{
"notes": "Main money keyword.",
"source_label": "Ahrefs via Claude",
"their_monthly_searches": 2400,
"their_difficulty": 35,
"target_url": "/sourdough-starter"
}'

Credentials

Sent as a Bearer token and used in the samples above and in Try it. Kept only in this browser tab until you close it. Use an sk_test_ key to stay in your sandbox.

Response · 200

{
"data": {
"id": "3f2b9c44-8f4e-4d0a-9c1b-2a7d6e5f1a23",
"site_id": "3f2b9c44-8f4e-4d0a-9c1b-2a7d6e5f1a23",
"query_text": "sourdough starter",
"notes": "Main money keyword.",
"source_label": "Ahrefs via Claude",
"their_monthly_searches": 2400,
"their_difficulty": 35,
"target_url": null,
"added_via": "connected_app",
"added_by_label": "Claude",
"created_at": "2026-09-01T09:00:00.000Z",
"updated_at": "2026-09-01T09:00:00.000Z"
}
}