curl --request POST \
--url https://data.otterly.ai/v1/reports/brand/{reportId}/prompts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"promptIds": [
"01HXP1DRTM5G8Z2N3KQ7VAW4PA"
]
}
'import requests
url = "https://data.otterly.ai/v1/reports/brand/{reportId}/prompts"
payload = { "promptIds": ["01HXP1DRTM5G8Z2N3KQ7VAW4PA"] }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({promptIds: ['01HXP1DRTM5G8Z2N3KQ7VAW4PA']})
};
fetch('https://data.otterly.ai/v1/reports/brand/{reportId}/prompts', 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://data.otterly.ai/v1/reports/brand/{reportId}/prompts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'promptIds' => [
'01HXP1DRTM5G8Z2N3KQ7VAW4PA'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://data.otterly.ai/v1/reports/brand/{reportId}/prompts"
payload := strings.NewReader("{\n \"promptIds\": [\n \"01HXP1DRTM5G8Z2N3KQ7VAW4PA\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://data.otterly.ai/v1/reports/brand/{reportId}/prompts")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"promptIds\": [\n \"01HXP1DRTM5G8Z2N3KQ7VAW4PA\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://data.otterly.ai/v1/reports/brand/{reportId}/prompts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"promptIds\": [\n \"01HXP1DRTM5G8Z2N3KQ7VAW4PA\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"reportId": "01HXBR1DGM5XY8Z2N3KQ7VAW4P",
"promptIds": [
"01HXP1DRTM5G8Z2N3KQ7VAW4PA",
"01HXP2DRTM5G8Z2N3KQ7VAW4PB"
],
"added": [
"01HXP1DRTM5G8Z2N3KQ7VAW4PA"
],
"alreadyAssigned": [
"01HXP2DRTM5G8Z2N3KQ7VAW4PB"
]
}{
"message": "Validation failed",
"target": "query",
"errors": [
{
"path": "country",
"message": "Required",
"code": "invalid_type"
}
]
}{
"message": "Report not found"
}{
"message": "Report not found"
}{
"message": "Report not found"
}{
"message": "Report not found"
}Add prompts to a brand report
Adds prompts that already exist in the report workspace to the brand report, exactly like ticking the report in the UI. It does not create prompts — use POST /v1/workspaces/{id}/prompts for that. Prompt IDs already assigned to the report are returned in alreadyAssigned and left unchanged; unknown prompt IDs are rejected with a 400 naming them. The report is recalculated for the added prompts asynchronously, so their data appears with a delay. A prompt that was previously removed from this report is reprocessed for the most recent 7 days of citation history only.
curl --request POST \
--url https://data.otterly.ai/v1/reports/brand/{reportId}/prompts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"promptIds": [
"01HXP1DRTM5G8Z2N3KQ7VAW4PA"
]
}
'import requests
url = "https://data.otterly.ai/v1/reports/brand/{reportId}/prompts"
payload = { "promptIds": ["01HXP1DRTM5G8Z2N3KQ7VAW4PA"] }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({promptIds: ['01HXP1DRTM5G8Z2N3KQ7VAW4PA']})
};
fetch('https://data.otterly.ai/v1/reports/brand/{reportId}/prompts', 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://data.otterly.ai/v1/reports/brand/{reportId}/prompts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'promptIds' => [
'01HXP1DRTM5G8Z2N3KQ7VAW4PA'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://data.otterly.ai/v1/reports/brand/{reportId}/prompts"
payload := strings.NewReader("{\n \"promptIds\": [\n \"01HXP1DRTM5G8Z2N3KQ7VAW4PA\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://data.otterly.ai/v1/reports/brand/{reportId}/prompts")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"promptIds\": [\n \"01HXP1DRTM5G8Z2N3KQ7VAW4PA\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://data.otterly.ai/v1/reports/brand/{reportId}/prompts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"promptIds\": [\n \"01HXP1DRTM5G8Z2N3KQ7VAW4PA\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"reportId": "01HXBR1DGM5XY8Z2N3KQ7VAW4P",
"promptIds": [
"01HXP1DRTM5G8Z2N3KQ7VAW4PA",
"01HXP2DRTM5G8Z2N3KQ7VAW4PB"
],
"added": [
"01HXP1DRTM5G8Z2N3KQ7VAW4PA"
],
"alreadyAssigned": [
"01HXP2DRTM5G8Z2N3KQ7VAW4PB"
]
}{
"message": "Validation failed",
"target": "query",
"errors": [
{
"path": "country",
"message": "Required",
"code": "invalid_type"
}
]
}{
"message": "Report not found"
}{
"message": "Report not found"
}{
"message": "Report not found"
}{
"message": "Report not found"
}Authorizations
Provide your API key as a Bearer token: Authorization: Bearer YOUR_API_KEY.
Path Parameters
Brand report identifier.
1"01HX7K2YV9D3M8N0G6Q5R4S3T2"
Body
IDs of prompts that already exist in the report workspace — look them up with GET /v1/workspaces/{id}/prompts. Up to 1000 IDs per call. Duplicate IDs are removed, and the de-duplicated list comes back as promptIds in the response.
1 - 1000 elements1 - 64Response
The prompts assigned to the brand report. Recalculation completes asynchronously.
1"01HX7K2YV9D3M8N0G6Q5R4S3T2"
The prompt IDs the request asked to assign.
Prompt IDs newly assigned to the report by this request.
Prompt IDs that were already assigned to the report, left unchanged.