Skip to main content

API Reference

Everything the 데브다이브-모두의창업 AI API can do, gathered in one place. Each entry has a one-line description of what the request does, a table of request fields, a copy-and-run example, and an example response.

If this is your first time, we recommend starting with the Quickstart.


Authentication

Every request requires an API key. Put it in the request header (the extra information sent along with a request) like this.

Authorization: Bearer sk-modoo-...
  • API keys are issued from the dashboard after you subscribe. It's a string that starts with sk-modoo-.
  • A key is like a password. Don't expose it to anyone.
What is the cost in the response?

The cost (or charge) in a response is the credits deducted by this call. Credits are topped up through your subscription or by charging up. You can check your remaining credits with GET /v1/credits.


Base URL

Every request begins with the base address below.

https://modoo.devdive.me

For example, the full address to look up the model list is as follows.

https://modoo.devdive.me/v1/models

Read endpoints

GET /v1/models — Available model list

Tells you the list of AI models you can use right now. (Useful for confirming the exact model name.)

# This request: fetches the list of available AI models.
curl https://modoo.devdive.me/v1/models \
-H "Authorization: Bearer sk-modoo-..."

Example response — each id in the data array is a model name you can actually use.

{
"object": "list",
"data": [
{ "id": "modoo-text", "modality": "chat", "kind": "text" },
{ "id": "modoo-image-z", "modality": "image", "kind": "poll" }
]
}

For detailed descriptions of each model, see the Models guide.


GET /v1/credits — Check your remaining credits

Tells you your current remaining credit balance.

# This request: checks your remaining credits.
curl https://modoo.devdive.me/v1/credits \
-H "Authorization: Bearer sk-modoo-..."

Example response — balance is your remaining credits.

{ "balance": 42.5 }

GET /v1/usage — Recent usage history

Shows the history of your recent requests, newest first.

Field (query)RequiredDescription
limitOptionalHow many to fetch (default 50, max 200)
# This request: fetches up to 50 recent usage records.
curl "https://modoo.devdive.me/v1/usage?limit=50" \
-H "Authorization: Bearer sk-modoo-..."

Example response — each item's charge is the credits deducted by that request.

{
"data": [
{
"id": "req_abc123",
"model": "modoo-text",
"modality": "text",
"input_tokens": 12,
"output_tokens": 30,
"charge": 0.05,
"status": "succeeded",
"created_at": "2026-07-01T09:00:00Z"
}
]
}

A token is the unit in which the AI processes text. Think of it as roughly one or two Korean characters.

Don't add up async jobs from this list

Asynchronous work that returns a job_id (speech-to-text, image, video) is billed in two parts — at submission and at completion — so it appears here as two entries, and entries carry no job_id. To see what a specific job cost, read charge from GET /v1/jobs/{job_id}; that value is the job's total.


Text generation

POST /v1/chat/completions — Text generation (synchronous)

Send a question or instruction and the AI replies in text. This is the most commonly used feature.

FieldRequiredDescription
modelOptionalThe model to use (default modoo-text)
messagesOne of the two requiredA conversation array of { role, content } items
promptOne of the two requiredA single-sentence question/instruction
system_promptOptionalA role/rule guidance given to the AI in advance
max_tokensOptionalMaximum answer length
temperatureOptionalThe answer's creativity (lower is more consistent)
streamOptionalIf true, receive the answer bit by bit in real time

You only need one of messages or prompt. messages is combined into a single request on the server; it does not remember previous conversations. (Function calling / tool features are not supported.)

# This request: asks the AI to write a short greeting.
curl https://modoo.devdive.me/v1/chat/completions \
-H "Authorization: Bearer sk-modoo-..." \
-H "Content-Type: application/json" \
-d '{
"model": "modoo-text",
"messages": [
{ "role": "user", "content": "Write a one-sentence greeting for a new cafe opening" }
]
}'

Example response — the answer is in content, and cost is the credits deducted.

{
"id": "chatcmpl_abc123",
"object": "chat.completion",
"model": "modoo-text",
"content": "We warmly invite you to our newly opened cafe today!",
"usage": {
"input_tokens": 18,
"output_tokens": 24,
"total_tokens": 42
},
"cost": 0.05
}

POST /v1/chat/completions (streaming) — Receive the answer in real time

If you add stream: true, you can receive the answer bit by bit as the text is generated, without waiting for it to finish. This is great for showing it in real time, like in a chat window.

This approach is called SSE (Server-Sent Events). It's a way for the server to keep sending one line at a time in the form data: ....

# This request: receives the answer in real time (streaming).
curl https://modoo.devdive.me/v1/chat/completions \
-H "Authorization: Bearer sk-modoo-..." \
-H "Content-Type: application/json" \
-d '{
"model": "modoo-text",
"prompt": "Write a welcome message",
"stream": true
}'

The response arrives as several lines in order, like this.

data: {"text": "A"}
data: {"text": " newly"}
data: {"text": " opened cafe."}
data: {"usage": {"input_tokens": 10, "output_tokens": 12, "total_tokens": 22}, "cost": 0.03}
data: [DONE]
  • Concatenate the text from the middle lines to get the finished answer.
  • The second-to-last line carries the usage (usage) and deducted credits (cost).
  • When data: [DONE] arrives, it's finished.
  • If a problem occurs during processing, an error line may arrive like this.
data: {"error": {"code": "upstream_error", "message": "A temporary processing error occurred."}}

Multimodal (audio, images, documents, video)

These are convenience features that handle not only text but also audio, images, documents, and video. Input is accepted as a URL, an uploaded file, or plain text, and the output (audio/image/video) is returned as a download URL.

Sending files (multipart) vs. sending only text (JSON)
  • Features that require directly uploading a file (speech recognition, image analysis, document analysis) are sent as multipart/form-data. In curl, use the -F option.
  • Features that send only text (text-to-speech, image generation, video generation) are sent as regular JSON.

POST /v1/audio/speech — Text-to-speech (TTS, synchronous)

Creates an audio file that reads text aloud in a human voice.

FieldRequiredDescription
textRequiredThe sentence to read aloud
modelOptionalmodoo-tts-minimax (default) or modoo-tts-eleven (ElevenLabs)
voice_idOptionalVoice type (minimax default Korean_CalmLady). Required for ElevenLabs — a voice_id from that account (e.g. EXAVITQu4vr4xnSDxMaL)
voice_modelOptionalminimax: speech-2.6-turbo (default) · speech-2.6-hd · ElevenLabs model_id: eleven_flash_v2_5 · eleven_multilingual_v2 (default) · eleven_v3
voice_settingsOptionalElevenLabs-only voice tuning — stability · similarity_boost · style · speed · use_speaker_boost
language_codeOptionalElevenLabs-only — language code (e.g. ko)
output_formatOptionalElevenLabs-only — output format (e.g. mp3_44100_128)
previous_textOptionalElevenLabs-only — the text that comes before this one. It is not spoken; it only carries intonation and pacing over
next_textOptionalElevenLabs-only — the text that comes after this one. Same purpose as above
seedOptionalElevenLabs-only — 0–4294967295. The same seed with the same options returns the same audio (best effort, not guaranteed)
apply_text_normalizationOptionalElevenLabs-only — auto (default) · on · off. Whether numbers, dates and abbreviations are spelled out
Splitting a long script

Calling the API once per paragraph (section) makes the intonation reset at every boundary. Pass the previous paragraph's last sentence as previous_text and the next paragraph's first sentence as next_text, and the sections sound like one continuous read. Both values are context only — they are never spoken, and they need the neighbouring text, not the neighbouring result, so every section can still be requested in parallel.

  • They are unavailable with voice_model: "eleven_v3" (rejected upstream) — use eleven_multilingual_v2 or eleven_flash_v2_5 instead.
  • All four fields are ElevenLabs-only; sending them to minimax (modoo-tts-minimax) returns 422.
# This request: turns a sentence into an audio file.
curl https://modoo.devdive.me/v1/audio/speech \
-H "Authorization: Bearer sk-modoo-..." \
-H "Content-Type: application/json" \
-d '{ "text": "Hello, this is 데브다이브-모두의창업." }'

# With ElevenLabs and voice tuning:
curl https://modoo.devdive.me/v1/audio/speech \
-H "Authorization: Bearer sk-modoo-..." \
-H "Content-Type: application/json" \
-d '{
"text": "Hello, this is 데브다이브-모두의창업.",
"model": "modoo-tts-eleven",
"voice_id": "EXAVITQu4vr4xnSDxMaL",
"voice_model": "eleven_multilingual_v2",
"voice_settings": { "stability": 0.5, "similarity_boost": 0.75 }
}'

Example response — result.audio_url is the address of the created audio file.

{
"id": "aud_abc123",
"model": "modoo-tts-minimax",
"modality": "tts",
"result": { "audio_url": "https://.../speech.mp3" },
"charge": 0.10
}

POST /v1/audio/transcriptions — Speech-to-text (STT, asynchronous)

Transcribes a recording into text. Because processing takes time, it's asynchronous (submit first → check the result later). (See Checking asynchronous job results below.)

Field (form)RequiredDescription
fileOne of file or url requiredThe audio file to upload
urlOne of file or url requiredThe URL of the audio file
languageOptionalLanguage code (default ko)
# This request: submits an audio file to be transcribed into text.
curl https://modoo.devdive.me/v1/audio/transcriptions \
-H "Authorization: Bearer sk-modoo-..." \
-F "[email protected]" \
-F "language=ko"

Example response — you receive a job_id to check the result later.

{
"job_id": "job_abc123",
"status": "processing",
"model": "modoo-stt",
"modality": "stt",
"charge": 0.20
}

POST /v1/images/analyses — Image analysis (synchronous)

Describes what's in a photo, or answers questions about a photo.

Field (form)RequiredDescription
fileOne of file or url requiredThe image file to upload
urlOne of file or url requiredThe image URL
# This request: asks it to describe the contents of an image.
curl https://modoo.devdive.me/v1/images/analyses \
-H "Authorization: Bearer sk-modoo-..." \
-F "[email protected]"

Example response — the analysis result is in result.content as text.

{
"id": "img_abc123",
"model": "modoo-image-analyze",
"modality": "image",
"result": { "content": "It's a photo of a menu board showing an americano and a latte." },
"charge": 0.03
}

POST /v1/documents/analyses — Document analysis (synchronous)

Reads a document and summarizes or analyzes it for you.

Field (form)RequiredDescription
fileOne of file or url requiredThe document file to upload
urlOne of file or url requiredThe document URL
operationOptionalThe task to perform (default summary)
# This request: asks it to summarize a document.
curl https://modoo.devdive.me/v1/documents/analyses \
-H "Authorization: Bearer sk-modoo-..." \
-F "[email protected]" \
-F "operation=summary"

Example response — the result is in result.content.

{
"id": "doc_abc123",
"model": "modoo-docs-analyze",
"modality": "document",
"result": { "content": "This report covers Q1 revenue growth..." },
"charge": 0.04
}

POST /v1/images/generations — Image generation (asynchronous)

Describe the picture you want in words, and it creates the image. Because it takes time, it's asynchronous.

FieldRequiredDescription
promptRequiredA description of the picture you want to draw (for edit models, the change you want)
modelOptionalImage model (default modoo-image-z, others -gpt, editing -edit/-edit-max/-gpt-edit)
sizeOptionalImage size — allowed values differ per model (table below). Omit for the model default
nOptionalHow many to create (default 1; modoo-image-gpt/modoo-image-gpt-edit only, 1–10)
image_urlRequired for edit models*Original image address (image-to-image)
encoded_imageRequired for edit models*Original image as base64 — alternative to image_url
image_urlsOptionalArray of reference image URLs (up to 3) — modoo-image-gpt-edit only

Allowed size values — the notation differs per model family (x vs *). Anything else returns a 422.

ModelAllowed valuesDefault (when omitted)
modoo-image-gpt, modoo-image-gpt-editauto · 1024x1024 · 1536x1024 · 1024x1536auto
modoo-image-z33 width*height values — 1024*1024, 832*1248, 1248*832, 864*1152, 1152*864, 896*1152, 1152*896, 720*1280, 576*1344, 1280*720, 1344*576, 1280*1280, 1024*1536, 1536*1024, 1104*1472, 1472*1104, 1120*1440, 1440*1120, 864*1536, 720*1680, 1536*864, 1680*720, 1536*1536, 1248*1872, 1872*1248, 1296*1728, 1728*1296, 1344*1728, 1728*1344, 1152*2048, 864*2016, 2048*1152, 2016*8641024*1536
modoo-image-edit, modoo-image-edit-max16 width*height values — 1024*1024, 1536*1536, 768*1152, 1024*1536, 1152*768, 1536*1024, 960*1280, 1080*1440, 1280*960, 1440*1080, 720*1280, 1080*1920, 1280*720, 1920*1080, 1344*576, 2048*8721024*1024

* Edit models (modoo-image-edit/-edit-max/-gpt-edit) require a reference image: send one of image_url or encoded_image (base64). modoo-image-gpt-edit also accepts multiple references via image_urls. Sending a reference image to a plain generation model returns a 422 error.

# This request: submits a request to create an image as described.
curl https://modoo.devdive.me/v1/images/generations \
-H "Authorization: Bearer sk-modoo-..." \
-H "Content-Type: application/json" \
-d '{ "prompt": "A small, cozy neighborhood cafe with a warm atmosphere", "model": "modoo-image-z" }'

Example response — you receive a job_id, and once done, the result contains the address of the created image.

{
"job_id": "job_img123",
"status": "processing",
"model": "modoo-image-z",
"modality": "image",
"charge": 0.50
}

Once done, the result includes image_urls, image_url, and fileKeys together.

{
"job_id": "job_img123",
"status": "succeeded",
"model": "modoo-image-z",
"result": {
"image_urls": ["https://.../image1.png"],
"image_url": "https://.../image1.png",
"fileKeys": ["images/image1.png"]
}
}

POST /v1/videos/generations — Video generation (asynchronous)

Describe the video you want in words, and it creates a short video. Because it takes time, it's asynchronous.

FieldRequiredDescription
promptRequiredA description of the video you want to create
modelOptionalVideo model (default modoo-video; image→video is modoo-video-i2v; HappyHorse is modoo-video-happyhorse-t2v/-i2v/-r2v)
negative_promptOptionalA description of elements to avoid
image_urlRequired for i2vhttps address of the first-frame image — modoo-video-i2v/modoo-video-happyhorse-i2v only (base64 not supported)
end_image_urlOptionalhttps address of the closing-frame image for first→last interpolation. Send alongside image_url (the first frame); modoo-video-i2v (WAN 2.7) only
driving_audio_urlOptionalhttps address of audio that drives the motion (e.g. a talking avatar) — modoo-video-i2v (WAN 2.7) only
first_clip_urlOptionalhttps address of an existing clip to continue/extend from — modoo-video-i2v (WAN 2.7) only
reference_image_urlsRequired for r2vList of https addresses for 1–9 character reference images — modoo-video-happyhorse-r2v only
resolutionOptional720P or 1080P — WAN 2.7 · HappyHorse
ratioOptionalaspect ratio (e.g. 16:9·9:16·1:1·4:3·3:4), t2v·r2v only. i2v preserves the input image's ratio
durationOptionalvideo length in seconds (integer) — WAN 2.7 · HappyHorse
watermarkOptionalwhether to show a watermark (true/false) — WAN 2.7 · HappyHorse
seedOptionalseed for reproducibility (integer) — WAN 2.7 · HappyHorse
prompt_extendOptionalupstream prompt expansion (true/false) — WAN 2.7 only

modoo-video-happyhorse-r2v requires reference_image_urls (1–9 images). resolution·ratio·duration·watermark·seed apply to both WAN 2.7 (modoo-video/-i2v) and HappyHorse models (each model ignores knobs it doesn't accept). prompt_extend is WAN 2.7 only.

# This request: submits a request to create a video as described.
curl https://modoo.devdive.me/v1/videos/generations \
-H "Authorization: Bearer sk-modoo-..." \
-H "Content-Type: application/json" \
-d '{ "prompt": "A beach with gentle waves", "model": "modoo-video" }'

Example response — you receive a job_id, and once done, the result contains video_url.

{
"job_id": "job_vid123",
"status": "processing",
"model": "modoo-video",
"modality": "video",
"charge": 2.00
}

POST /v1/audio/music — Music generation (asynchronous)

Give it lyrics and it creates a full song. Because it takes time, it's asynchronous.

FieldRequiredDescription
lyricsRequiredThe lyrics to turn into a song (1–3,500 chars). Use \n for line breaks; structural tags like [Verse]/[Chorus] are allowed
modelOptionalMusic engine versionmusic-2.5 (default) or music-2.0
promptOptionalA description of the desired mood/style (up to 2,000 chars, e.g. a gentle acoustic ballad)
audio_settingOptionalOutput audio settings — sample_rate (16000·24000·32000·44100) · bitrate (32000·64000·128000·256000) · format (mp3·wav·pcm). Anything you omit keeps its default
model means something different here

On every other endpoint, model is a modoo model ID (modoo-...). For music generation it is the upstream music engine version (music-2.5/music-2.0). The modoo model ID is always modoo-music, and that is what the response's model field returns.

# This request: submits a request to make a song from lyrics.
curl https://modoo.devdive.me/v1/audio/music \
-H "Authorization: Bearer sk-modoo-..." \
-H "Content-Type: application/json" \
-d '{
"lyrics": "Autumn night alley, a warm cup of coffee",
"model": "music-2.5",
"prompt": "A gentle acoustic ballad"
}'

Example response — you receive a job_id, and once done, the result's result.audio_url contains the finished song file's address.

{
"job_id": "job_music123",
"status": "processing",
"model": "modoo-music",
"modality": "music",
"charge": 1.50
}

Advanced usage

POST /v1/tasks/{model} — Raw call (advanced)

An advanced feature for using a model that has no separate convenience endpoint (e.g. modoo-web-search, modoo-tts-eleven), or when you want to pass detailed options directly. Put the model name in the {model} slot of the address.

# This request: runs a specific model by passing detailed options directly.
curl https://modoo.devdive.me/v1/tasks/modoo-tts-eleven \
-H "Authorization: Bearer sk-modoo-..." \
-H "Content-Type: application/json" \
-d '{ "text": "Hello" }'
  • For a synchronous model, the result comes back right away.
{
"id": "task_abc123",
"model": "modoo-tts-eleven",
"modality": "tts",
"result": { "audio_url": "https://.../out.mp3" },
"charge": 0.10
}
  • For an asynchronous model, you receive a job_id and check the result with the method below.
{
"job_id": "job_abc123",
"status": "processing",
"model": "modoo-video",
"modality": "video",
"charge": 2.00
}

GET /v1/jobs/{job_id} — Checking asynchronous job results

What is asynchronous (async)? Time-consuming tasks like speech recognition and image/video generation can't return a result right away. So they work in the following order.

  1. When you request a task, you immediately receive a job_id (a job ticket number).
  2. A little later, you check this address with the job_id to see whether the result is ready (polling).
  3. Once status becomes succeeded, you retrieve the result.
# This request: checks whether the submitted job is finished.
curl https://modoo.devdive.me/v1/jobs/job_abc123 \
-H "Authorization: Bearer sk-modoo-..."

Example response — check status first.

{
"job_id": "job_abc123",
"status": "succeeded",
"model": "modoo-image-z",
"charge": 2.4,
"result": {
"image_urls": ["https://.../image1.png"]
}
}
  • status is one of processing (in progress) / succeeded (done) / failed (failed).
  • If it's still processing, check again after a few seconds.
  • If the job number doesn't exist or isn't yours, you'll get a 404.
  • charge is the total credits deducted for this job so far. Async jobs are billed in two parts (at submission and at completion), so the value once status is succeeded is the final amount. On failed it is 0 — the submission charge is refunded.
Don't save media URLs

The image/audio/video URLs in the result expire after a certain amount of time. So don't save the URL itself for long — look it up again when you need it and use the latest URL at that time.


Error format

When a problem occurs, the reason is returned in the response in the form below.

{
"error": {
"code": "invalid_api_key",
"message": "The key is wrong or inactive.",
"type": "modoo_error"
}
}

The meaning of each error code and how to resolve it is explained in detail in the Error guide.


What's next