Base URL

Recommended Base URL for the OpenAI-compatible API:

https://miyang.cn/api/v1
The legacy URL https://miyang.cn/v1 still works for existing clients; new integrations should use https://miyang.cn/api/v1.
Authentication

Except for the public model list, inference endpoints require an API key in the request headers. Two headers are supported:

  • RecommendedAuthorization: Bearer miyang-xxxxx
  • Fallbackx-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.

bash
# 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 naming

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 request
  • miyang/standard — Standard-tier model
  • miyang/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.

python
# 自动选择适合当前请求的模型
model = "miyang/auto"
Rate limits

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.

http
{
  "error": {
    "message": "Rate limit exceeded",
    "type": "rate_limit_error",
    "code": 1002
  }
}
Billing

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_tokens is billed at a discounted rate

Top up credits (米粒) in the console and review calls and spend under Usage.

json
// 余额不足响应(402)
{
  "error": {
    "message": "Insufficient balance",
    "type": "insufficient_balance",
    "code": 1004
  }
}
Chat Completions
POST /api/v1/chat/completions

OpenAI-compatible chat endpoint with streaming and non-streaming output. Point the OpenAI SDK base_url here.

ParameterTypeDescription
model requiredstringModel ID, format provider_slug/model
messages requiredarrayChat messages; each item has role and content
streambooleanEnable streaming (SSE); default false
temperaturefloatSampling temperature, range 0–2
max_tokensintegerMaximum output tokens
response_formatobjectStructured output format; see Structured output
bash
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
  }'
List models
GET /api/v1/models

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.

json
{
  "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
    }
  ]
}
Embeddings
POST /api/v1/embeddings

OpenAI-compatible embeddings endpoint. Whether a model supports embedding tasks is marked on the model list and in the console.

ParameterTypeDescription
model requiredstringEmbedding model call ID
input requiredstring / arrayText or array of texts to embed
encoding_formatstringVector encoding format; commonly float
bash
curl https://miyang.cn/api/v1/embeddings \
  -H "Authorization: Bearer miyang-xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "provider/embedding-model",
    "input": "需要向量化的文本"
  }'
Structured Decisions (Jev)
POST /api/v1/decisions

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.

Any valid Miyang API key can call it with 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 informationValue
Miyang model IDmiyang/jev-1.13
Decision enginetypesafe/jev-1.13
Context limit32768 tokens
Question typesnoul / choice / score
Price Input $0.042 / 1M tokens; output $0.000 / 1M tokens. Billing uses the actual token usage returned upstream.
AvailabilityAll 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.

ParameterTypeDescription
model requiredstringUse miyang/jev-1.13 for public calls. Ordinary API users cannot call internal scenario shells.
state requiredobjectStructured state used for the decision; callers should remove unnecessary sensitive data before sending.
questions requiredobjectObject keyed by question name; 1 to 24 questions.
questions.*.type requiredstringnoul (0–1 probability), choice, or score.
questions.*.instructions requiredstringA precise description of the decision to make.
questions.*.criteriaobjectOptional 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.

bash
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"
        }
      }
    }
  }'
json
{
  "model": "miyang/jev-1.13",
  "provider": "miyang",
  "answers": {
    "remember": {
      "type": "noul",
      "noul": 0.02
    }
  }
}
Images Generations (text-to-image)
POST /api/v1/images/generations

OpenAI-compatible image generation. Send a text prompt and get an image URL or Base64 data, fully compatible with the OpenAI Images API.

Image generation is slow (typically 30–120 seconds). Set the timeout in your SDK or HTTP client to at least 180 seconds.
ParameterTypeDescription
model requiredstringModel ID, format provider/model, e.g. ts/gpt-image-2
prompt requiredstringImage description
nintegerNumber of images; default 1, multiple allowed
sizestringImage 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
qualitystringRender quality: low (fast draft), medium, high, auto (default, model chooses)
output_formatstringOutput format: png (default), jpeg (faster), webp
output_compressionintegerCompression 0–100; JPEG / WebP only
backgroundstringopaque (default) or transparent (transparent background, good for icons/stickers)
moderationstringModeration: auto (default) or low (lenient)

Basic example — text-to-image:

bash
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"
  }'
python
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:

python
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"])
json
// 响应示例
{
  "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

ParameterValuesDescription
size1024x1024 (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
qualitylow · medium · high · autolow is fastest, good for drafts; high is most detailed, good for finals
output_formatpng · jpeg · webpjpeg is faster than png; prefer it when latency matters

GPT Image 2 reference pricing (credits (米粒) / image)

Quality1024×10241024×1536 / 1536×1024
Low6 credits (米粒)5 credits (米粒)
Medium53 credits (米粒)41 credits (米粒)
High211 credits (米粒)165 credits (米粒)
Images Edits (reference / image-to-image)
POST /api/v1/images/edits

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"
ParameterTypeDescription
model requiredstringModel ID, e.g. ts/gpt-image-2
image requiredfile / file[]Reference image(s). One file as image; multiple as image[] (repeat image[]=@file.png)
prompt requiredstringEdit instruction
maskfileMask image (must include an alpha channel); transparent pixels are edited. With multiple images the mask applies to the first one
nintegerNumber of images; default 1
sizestringOutput size; default auto; same size options as Generations
qualitystringlow · medium · high · auto

Single-image edit — style transfer:

bash
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"
python
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:

bash
# 多图参考:用 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:

python
# 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)
Mask requirements:The mask and source image must share size and format, each < 50MB. The mask must include an alpha channel (transparent pixels are edited). GPT Image treats the mask as prompt guidance and may not follow the edge exactly.
Videos Generations
POST /api/v1/videos/generations

Asynchronous video generation. A successful request returns a task_id; poll the query endpoint for status instead of submitting the same business request again.

Currently available only to Alice and internal accounts. Supported models are miyang/h3 and miyang/h3-max.
ParameterTypeDescription
model requiredstringmiyang/h3 or miyang/h3-max
content requiredarrayMultimodal content array with exactly one non-empty text item; images, video, and audio may also be included
duration requiredintegerOutput duration in seconds. H3 supports 4–15; H3 Max supports 5–15
resolutionstringDefault 768P. H3 supports 768P / 2K; H3 Max supports 480P / 768P
ratiostringAspect ratio: 21:9, 16:9, 4:3, 1:1, 3:4, or 9:16; reference media may use adaptive
aigc_watermarkbooleanWhether to add an AIGC watermark
extraobjectH3 Max only. prompt_expansion_mode may be disabled, balanced, or quality

content media format

typeroleDescription
textRequired exactly once, up to 7,000 characters
image_urlfirst_frame / last_frame / reference_imageFirst frame, last frame, or reference image; one image without a role becomes the first frame
video_urlreference_videoReference video, up to 3; role is required
audio_urlreference_audioReference audio, up to 3; role is required
bash
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"
  }'
json
{
  "task_id": "443429054845209"
}

User billing

The table shows exact CNY-denominated prices. Credits (米粒) are calculated as CNY price ÷ CNY-per-USD rate × 1000.

ModelBillable itemUser price
miyang/h3Output video · 768P¥1.25 / s
miyang/h3Output video · 2K¥2.0 / s
miyang/h3Reference video input · 768P¥1.25 / s
miyang/h3Reference video input · 2K¥2.0 / s
miyang/h3Reference image input (first 5 free; excess only)¥0.5 / image
miyang/h3-maxOutput video · 480P¥0.825 / s
miyang/h3-maxOutput video · 768P¥1.25 / s
miyang/h3-maxReference video input · 480P¥0.925 / s
miyang/h3-maxReference video input · 768P¥2.425 / s
miyang/h3-maxReference image input (first 2 free; excess only)¥1.25 / image
Reference audio inputFree
Output video, reference-video input, and excess-image charges are added together. Credit conversion uses the live exchange rate when the task settles; the Usage record is authoritative.
Query video task
GET /api/v1/videos/generations/{task_id}

Poll with the task_id returned at creation. Status may be queued, running, succeeded, failed, or cancelled. Poll every 5–15 seconds.

Successful videos are automatically copied to the current user's Miyang Drive and consume cloud quota. If storage is full, quota_full is returned; clean up files or expand storage before delivery and settlement can finish. Playback URLs are temporary signed URLs—query again when needed.
bash
curl https://miyang.cn/api/v1/videos/generations/443429054845209 \
  -H "Authorization: Bearer miyang-xxx"
json
{
  "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 video task
DELETE /api/v1/videos/generations/{task_id}

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.

bash
curl -X DELETE https://miyang.cn/api/v1/videos/generations/443429054845209 \
  -H "Authorization: Bearer miyang-xxx"
Web search (overview & billing)

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).

Billing: quick search, page reader, and news search cost 10 credits (米粒) each; deep search costs 50 credits (米粒) each.Failed requests (upstream errors, bad parameters, or no news results) are not charged.
EndpointParameterDescription
/api/v1/websearch/searchqDeep search: results include extracted page text and reranked context, good for RAG
/api/v1/websearch/simple-searchqQuick search: titles and snippets only, faster response
/api/v1/websearch/readerurlPage reader: fetch a URL and return clean text
/api/v1/websearch/search-newsqNews search: recent news sources only; results also include retrieval context
Quick search
GET /api/v1/websearch/simple-search

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.

ParameterTypeDescription
q requiredstringSearch query
bash
curl "https://miyang.cn/api/v1/websearch/simple-search?q=最新AI新闻" \
  -H "Authorization: Bearer miyang-xxx"
json
// 响应示例
{
  "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..."
      }
    ]
  }
}
Page reader
GET /api/v1/websearch/reader

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.

ParameterTypeDescription
url requiredstringPage URL to read; must start with http:// or https://
bash
curl "https://miyang.cn/api/v1/websearch/reader?url=https://go.dev" \
  -H "Authorization: Bearer miyang-xxx"
json
// 响应示例(content 为页面正文)
{
  "code": 200,
  "message": "ok",
  "content": "# The Go Programming Language\n\nGo is an open source programming language..."
}
News search
GET /api/v1/websearch/search-news

Searches recent news sources only. The rest of the pipeline matches deep search, and results also include contexts snippets.

No matching news returns 404 (body {"code": 404, "message": "no search results"}). That is a normal business result and is not charged.
ParameterTypeDescription
q requiredstringNews search query
bash
curl "https://miyang.cn/api/v1/websearch/search-news?q=OpenAI" \
  -H "Authorization: Bearer miyang-xxx"
json
// 响应示例
{
  "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": "..." }
        ]
      }
    ]
  }
}
Streaming (SSE)

Set "stream": true in the request body to stream. The response matches OpenAI's SSE spec. The stream ends with data: [DONE].

python
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="")
Structured output

response_format is passed through and supports JSON Schema. The upstream model enforces the format; the platform does not rewrite it.

json
{
  "model": "miyang/auto",
  "messages": [...],
  "response_format": {
    "type": "json_schema",
    "json_schema": {
      "name": "result",
      "schema": {
        "type": "object",
        "properties": {
          "answer": { "type": "string" }
        }
      }
    }
  }
}
Prompt Cache

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 — Anthropic
  • prompt_cache_hit_tokens — DeepSeek
  • cached_tokens — OpenAI
json
{
  "usage": {
    "prompt_tokens": 1000,
    "completion_tokens": 200,
    "cache_read_input_tokens": 800,   // Anthropic
    "prompt_cache_hit_tokens": 800,    // DeepSeek
    "cached_tokens": 800               // OpenAI
  }
}
Python SDK example

Swap base_url and api_key, then call through the OpenAI SDK.

python
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 example
bash
# 非流式
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
  }'