Skip to main content
mulberry is steered by a description: one natural sentence that says how the voice should sound. write the voice you want, then your spoken text. hear one:

the description formula

weave the attributes into one sentence instead of listing them as fields. a useful shape is:
a {gender} {age} {accent} voice, {pitch} pitch, {timbre}, {pacing} pacing, {emotion}, {register} register, like a {role}.
the {...} parts are placeholders you fill in. mention only the ones you care about; the model fills in the rest.

hear different voices

each one follows the formula. press play, and copy any sample to start from it.
saying numbers, IDs and dates. silk normalizes your text before speaking it, so amounts, dates, times and percentages are read out for you. anything that must be read digit by digit, like an OTP or an order number, has to be wrapped in double quotes. your description is never touched. see numbers, IDs & dates.

send it

put the voice in description and your spoken text in text. add speaker to use a preset voice instead of a description.
see the API reference for the full request schema.

voice attributes

mention any of these in your description. write hindi words in devanagari and english words in latin, e.g. आज का episode थोड़ा अलग है.
  • gender: male, female
  • age: 20s, 30s, 40s
  • pitch: low, normal, high
  • pacing: very slow, slow, conversational, brisk, fast, very_fast
  • emotion: neutral, energetic, excited, sad, sarcastic, dry, crying, angry
  • intensity: low, med, high
  • register: formal, neutral, casual
global: american, british, middle_eastern, asian_american, indianindian regional: hindi, punjabi, bihari, south_indian, bengali, rajasthani, marathi, gujarati, kashmiri, assamese, odia, telugu, kannada, malayali, haryanvi, chhattisgarhi
realistic: deep, warm, gravelly, smooth, raspy, nasally, throaty, harsh, whispercreative: adds robotic, ethereal to the realistic set
pick a role from a domain to anchor the delivery style.
  • social: youtube_vlogger, social_media_creator, influencer_voice, streamer_companion
  • podcast: podcast_host, interviewer
  • commercial: ad_narrator, brand_spokesperson, product_demo_voice, sales_pitch_voice
  • education: elearning_instructor, kids_story_voice
  • support: customer_support_agent, virtual_receptionist, healthcare_assistant
  • entertainment: storyteller, social_media_reaction, meme_voice
  • corporate: explainer_video_voice, event_host, corporate_training_narrator
  • viral: short_form_narrator, meme_voice
available when you want a non-realistic timbre (characters, stylized voices):

inline tags

drop these in the text to trigger a sound. they render as part of the performance, not as words.

preset voices

your description is always required, and on its own it’s what the voice is built from. add speaker to pin one of the twelve named voices instead: names are case-insensitive, and description still goes with the request. see the mulberry page for a full request.

using mulberry in a voice agent

mulberry reads a complete sentence or utterance at once, not a running token stream. but it streams the audio out, so the first audio comes back before the whole line finishes synthesizing. wait until your LLM has a full sentence, send that, and stream the audio to the caller. that makes it a good fit for low-latency conversational agents. keep one voice across the conversation. the description defines the voice, so for a given bot send the same description string on every request. reusing it keeps the persona consistent turn to turn. a preset speaker is the other way to pin a fixed voice. an unknown or misspelled inline tag is spoken literally, not rejected, so validate the text before production. for transport, see streaming and the pipecat integration.

system prompt for your agent’s LLM

hand this to the LLM that writes mulberry’s lines. tune the wording, not the attributes.

common mistakes

most “the voice ignored me” cases trace back to one of these:

faq

one sentence with 3 to 5 attributes beats a paragraph of vague adjectives. mention only what you care about; the model fills in the rest.
it isn’t either/or. description is always required; send it every time. on its own, the voice is generated from it. add speaker when you want one of the twelve named voices instead of a generated one.
send the identical description on every request for that bot. pinning a speaker as well makes it steadier still.
yes. drop inline tags like <laugh>, <sigh>, <chuckle> directly in the text where you want the sound.