Documentation

Brand Voice Check

Every post is checked against your brand voice before it publishes or schedules. What it compares, how it scores, and how to read the result.

Before anything goes out, BlackOps checks what's written against the brand voice you've set up for that site. Content that doesn't sound like you is stopped with the rules it broke, so you can fix it or go ahead anyway.

When it runs

The check runs at the moment content is committed: when you publish, and when you schedule. Scheduling counts, so a queue is checked when you build it rather than when each item fires. It covers tweets and threads, blog posts, X articles, LinkedIn, Threads and TikTok, and each item in a campaign.

What it checks against

Your site's brand voice in BlackOps: the voice profile plus its style rules (for example "never use em dashes" or "write in first person"). Rules you've scoped to a platform or mode apply only there.

The voice is per site. A post going to one site is checked against that site's voice, not another's.

How it scores

The check is run by Jev, TypeSafe's typed judgment engine. It answers these questions about the text:

  1. Overall voice. How well does it match your voice? There are five levels, from "a reader who knows you wouldn't recognise it as yours" to "every sentence reads as you". The level sets the score: 15, 40, 60, 80 or 95.
  2. Each style rule. Does the text clearly break it? A rule it's fairly sure is broken is listed as a violation.
  3. How serious each break is. This is a separate question: is the break repeated, in a prominent place like the opening, or bad enough on its own that a reader would doubt you wrote it? A serious break caps the score at 49. A break that's certain but minor, such as one slip in a passing phrase, is still listed but doesn't fail the post on its own.

The pass mark is 70. "Your voice throughout, with at most an isolated slip a reader would pass over" (80) passes. "Slips recur often enough that a reader would notice the voice wavering" (60) does not. The levels describe what a reader notices rather than counting sentences, so a long post isn't held to a stricter standard than a short one.

It judges the text as the platform it's going to. A terse reply on X isn't marked down for being terse the way a blog post would be.

It only judges voice. It doesn't check facts, links or whether the content is good.

When it fails

Publishing or scheduling is refused, and the message names what broke, worst first. If nothing specific broke but the overall voice missed, it names the level it landed on.

Revise the text and try again, or go ahead anyway with override_brand_voice: true. An override is recorded with who did it, so it stays answerable.

Checking before you publish

To find out whether a draft would pass without publishing it, run the same check as a dry run. In an AI assistant connected to BlackOps, ask it to check the draft's voice; it calls the check_brand_voice tool. Over the API, it's POST /api/v2/brand/voice/check:

{
  "domain": "example.com",
  "surface": "tweet",
  "content": "Shipped the scheduler fix. It polls every 5 minutes now."
}

surface is where the text would go: post (a blog post, with an optional title), tweet, thread (an X thread, with content as one string per tweet), linkedin, threads or tiktok.

The answer is the verdict publishing would give for that exact text: passed, score, pass_mark, every violation worst first, the passages it quoted as least like you, and on a failure the same message a refused publish returns. It also carries the voice_check object described below.

A dry run publishes nothing and records nothing. Publishing the same text later still runs its own check.

When content goes through without a verdict

The check lets content through rather than blocking your publishing when it can't give a real opinion:

  • No brand voice set up for the site.
  • The site's very first piece of content. There's nothing yet to drift from.
  • The check couldn't run, for example the service didn't answer in time.

These show up as degraded in the result (see below), so they're never confused with a pass.

Empty content (an image-only post, say) is skipped.

Checked once per version

A verdict applies to the exact text that was checked. Publishing or rescheduling the same text reuses it. Change one character and it's checked again.

Reading the result

Publish and schedule responses include a voice_check object:

{
  "status": "passed",
  "engine": "jev",
  "model": "jev:jev-1.13.0",
  "score": 80,
  "threshold": 70
}
FieldMeaning
statuspassed, failed, overridden, degraded (went through without a verdict) or skipped (nothing to check)
reasonWhy there was no verdict: no_voice_configured, first_content, critic_error, critic_unavailable or empty_content
engineWhat judged it: jev, llm (the fallback checker) or mechanical
modelThe exact model behind the verdict
score, thresholdThe score, and the pass mark it was held to
violationsUp to three rules it broke, worst first
reusedThe verdict came from an earlier check of the same text

On a refusal, the same object comes back with the error so you can see exactly why.

Related

Want this page as machine-readable markdown? GET /docs/features/brand-voice-check.md