Recommended Base URL for the OpenAI-compatible API:
https://miyang.cn/v1 still works for existing clients; new integrations should use https://miyang.cn/api/v1.
Except for the public model list and model-pricing endpoints, inference endpoints require an API key in the request headers. Two headers are supported:
- Recommended:
Authorization: Bearer miyang-xxxxx - Fallback:
x-api-key: miyang-xxxxx
Create API keys in the console; they are stored encrypted and can be viewed and copied again on the API Keys page.
# Bearer Token(推荐) curl https://miyang.cn/api/v1/models \ -H "Authorization: Bearer miyang-xxx" # x-api-key(备用) curl https://miyang.cn/api/v1/models \ -H "x-api-key: miyang-xxx"
Model IDs usually follow {provider_slug}/{model_name}. Prefer miyang/auto to pick a model automatically, or copy another call ID from the model list or the console.
miyang/auto— Automatically pick a model for the current requestmiyang/standard— Standard-tier modelmiyang/premium— Premium-tier model
miyang/* models are for the Alice client; other apps or scripts should pick models whose usage_scope is general from the model list.
# 自动选择适合当前请求的模型 model = "miyang/auto"
Each API key is counted separately. The default is 60 requests/minute and you can raise the cap in the console. Exceeding the limit returns 429 Too Many Requests.
{
"error": {
"message": "Rate limit exceeded",
"type": "rate_limit_error",
"code": 1002
}
}
Calls are settled against actual usage in real time. Refer to the console and the model-pricing response for current rates.
- Checks that balance > 0 before the call; insufficient balance returns
402 - Billed by prompt + completion token usage
- Prompt Cache is supported:
cache_read_tokensis billed at a discounted rate
Top up credits (米粒) in the console and review calls and spend under Usage.
// 余额不足响应(402) { "error": { "message": "Insufficient balance", "type": "insufficient_balance", "code": 1004 } }
OpenAI-compatible chat endpoint with streaming and non-streaming output. Point the OpenAI SDK base_url here.
| Parameter | Type | Description |
|---|---|---|
| model required | string | Model ID, format provider_slug/model |
| messages required | array | Chat messages; each item has role and content |
| stream | boolean | Enable streaming (SSE); default false |
| temperature | float | Sampling temperature, range 0–2 |
| max_tokens | integer | Maximum output tokens |
| response_format | object | Structured output format; see Structured output |
curl https://miyang.cn/api/v1/chat/completions \ -H "Authorization: Bearer miyang-xxx" \ -H "Content-Type: application/json" \ -d '{ "model": "miyang/auto", "messages": [ {"role": "user", "content": "Hello!"} ], "stream": false }'
miyang/miyang-omni-v1 is an omni-modal model for audio/video understanding, meeting notes, and content analysis. A single user message may combine text, images, audio, and video, with text output.
miyang-asr.
| Model information | Value |
|---|---|
| Call ID | miyang/miyang-omni-v1 |
| Input modalities | Text, image, audio, and video; inputs may be combined |
| Output modality | Text (no speech generation) |
| Context limit | 1000000 tokens |
Multimodal content format
| type | Description |
|---|---|
text | Text instruction in the text field |
image_url | Public URL or Base64 data URL in image_url.url |
input_audio | Public URL or Base64 data URL in input_audio.data, with format |
video_url | Public video URL or Base64 data URL in video_url.url |
Omni extensions
| Parameter | Type | Description |
|---|---|---|
| reasoning_effort | string | none, low, medium, or xhigh. Upstream defaults to xhigh; use none for transcription or quick summaries. |
| use_multichannel | boolean | Preserve stereo or four-channel FOA spatial information; default false. Enable only when the input actually has a supported channel layout. |
Audio understanding example
curl https://miyang.cn/api/v1/chat/completions \ -H "Authorization: Bearer miyang-xxx" \ -H "Content-Type: application/json" \ -d '{ "model": "miyang/miyang-omni-v1", "reasoning_effort": "none", "messages": [{ "role": "user", "content": [ {"type": "text", "text": "Transcribe this recording chronologically and summarize it."}, {"type": "input_audio", "input_audio": { "data": "https://example.com/meeting.mp3", "format": "mp3" }} ] }], "stream": false }'
Public endpoint, no API key required. Returns publicly available models; with an API key it also returns internal or allowlisted models for that account. The response extends the standard OpenAI shape with context_length and usage-scope fields.
{
"object": "list",
"data": [
{
"id": "miyang/auto",
"object": "model",
"owned_by": "miyang",
"name": "自动",
"model_type": "text",
"usage_scope": "alice",
"usage_hint": "请在 Alice 客户端内使用",
"context_length": 262144
}
]
}
Returns pricing for every model visible to the current account. Without an API key it lists public models; with one it also includes internal or allowlisted models permitted for that account.
Billing units vary by model type, so use billing_unit as the source of truth. rates contains the currently effective prices, while effective_pricing identifies base, time-based, or promotional pricing.
mili_per_usd provides the conversion between the USD balance and mili.
curl https://miyang.cn/api/v1/pricing \
-H "Authorization: Bearer miyang-xxx"
{
"object": "pricing.list",
"mili_per_usd": 1000,
"data": [
{
"id": "miyang/auto",
"model_type": "text",
"currency": "USD",
"billing_mode": "tokens",
"billing_unit": "per_1m_tokens",
"effective_pricing": "<base | peak | promotion>",
"rates": {
"input": "<current rate>",
"output": "<current rate>",
"cache_read": "<current rate>",
"cache_write": "<current rate>"
}
}
]
}
OpenAI-compatible embeddings endpoint. Whether a model supports embedding tasks is marked on the model list and in the console.
| Parameter | Type | Description |
|---|---|---|
| model required | string | Embedding model call ID |
| input required | string / array | Text or array of texts to embed |
| encoding_format | string | Vector encoding format; commonly float |
curl https://miyang.cn/api/v1/embeddings \ -H "Authorization: Bearer miyang-xxx" \ -H "Content-Type: application/json" \ -d '{ "model": "provider/embedding-model", "input": "需要向量化的文本" }'
miyang/jev-1.13 is a low-cost structured decision model available to every Miyang API user and pinned to typesafe/jev-1.13. It answers explicit questions instead of generating chat text. Alice's long-term memory pre-filter is its first production use.
Authorization: Bearer miyang-xxx. It uses a dedicated Decisions protocol rather than /api/v1/chat/completions, so it is not mixed into the Chat-only /api/v1/models list.
| Model information | Value |
|---|---|
| Miyang model ID | miyang/jev-1.13 |
| Decision engine | typesafe/jev-1.13 |
| Context limit | 32768 tokens |
| Question types | noul / choice / score |
| Availability | All users with a valid Miyang API key |
Requests must name a registered Decisions shell. The Gateway bills that shell while pinning the real upstream engine. state holds structured context and questions defines the decisions to make.
| Parameter | Type | Description |
|---|---|---|
| model required | string | Use miyang/jev-1.13 for public calls. Ordinary API users cannot call internal scenario shells. |
| state required | object | Structured state used for the decision; callers should remove unnecessary sensitive data before sending. |
| questions required | object | Object keyed by question name; 1 to 24 questions. |
| questions.*.type required | string | noul (0–1 probability), choice, or score. |
| questions.*.instructions required | string | A precise description of the decision to make. |
| questions.*.criteria | object | Optional meaning for each answer or score, used to reduce ambiguity. |
Each request is limited to 64 KiB and 24 questions. The server does not log state content or decision answers; only question count, latency, and token usage are retained.
curl https://miyang.cn/api/v1/decisions \ -H "Authorization: Bearer miyang-xxx" \ -H "Content-Type: application/json" \ -d '{ "model": "miyang/jev-1.13", "state": {"dialog": "The user asked a routine technical question"}, "questions": { "remember": { "type": "noul", "instructions": "Does this conversation contain information worth retaining long term?", "criteria": { "true": "Stable identity, long-term preference, or an explicit relationship event", "false": "One-off task, routine Q&A, or small talk" } } } }'
{
"model": "miyang/jev-1.13",
"provider": "miyang",
"answers": {
"remember": {
"type": "noul",
"noul": 0.02
}
}
}
OpenAI-compatible image generation. Send a text prompt and get an image URL or Base64 data, fully compatible with the OpenAI Images API.
| Parameter | Type | Description |
|---|---|---|
| model required | string | Model ID, format provider/model, e.g. ts/gpt-image-2 |
| prompt required | string | Image description |
| n | integer | Number of images; default 1, multiple allowed |
| size | string | Image size. Common values: 1024x1024 (square), 1024x1536 (portrait), 1536x1024 (landscape), auto (model chooses). Max edge 3840px; both sides must be multiples of 16; aspect ratio at most 3:1 |
| quality | string | Render quality: low (fast draft), medium, high, auto (default, model chooses) |
| output_format | string | Output format: png (default), jpeg (faster), webp |
| output_compression | integer | Compression 0–100; JPEG / WebP only |
| background | string | opaque (default) or transparent (transparent background, good for icons/stickers) |
| moderation | string | Moderation: auto (default) or low (lenient) |
Basic example — text-to-image:
curl https://miyang.cn/api/v1/images/generations \ -H "Authorization: Bearer miyang-xxx" \ -H "Content-Type: application/json" \ -d '{ "model": "ts/gpt-image-2", "prompt": "A children'\''s book drawing of a veterinarian listening to the heartbeat of a baby otter", "size": "1024x1024", "quality": "high" }'
from openai import OpenAI import base64 client = OpenAI( api_key="miyang-xxx", base_url="https://miyang.cn/api/v1", timeout=180.0, # 图像生成需要较长超时 ) result = client.images.generate( model="ts/gpt-image-2", prompt="A children's book drawing of a veterinarian listening to the heartbeat of a baby otter", size="1024x1024", quality="high", ) print(result.data[0].url)
Advanced example — JPEG output + compression + save locally:
import httpx, json, base64 resp = httpx.post( "https://miyang.cn/api/v1/images/generations", headers={"Authorization": "Bearer miyang-xxx"}, json={ "model": "ts/gpt-image-2", "prompt": "A serene Japanese garden with a koi pond", "size": "1536x1024", "quality": "medium", "output_format": "jpeg", # jpeg 比 png 更快 "output_compression": 80, # 压缩率 0-100 }, timeout=180.0, ) data = resp.json() print(data["data"][0]["url"])
// 响应示例 { "created": 1779691963, "data": [ { "url": "https://image.token-recyclebin.com/images/2026/05/25/xxx.png", "revised_prompt": "A serene Japanese garden with a koi pond..." } ] }
Size and quality notes
| Parameter | Values | Description |
|---|---|---|
| size | 1024x1024 (square)1536x1024 (landscape)1024x1536 (portrait)2048x2048(2K)3840x2160 (4K landscape)auto | Max edge ≤ 3840px; both sides multiples of 16; ratio ≤ 3:1; total pixels 655,360 – 8,294,400 |
| quality | low · medium · high · auto | low is fastest, good for drafts; high is most detailed, good for finals |
| output_format | png · jpeg · webp | jpeg is faster than png; prefer it when latency matters |
OpenAI-compatible image edits. Upload one or more reference images plus a text prompt to generate a new image. Supports inpainting (mask) and multi-image compose. Requests use multipart/form-data.
Typical uses:
- Style transfer — Upload a photo + "turn into an oil painting"
- Multi-image compose — Upload several assets + "make a gift basket with these items"
- Inpainting — Upload the original + mask + "add a flamingo in the masked area"
| Parameter | Type | Description |
|---|---|---|
| model required | string | Model ID, e.g. ts/gpt-image-2 |
| image required | file / file[] | Reference image(s). One file as image; multiple as image[] (repeat image[]=@file.png) |
| prompt required | string | Edit instruction |
| mask | file | Mask image (must include an alpha channel); transparent pixels are edited. With multiple images the mask applies to the first one |
| n | integer | Number of images; default 1 |
| size | string | Output size; default auto; same size options as Generations |
| quality | string | low · medium · high · auto |
Single-image edit — style transfer:
curl https://miyang.cn/api/v1/images/edits \ -H "Authorization: Bearer miyang-xxx" \ -F "model=ts/gpt-image-2" \ -F "prompt=Turn this photo into a Studio Ghibli style illustration" \ -F "image=@photo.png" \ -F "size=1536x1024"
from openai import OpenAI client = OpenAI( api_key="miyang-xxx", base_url="https://miyang.cn/api/v1", timeout=180.0, ) result = client.images.edit( model="ts/gpt-image-2", image=open("photo.png", "rb"), prompt="Turn this photo into a Studio Ghibli style illustration", ) print(result.data[0].url)
Multi-image compose — merge several assets:
# 多图参考:用 image[] 传多张 curl https://miyang.cn/api/v1/images/edits \ -H "Authorization: Bearer miyang-xxx" \ -F "model=ts/gpt-image-2" \ -F "image[]=@lotion.png" \ -F "image[]=@soap.png" \ -F "image[]=@candle.png" \ -F 'prompt=A gift basket on a white background containing all these items'
Inpainting — use a mask:
# mask 需要有 alpha 通道,透明区域为编辑区 result = client.images.edit( model="ts/gpt-image-2", image=open("room.png", "rb"), mask=open("mask.png", "rb"), prompt="Add a flamingo in the pool area", quality="high", ) print(result.data[0].url)
Use this when a user needs to remove periodic artifacts—such as grid, scale, or roof-tile patterns—that build up as AI images are repeatedly used as references or regenerated. The service diagnoses, cleans, optionally regenerates, and quality-checks the source image in the background, returning a clean result ready to publish, print, or edit further.
Idempotency-Key is required. Reusing it after a network timeout returns the original job; reusing it with another image or parameter set returns 409.
| Parameter | Type | Description |
|---|---|---|
| image required | file | Image to restore; PNG, JPEG, or WebP, up to 40 MB and 8.3 MP |
| allow_regen | boolean | Allow regeneration when rule-based cleanup is insufficient; default true |
| max_regen | integer | Maximum regeneration rounds, 1–2; default 2 |
curl https://lab.miyang.cn/ripple/api/v1/jobs \ -H "Authorization: Bearer miyang-xxx" \ -H "Idempotency-Key: restore-order-001" \ -F "image=@photo.png" \ -F "allow_regen=true" \ -F "max_regen=2"
{
"id": "rp-api-...",
"object": "ripple.job",
"status": "queued",
"phase": "queued",
"result": null,
"error": null
}
Use this endpoint after creating a job to retrieve progress and the final artifacts. Asynchronous polling avoids holding a connection open or keeping the user waiting, and returns the finished artifact URL when the job succeeds.
status may be queued, processing, succeeded, failed, cancelled, or expired. On success, result.artifacts lists the final and process artifacts.
curl https://lab.miyang.cn/ripple/api/v1/jobs/rp-api-... \
-H "Authorization: Bearer miyang-xxx"
{
"id": "rp-api-...",
"status": "succeeded",
"result": {
"outcome": "delivered",
"regen_rounds": 1,
"artifacts": [
{
"name": "photo_restored.png",
"primary": true,
"url": "https://lab.miyang.cn/ripple/api/v1/jobs/rp-api-.../artifacts/photo_restored.png"
}
]
},
"error": null
}
Asynchronous video generation. A successful request returns a task_id; poll the query endpoint for status instead of submitting the same business request again.
miyang/h3 and miyang/h3-max.
| Parameter | Type | Description |
|---|---|---|
| model required | string | miyang/h3 or miyang/h3-max |
| content required | array | Multimodal content array with exactly one non-empty text item; images, video, and audio may also be included |
| duration required | integer | Output duration in seconds. H3 supports 4–15; H3 Max supports 5–15 |
| resolution | string | Default 768P. H3 supports 768P / 2K; H3 Max supports 480P / 768P |
| ratio | string | Aspect ratio: 21:9, 16:9, 4:3, 1:1, 3:4, or 9:16; reference media may use adaptive |
| aigc_watermark | boolean | Whether to add an AIGC watermark |
| extra | object | H3 Max only. prompt_expansion_mode may be disabled, balanced, or quality |
content media format
| type | role | Description |
|---|---|---|
| text | — | Required exactly once, up to 7,000 characters |
| image_url | first_frame / last_frame / reference_image | First frame, last frame, or reference image; one image without a role becomes the first frame |
| video_url | reference_video | Reference video, up to 3; role is required |
| audio_url | reference_audio | Reference audio, up to 3; role is required |
curl https://miyang.cn/api/v1/videos/generations \ -H "Authorization: Bearer miyang-xxx" \ -H "Idempotency-Key: alice-video-001" \ -H "Content-Type: application/json" \ -d '{ "model": "miyang/h3", "content": [ {"type": "text", "text": "A lamb runs across a sunlit meadow"} ], "duration": 5, "resolution": "768P", "ratio": "16:9" }'
{
"task_id": "443429054845209"
}
Poll with the task_id returned at creation. Status may be queued, running, succeeded, failed, or cancelled. Poll every 5–15 seconds.
curl https://miyang.cn/api/v1/videos/generations/443429054845209 \
-H "Authorization: Bearer miyang-xxx"
{
"task": {
"status": "succeeded",
"resolution": "768P",
"duration": 5,
"content": {
"url": "https://signed.example/video.mp4",
"drive_file_id": "drv-xxx",
"size_bytes": 1757278,
"expires_in": 3600
}
}
}
Cancel a task still being processed and release its billing hold. Any associated Miyang Drive file is also removed. For completed tasks that the upstream cannot cancel, follow the endpoint response.
curl -X DELETE https://miyang.cn/api/v1/videos/generations/443429054845209 \
-H "Authorization: Bearer miyang-xxx"
Use miyang-asr to asynchronously transcribe a prerecorded audio or video file. It supports 30 languages and many Chinese dialects, and can identify speakers. Creation returns a task ID; query it for the transcript, segments, speakers, and duration.
multipart/form-data are limited to 50 MB, saved automatically to the current user's Miyang Drive, and count toward storage. file_url accepts public HTTP(S) files up to 2 GB and 12 hours, and does not copy them to Drive.
The legacy model names miyang/transcription and miyang/transcription-realtime keep working and map automatically to miyang-asr and miyang-asr-realtime; existing code needs no changes.
| Parameter | Type | Description |
|---|---|---|
| model | string | Use miyang-asr (or miyang/miyang-asr). This model is selected when omitted |
| file | file | Choose either file or file_url. Supports mp3, wav, m4a, aac, flac, ogg, opus, mp4, mov, mkv, webm, and more; direct uploads are limited to 50 MB |
| file_url | string | Choose either file_url or file. Publicly reachable HTTP(S) URL whose hostname resolves to a public IP; up to 2 GB and 12 hours |
| source_language | string | Defaults to auto detection. Accepts cn, en, yue, ja, and ko; multilingual requires language_hints; fspk means mixed Chinese and English |
| language_hints | array / string | Available only with source_language=multilingual; supports cn, en, yue, ja, ko, de, fr, and ru, up to 4 |
| diarization | boolean | Whether to identify speakers; defaults to true. Audio under 2 hours is recommended when enabled |
| speaker_count | integer | Expected number of speakers. Use 0 for automatic detection; otherwise 2–100 |
Billing uses the token usage reported by the upstream model, with audio input tokens and text output tokens priced separately. Refer to the console usage ledger for current pricing and final charges.
Creation places a Mili hold sized for 12 hours of audio. On completion, only actual usage is charged and the remainder is released. Failed tasks are not charged.
Example 1: upload a file and save it to Miyang Drive
curl https://miyang.cn/api/v1/audio/transcriptions \ -H "Authorization: Bearer miyang-xxx" \ -H "Idempotency-Key: meeting-20260921" \ -F "model=miyang-asr" \ -F "source_language=cn" \ -F "diarization=true" \ -F "file=@meeting.m4a"
Example 2: submit a public file URL (recommended for large files)
curl https://miyang.cn/api/v1/audio/transcriptions \ -H "Authorization: Bearer miyang-xxx" \ -H "Idempotency-Key: archive-001" \ -H "Content-Type: application/json" \ -d '{ "model": "miyang-asr", "file_url": "https://example.com/recording.mp3", "source_language": "multilingual", "language_hints": ["cn", "en"] }'
{
"id": "6f3a...task",
"object": "audio.transcription.job",
"status": "processing",
"model": "miyang/miyang-asr",
"request_id": "3d7e...request",
"source_file_id": "drv-..."
}
Query with the id returned at creation, typically every 5–15 seconds. If submission is uncertain, request_id can also locate the same task.
curl https://miyang.cn/api/v1/audio/transcriptions/6f3a...task \
-H "Authorization: Bearer miyang-xxx"
{
"id": "6f3a...task",
"object": "audio.transcription.job",
"status": "completed",
"model": "miyang/miyang-asr",
"text": "Meeting transcript...",
"duration": 93.4,
"segments": [
{"speaker": "0", "start": 0.0, "end": 5.2, "text": "..."}
],
"usage": {
"audio_seconds": 93.4,
"duration_ms": 93400,
"input_tokens": 3270,
"output_tokens": 412
},
"source_file_id": "drv-..."
}
Common errors:402 means insufficient Mili; 409 means the idempotency key was reused for a different request; 411/413 means the upload lacks a length or exceeds 50 MB; 429 is rate limiting; 503 submission_uncertain means the upstream outcome is pending confirmation.
Create a realtime record, then connect to the one-time stream_url. Clients may send PCM directly or common audio streams such as WAV, MP3, AAC, Ogg, WebM, and M4A. Miyang automatically decodes them into the optimal internal recognition format and returns unified recognition events, so clients never need to adapt to a specific recognition route.
| Parameter | Type | Description |
|---|---|---|
| model | string | Use miyang-asr-realtime (or miyang/miyang-asr-realtime). This model is selected when omitted |
| format | string | pcm / wav / mp3 / aac / opus / speex / ogg / webm / m4a / mp4 |
| sample_rate | integer | 16000 is supported; 8000 is also supported for Chinese only |
| source_language | string | cn / en / yue / ja / ko / multilingual |
| language_hints | array | Available only with source_language=multilingual; realtime recognition uses only the first hint |
| prompt | string | Optional recognition context, up to 400 characters. Use names, product names, meeting topics, domain terms, or immediately preceding text to improve accuracy. It does not change the response format and is not a general chat system prompt |
| output_level | integer | 1 = final sentences only; 2 = interim and final results (default) |
| max_duration_seconds | integer | Maximum duration of this realtime stream in seconds, from 1 to 86400. The Mili hold uses this limit; final billing uses actual usage |
Format conventions: opus and speex use Ogg containers, aac uses ADTS, and m4a/mp4 use streamable fragmented MP4. WebM/Opus is recommended for browsers and M4A/AAC for Apple clients; Miyang handles decoding, mono conversion, and resampling.
Context enhancement examples
A prompt should state factual background likely to appear in the next audio segment, not ask the model to perform a task. The closer it matches the upcoming content, the more reliably names, products, and domain terms are recognized.
| Use case | Recommended prompt |
|---|---|
| Names and proper nouns | Participants include Luo Xiaoshan and Eason. The product is Miyang and the project is Xingchao. |
| Meeting or class background | This is a product weekly meeting about the screenshot cloud library, storage budgets, and the seven-day pending-deletion area. |
| Continue from prior context | The previous segment discussed realtime speech recognition; next comes context enhancement and dynamic updates. |
| Change topics during a session | The next topic is the Xingchao release plan, led by Luo Xiaoshan. |
curl https://miyang.cn/api/v1/audio/transcriptions/realtime \ -H "Authorization: Bearer miyang-xxx" \ -H "Idempotency-Key: live-meeting-001" \ -H "Content-Type: application/json" \ -d '{ "model": "miyang-asr-realtime", "format": "pcm", "sample_rate": 16000, "source_language": "cn", "prompt": "这是一场米羊产品会议,参会人包括洛小山,项目名称是星潮计划。", "max_duration_seconds": 300, "output_level": 2 }'
{
"id": "realtime-task-id",
"status": "ready",
"mode": "realtime",
"model": "miyang/miyang-asr-realtime",
"stream_url": "wss://miyang.cn/api/v1/audio/transcriptions/realtime/.../stream?token=...",
"stream_token_expires_in": 600
}
stream_url expires in 10 minutes and can be connected only once; a successful connection means recognition has started. Keep sending audio bytes matching the creation parameters; Miyang handles format conversion and speech pauses automatically. To finish, send {"header":{"name":"StopTranscription"}}; the server delivers the final SentenceEnd and TranscriptionCompleted, then closes with 1000. You can also just close the connection. Afterwards, use the common query endpoint for the full transcript and settlement. Server events are JSON with these header.name values:
When the context changes, send {"type":"context.update","prompt":"接下来讨论星潮计划的发布安排。"} on the same WebSocket. The new prompt applies to subsequent audio, and Miyang returns ContextUpdated after accepting it.
// Update the context used for subsequent audio when the topic changes ws.send(JSON.stringify({ type: "context.update", prompt: "The next topic is the Xingchao release plan, led by Luo Xiaoshan." })); // Continue sending audio after receiving ContextUpdated ws.send(nextAudioChunk);
| Event | Description |
|---|---|
| SentenceBegin | A sentence started; payload contains the sentence index and start time (ms) |
| TranscriptionResultChanged | Interim result for the current sentence in payload.result; not sent when output_level=1 |
| SentenceEnd | A sentence ended; payload contains the final result, begin_time, time, and per-word timings in words |
| ContextUpdated | Miyang accepted context.update; the new prompt applies to subsequent audio |
| ContextUpdateFailed | context.update failed validation; payload.status_text explains why, and the client may retry with a corrected prompt |
| TranscriptionCompleted | Recognition finished; the server closes the connection next |
| TaskFailed | Recognition failed; header.status is 40000000 and payload.status_text gives the reason. The server then closes with 1011 |
{
"header": {"namespace": "SpeechTranscriber", "name": "SentenceEnd", "status": 20000000},
"payload": {
"index": 1,
"begin_time": 0,
"time": 1820,
"result": "今天的会议先同步进度。",
"words": [{"text": "今天", "startTime": 0, "endTime": 320, "punctuation": ""}]
}
}
Set model to miyang-asr-flash on the same transcription endpoint to get the text back directly, without an asynchronous task. Suited to audio under 5 minutes; use miyang-asr for longer recordings. The request body matches file transcription: choose either file or file_url.
Billed by the token usage reported upstream and charged immediately on success; failures are not charged.
curl https://miyang.cn/api/v1/audio/transcriptions \ -H "Authorization: Bearer miyang-xxx" \ -F "model=miyang-asr-flash" \ -F "file=@voice-note.m4a"
{
"text": "明天上午十点提醒我开会。",
"model": "miyang/miyang-asr-flash",
"usage": {"input_tokens": 125, "output_tokens": 9, "total_tokens": 134},
"request_id": "3d7e...request"
}
Returns audio bytes synchronously with a Content-Type matching response_format. miyang-tts-v1 is optimized for realtime interaction and supports voices, pitch, and style instructions; miyang-tts-v1-pro is a unified audio generation model, currently exposed for single-speaker synthesis with optional reference audio.
| Parameter | Type | Description |
|---|---|---|
| model | string | miyang-tts-v1 or miyang-tts-v1-pro |
| input | string | Text to synthesize (text is also accepted); up to 20000 characters for v1 and 3000 for v1 Pro |
| voice | string | Voice ID, default longanhuan_v3.1; v1 only |
| response_format | string | mp3 (default), wav, pcm; v1 also supports opus |
| sample_rate | integer | 8000, 16000, 22050, 24000, 44100, 48000; v1 defaults to 24000, v1 Pro defaults to 48000 and does not support 22050 |
| speed | number | Speaking rate 0.5–2, default 1 |
| volume | number | Volume 0–100, default 50 |
| pitch | number | Pitch 0.5–2, default 1; v1 only |
| instruction | string | Natural-language style instruction, up to 500 characters; v1 only |
| references | array | Reference audio, up to 3 items, each with exactly one of audio_url or audio_data; v1 Pro only |
Billed by the input and output tokens reported upstream; usage is also returned in the X-Usage-Input-Tokens and X-Usage-Output-Tokens response headers.
curl https://miyang.cn/api/v1/audio/speech \ -H "Authorization: Bearer miyang-xxx" \ -H "Content-Type: application/json" \ -d '{ "model": "miyang-tts-v1", "input": "欢迎使用米羊语音合成。", "voice": "longanhuan_v3.1", "response_format": "mp3" }' \ --output speech.mp3
miyang-omni-v1-realtime is a full-duplex voice conversation model. Connect over WebSocket and authenticate with the Authorization: Bearer miyang-xxx request header. Miyang transparently relays Realtime protocol client and server events (such as session.update, input_audio_buffer.append, response.create, and response.audio.delta).
Rejected connections close with: 4401 authentication failed, 4402 insufficient Mili, 4403 model access denied, 4429 rate limited, 4503 route unavailable.
import WebSocket from "ws"; const ws = new WebSocket( "wss://miyang.cn/api/v1/realtime?model=miyang-omni-v1-realtime", { headers: { Authorization: "Bearer miyang-xxx" } } ); ws.on("open", () => { ws.send(JSON.stringify({ type: "session.update", session: { modalities: ["text", "audio"] } })); // then send input_audio_buffer.append (Base64 PCM) and read response.audio.delta }); ws.on("message", (data) => console.log(JSON.parse(data).type));
Realtime web access for agents and apps: web search, news search, and page reading. All endpoints are GET and use the same API key as inference (Authorization: Bearer miyang-xxx).
| Endpoint | Parameter | Description |
|---|---|---|
| /api/v1/websearch/search | q | Deep search: results include extracted page text and reranked context, good for RAG |
| /api/v1/websearch/simple-search | q | Quick search: titles and snippets only, faster response |
| /api/v1/websearch/reader | url | Page reader: fetch a URL and return clean text |
| /api/v1/websearch/search-news | q | News search: recent news sources only; results also include retrieval context |
Full pipeline: search → extract page text → retrieve → rerank. Each result includes contexts snippets you can feed to a model for cited answers. Typically 3–8 seconds.
| Parameter | Type | Description |
|---|---|---|
| q required | string | Search query |
curl "https://miyang.cn/api/v1/websearch/search?q=最新AI新闻" \ -H "Authorization: Bearer miyang-xxx"
// 响应示例 { "code": 200, "message": "ok", "took_ms": 4200, "data": { "organic": [ { "title": "AI News", "link": "https://example.com", "snippet": "Latest updates...", "contexts": [ { "idx": 0, "text": "..." } ] } ] } }
Search only—no extraction or reranking. Usually returns within 1 second. Use it when you only need title + snippet + link. If an answer card is hit, the response also includes answerBox.
| Parameter | Type | Description |
|---|---|---|
| q required | string | Search query |
curl "https://miyang.cn/api/v1/websearch/simple-search?q=最新AI新闻" \ -H "Authorization: Bearer miyang-xxx"
// 响应示例 { "code": 200, "message": "ok", "took_ms": 950, "data": { "answerBox": { "title": "Latest AI news", "snippet": "..." }, "organic": [ { "title": "AI News", "link": "https://example.com", "snippet": "Latest updates..." } ] } }
When you already have a page URL, fetch it and convert it to clean Markdown. This endpoint returns a top-level content field, not data.
| Parameter | Type | Description |
|---|---|---|
| url required | string | Page URL to read; must start with http:// or https:// |
curl "https://miyang.cn/api/v1/websearch/reader?url=https://go.dev" \ -H "Authorization: Bearer miyang-xxx"
// 响应示例(content 为页面正文) { "code": 200, "message": "ok", "content": "# The Go Programming Language\n\nGo is an open source programming language..." }
Searches recent news sources only. The rest of the pipeline matches deep search, and results also include contexts snippets.
404 (body {"code": 404, "message": "no search results"}). That is a normal business result and is not charged.
| Parameter | Type | Description |
|---|---|---|
| q required | string | News search query |
curl "https://miyang.cn/api/v1/websearch/search-news?q=OpenAI" \ -H "Authorization: Bearer miyang-xxx"
// 响应示例 { "code": 200, "message": "ok", "took_ms": 4200, "data": { "organic": [ { "title": "Latest OpenAI news", "link": "https://example.com/news", "snippet": "Recent product and research updates...", "contexts": [ { "idx": 0, "text": "..." } ] } ] } }
Set "stream": true in the request body to stream. The response matches OpenAI's SSE spec. The stream ends with data: [DONE].
from openai import OpenAI client = OpenAI( api_key="miyang-xxx", base_url="https://miyang.cn/api/v1", ) stream = client.chat.completions.create( model="miyang/auto", messages=[{"role": "user", "content": "Hello!"}], stream=True, ) for chunk in stream: print(chunk.choices[0].delta.content, end="")
response_format is passed through and supports JSON Schema. The upstream model enforces the format; the platform does not rewrite it.
{
"model": "miyang/auto",
"messages": [...],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "result",
"schema": {
"type": "object",
"properties": {
"answer": { "type": "string" }
}
}
}
}
}
For models that support Prompt Cache, cache-hit tokens from upstream are billed at a discount. The platform passes through the upstream usage field, and the invoice shows cache hits.
Field names differ by vendor:
cache_read_input_tokens— Anthropicprompt_cache_hit_tokens— DeepSeekcached_tokens— OpenAI
{
"usage": {
"prompt_tokens": 1000,
"completion_tokens": 200,
"cache_read_input_tokens": 800, // Anthropic
"prompt_cache_hit_tokens": 800, // DeepSeek
"cached_tokens": 800 // OpenAI
}
}
Swap base_url and api_key, then call through the OpenAI SDK.
from openai import OpenAI client = OpenAI( api_key="miyang-xxx", base_url="https://miyang.cn/api/v1", ) resp = client.chat.completions.create( model="miyang/auto", messages=[{"role": "user", "content": "Hello!"}], ) print(resp.choices[0].message.content)
Verify an API key, connectivity, and request parameters without installing an SDK—ideal for a first integration or diagnosing request failures.
# 非流式 curl https://miyang.cn/api/v1/chat/completions \ -H "Authorization: Bearer miyang-xxx" \ -H "Content-Type: application/json" \ -d '{ "model": "miyang/auto", "messages": [{"role": "user", "content": "Hello"}] }' # 流式 curl https://miyang.cn/api/v1/chat/completions \ -H "Authorization: Bearer miyang-xxx" \ -H "Content-Type: application/json" \ -d '{ "model": "miyang/auto", "messages": [{"role": "user", "content": "Hello"}], "stream": true }'