curl --request DELETE \
--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.delete(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'DELETE',
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 => "DELETE",
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("DELETE", 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.delete("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::Delete.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"
],
"removed": [
"01HXP1DRTM5G8Z2N3KQ7VAW4PA"
],
"notAssigned": [
"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"
}Remove prompts from a brand report
Unassigns prompts from the brand report and recalculates it without them (asynchronously). The prompt IDs travel in a JSON request body, which some HTTP clients drop on DELETE — send it explicitly. The prompts themselves are not deleted and stay in the workspace — use DELETE /v1/workspaces/{id}/prompts/{promptId} for that. Prompt IDs that are not assigned to the report are returned in notAssigned and left unchanged; unknown prompt IDs are rejected with a 400 naming them. This discards the citation data collected for those prompts in this report: re-adding one later reprocesses only the most recent 7 days of its citation history, so a remove-then-re-add round trip is not reversible.
curl --request DELETE \
--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.delete(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'DELETE',
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 => "DELETE",
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("DELETE", 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.delete("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::Delete.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"
],
"removed": [
"01HXP1DRTM5G8Z2N3KQ7VAW4PA"
],
"notAssigned": [
"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 to unassign from the report — look them up with GET /v1/reports/brand/{reportId}/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 unassigned from the brand report. Recalculation completes asynchronously.
1"01HX7K2YV9D3M8N0G6Q5R4S3T2"
The prompt IDs the request asked to unassign.
Prompt IDs unassigned from the report by this request.
Prompt IDs that were not assigned to the report, left unchanged.