Create a brand report
curl --request POST \
--url https://data.otterly.ai/v1/reports/brand \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"workspaceId": "01HX7K2YV9D3M8N0G6Q5R4S3T2",
"reportTitle": "Adidas Visibility Report",
"brand": "Adidas",
"brandDomain": "adidas.com",
"promptIds": [
"01HXP1DRTM5G8Z2N3KQ7VAW4PA"
],
"competitors": [
{
"brand": "Nike",
"brandDomain": "nike.com"
}
]
}
'import requests
url = "https://data.otterly.ai/v1/reports/brand"
payload = {
"workspaceId": "01HX7K2YV9D3M8N0G6Q5R4S3T2",
"reportTitle": "Adidas Visibility Report",
"brand": "Adidas",
"brandDomain": "adidas.com",
"promptIds": ["01HXP1DRTM5G8Z2N3KQ7VAW4PA"],
"competitors": [
{
"brand": "Nike",
"brandDomain": "nike.com"
}
]
}
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({
workspaceId: '01HX7K2YV9D3M8N0G6Q5R4S3T2',
reportTitle: 'Adidas Visibility Report',
brand: 'Adidas',
brandDomain: 'adidas.com',
promptIds: ['01HXP1DRTM5G8Z2N3KQ7VAW4PA'],
competitors: [{brand: 'Nike', brandDomain: 'nike.com'}]
})
};
fetch('https://data.otterly.ai/v1/reports/brand', 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",
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([
'workspaceId' => '01HX7K2YV9D3M8N0G6Q5R4S3T2',
'reportTitle' => 'Adidas Visibility Report',
'brand' => 'Adidas',
'brandDomain' => 'adidas.com',
'promptIds' => [
'01HXP1DRTM5G8Z2N3KQ7VAW4PA'
],
'competitors' => [
[
'brand' => 'Nike',
'brandDomain' => 'nike.com'
]
]
]),
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"
payload := strings.NewReader("{\n \"workspaceId\": \"01HX7K2YV9D3M8N0G6Q5R4S3T2\",\n \"reportTitle\": \"Adidas Visibility Report\",\n \"brand\": \"Adidas\",\n \"brandDomain\": \"adidas.com\",\n \"promptIds\": [\n \"01HXP1DRTM5G8Z2N3KQ7VAW4PA\"\n ],\n \"competitors\": [\n {\n \"brand\": \"Nike\",\n \"brandDomain\": \"nike.com\"\n }\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")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"workspaceId\": \"01HX7K2YV9D3M8N0G6Q5R4S3T2\",\n \"reportTitle\": \"Adidas Visibility Report\",\n \"brand\": \"Adidas\",\n \"brandDomain\": \"adidas.com\",\n \"promptIds\": [\n \"01HXP1DRTM5G8Z2N3KQ7VAW4PA\"\n ],\n \"competitors\": [\n {\n \"brand\": \"Nike\",\n \"brandDomain\": \"nike.com\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://data.otterly.ai/v1/reports/brand")
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 \"workspaceId\": \"01HX7K2YV9D3M8N0G6Q5R4S3T2\",\n \"reportTitle\": \"Adidas Visibility Report\",\n \"brand\": \"Adidas\",\n \"brandDomain\": \"adidas.com\",\n \"promptIds\": [\n \"01HXP1DRTM5G8Z2N3KQ7VAW4PA\"\n ],\n \"competitors\": [\n {\n \"brand\": \"Nike\",\n \"brandDomain\": \"nike.com\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "01HXBR1DGM5XY8Z2N3KQ7VAW4P",
"workspaceId": "01HX7K2YV9D3M8N0G6Q5R4S3T2",
"brand": "Adidas",
"brandVariations": [
"adidas",
"Adidas AG"
],
"brandDomain": "adidas.com",
"brandDomainVariations": [
"adidas.de",
"adidas.co.uk"
],
"brandDomainWildcard": false,
"brandRegex": null,
"countries": [
"us",
"de",
"uk"
],
"competitors": [
{
"brand": "Nike",
"brandVariations": [
"nike",
"Nike Inc."
],
"brandDomain": "nike.com",
"brandDomainVariations": [
"nike.de",
"nike.co.uk"
],
"brandDomainWildcard": false,
"brandRegex": null
}
],
"reportTitle": "Adidas Visibility Report",
"createdDate": "2024-11-01T12:00:00.000Z",
"updatedDate": "2025-05-01T08:30:00.000Z",
"promptIds": [
"01HXP1DRTM5G8Z2N3KQ7VAW4PA",
"01HXP2DRTM5G8Z2N3KQ7VAW4PB"
],
"countryPromptsTotal": {
"us": 50,
"de": 35,
"uk": 28
},
"tags": [
{
"id": "01HX8AB3CDE4FG5HJ6KL7MN8PQ",
"name": "Running Shoes",
"color": "orange"
}
]
}{
"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"
}Brand Reports
Create a brand report
Creates a brand report in a workspace, the same as creating it in the UI. The prompts must already exist in that workspace — create them with POST /v1/workspaces/{id}/prompts — and the report tracks their countries. Domains are normalized (protocol, www. and path stripped). Detect the brand either by brand and brandVariations, or by brandRegex together with reportTitle. Competitors can come straight from POST /v1/competitors/suggestions. Data for the report is collected asynchronously. Sending the same request again within 2 minutes returns the report the first request created instead of a second one; if that report is still being set up, the response is a 409 carrying its ID.
POST
/
v1
/
reports
/
brand
Create a brand report
curl --request POST \
--url https://data.otterly.ai/v1/reports/brand \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"workspaceId": "01HX7K2YV9D3M8N0G6Q5R4S3T2",
"reportTitle": "Adidas Visibility Report",
"brand": "Adidas",
"brandDomain": "adidas.com",
"promptIds": [
"01HXP1DRTM5G8Z2N3KQ7VAW4PA"
],
"competitors": [
{
"brand": "Nike",
"brandDomain": "nike.com"
}
]
}
'import requests
url = "https://data.otterly.ai/v1/reports/brand"
payload = {
"workspaceId": "01HX7K2YV9D3M8N0G6Q5R4S3T2",
"reportTitle": "Adidas Visibility Report",
"brand": "Adidas",
"brandDomain": "adidas.com",
"promptIds": ["01HXP1DRTM5G8Z2N3KQ7VAW4PA"],
"competitors": [
{
"brand": "Nike",
"brandDomain": "nike.com"
}
]
}
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({
workspaceId: '01HX7K2YV9D3M8N0G6Q5R4S3T2',
reportTitle: 'Adidas Visibility Report',
brand: 'Adidas',
brandDomain: 'adidas.com',
promptIds: ['01HXP1DRTM5G8Z2N3KQ7VAW4PA'],
competitors: [{brand: 'Nike', brandDomain: 'nike.com'}]
})
};
fetch('https://data.otterly.ai/v1/reports/brand', 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",
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([
'workspaceId' => '01HX7K2YV9D3M8N0G6Q5R4S3T2',
'reportTitle' => 'Adidas Visibility Report',
'brand' => 'Adidas',
'brandDomain' => 'adidas.com',
'promptIds' => [
'01HXP1DRTM5G8Z2N3KQ7VAW4PA'
],
'competitors' => [
[
'brand' => 'Nike',
'brandDomain' => 'nike.com'
]
]
]),
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"
payload := strings.NewReader("{\n \"workspaceId\": \"01HX7K2YV9D3M8N0G6Q5R4S3T2\",\n \"reportTitle\": \"Adidas Visibility Report\",\n \"brand\": \"Adidas\",\n \"brandDomain\": \"adidas.com\",\n \"promptIds\": [\n \"01HXP1DRTM5G8Z2N3KQ7VAW4PA\"\n ],\n \"competitors\": [\n {\n \"brand\": \"Nike\",\n \"brandDomain\": \"nike.com\"\n }\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")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"workspaceId\": \"01HX7K2YV9D3M8N0G6Q5R4S3T2\",\n \"reportTitle\": \"Adidas Visibility Report\",\n \"brand\": \"Adidas\",\n \"brandDomain\": \"adidas.com\",\n \"promptIds\": [\n \"01HXP1DRTM5G8Z2N3KQ7VAW4PA\"\n ],\n \"competitors\": [\n {\n \"brand\": \"Nike\",\n \"brandDomain\": \"nike.com\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://data.otterly.ai/v1/reports/brand")
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 \"workspaceId\": \"01HX7K2YV9D3M8N0G6Q5R4S3T2\",\n \"reportTitle\": \"Adidas Visibility Report\",\n \"brand\": \"Adidas\",\n \"brandDomain\": \"adidas.com\",\n \"promptIds\": [\n \"01HXP1DRTM5G8Z2N3KQ7VAW4PA\"\n ],\n \"competitors\": [\n {\n \"brand\": \"Nike\",\n \"brandDomain\": \"nike.com\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "01HXBR1DGM5XY8Z2N3KQ7VAW4P",
"workspaceId": "01HX7K2YV9D3M8N0G6Q5R4S3T2",
"brand": "Adidas",
"brandVariations": [
"adidas",
"Adidas AG"
],
"brandDomain": "adidas.com",
"brandDomainVariations": [
"adidas.de",
"adidas.co.uk"
],
"brandDomainWildcard": false,
"brandRegex": null,
"countries": [
"us",
"de",
"uk"
],
"competitors": [
{
"brand": "Nike",
"brandVariations": [
"nike",
"Nike Inc."
],
"brandDomain": "nike.com",
"brandDomainVariations": [
"nike.de",
"nike.co.uk"
],
"brandDomainWildcard": false,
"brandRegex": null
}
],
"reportTitle": "Adidas Visibility Report",
"createdDate": "2024-11-01T12:00:00.000Z",
"updatedDate": "2025-05-01T08:30:00.000Z",
"promptIds": [
"01HXP1DRTM5G8Z2N3KQ7VAW4PA",
"01HXP2DRTM5G8Z2N3KQ7VAW4PB"
],
"countryPromptsTotal": {
"us": 50,
"de": 35,
"uk": 28
},
"tags": [
{
"id": "01HX8AB3CDE4FG5HJ6KL7MN8PQ",
"name": "Running Shoes",
"color": "orange"
}
]
}{
"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
Body
application/json
Response
The created brand report.