Create a campaign
RankShark TrackScopetrack:write
Validated against the plan (points per scan, keywords per campaign, campaigns, engines). A grid campaign (mode "grid", the default) needs business and grid: find the business with POST /v1/track/find. A website campaign (mode "website") needs domain, location and country, on engine search, bing_search or ai. runNow: true also starts the first scan and needs track:run. Fields not listed in CampaignInput are ignored.
Scope: track:write.
AuthorizationBearer <rstk_… API key or OAuth access token>A Track API key (rstk_…, Settings → API & MCP) or an OAuth access token issued for this API
application/json- body
A campaign's settings. Create: keywords and (grid) business and grid, or (website) domain, location and country. Update: only the fields sent change.
name?stringDefault: the business name (website campaigns: the domain)
length <= 120mode?stringgrid (default): a business on a grid. website: domain (required) scanned at one location (required) in country; engine search, bing_search or ai; grid, center and zoom are not used; one point per keyword
"grid""website"location?business?A result of POST /v1/track/find as it is (grid campaigns); {name} (website campaigns, AI visibility); other fields are ignored
keywords?array<>Keywords (80 characters each), or prompts for engine "ai" (300); the plan sets how many (limits.keywordsPerTracker)
items <= 100engine?stringOne engine (when engines is not given). "search" / "bing_search" alone on a grid campaign: its local pack and web results on the grid
"maps""local_pack""search""bing_maps""bing_local_pack""bing_search""ai"engines?array<>Several engines, each paid at its own point cost: local_pack / bing_local_pack rank the listing in the search page's local pack, search / bing_search the website in the web results (at location, or on the grid with webGrid). "ai" asks aiEngines
webGrid?booleansearch / bing_search on the grid (default false: at location, the business's city unless given)
aiGrid?Rank engines and "ai" together: the AI answers' grid (same centre, radius and shape)
aiEngines?array<>engine "ai": the AI engines to ask (GET /v1/track/engines says which the plan has)
aliases?array<>Other names the AI answers may use (AI campaigns; up to 10)
items <= 10grid?center?Grid centre (default: the business position)
zoom?|10-18, null = automatic
10 <= value <= 18language?stringLanguage code (default en)
length <= 12country?stringISO 3166 alpha-2, lower case (default us)
length <= 2ipLocation?|Where the searches come from (default: suggested from the grid centre)
domain?|The business's site (organic rank, AI citations); required for a website campaign
length <= 500page?|AI campaigns: a page whose citations count on their own
length <= 1000schedule?paused?booleanScheduled runs paused
clientId?|The business the campaign belongs to (tc_…); null: not assigned
^tc_[A-Za-z0-9]{10,40}$folder?|A folder inside the business
length <= 60runNow?booleanCreate only: start the first scan (needs track:run)
OK
application/json- response
id*stringgt_…
name*stringmode*stringwebsite: a domain at one location (one point per keyword; on a search engine the metrics score its organic rank)
"grid""website"location?|A website campaign's location, or where a grid campaign's web results are searched (off the grid); null otherwise
business?|nullkeywords*array<string>engine*stringThe first of engines
"maps""local_pack""search""bing_maps""bing_local_pack""bing_search""ai"engines*array<>The engines it scans, in this order: maps, local_pack, search, bing_maps, bing_local_pack, bing_search, ai
webGrid?booleanThe web results (search / bing_search) on the grid; false: at location
grid?|nullcenter?|nullpoints?integerGrid points one scan of one keyword has
aiEngines?array<>|Campaigns with "ai"; null otherwise
aliases?array<string>|nullaiGrid?|Rank engines and AI together: the AI answers' grid; null otherwise
aiPoints?|Points of aiGrid (when it has one)
zoom?|null = automatic
language?stringcountry?stringipLocation?|nulldomain?string|nullpage?string|nullschedule?|nullnextRunAt?|The next scheduled run
date-timelastRunAt?|date-timepaused?booleanclientId?|The business the campaign belongs to (tc_…); null: not assigned
folder?|A folder inside the business
lastScheduleError?|Why the last scheduled run did not start
quickScan?booleanA quick scan (runs once); absent on campaigns
latest*array<>The latest result per keyword and engine
active?array<>List only: its unfinished scans
createdAt?|date-timeupdatedAt?|date-timecurl -X POST 'https://panel.rankshark.io/v1/track/campaigns' \ -H 'Content-Type: application/json' \ -d '{ "name": "Harbor Dental · Austin", "business": { "name": "Harbor Dental", "address": "1200 S Congress Ave, Austin, TX 78704", "category": "Dentist", "lat": 30.2509, "lng": -97.7493, "fid": "0x8644b50a3e3c0b1d:0x6a8d1e2f3c4b5a69", "pid": "ChIJd8BlQ2BZwokRAFUEcm_qrcA", "cid": "7677826127960431209", "website": "https://harbordental.example", "phone": "+1 512-555-0142", "mapsUrl": "https://www.google.com/maps/place/?q=place_id:ChIJd8BlQ2BZwokRAFUEcm_qrcA", "rating": 4.8, "reviews": 312 }, "keywords": [ "dentist near me", "emergency dentist", "teeth whitening austin" ], "engines": [ "maps" ], "grid": { "size": 7, "radiusM": 4828, "shape": "square", "unit": "mi" }, "schedule": { "freq": "weekly", "hour": 9, "dow": 1, "tz": "America/Chicago" }, "clientId": "tc_5Rw8Jn3Ys2QeLk", "folder": "Austin"}'{ "id": "gt_8fK2mQ9xLp3s", "name": "Harbor Dental · Austin", "mode": "grid", "location": null, "business": { "name": "Harbor Dental", "address": "1200 S Congress Ave, Austin, TX 78704", "category": "Dentist", "lat": 30.2509, "lng": -97.7493, "fid": "0x8644b50a3e3c0b1d:0x6a8d1e2f3c4b5a69", "pid": "ChIJd8BlQ2BZwokRAFUEcm_qrcA", "cid": "7677826127960431209", "website": "https://harbordental.example", "phone": "+1 512-555-0142", "mapsUrl": "https://www.google.com/maps/place/?q=place_id:ChIJd8BlQ2BZwokRAFUEcm_qrcA", "rating": 4.8, "reviews": 312 }, "keywords": [ "dentist near me", "emergency dentist", "teeth whitening austin" ], "engine": "maps", "engines": [ "maps" ], "webGrid": false, "grid": { "size": 7, "radiusM": 4828, "shape": "square", "unit": "mi" }, "center": { "lat": 30.2509, "lng": -97.7493 }, "points": 49, "aiEngines": null, "aliases": null, "aiGrid": null, "zoom": null, "language": "en", "country": "us", "ipLocation": { "country": "us", "region": "texas", "city": "austin" }, "domain": "harbordental.example", "page": null, "schedule": { "freq": "weekly", "hour": 9, "dow": 1, "dom": 1, "tz": "America/Chicago" }, "nextRunAt": "2026-11-09T15:00:00.000Z", "lastRunAt": null, "paused": false, "clientId": "tc_5Rw8Jn3Ys2QeLk", "folder": "Austin", "lastScheduleError": null, "latest": [], "createdAt": "2026-09-14T18:22:10.000Z", "updatedAt": "2026-11-02T15:06:12.000Z"}Update a business POST
name is required; the other fields are replaced by what is sent (displayName and logoDataUrl only when sent). Scope: `track:write`.
Delete a campaign and all its scans DELETE
Its unfinished scans are cancelled first, like POST /v1/track/scans/{id}/cancel: one cancelled before any point gives its points back. This cannot be undone. Scope: `track:delete`.