Skip to navigation

Keyword Boosting

Boost specific words or phrases so the Pulse speech-to-text model recognizes them correctly, on both.
View as Markdown
Pre-Recorded Real-Time

Keyword boosting lets you bias the Pulse speech-to-text model toward specific words or phrases. Useful for proper nouns, brand names, technical terms, and any domain vocabulary the model might otherwise misrecognize.

Supported on both surfaces:

  • Realtime WebSocket (WSS /waves/v1/stt/live?model=pulse): pass keywords on the connection URL.
  • Pre-recorded HTTP (POST /waves/v1/pulse/get_text): pass keywords as a query parameter on the request.

The parameter name, format, and tuning guidance are the same on both.

Format

Keywords are passed in the keywords query parameter. Each entry follows this shape:

KEYWORD:INTENSIFIER
PartRequiredDescription
KEYWORDYesThe word or phrase to boost. Matching is case-sensitive: use the exact casing you want in the output (Blackwell, not blackwell, if you want the brand name capitalized). Phrases can contain spaces (small language model).
INTENSIFIERNoA number controlling boost strength. Defaults to 1.0 if omitted. See the intensifier table below.

Intensifier scale

1 is the default when the intensifier is omitted. Start there and raise only if the word still isn’t recognized.

ValueWhen to use
1The starting point for every keyword. Good for rare proper nouns you expect to be spoken clearly.
2 to 3Domain jargon the model sometimes misrecognizes.
4 to 10Words the model consistently gets wrong at lower values.
Above 10Not recommended. The higher the intensifier, the more likely the model inserts the keyword when it was not spoken.

Keep the same starting point across all keywords in a list. Tuning one keyword up while others stay at 1 skews the balance of the boost.

Casing

Keyword matching is case-sensitive. Provide the exact casing you want the transcript to render.

  • Brand names, product names, and proper nouns: capitalize them.
    keywords=Blackwell:2,Jensen Huang:2,NVIDIA:2
  • Acronyms: keep them uppercase.
    keywords=CVV:2,CUDA:2,SLM:2
  • Common words that happen to be homophones of a proper noun (Sonnet the model vs sonnet the poem): boost the cased form you want, and the model will emit that spelling.

Realtime (WebSocket)

Add keywords to the WebSocket connection URL. Keywords stay in effect for the whole session.

Single keyword

const url = new URL("wss://api.smallest.ai/waves/v1/stt/live?model=pulse");
url.searchParams.append("language", "en");
url.searchParams.append("encoding", "linear16");
url.searchParams.append("sample_rate", "16000");
url.searchParams.append("keywords", "Blackwell:2");
const ws = new WebSocket(url.toString(), {
headers: {
Authorization: `Bearer ${API_KEY}`,
},
});

Multiple keywords

wss://api.smallest.ai/waves/v1/stt/live?model=pulse&language=en&encoding=linear16&sample_rate=16000&keywords=Blackwell:2,Jensen Huang:2,NVIDIA:1

Mix of boosted and default-intensity keywords

wss://api.smallest.ai/waves/v1/stt/live?model=pulse&language=en&encoding=linear16&sample_rate=16000&keywords=CEO,NVIDIA:2,Jensen

CEO and Jensen have no explicit intensifier, so both default to 1.0.

Pre-recorded (HTTP)

Add keywords to the query string on the pre-recorded endpoint. Both paths accept it:

  • POST /waves/v1/pulse/get_text: the legacy Pulse route.
  • POST /waves/v1/stt/?model=pulse: the unified STT route (recommended for new integrations).

The boost applies to that request only.

Accepted encodings

Three query-string encodings are accepted for multiple keywords. Comma-string is the recommended shape (shortest URL, single parameter, easiest to log).

ShapeExampleNotes
Comma-string (recommended)keywords=Blackwell:2,Jensen Huang:2,NVIDIA:1One parameter, entries joined with ,.
Repeated keykeywords=Blackwell:2&keywords=Jensen Huang:2&keywords=NVIDIA:1Standard multi-value query pattern.
Bracketed array keykeywords[]=Blackwell:2&keywords[]=Jensen Huang:2&keywords[]=NVIDIA:1PHP/Rails-style array notation.

Do not wrap the value in a JSON array literal (keywords=["Blackwell:2","Jensen Huang:2"]). The request succeeds but nothing is boosted. Use one of the three encodings above.

URLSearchParams in JavaScript and urlencode() in Python handle the URL-encoding for you; pass the raw comma-string.

cURL, legacy route

curl -X POST "https://api.smallest.ai/waves/v1/pulse/get_text?language=en&keywords=Blackwell:2,Jensen%20Huang:2,NVIDIA:1" \
-H "Authorization: Bearer $SMALLEST_API_KEY" \
-H "Content-Type: application/octet-stream" \
--data-binary "@./call.wav"

cURL, unified route

curl -X POST "https://api.smallest.ai/waves/v1/stt/?model=pulse&language=en&keywords=Blackwell:2,Jensen%20Huang:2,NVIDIA:1" \
-H "Authorization: Bearer $SMALLEST_API_KEY" \
-H "Content-Type: application/octet-stream" \
--data-binary "@./call.wav"

Python

import requests
with open("./call.wav", "rb") as f:
audio = f.read()
params = {
"language": "en",
"keywords": "Blackwell:2,Jensen Huang:2,NVIDIA:1",
}
r = requests.post(
"https://api.smallest.ai/waves/v1/pulse/get_text",
params=params,
data=audio,
headers={
"Authorization": f"Bearer {SMALLEST_API_KEY}",
"Content-Type": "application/octet-stream",
},
timeout=60,
)
print(r.json()["transcription"])

JavaScript / TypeScript

import { readFileSync } from "node:fs";
const audio = readFileSync("./call.wav");
const params = new URLSearchParams({
language: "en",
keywords: "Blackwell:2,Jensen Huang:2,NVIDIA:1",
});
const res = await fetch(`https://api.smallest.ai/waves/v1/pulse/get_text?${params}`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SMALLEST_API_KEY}`,
"Content-Type": "application/octet-stream",
},
body: audio,
});
console.log((await res.json()).transcription);

Works with

keywords combines freely with diarize, word_timestamps, redact_pii, and redact_pci on both surfaces, and with webhook_url on the pre-recorded endpoint.

Reuse your keyword list

Keep the same keyword list across requests when the vocabulary is stable (a caller’s brand names, a product’s technical terms, a customer’s account glossary). Regenerate the list only when the vocabulary changes.

Limits

  • Max 100 keywords. Sending more returns 400 with keywords too large (max 100) in errors[].
  • Intensifier: default 1, recommended 1 to 3. Above 10 is not recommended.
  • Each keyword is a string. Phrases can include spaces (small language model:2). A phrase cannot contain a comma; commas separate entries.
  • Matching is case-sensitive. Use the exact casing you want in the transcript.
  • Duplicates: last-wins. NVIDIA:1,NVIDIA:5 is equivalent to NVIDIA:5.
  • Non-numeric intensifier: must be a number. Pulse:notanumber is read as the whole phrase at intensifier 1.
  • Negative intensifier suppresses instead of boosting (checkout:-5), to prefer against a homograph.

Colons in a phrase

The intensifier is the number after the last :. A brand name that contains a colon (re:Invent) round-trips as the whole phrase at the default intensifier:

keywords=re:Invent

Add an explicit intensifier by suffixing :N. x:y:2 is phrase x:y at intensifier 2:

keywords=re:Invent:2

Start every keyword at 1. Raise to 2 or 3 only if the base intensity is missing the word. The maximum is 10; above that the model may insert the keyword when it was not spoken. Keep intensifiers in the 1 to 3 range.