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/drive/files — Upload a file to your drive
Saves an image, video, audio or PDF file to your devdive drive and returns a short link you can pass straight to the generation APIs. It is not a model call, so no credits are needed. Send it in one of three ways:
| Way | Body |
|---|---|
| File upload | multipart/form-data, field file |
| Address | JSON {"url": "https://...", "file_name": "photo.png"} (https only, file_name optional) |
| base64 | JSON {"data": "<base64 or data: URI>", "file_name": "photo.png"} |
# This request: uploads one photo to your drive.
curl https://modoo.devdive.me/v1/drive/files \
-H "Authorization: Bearer sk-modoo-..." \
-F "[email protected]"
{
"file_key": "photo-1a2b3c4d.png",
"file_name": "photo-1a2b3c4d.png",
"size": 48213,
"content_type": "image/png",
"url": "https://modoo.devdive.me/v1/media/<token>/photo-1a2b3c4d.png",
"expires_in_days": 3
}
Up to 50 MB per file; only images, video, audio and PDF are accepted (other types get 415, oversize gets 413). Uploads are rate limited per minute (429).
The type is decided by the file's content, not its name or Content-Type. An executable renamed to .png, archives, and script-capable SVG/HTML are refused with 415.
Accepted files aren't stored as uploaded either: they are rebuilt from their content, so hidden extras such as data appended to the end of a file are dropped.
- Images: re-saved from their pixels. Metadata such as the shooting location is removed; the photo's orientation is kept. HEIC, HEIF and AVIF become JPEG (PNG when transparent).
- Video and audio: the file structure is rebuilt without re-encoding, so there's no quality loss. Subtitles, data tracks, cover art and metadata are left out.
- PDF: PDFs containing scripts (JavaScript), actions such as launching programs or submitting forms, or attached files, and password-protected PDFs are refused with
415. - Unreadable (damaged) files also get
415.
The returned url can be used as-is in any input address field: image_url, image_urls, end_image_url, video_url, audio_url, reference_*_urls, and the url of the document/image/speech analysis endpoints. Links are valid for 3 days and only work for files of your own account (another account's link gives 403 forbidden_media_link; an expired one gives 410 link_expired).
GET /v1/drive/files — List your drive
# This request: fetches your drive files, 20 at a time.
curl "https://modoo.devdive.me/v1/drive/files?page=1&size=20" \
-H "Authorization: Bearer sk-modoo-..."
{
"items": [
{
"file_key": "photo-1a2b3c4d.png",
"file_name": "photo-1a2b3c4d.png",
"url": "https://modoo.devdive.me/v1/media/<token>/photo-1a2b3c4d.png",
"size": 48213,
"created_at": "2026-09-30T01:23:45"
}
],
"total": 1, "page": 1, "size": 20, "total_pages": 1,
"expires_in_days": 3
}
size is at most 50. Uploaded files and generated results are listed together.
POST /v1/drive/upload-links — Create a one-time upload link
Creates a one-time link that adds files to your drive without an API key. AI tools that can't pass an attached file to a tool (Claude, ...) use it through the MCP tool create_upload_link. A link takes files for 30 minutes, up to 10 files per link.
# This request: creates an upload link.
curl -X POST https://modoo.devdive.me/v1/drive/upload-links \
-H "Authorization: Bearer sk-modoo-..."
{
"id": "<token>",
"upload_url": "https://modoo.devdive.me/v1/drive/uploads/<token>",
"page_url": "https://modoo.devdive.me/upload/<token>",
"expires_at": "2026-10-07T10:30:00+00:00",
"expired": false,
"max_files": 10,
"max_upload_mb": 50,
"files": []
}
-
upload_url: send a file asmultipart/form-datafieldfile; it is saved to your drive and you get the same response as POST /v1/drive/files (including the short linkurl). No API key needed — the link itself is the credential.# This request: uploads one photo through an upload link (no key).
curl -F "[email protected]" https://modoo.devdive.me/v1/drive/uploads/<token> -
page_url: a page for choosing and uploading files in the browser. Opens without login.
An unknown link is 404 upload_link_not_found, an expired one 410 link_expired, and a link that already took its maximum number of files 409 upload_link_full. Size, type and per-minute limits are the same as POST /v1/drive/files. Anyone with the link can add files to your drive, so don't share it.
GET /v1/drive/upload-links/{id} — Files uploaded through a link
# This request: checks the files uploaded through an upload link so far.
curl https://modoo.devdive.me/v1/drive/upload-links/<token> \
-H "Authorization: Bearer sk-modoo-..."
The response has the same shape as when the link was created, with the uploaded files (url, file_name, size, content_type) in files, in order. Only the account that created the link can read it, and it stays readable for an hour after the link expires.
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-gpt-2-5-flare, others -gpt-2-5-sunburst/-gpt/-z, 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; GPT Image models (modoo-image-gpt*) only, 1–10) |
quality | Optional | Quality — auto (default)·low·medium·high. GPT Image models (modoo-image-gpt*) only (422 on other models) |
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-2-5-flare, modoo-image-gpt-2-5-sunburst, 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 — optional for modoo-video-wan30-r2v, must be omitted for modoo-video-wan-action |
model | Optional | Video model (default modoo-video; image→video is modoo-video-i2v; HappyHorse is modoo-video-happyhorse-t2v/-i2v/-r2v/-edit; WAN 3.0 is modoo-video-wan30-t2v/-r2v; motion transfer is modoo-video-wan-action) |
negative_prompt | Optional | A description of elements to avoid |
image_url | Required for i2v·action | https address of the first-frame image — modoo-video-i2v/modoo-video-happyhorse-i2v (required), modoo-video-wan30-r2v (optional), modoo-video-wan-action (required: the person to animate). 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) and modoo-video-wan30-r2v 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 of reference images — modoo-video-happyhorse-r2v (required, 1–9 images), modoo-video-wan30-r2v/modoo-video-happyhorse-edit (optional) |
reference_video_urls | Optional | List of https addresses of reference videos — modoo-video-wan30-r2v only |
reference_audio_urls | Optional | List of https addresses of reference audio — modoo-video-wan30-r2v only |
video_url | Required for edit·action | https address of the source video — modoo-video-happyhorse-edit (the video to edit) / modoo-video-wan-action (the motion to copy) only |
resolution | Optional | 720P or 1080P (WAN 3.0 also 480P) — WAN · 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 |
audio | Optional | whether the video has sound (true/false) — WAN 3.0 (modoo-video-wan30-*) only |
audio_setting | Optional | auto (default) or origin (keep the source video's sound) — modoo-video-happyhorse-edit only |
mode | Optional | wan-std (default) or wan-pro (higher quality) — modoo-video-wan-action 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.Each model takes different inputs —
modoo-video-wan30-r2vneeds at least one ofimage_url·reference_image_urls·reference_video_urls·reference_audio_urls(end_image_urlgoes withimage_url),modoo-video-happyhorse-editrequiresprompt+video_url, andmodoo-video-wan-actionrequiresimage_url+video_url(noprompt). Sending a media input (image_url·video_url·reference_*_urls, …) or a model-specific option (audio·audio_setting·mode) to a model that doesn't take it is not ignored — it returns a 422.
# 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