Brand Boards Update Voice
Immutable Catalog Entry
This descriptor comes from the active versioned Portal catalog.
- Contract tier:
agent_ready - Risk:
write - Catalog version:
2026-07-12.2 - Descriptor hash:
8fee95bd135386139c956427f737cafa4c9c98875603b5a40e0a78af25d51047
Update an existing GHL Brand Voice. GHL category: Marketing / Brand Boards. This writes to Brand Voice configuration. Verified manual/scratch Brand Voice payloads use body.type = "manual" and body.answers as an object containing the UI form answers such as brandName, businessType, toneOfVoice, targetAudience, customerPainPoints, brandPromise, brandValues, whatDoesYourBrandDo, competitorDifference, uniqueSellingProposition, risksOfInaction, and callToAction. Use disposable Brand Voice names during validation and delete test voices in the same flow.
Request Body
{
"jsonrpc": "2.0",
"id": "ghl-brand-boards-update-voice-example",
"method": "tools/call",
"params": {
"name": "ghl.brand_boards_update_voice",
"arguments": {
"brandVoiceId": "brandVoiceId_123",
"body": {},
"query": {},
"tenantId": "tenantId_123",
"locationId": "locationId_123",
"strictTenant": false
}
}
}
Arguments Schema
{
"type": "object",
"required": [
"brandVoiceId",
"body"
],
"properties": {
"body": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Brand Voice name. Use a clear disposable prefix such as MAD_AUDIT_DELETE_ME_* for validation."
},
"type": {
"enum": [
"manual"
],
"type": "string",
"description": "Verified GHL Brand Voice type for the Start from scratch/manual UI flow."
},
"answers": {
"type": "object",
"properties": {
"brandName": {
"type": "string",
"description": "Brand, company, or account name."
},
"brandValues": {
"type": "string",
"description": "Values or standards the brand does not compromise on."
},
"phoneNumber": {
"type": "string",
"description": "Business phone number."
},
"toneOfVoice": {
"type": "string",
"description": "Tone of voice, for example Professional."
},
"brandPromise": {
"type": "string",
"description": "How the brand benefits the audience."
},
"businessType": {
"type": "string",
"description": "Type of business, such as technology services or restaurant."
},
"callToAction": {
"type": "string",
"description": "Most important user action the brand wants people to take."
},
"companyEmail": {
"type": "string",
"description": "Company email."
},
"businessHours": {
"type": "string",
"description": "Business hours."
},
"companyAddress": {
"type": "string",
"description": "Company address."
},
"companyWebsite": {
"type": "string",
"description": "Company website URL."
},
"targetAudience": {
"type": "string",
"description": "Primary audience the brand speaks to."
},
"risksOfInaction": {
"type": "string",
"description": "What happens if the audience does not take action."
},
"customerPainPoints": {
"type": "string",
"description": "Problems or frustrations the brand helps solve."
},
"whatDoesYourBrandDo": {
"type": "string",
"description": "Core products or services the brand provides."
},
"competitorDifference": {
"type": "string",
"description": "What makes the brand better than competitors."
},
"uniqueSellingProposition": {
"type": "string",
"description": "What sets the brand apart in the market."
}
},
"description": "Answers from the GHL Brand Voice manual form. Required when type is manual.",
"additionalProperties": true
}
},
"description": "Verified scratch/manual Brand Voice update body. Use type \"manual\" with answers when updating voice content; name-only updates may also be accepted by GHL.",
"additionalProperties": true
},
"query": {
"type": "object",
"description": "Optional GHL-supported query parameters for this official Brand Boards endpoint, such as pagination or documented filters.",
"additionalProperties": true
},
"tenantId": {
"type": "string",
"description": "Tenant ID from list_tenants."
},
"locationId": {
"type": "string",
"description": "Optional GHL location ID. If provided, it must match the authenticated runtime location; otherwise the runtime location is injected where the official Brand Boards endpoint requires it."
},
"brandVoiceId": {
"type": "string",
"description": "brandVoiceId path parameter required by /brand-boards/public/v1/locations/:locationId/voices/:brandVoiceId."
},
"strictTenant": {
"type": "boolean",
"default": true,
"description": "Require tenantId to match locationId routing (default: true)."
}
},
"additionalProperties": false
}
Output Schema
{
"type": "object",
"required": [
"ok",
"data",
"error",
"meta"
],
"properties": {
"ok": {
"type": "boolean",
"description": "Whether the GHL MCP operation completed successfully."
},
"data": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "array",
"items": {}
},
{
"type": "string"
},
{
"type": "number"
},
{
"type": "boolean"
},
{
"type": "null"
}
],
"description": "Tool-specific GHL or local navigation result when ok is true."
},
"meta": {
"type": "object",
"description": "Safe execution, routing, and timing metadata.",
"additionalProperties": true
},
"error": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"description": "Safe error details when ok is false; credential values are never returned."
}
},
"description": "Normalized GHL MCP response envelope.",
"additionalProperties": false
}
Code Examples
- cURL
- Node.js
- Python
curl -X POST 'https://portal.madpanda3d.com/api/mcp' \
-H 'Authorization: Bearer mad_live_***' \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"id": "ghl-brand-boards-update-voice-example",
"method": "tools/call",
"params": {
"name": "ghl.brand_boards_update_voice",
"arguments": {
"brandVoiceId": "brandVoiceId_123",
"body": {},
"query": {},
"tenantId": "tenantId_123",
"locationId": "locationId_123",
"strictTenant": false
}
}
}'
const response = await fetch('https://portal.madpanda3d.com/api/mcp', {
method: 'POST',
headers: {
Authorization: 'Bearer mad_live_***',
'Content-Type': 'application/json',
},
body: JSON.stringify({
"jsonrpc": "2.0",
"id": "ghl-brand-boards-update-voice-example",
"method": "tools/call",
"params": {
"name": "ghl.brand_boards_update_voice",
"arguments": {
"brandVoiceId": "brandVoiceId_123",
"body": {},
"query": {},
"tenantId": "tenantId_123",
"locationId": "locationId_123",
"strictTenant": false
}
}
}),
});
const data = await response.json();
console.log(data);
import requests
url = 'https://portal.madpanda3d.com/api/mcp'
headers = {
'Authorization': 'Bearer mad_live_***',
'Content-Type': 'application/json',
}
payload = {
"jsonrpc": "2.0",
"id": "ghl-brand-boards-update-voice-example",
"method": "tools/call",
"params": {
"name": "ghl.brand_boards_update_voice",
"arguments": {
"brandVoiceId": "brandVoiceId_123",
"body": {},
"query": {},
"tenantId": "tenantId_123",
"locationId": "locationId_123",
"strictTenant": false
}
}
}
response = requests.post(url, headers=headers, json=payload, timeout=60)
print(response.json())
Example Responses
- 200 Success
- 502 Upstream Error
{
"ok": true,
"message": "Tool ghl.brand_boards_update_voice executed successfully.",
"note": "Response shape varies by MCP tool. Inspect live responses for exact fields."
}
{
"ok": false,
"classification": "upstream_http_error",
"message": "Upstream MCP returned a non-success status."
}