curl --request GET \
--url https://app.surferseo.com/api/v2/workspaces/{workspace_id}/content_editors/{content_editor_id}/ai_search_guidelines \
--header 'API-KEY: <api-key>'import requests
url = "https://app.surferseo.com/api/v2/workspaces/{workspace_id}/content_editors/{content_editor_id}/ai_search_guidelines"
headers = {"API-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'API-KEY': '<api-key>'}};
fetch('https://app.surferseo.com/api/v2/workspaces/{workspace_id}/content_editors/{content_editor_id}/ai_search_guidelines', 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.surferseo.com/api/v2/workspaces/{workspace_id}/content_editors/{content_editor_id}/ai_search_guidelines",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"API-KEY: <api-key>"
],
]);
$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.surferseo.com/api/v2/workspaces/{workspace_id}/content_editors/{content_editor_id}/ai_search_guidelines"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("API-KEY", "<api-key>")
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.surferseo.com/api/v2/workspaces/{workspace_id}/content_editors/{content_editor_id}/ai_search_guidelines")
.header("API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.surferseo.com/api/v2/workspaces/{workspace_id}/content_editors/{content_editor_id}/ai_search_guidelines")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"inserted_at": "2024-04-12T15:23:45Z",
"factors": [
{
"covered_facts": [
"Surfer SEO is an SEO platform with a Content Editor."
],
"name": "facts_coverage",
"value": 62
},
{
"found": true,
"name": "introduction_covered_topics"
}
],
"facts": [
{
"fact": "Surfer SEO is an SEO platform with a Content Editor.",
"id": "f1e2c3d4-5678-49ab-9cde-0123456789ab",
"sources": [
{
"cited_by": [
"openai",
"perplexity"
],
"url": "https://example.com/article"
}
]
}
],
"id": 123,
"score": 62,
"status": "executing",
"updated_at": "2024-06-01T09:17:33Z"
}{
"error": {
"details": [
{
"field": "keywords",
"reason": "required"
}
],
"reason": "validation_error"
}
}{
"error": {
"details": [],
"reason": "unauthorized"
}
}{
"error": {
"details": [],
"reason": "permission_denied"
}
}{
"error": {
"details": [],
"reason": "not_found"
}
}{
"error": {
"details": [
{
"allowed": [
"application/json"
],
"field": "accept",
"reason": "unsupported"
}
],
"message": "Accept must be one of: application/json",
"reason": "not_acceptable"
}
}{
"error": {
"details": [],
"message": "The request conflicts with the current resource state.",
"reason": "conflict"
}
}{
"error": {
"details": [
{
"retry_after": 30
}
],
"reason": "rate_limit_exceeded"
}
}Get AI Search guidelines for a Content Editor
Returns the AI Search guidelines for the Content Editor — a list of facts gathered from the SERP and from the major AI engines (Google AI Overviews and AI Mode, Gemini, OpenAI, Perplexity) for the Content Editor’s main keyword and location, with the source URLs and where each one was cited.
Each source’s cited_by lists where the URL was found: serp for SERP-only sources,
otherwise a subset of ai_mode, ai_overviews, gemini, openai, perplexity.
score is the AI Search score for the current content, 0–100. null until the score
has been calculated; recalculated whenever the Content Editor’s content changes.
factors breaks that score down. The facts_coverage factor reports how much of facts the
content covers, and its covered_facts lists which ones. The facts still missing are the rest
of facts. An empty covered_facts alongside a non-zero value means the score was last
calculated before this field existed, not that the content covers none of them. The
introduction_* factors each assess one aspect of the draft’s introduction.
Returns 409 while the Content Editor is scheduled, executing, or failed. Once the
editor is completed, returns 200 with the analysis status; facts populate only when
status is completed. Poll this endpoint’s status to detect readiness; the same
value is also surfaced as ai_search_guidelines.status on GET /content_editors/:id.
Rate limit: 10 requests/sec
curl --request GET \
--url https://app.surferseo.com/api/v2/workspaces/{workspace_id}/content_editors/{content_editor_id}/ai_search_guidelines \
--header 'API-KEY: <api-key>'import requests
url = "https://app.surferseo.com/api/v2/workspaces/{workspace_id}/content_editors/{content_editor_id}/ai_search_guidelines"
headers = {"API-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'API-KEY': '<api-key>'}};
fetch('https://app.surferseo.com/api/v2/workspaces/{workspace_id}/content_editors/{content_editor_id}/ai_search_guidelines', 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.surferseo.com/api/v2/workspaces/{workspace_id}/content_editors/{content_editor_id}/ai_search_guidelines",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"API-KEY: <api-key>"
],
]);
$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.surferseo.com/api/v2/workspaces/{workspace_id}/content_editors/{content_editor_id}/ai_search_guidelines"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("API-KEY", "<api-key>")
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.surferseo.com/api/v2/workspaces/{workspace_id}/content_editors/{content_editor_id}/ai_search_guidelines")
.header("API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.surferseo.com/api/v2/workspaces/{workspace_id}/content_editors/{content_editor_id}/ai_search_guidelines")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"inserted_at": "2024-04-12T15:23:45Z",
"factors": [
{
"covered_facts": [
"Surfer SEO is an SEO platform with a Content Editor."
],
"name": "facts_coverage",
"value": 62
},
{
"found": true,
"name": "introduction_covered_topics"
}
],
"facts": [
{
"fact": "Surfer SEO is an SEO platform with a Content Editor.",
"id": "f1e2c3d4-5678-49ab-9cde-0123456789ab",
"sources": [
{
"cited_by": [
"openai",
"perplexity"
],
"url": "https://example.com/article"
}
]
}
],
"id": 123,
"score": 62,
"status": "executing",
"updated_at": "2024-06-01T09:17:33Z"
}{
"error": {
"details": [
{
"field": "keywords",
"reason": "required"
}
],
"reason": "validation_error"
}
}{
"error": {
"details": [],
"reason": "unauthorized"
}
}{
"error": {
"details": [],
"reason": "permission_denied"
}
}{
"error": {
"details": [],
"reason": "not_found"
}
}{
"error": {
"details": [
{
"allowed": [
"application/json"
],
"field": "accept",
"reason": "unsupported"
}
],
"message": "Accept must be one of: application/json",
"reason": "not_acceptable"
}
}{
"error": {
"details": [],
"message": "The request conflicts with the current resource state.",
"reason": "conflict"
}
}{
"error": {
"details": [
{
"retry_after": 30
}
],
"reason": "rate_limit_exceeded"
}
}Authorizations
Path Parameters
x >= 1123
x >= 1123
Response
AI Search guidelines
"2024-04-12T15:23:45Z"
What the score is made of. Empty until the score has been calculated.
How much of the AI Search facts the content already states.
- AiSearchGuidelinesFactsCoverageFactor
- AiSearchGuidelinesIntroductionFactor
Show child attributes
Show child attributes
[
{
"covered_facts": [
"Surfer SEO is an SEO platform with a Content Editor."
],
"name": "facts_coverage",
"value": 62
},
{
"found": true,
"name": "introduction_covered_topics"
}
]
Empty until status is completed.
Show child attributes
Show child attributes
x >= 1123
AI Search score, 0–100. null until calculation finishes; recalculated whenever the Content Editor's content changes.
62
executing while SERP analysis or LLM merging is in progress. completed once both have settled and facts is final — LLM-only sources may be missing when the LLM merge failed. failed if SERP analysis failed.
executing, completed, failed "2024-06-01T09:17:33Z"
Was this page helpful?