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, 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
}
}
Usage is billed in credits (米粒) and deducted in real time. Top-ups currently credit 1 CNY = 140 credits (米粒); campaign bonuses are extra.
- 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 }'
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 pricing, 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 客户端内使用",
"pricing": {
"prompt": "3.250000",
"completion": "13.500000",
"cache_read": "0.550000",
"cache_write": "0.000000"
},
"context_length": 262144
}
]
}
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 |
| Price | Input $0.042 / 1M tokens; output $0.000 / 1M tokens. Billing uses the actual token usage returned upstream. |
| 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 |
GPT Image 2 reference pricing (credits (米粒) / image)
| Quality | 1024×1024 | 1024×1536 / 1536×1024 |
|---|---|---|
| Low | 6 credits (米粒) | 5 credits (米粒) |
| Medium | 53 credits (米粒) | 41 credits (米粒) |
| High | 211 credits (米粒) | 165 credits (米粒) |
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)
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"
}
User billing
The table shows exact CNY-denominated prices. Credits (米粒) are calculated as CNY price ÷ CNY-per-USD rate × 1000.
| Model | Billable item | User price |
|---|---|---|
| miyang/h3 | Output video · 768P | ¥1.25 / s |
| miyang/h3 | Output video · 2K | ¥2.0 / s |
| miyang/h3 | Reference video input · 768P | ¥1.25 / s |
| miyang/h3 | Reference video input · 2K | ¥2.0 / s |
| miyang/h3 | Reference image input (first 5 free; excess only) | ¥0.5 / image |
| miyang/h3-max | Output video · 480P | ¥0.825 / s |
| miyang/h3-max | Output video · 768P | ¥1.25 / s |
| miyang/h3-max | Reference video input · 480P | ¥0.925 / s |
| miyang/h3-max | Reference video input · 768P | ¥2.425 / s |
| miyang/h3-max | Reference image input (first 2 free; excess only) | ¥1.25 / image |
| — | Reference audio input | Free |
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"
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)
# 非流式 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 }'