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.
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) | Required | Description |
|---|---|---|
limit | Optional | How 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.
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.
| Field | Required | Description |
|---|---|---|
model | Optional | The model to use (default modoo-text) |
messages | One of the two required | A conversation array of { role, content } items |
prompt | One of the two required | A single-sentence question/instruction |
system_prompt | Optional | A role/rule guidance given to the AI in advance |
max_tokens | Optional | Maximum answer length |
temperature | Optional | The answer's creativity (lower is more consistent) |
stream | Optional | If true, receive the answer bit by bit in real time |
You only need one of
messagesorprompt.messagesis 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
textfrom 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.
- Features that require directly uploading a file (speech recognition, image analysis, document analysis) are sent as
multipart/form-data. In curl, use the-Foption. - 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.
| Field | Required | Description |
|---|---|---|
text | Required | The sentence to read aloud |
model | Optional | modoo-tts-minimax (default) or modoo-tts-eleven (ElevenLabs) |
voice_id | Optional | Voice type (minimax default Korean_CalmLady). Required for ElevenLabs — a voice_id from that account (e.g. EXAVITQu4vr4xnSDxMaL) |
voice_model | Optional | minimax: speech-2.6-turbo (default) · speech-2.6-hd · ElevenLabs model_id: eleven_flash_v2_5 · eleven_multilingual_v2 (default) · eleven_v3 |
voice_settings | Optional | ElevenLabs-only voice tuning — stability · similarity_boost · style · speed · use_speaker_boost |
language_code | Optional | ElevenLabs-only — language code (e.g. ko) |
output_format | Optional | ElevenLabs-only — output format (e.g. mp3_44100_128) |
previous_text | Optional | ElevenLabs-only — the text that comes before this one. It is not spoken; it only carries intonation and pacing over |
next_text | Optional | ElevenLabs-only — the text that comes after this one. Same purpose as above |
seed | Optional | ElevenLabs-only — 0–4294967295. The same seed with the same options returns the same audio (best effort, not guaranteed) |
apply_text_normalization | Optional | ElevenLabs-only — auto (default) · on · off. Whether numbers, dates and abbreviations are spelled out |
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) — useeleven_multilingual_v2oreleven_flash_v2_5instead. - 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) | Required | Description |
|---|---|---|
file | One of file or url required | The audio file to upload |
url | One of file or url required | The URL of the audio file |
language | Optional | Language 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) | Required | Description |
|---|---|---|
file | One of file or url required | The image file to upload |
url | One of file or url required | The 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) | Required | Description |
|---|---|---|
file | One of file or url required | The document file to upload |
url | One of file or url required | The document URL |
operation | Optional | The 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.
| Field | Required | Description |
|---|---|---|
prompt | Required | A description of the picture you want to draw (for edit models, the change you want) |
model | Optional | Image model (default modoo-image-z, others -gpt, editing -edit/-edit-max/-gpt-edit) |
size | Optional | Image size — allowed values differ per model (table below). Omit for the model default |
n | Optional | How many to create (default 1; modoo-image-gpt/modoo-image-gpt-edit only, 1–10) |
image_url | Required for edit models* | Original image address (image-to-image) |
encoded_image | Required for edit models* | Original image as base64 — alternative to image_url |
image_urls | Optional | Array 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.
| Model | Allowed values | Default (when omitted) |
|---|---|---|
modoo-image-gpt, modoo-image-gpt-edit | auto · 1024x1024 · 1536x1024 · 1024x1536 | auto |
modoo-image-z | 33 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*864 | 1024*1536 |
modoo-image-edit, modoo-image-edit-max | 16 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*872 | 1024*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.
| Field | Required | Description |
|---|---|---|
prompt | Required | A description of the video you want to create |
model | Optional | Video model (default modoo-video; image→video is modoo-video-i2v; HappyHorse is modoo-video-happyhorse-t2v/-i2v/-r2v) |
negative_prompt | Optional | A description of elements to avoid |
image_url | Required for i2v | https address of the first-frame image — modoo-video-i2v/modoo-video-happyhorse-i2v only (base64 not supported) |
end_image_url | Optional | https 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_url | Optional | https address of audio that drives the motion (e.g. a talking avatar) — modoo-video-i2v (WAN 2.7) only |
first_clip_url | Optional | https address of an existing clip to continue/extend from — modoo-video-i2v (WAN 2.7) only |
reference_image_urls | Required for r2v | List of https addresses for 1–9 character reference images — modoo-video-happyhorse-r2v only |
resolution | Optional | 720P or 1080P — WAN 2.7 · HappyHorse |
ratio | Optional | aspect ratio (e.g. 16:9·9:16·1:1·4:3·3:4), t2v·r2v only. i2v preserves the input image's ratio |
duration | Optional | video length in seconds (integer) — WAN 2.7 · HappyHorse |
watermark | Optional | whether to show a watermark (true/false) — WAN 2.7 · HappyHorse |
seed | Optional | seed for reproducibility (integer) — WAN 2.7 · HappyHorse |
prompt_extend | Optional | upstream prompt expansion (true/false) — WAN 2.7 only |
modoo-video-happyhorse-r2vrequiresreference_image_urls(1–9 images).resolution·ratio·duration·watermark·seedapply to both WAN 2.7 (modoo-video/-i2v) and HappyHorse models (each model ignores knobs it doesn't accept).prompt_extendis 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.
| Field | Required | Description |
|---|---|---|
lyrics | Required | The lyrics to turn into a song (1–3,500 chars). Use \n for line breaks; structural tags like [Verse]/[Chorus] are allowed |
model | Optional | Music engine version — music-2.5 (default) or music-2.0 |
prompt | Optional | A description of the desired mood/style (up to 2,000 chars, e.g. a gentle acoustic ballad) |
audio_setting | Optional | Output 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 hereOn 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_idand 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.
- When you request a task, you immediately receive a
job_id(a job ticket number). - A little later, you check this address with the
job_idto see whether the result is ready (polling). - Once
statusbecomessucceeded, 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"]
}
}
statusis one ofprocessing(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. chargeis the total credits deducted for this job so far. Async jobs are billed in two parts (at submission and at completion), so the value oncestatusissucceededis the final amount. Onfailedit is0— the submission charge is refunded.
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
- To chain several AIs together in sequence → Workflows
- To connect it to tools like Claude and Cursor → MCP integration
- If you haven't tried it yet → Quickstart