curl --request GET \
--url https://app.searchable.com/api/mcp/projects/{projectId}/traffic/correlation \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.searchable.com/api/mcp/projects/{projectId}/traffic/correlation"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.searchable.com/api/mcp/projects/{projectId}/traffic/correlation', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.searchable.com/api/mcp/projects/{projectId}/traffic/correlation",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://app.searchable.com/api/mcp/projects/{projectId}/traffic/correlation"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://app.searchable.com/api/mcp/projects/{projectId}/traffic/correlation")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.searchable.com/api/mcp/projects/{projectId}/traffic/correlation")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"pages": [
{
"path": "<string>",
"crawls": 123,
"lastCrawl": "<string>",
"aiReferralSessions": 123,
"newAiVisitors": 123,
"pageviews": 123,
"gscClicks": 123,
"byPlatform": [
{
"platform": "<string>",
"visits": 1
}
],
"byCategory": [
{
"botCategory": "<string>",
"visits": 1
}
],
"byBot": [
{
"botId": 123,
"botName": "<string>",
"botVendor": "<string>",
"botCategory": "<string>",
"visits": 1
}
]
}
],
"pagesConsidered": 123,
"populationTruncated": true,
"dateRange": {
"from": "2023-11-07T05:31:56Z",
"to": "2023-11-07T05:31:56Z"
},
"groupBy": "platform"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "unauthorized",
"error": "<string>",
"message": "<string>",
"howToFix": "<string>",
"requestId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"requiresUpgrade": true,
"retryable": true,
"timeout": true,
"quotaExceeded": true,
"current": 123,
"limit": 123,
"bulkLimitExceeded": true,
"requested": 123,
"maxAllowed": 123,
"details": {
"formErrors": [
"<string>"
],
"fieldErrors": {}
}
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "unauthorized",
"error": "<string>",
"message": "<string>",
"howToFix": "<string>",
"requestId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"requiresUpgrade": true,
"retryable": true,
"timeout": true,
"quotaExceeded": true,
"current": 123,
"limit": 123,
"bulkLimitExceeded": true,
"requested": 123,
"maxAllowed": 123,
"details": {
"formErrors": [
"<string>"
],
"fieldErrors": {}
}
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "unauthorized",
"error": "<string>",
"message": "<string>",
"howToFix": "<string>",
"requestId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"requiresUpgrade": true,
"retryable": true,
"timeout": true,
"quotaExceeded": true,
"current": 123,
"limit": 123,
"bulkLimitExceeded": true,
"requested": 123,
"maxAllowed": 123,
"details": {
"formErrors": [
"<string>"
],
"fieldErrors": {}
}
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "unauthorized",
"error": "<string>",
"message": "<string>",
"howToFix": "<string>",
"requestId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"requiresUpgrade": true,
"retryable": true,
"timeout": true,
"quotaExceeded": true,
"current": 123,
"limit": 123,
"bulkLimitExceeded": true,
"requested": 123,
"maxAllowed": 123,
"details": {
"formErrors": [
"<string>"
],
"fieldErrors": {}
}
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "unauthorized",
"error": "<string>",
"message": "<string>",
"howToFix": "<string>",
"requestId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"requiresUpgrade": true,
"retryable": true,
"timeout": true,
"quotaExceeded": true,
"current": 123,
"limit": 123,
"bulkLimitExceeded": true,
"requested": 123,
"maxAllowed": 123,
"details": {
"formErrors": [
"<string>"
],
"fieldErrors": {}
}
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "unauthorized",
"error": "<string>",
"message": "<string>",
"howToFix": "<string>",
"requestId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"requiresUpgrade": true,
"retryable": true,
"timeout": true,
"quotaExceeded": true,
"current": 123,
"limit": 123,
"bulkLimitExceeded": true,
"requested": 123,
"maxAllowed": 123,
"details": {
"formErrors": [
"<string>"
],
"fieldErrors": {}
}
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "unauthorized",
"error": "<string>",
"message": "<string>",
"howToFix": "<string>",
"requestId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"requiresUpgrade": true,
"retryable": true,
"timeout": true,
"quotaExceeded": true,
"current": 123,
"limit": 123,
"bulkLimitExceeded": true,
"requested": 123,
"maxAllowed": 123,
"details": {
"formErrors": [
"<string>"
],
"fieldErrors": {}
}
}Get crawl-to-visit correlation
Per page: how often AI crawlers fetched it versus same-window AI-referred human sessions. groupBy=platform|botCategory|botName adds the requested crawl-side breakdown; it does not attribute sessions to a crawler. Rows are ranked by AI-referral sessions. limit defaults to 50, max 200.
curl --request GET \
--url https://app.searchable.com/api/mcp/projects/{projectId}/traffic/correlation \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.searchable.com/api/mcp/projects/{projectId}/traffic/correlation"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.searchable.com/api/mcp/projects/{projectId}/traffic/correlation', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.searchable.com/api/mcp/projects/{projectId}/traffic/correlation",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://app.searchable.com/api/mcp/projects/{projectId}/traffic/correlation"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://app.searchable.com/api/mcp/projects/{projectId}/traffic/correlation")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.searchable.com/api/mcp/projects/{projectId}/traffic/correlation")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"pages": [
{
"path": "<string>",
"crawls": 123,
"lastCrawl": "<string>",
"aiReferralSessions": 123,
"newAiVisitors": 123,
"pageviews": 123,
"gscClicks": 123,
"byPlatform": [
{
"platform": "<string>",
"visits": 1
}
],
"byCategory": [
{
"botCategory": "<string>",
"visits": 1
}
],
"byBot": [
{
"botId": 123,
"botName": "<string>",
"botVendor": "<string>",
"botCategory": "<string>",
"visits": 1
}
]
}
],
"pagesConsidered": 123,
"populationTruncated": true,
"dateRange": {
"from": "2023-11-07T05:31:56Z",
"to": "2023-11-07T05:31:56Z"
},
"groupBy": "platform"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "unauthorized",
"error": "<string>",
"message": "<string>",
"howToFix": "<string>",
"requestId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"requiresUpgrade": true,
"retryable": true,
"timeout": true,
"quotaExceeded": true,
"current": 123,
"limit": 123,
"bulkLimitExceeded": true,
"requested": 123,
"maxAllowed": 123,
"details": {
"formErrors": [
"<string>"
],
"fieldErrors": {}
}
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "unauthorized",
"error": "<string>",
"message": "<string>",
"howToFix": "<string>",
"requestId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"requiresUpgrade": true,
"retryable": true,
"timeout": true,
"quotaExceeded": true,
"current": 123,
"limit": 123,
"bulkLimitExceeded": true,
"requested": 123,
"maxAllowed": 123,
"details": {
"formErrors": [
"<string>"
],
"fieldErrors": {}
}
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "unauthorized",
"error": "<string>",
"message": "<string>",
"howToFix": "<string>",
"requestId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"requiresUpgrade": true,
"retryable": true,
"timeout": true,
"quotaExceeded": true,
"current": 123,
"limit": 123,
"bulkLimitExceeded": true,
"requested": 123,
"maxAllowed": 123,
"details": {
"formErrors": [
"<string>"
],
"fieldErrors": {}
}
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "unauthorized",
"error": "<string>",
"message": "<string>",
"howToFix": "<string>",
"requestId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"requiresUpgrade": true,
"retryable": true,
"timeout": true,
"quotaExceeded": true,
"current": 123,
"limit": 123,
"bulkLimitExceeded": true,
"requested": 123,
"maxAllowed": 123,
"details": {
"formErrors": [
"<string>"
],
"fieldErrors": {}
}
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "unauthorized",
"error": "<string>",
"message": "<string>",
"howToFix": "<string>",
"requestId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"requiresUpgrade": true,
"retryable": true,
"timeout": true,
"quotaExceeded": true,
"current": 123,
"limit": 123,
"bulkLimitExceeded": true,
"requested": 123,
"maxAllowed": 123,
"details": {
"formErrors": [
"<string>"
],
"fieldErrors": {}
}
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "unauthorized",
"error": "<string>",
"message": "<string>",
"howToFix": "<string>",
"requestId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"requiresUpgrade": true,
"retryable": true,
"timeout": true,
"quotaExceeded": true,
"current": 123,
"limit": 123,
"bulkLimitExceeded": true,
"requested": 123,
"maxAllowed": 123,
"details": {
"formErrors": [
"<string>"
],
"fieldErrors": {}
}
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"code": "unauthorized",
"error": "<string>",
"message": "<string>",
"howToFix": "<string>",
"requestId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"requiresUpgrade": true,
"retryable": true,
"timeout": true,
"quotaExceeded": true,
"current": 123,
"limit": 123,
"bulkLimitExceeded": true,
"requested": 123,
"maxAllowed": 123,
"details": {
"formErrors": [
"<string>"
],
"fieldErrors": {}
}
}Authorizations
A Searchable API key, created under Settings → Workspace → Integrations. Send as Authorization: Bearer sea_xxxxx. Every key carries one or more scopes (read, write, admin) and may optionally be bound to a single project — see Getting started.
Path Parameters
The project id.
Query Parameters
Lookback window in days. Default and maximum vary by endpoint — see the operation description.
x >= 1Start of an absolute window (inclusive, UTC). Accepts YYYY-MM-DD or a full ISO timestamp. Requires to, and is mutually exclusive with days — sending both returns 400 invalid_argument. A range longer than the endpoint's maximum is rejected rather than clamped.
"2026-03-01"
End of an absolute window (inclusive, UTC). Accepts YYYY-MM-DD or a full ISO timestamp. Requires from.
"2026-03-31"
Comma-separated hostnames to narrow the report to. Useful on multi-domain projects; omit for every host in the project.
"blog.acme.com"
Optional crawler-breakdown dimension on traffic overview, bots, and correlation. Omit for the legacy response. platform requests byPlatform, botCategory adds byCategory, and botName adds byBot. Overview and bots retain their existing byPlatform array. These rows classify crawl requests only; AI-referral sessions are not attributed to a crawler. Unknown values return 400 invalid_argument.
platform, botCategory, botName Page size. Defaults and caps vary by endpoint (see each operation's description); big list endpoints (cited domains/URLs, prompts, opportunities) cap at 1000, issues at 5000. Values above an endpoint's cap are clamped server-side, never rejected.
x >= 1Response
Per-page crawl and AI-referral correlation rows.
Per page, crawls and AI-referred sessions over the SAME window, joined by path. Co-occurrence, not attribution.
Show child attributes
Show child attributes
Size of the ranked population — a floor on the true page count, not a site-wide total.
True when the upstream per-set cap (500) was reached, so pages are certainly missing.
Show child attributes
Show child attributes
Present when the request selected a crawl-side grouping.
platform, botCategory, botName