Brand Voice Pipeline
This guide walks you through importing a brand voice from your website, verifying the result, and using it to generate on-brand content.
What you'll build
- Import a brand voice from a URL (draft/preview)
- Save the draft to your workspace
- Use it as a system message in chat completions
- List your workspace's brand voices
Prerequisites
- A neuroflash account with API access
- Your
client_idandclient_secret(see Authentication)
Step 1: Authenticate
- cURL
- Python
- Node.js
- Go
curl -X POST https://id.neuroflash.com/oauth/v2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "scope=openid"
import requests
BASE_URL = "https://app.neuroflash.com/api"
token = requests.post(
"https://id.neuroflash.com/oauth/v2/token",
data={"grant_type": "client_credentials", "client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET", "scope": "openid"},
).json()["access_token"]
headers = {"Authorization": f"Bearer {token}"}
const BASE_URL = "https://app.neuroflash.com/api";
const { access_token } = await fetch("https://id.neuroflash.com/oauth/v2/token", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "client_credentials",
client_id: "YOUR_CLIENT_ID",
client_secret: "YOUR_CLIENT_SECRET",
scope: "openid",
}),
}).then((r) => r.json());
const headers = { Authorization: `Bearer ${access_token}` };
data := url.Values{
"grant_type": {"client_credentials"},
"client_id": {"YOUR_CLIENT_ID"},
"client_secret": {"YOUR_CLIENT_SECRET"},
"scope": {"openid"},
}
resp, _ := http.Post("https://id.neuroflash.com/oauth/v2/token",
"application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
defer resp.Body.Close()
Step 2: Get Your Workspace
- cURL
- Python
- Node.js
- Go
curl "https://app.neuroflash.com/api/workspace-service/v1/workspaces" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
workspaces = requests.get(f"{BASE_URL}/workspace-service/v1/workspaces", headers=headers).json()
workspace_id = workspaces["_embedded"]["workspaces"][0]["id"]
const workspaces = await fetch(`${BASE_URL}/workspace-service/v1/workspaces`, { headers })
.then((r) => r.json());
const workspaceId = workspaces._embedded.workspaces[0].id;
req, _ := http.NewRequest("GET", baseURL+"/workspace-service/v1/workspaces", nil)
req.Header.Set("Authorization", "Bearer "+token)
// parse _embedded.workspaces[0].id into workspaceID
Step 3: Import from URL (Get the Draft)
Brand voice import involves AI analysis and may take 10–30 seconds.
- cURL
- Python
- Node.js
- Go
curl -X POST "https://app.neuroflash.com/api/brand-voice-service/v1/workspaces/{workspace_id}/brand-voice-url-imports" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"audienceModelId": "538b1efc6f88ad88feebf7acd8c618facb54fe82",
"country": "us",
"language": "en",
"url": "https://your-brand.com"
}'
draft = requests.post(
f"{BASE_URL}/brand-voice-service/v1/workspaces/{workspace_id}/brand-voice-url-imports",
headers={**headers, "Content-Type": "application/json"},
json={
"audienceModelId": "538b1efc6f88ad88feebf7acd8c618facb54fe82",
"country": "us",
"language": "en",
"url": "https://your-brand.com",
},
).json()
# draft["brandVoice"] is a preview — no id, not saved yet
brand_voice_draft = draft["brandVoice"]
const draft = await fetch(
`${BASE_URL}/brand-voice-service/v1/workspaces/${workspaceId}/brand-voice-url-imports`,
{
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify({
audienceModelId: "538b1efc6f88ad88feebf7acd8c618facb54fe82",
country: "us",
language: "en",
url: "https://your-brand.com",
}),
}
).then((r) => r.json());
// draft.brandVoice is a preview — no id, not saved yet
body, _ := json.Marshal(map[string]any{
"audienceModelId": "538b1efc6f88ad88feebf7acd8c618facb54fe82",
"country": "us",
"language": "en",
"url": "https://your-brand.com",
})
req, _ := http.NewRequest("POST",
baseURL+"/brand-voice-service/v1/workspaces/"+workspaceID+"/brand-voice-url-imports",
bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
Response:
{
"brandVoice": {
"name": "neuroflash",
"description": "A clear, confident, and human tone that emphasises speed, simplicity, and trust. Prefers active voice, short sentences, and practical examples over jargon.",
"language": "en",
"country": "us"
},
"brand": {
"name": "neuroflash",
"values": ["innovation", "simplicity"],
"phones": []
}
}
The import response contains no id and is not saved to your workspace. The brandVoice
object is a draft — an AI-extracted style profile ready to be reviewed and saved.
If you want full control over the brand voice settings from the start, use POST /brand-voices
with creationSourceType: "manual" and a brand object instead. The import endpoints are
faster for bootstrapping but require a publicly accessible URL.
Import parameters reference
| Parameter | Description | Default |
|---|---|---|
audienceModelId | Embedding model for audience analysis | 538b1efc6f88ad88feebf7acd8c618facb54fe82 |
country | 2-letter ISO country code, lowercase | — (required) |
language | 2-letter ISO language code, lowercase | — (required) |
Note: country and language must form a valid pair. Refer to the
supported locale pairs table.
Step 4: Save the Brand Voice
The import response is a draft. To persist it, pass the extracted attributes to
POST /brand-voices:
- cURL
- Python
- Node.js
- Go
curl -X POST "https://app.neuroflash.com/api/brand-voice-service/v1/workspaces/{workspace_id}/brand-voices" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "neuroflash",
"description": "A clear, confident, and human tone that emphasises speed, simplicity, and trust.",
"language": "en",
"country": "us",
"creationSourceType": "url",
"creationSourceURL": "https://your-brand.com",
"brand": { "name": "neuroflash", "values": ["innovation", "simplicity"], "phones": [] }
}'
bv = brand_voice_draft
saved = requests.post(
f"{BASE_URL}/brand-voice-service/v1/workspaces/{workspace_id}/brand-voices",
headers={**headers, "Content-Type": "application/json"},
json={
"name": bv["name"],
"description": bv.get("description"),
"language": bv.get("language"),
"country": bv.get("country"),
"creationSourceType": "url",
"creationSourceURL": "https://your-brand.com",
"brand": {
"name": draft["brand"].get("name", bv["name"]),
"values": draft["brand"].get("values", []),
"phones": draft["brand"].get("phones", []),
},
},
).json()
brand_voice_id = saved["id"]
brand_voice_description = saved["description"]
const { brandVoice: bv, brand } = draft;
const saved = await fetch(
`${BASE_URL}/brand-voice-service/v1/workspaces/${workspaceId}/brand-voices`,
{
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify({
name: bv.name,
description: bv.description,
language: bv.language,
country: bv.country,
creationSourceType: "url",
creationSourceURL: "https://your-brand.com",
brand: { name: brand.name || bv.name, values: brand.values || [], phones: [] },
}),
}
).then((r) => r.json());
const brandVoiceId = saved.id;
createBody, _ := json.Marshal(map[string]any{
"name": bv["name"], "description": bv["description"],
"language": bv["language"], "country": bv["country"],
"creationSourceType": "url", "creationSourceURL": "https://your-brand.com",
"brand": map[string]any{
"name": draft.Brand["name"], "values": []any{}, "phones": []any{},
},
})
req, _ = http.NewRequest("POST",
baseURL+"/brand-voice-service/v1/workspaces/"+workspaceID+"/brand-voices",
bytes.NewReader(createBody))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
// parse response to get the saved brand voice with id
Response (the brand voice is now saved with an id and workspaceId):
{
"id": "7d3a6a83-2e19-4dcb-a8a0-5d8f2f8c1c6f",
"workspaceId": "b481b98b-a7ed-4d72-a1f2-8b2ae3a57854",
"name": "neuroflash",
"description": "A clear, confident, and human tone that emphasises speed, simplicity, and trust.",
"language": "en",
"country": "us",
"createdAt": "2026-04-09T12:00:00Z"
}
Step 5: Verify the Brand Voice
- cURL
- Python
- Node.js
- Go
curl "https://app.neuroflash.com/api/brand-voice-service/v1/workspaces/{workspace_id}/brand-voices/{brand_voice_id}" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
bv = requests.get(
f"{BASE_URL}/brand-voice-service/v1/workspaces/{workspace_id}/brand-voices/{brand_voice_id}",
headers=headers,
).json()
print(bv["name"], bv["language"], bv["country"])
const bv = await fetch(
`${BASE_URL}/brand-voice-service/v1/workspaces/${workspaceId}/brand-voices/${brandVoiceId}`,
{ headers }
).then((r) => r.json());
req, _ := http.NewRequest("GET",
baseURL+"/brand-voice-service/v1/workspaces/"+workspaceID+"/brand-voices/"+brandVoiceID, nil)
req.Header.Set("Authorization", "Bearer "+token)
Key fields: id, name, description, language, country.
Step 6: Use in Content Generation
Pass brandVoice.description as a system message. This is the recommended pattern for keeping
generated content on-brand.
- cURL
- Python
- Node.js
- Go
curl -X POST "https://app.neuroflash.com/api/ds-prototypes/chat/completions" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-workspace-id: YOUR_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-4.1-mini",
"messages": [
{ "role": "system", "content": "Follow this brand voice: A clear, confident, and human tone..." },
{ "role": "user", "content": "Write a product announcement for our new feature." }
]
}'
response = requests.post(
f"{BASE_URL}/ds-prototypes/chat/completions",
headers={**headers, "x-workspace-id": workspace_id, "Content-Type": "application/json"},
json={
"model": "openai/gpt-4.1-mini",
"messages": [
{"role": "system", "content": f"Follow this brand voice: {brand_voice_description}"},
{"role": "user", "content": "Write a product announcement for our new feature."},
],
},
).json()
const response = await fetch(`${BASE_URL}/ds-prototypes/chat/completions`, {
method: "POST",
headers: { ...headers, "x-workspace-id": workspaceId, "Content-Type": "application/json" },
body: JSON.stringify({
model: "openai/gpt-4.1-mini",
messages: [
{ role: "system", content: `Follow this brand voice: ${imported.brandVoice.description}` },
{ role: "user", content: "Write a product announcement for our new feature." },
],
}),
}).then((r) => r.json());
body, _ := json.Marshal(map[string]any{
"model": "openai/gpt-4.1-mini",
"messages": []map[string]string{
{"role": "system", "content": "Follow this brand voice: " + brandVoiceDescription},
{"role": "user", "content": "Write a product announcement for our new feature."},
},
})
req, _ := http.NewRequest("POST", baseURL+"/ds-prototypes/chat/completions", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("x-workspace-id", workspaceID)
req.Header.Set("Content-Type", "application/json")
Step 7: List Your Brand Voices
- cURL
- Python
- Node.js
- Go
curl "https://app.neuroflash.com/api/brand-voice-service/v1/workspaces/{workspace_id}/brand-voices" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
voices = requests.get(
f"{BASE_URL}/brand-voice-service/v1/workspaces/{workspace_id}/brand-voices",
headers=headers,
).json()
for v in voices.get("_embedded", {}).get("brandVoices", []):
print(v["id"], v["name"])
const voices = await fetch(
`${BASE_URL}/brand-voice-service/v1/workspaces/${workspaceId}/brand-voices`,
{ headers }
).then((r) => r.json());
req, _ := http.NewRequest("GET",
baseURL+"/brand-voice-service/v1/workspaces/"+workspaceID+"/brand-voices", nil)
req.Header.Set("Authorization", "Bearer "+token)