Reports
Get RankShark Track report data as JSON, download a PDF, save a report, group campaigns by business, and email reports to clients on a schedule.
A report covers a business (or some campaigns) over a period: the latest scan of each keyword in the period against the scan before it, point changes, competitors and the trend. AI campaigns add their visibility.
Report settings
Every report call takes the same settings:
| Field | What it is |
|---|---|
name | The report's title. |
clientId | A business (tc_…): the report covers its campaigns. |
trackerIds | Campaign ids (gt_…). Default: the business's campaigns, or all. |
period | { "preset": "7d" }, 30d, 90d, month (the last full calendar month), or custom with from and to (YYYY-MM-DD). |
compare | previous (default) or none. |
sections | Turn sections off with false: summary, changes, keywords, heatmaps, competitors, trend, ai. |
Get the data
curl -X POST https://panel.rankshark.io/v1/track/report-data \
-H "Authorization: Bearer $RANKSHARK_TRACK_KEY" \
-H "Content-Type: application/json" \
-d '{
"clientId": "tc_5Rw8Jn3Ys2QeLk",
"period": {
"preset": "30d"
},
"compare": "previous"
}'{
"name": "Harbor Dental · monthly",
"period": {
"preset": "month",
"from": "2026-10-01T05:00:00.000Z",
"to": "2026-11-01T04:59:59.999Z",
"label": "October 2026",
"tz": "America/Chicago"
},
"compare": "previous",
"sections": {
"summary": true,
"changes": true,
"keywords": true,
"heatmaps": true,
"competitors": true,
"trend": true,
"ai": true
},
"client": {
"id": "tc_5Rw8Jn3Ys2QeLk",
"name": "Harbor Dental",
"website": "https://harbordental.example",
"color": "#0e7490"
},
"brand": {
"name": "RankShark Track",
"logo": null,
"logoDark": null,
"color": "#0e7490",
"footer": null,
"website": null,
"supportUrl": null,
"supportEmail": null,
"poweredBy": false,
"locale": "en",
"pageSize": "A4",
"whiteLabel": false
},
"report": {
"id": "rp_7Tb2Xc9Mv4LdWs",
"preparedBy": null,
"message": null,
"closing": null,
"subjectTemplate": null
},
"shareUrl": null,
"summary": {
"keywords": 3,
"keywordsScanned": 3,
"scans": 12,
"solv": 48.3,
"solvBefore": 41.5,
"solvNowCompared": 48.3,
"arp": 4.6,
"arpBefore": 5.1,
"arpNowCompared": 4.6,
"foundPct": 86.4,
"improvedKeywords": 2,
"declinedKeywords": 1,
"changes": {
"improved": 38,
"declined": 9,
"same": 100,
"newlyFound": 6,
"lost": 1,
"compared": 147
},
"ai": null
},
"campaigns": [
{
"id": "gt_8fK2mQ9xLp3s",
"name": "Harbor Dental · Austin",
"engine": "maps",
"engines": [
"maps"
],
"mode": "grid",
"keywords": [
{
"keyword": "dentist near me",
"current": {
"id": "gs_3Hq7Vt2NwR8cYp",
"metrics": {
"points": 49,
"total": 49,
"found": 44,
"foundPct": 89.8,
"top3": 27,
"top10": 39,
"arp": 4.18,
"atrp": 5.9,
"solv": 55.1
}
},
"baseline": {
"id": "gs_9Lm4Kd6PzX1aQe",
"metrics": {
"points": 49,
"total": 49,
"found": 40,
"foundPct": 81.63,
"top3": 21,
"top10": 33,
"arp": 5.02,
"atrp": 7.71,
"solv": 42.86
}
},
"delta": {
"arp": 0.84,
"atrp": 1.81,
"solv": 12.24,
"foundPct": 8.17
}
}
]
}
],
"generatedAt": "2026-11-05T10:00:00.000Z"
}summary covers all keywords; campaigns has each campaign's keywords with their current scan, the scan they are compared with and the delta, where positive means better. Needs track:read.
Download a PDF
Send the same settings to POST /v1/track/report-pdf. The answer is the PDF file:
curl -X POST https://panel.rankshark.io/v1/track/report-pdf \
-H "Authorization: Bearer $RANKSHARK_TRACK_KEY" \
-H "Content-Type: application/json" \
-d '{
"clientId": "tc_5Rw8Jn3Ys2QeLk",
"period": {
"preset": "month"
},
"compare": "previous"
}' \
-o harbor-dental-report.pdfSave a report and email it on a schedule
A saved report keeps its settings. With a schedule, it is emailed as a PDF on that schedule. Needs track:reports.
curl -X POST https://panel.rankshark.io/v1/track/reports \
-H "Authorization: Bearer $RANKSHARK_TRACK_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Harbor Dental · monthly",
"clientId": "tc_5Rw8Jn3Ys2QeLk",
"trackerIds": [],
"period": {
"preset": "month"
},
"compare": "previous",
"sections": {
"summary": true,
"changes": true,
"keywords": true,
"heatmaps": true,
"competitors": true,
"trend": true,
"ai": true
},
"schedule": {
"freq": "monthly",
"dow": 1,
"dom": 1,
"hour": 8,
"tz": "America/Chicago",
"emails": [
"[email protected]"
]
}
}'{
"id": "rp_7Tb2Xc9Mv4LdWs",
"name": "Harbor Dental · monthly",
"clientId": "tc_5Rw8Jn3Ys2QeLk",
"trackerIds": [],
"period": {
"preset": "month"
},
"compare": "previous",
"sections": {
"summary": true,
"changes": true,
"keywords": true,
"heatmaps": true,
"competitors": true,
"trend": true,
"ai": true
},
"schedule": {
"freq": "monthly",
"dow": 1,
"dom": 1,
"hour": 8,
"tz": "America/Chicago",
"emails": [
"[email protected]"
]
},
"nextSendAt": "2026-12-01T14:00:00.000Z",
"lastSentAt": "2026-11-01T13:00:07.000Z",
"lastSendError": null,
"sendAttempts": 0,
"sendRetrying": false,
"subjectTemplate": null,
"message": null,
"closing": null,
"preparedBy": null,
"createdAt": "2026-09-20T09:15:00.000Z",
"updatedAt": "2026-10-02T11:40:00.000Z"
}schedule.freqisoff,weekly(withdow, 0 = Sunday) ormonthly(withdom).- Up to 10 recipients. Without
emails, the report goes to the business's report recipients. - A scheduled report covers full days up to the day before it is sent.
lastSendErrorsays why the last email did not go out.
To send a saved report now:
curl -X POST https://panel.rankshark.io/v1/track/reports/rp_7Tb2Xc9Mv4LdWs/send \
-H "Authorization: Bearer $RANKSHARK_TRACK_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": [
"[email protected]"
]
}'{
"ok": true,
"to": [
"[email protected]"
]
}You can only send to addresses already set up in your workspace: the report's or business's recipients, or your workspace members. Up to 30 manual sends an hour.
Group campaigns under a business
Reports are easiest per business. A business is the company you track, called a client in the API:
curl -X POST https://panel.rankshark.io/v1/track/clients \
-H "Authorization: Bearer $RANKSHARK_TRACK_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Harbor Dental",
"website": "https://harbordental.example",
"color": "#0e7490",
"emails": [
"[email protected]"
],
"notes": "Two locations; South Congress is the main one."
}'{
"id": "tc_5Rw8Jn3Ys2QeLk",
"name": "Harbor Dental",
"website": "https://harbordental.example",
"color": "#0e7490",
"emails": [
"[email protected]"
],
"notes": "Two locations; South Congress is the main one.",
"campaigns": 2,
"folders": [
"Austin"
],
"solv": 55.1,
"solvPrev": 42.86,
"arp": 4.18,
"aiMention": 44.44,
"lastRunAt": "2026-11-02T15:00:04.000Z",
"createdAt": "2026-09-14T18:20:00.000Z",
"displayName": null,
"logoVersion": null
}Then move campaigns into it, optionally into a folder:
curl -X POST https://panel.rankshark.io/v1/track/assign \
-H "Authorization: Bearer $RANKSHARK_TRACK_KEY" \
-H "Content-Type: application/json" \
-d '{
"trackerIds": [
"gt_8fK2mQ9xLp3s",
"gt_2Wd6Hs9Kq4Tn"
],
"clientId": "tc_5Rw8Jn3Ys2QeLk",
"folder": "Austin"
}'{
"ok": true,
"updated": 2
}On white-label plans (Track Pro and up), reports carry your own brand, and the business can have its own logo and display name.