Miso One API

Generate multi-voice dialogue audio with the Miso One API.

Overview

The Miso One API turns a written multi-speaker script into an audio file. Send a dialogue request, receive a task ID, then poll the task until the audio result is ready.

Miso One currently authenticates with your logged-in web session. Include your session cookie when calling the API from a browser session or a trusted tool that can access that session.

Authentication

Cookie: <session cookie>

If the session is missing or expired, the API returns an auth error.

Create a dialogue task

POST /api/ai/generate
Content-Type: application/json
Cookie: <session cookie>

Request body

{
  "mediaType": "speech",
  "presetId": "miso-one",
  "options": {
    "dialogue": [
      { "voice": "Adam", "text": "[excited] Did you hear the news?" },
      { "voice": "Brian", "text": "[laughs] Tell me everything." }
    ],
    "language_code": "en"
  }
}
FieldTypeRequiredDescription
mediaTypestringyesAlways "speech"
presetIdstringyesAlways "miso-one"
options.dialoguearrayyesOrdered speaker lines. Each item needs voice and text.
options.language_codestringnoLanguage hint such as "en", "zh", "ja", or "ko".
options.stabilitynumbernoVoice stability setting. Omit this field to use the default value.
promptstringnoOptional note saved with the task.

Dialogue line format

{
  "voice": "Adam",
  "text": "[excited] The launch went perfectly."
}

Use one dialogue line per speaker turn. The total spoken text in a single request can include up to 5,000 characters.

Poll task status

The create endpoint returns immediately with a task object. Use the task id to check progress.

POST /api/ai/query
Content-Type: application/json
Cookie: <session cookie>

Query body

{
  "taskId": "task_xxx"
}

Pending response

{
  "code": 0,
  "message": "ok",
  "data": {
    "id": "task_xxx",
    "status": "processing",
    "mediaType": "speech",
    "presetId": "miso-one",
    "displayModel": "Miso One",
    "prompt": null,
    "taskInfo": null
  }
}

Completed response

When status is "success", parse data.taskInfo. It contains an audios array with the generated audio URL.

{
  "code": 0,
  "message": "ok",
  "data": {
    "id": "task_xxx",
    "status": "success",
    "mediaType": "speech",
    "presetId": "miso-one",
    "displayModel": "Miso One",
    "taskInfo": "{\"audios\":[{\"id\":\"task_xxx-0\",\"audioUrl\":\"https://cdn.example.com/audio.mp3\"}]}"
  }
}

Task statuses:

StatusMeaning
pendingThe task has been created.
processingThe audio is still being generated.
successThe audio is ready in taskInfo.audios.
failedThe task failed. Check taskInfo.errorCode.
canceledThe task was canceled.

Supported voices

VoiceCharacter
AdamWarm, expressive male
BrianNatural, conversational male
RogerClear, authoritative male
RachelCalm, professional female
AntoniSmooth, focused male
BellaBright, energetic female
ElliFriendly, approachable female
JoshDeep, confident male
ArnoldFirm, grounded male
ClydeRelaxed, casual male
DomiClear, neutral female
FreyaWarm, empathetic female
GraceLight, pleasant female
NicoleSoft, thoughtful female
SamVersatile, neutral
SarahCrisp, professional female

Emotion tags

Add emotion tags at the start of a line to guide delivery:

[excited] Great news!
[whispers] Can you keep a secret?
[laughs] That is hilarious.
[sighs] I was not expecting that.

Credit cost

Dialogue generation uses dynamic credit billing based on total spoken text:

RuleValue
Min30 credits per generation
Rate500 credits per 1,000 characters
Limit5,000 characters per request

curl example

APP_URL="https://misooneai.com"

TASK_RESPONSE=$(curl "$APP_URL/api/ai/generate" \
  -H "Content-Type: application/json" \
  -H "Cookie: <your-session-cookie>" \
  -d '{
    "mediaType": "speech",
    "presetId": "miso-one",
    "options": {
      "dialogue": [
        { "voice": "Adam", "text": "[excited] The launch went perfectly." },
        { "voice": "Rachel", "text": "Incredible. What happens next?" },
        { "voice": "Adam", "text": "We scale." }
      ],
      "language_code": "en"
    }
  }')

echo "$TASK_RESPONSE"

Then poll the returned task ID:

curl "$APP_URL/api/ai/query" \
  -H "Content-Type: application/json" \
  -H "Cookie: <your-session-cookie>" \
  -d '{"taskId":"task_xxx"}'

JavaScript example

const createResponse = await fetch('/api/ai/generate', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    mediaType: 'speech',
    presetId: 'miso-one',
    options: {
      dialogue: [
        { voice: 'Adam', text: '[excited] The launch went perfectly.' },
        { voice: 'Rachel', text: 'Incredible. What happens next?' },
      ],
      language_code: 'en',
    },
  }),
});

const createPayload = await createResponse.json();
if (createPayload.code !== 0) {
  throw new Error(createPayload.message);
}

const taskId = createPayload.data.id;

const queryResponse = await fetch('/api/ai/query', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ taskId }),
});

const queryPayload = await queryResponse.json();
const taskInfo = queryPayload.data.taskInfo
  ? JSON.parse(queryPayload.data.taskInfo)
  : {};
const audioUrl = taskInfo.audios?.[0]?.audioUrl;

Errors

All API responses use the same envelope:

{
  "code": -1,
  "message": "generate ai task failed",
  "data": {
    "errorCode": "auth_required"
  }
}

Common error codes:

Error codeMeaning
auth_requiredThe user is not logged in or the session expired.
insufficient_creditsThe account does not have enough credits.
invalid_inputThe request body is missing required fields.
content_policyThe dialogue content was rejected.