ciyuan_market Docs
Quickstart
ciyuan_market gives production teams one stable API for model access, routing, fallback, usage tracking, and credit-based billing. LLM token supply is sourced from trusted enterprise cloud original-provider accounts, with privacy protection, high stability, and request traceability built into the gateway.
https://api.ciyuan-market.com/apihttps://api.ciyuan-market.com/api/v1https://api.ciyuan-market.com/api/v1Authorization: Bearer <key>Create an API key
Create a ciyuan_market API key in the console. Keep the key on your server and never expose it in browser or mobile client code.
Recommended key strategy:
| Key type | Recommended usage |
|---|---|
| Development key | Local development, staging, testing, and prototypes. |
| Production key | Backend production workloads only. |
| Integration key | Dedicated key for tools such as Cursor, Claude Code, Codex, Hermes, or OpenClaw. |
| Customer / tenant key | Optional key isolation for enterprise customers, tenant traffic, or business units. |
Rotate keys when team access changes. Revoke keys that are no longer used.
Point your SDK at ciyuan_market
Most OpenAI-compatible clients only need a new base URL and API key.
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.CIYUAN_MARKET_API_KEY,
baseURL: "https://api.ciyuan-market.com/api/v1"
});
Send a chat completion
curl --request POST \
--url https://api.ciyuan-market.com/api/v1/chat/completions \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"model": "claude-sonnet-5",
"messages": [
{ "role": "user", "content": "Explain ciyuan_market in one sentence." }
]
}'
Check usage and balance
curl --request GET \
--url https://api.ciyuan-market.com/api/v1/billing/balance \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY"
Model Discovery
Use the Models page or the Models API to inspect available text models. Model metadata includes vendor, serving provider, modality, context length, supported API families, supported capabilities, availability, account-level limits, and credit pricing.
Endpoint: GET /v1/models Purpose: List
models available to the current account.
curl --request GET \
--url https://api.ciyuan-market.com/api/v1/models \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY"
Capability matrix
| Capability | Description | Commonly used by |
|---|---|---|
streaming | Supports server-sent event streaming. | Chat apps, coding agents, real-time UX. |
tool_calling | Supports tool or function calling. | Agents, workflow automation, coding assistants. |
structured_outputs | Supports schema-constrained or JSON outputs. | Data extraction, workflow automation, enterprise apps. |
json_mode | Can return JSON-formatted output. | Lightweight structured responses. |
vision | Accepts image input. | Multimodal chat, UI analysis, document screenshots. |
prompt_caching | Supports cached input or context reuse. | Long-context agents, repeated system prompts. |
reasoning | Supports explicit reasoning controls where available. | Complex planning, coding, analysis workflows. |
logprobs | Supports token probability output. | Evaluation, ranking, advanced NLP workflows. |
API family compatibility matrix
| API family | Text | Vision input | Tool calling | Structured output | Streaming | Notes |
|---|---|---|---|---|---|---|
| OpenAI Chat Completions | Yes | Model-dependent | Model-dependent | Model-dependent | Yes | Best default for OpenAI-compatible agents and SDKs. |
| OpenAI Responses | Yes | Model-dependent | Model-dependent | Model-dependent | Yes | Recommended for newer OpenAI-style agent workflows. |
| Anthropic Messages | Yes | Model-dependent | Model-dependent | Model-dependent | Yes | Best for Claude-compatible clients and Claude Code. |
| ciyuan_market image generation | No | Model-dependent | No | No | No | Uses async task polling or webhook. |
| ciyuan_market video generation | No | Model-dependent | No | No | No | Uses async task polling or webhook. |
Authentication
Every API request uses a bearer token. Store keys in server-side environment variables, rotate them when team access changes, and log request IDs for debugging.
| Header | Value | Notes |
|---|---|---|
Authorization | Bearer YOUR_API_KEY | Required for every request. |
Content-Type | application/json | Required for JSON request bodies. |
Key security recommendations
- Keep API keys on the server. Do not expose keys in browser or mobile client code.
- Use separate keys for development, staging, production, and third-party integrations.
- Scope keys by environment, service, customer, or tenant when available.
- Rotate keys after employee departures, vendor access changes, or suspected leakage.
- Store keys in secret managers or environment variables, not source code.
Coding Agents
ciyuan_market works with coding agents and AI development tools that support
OpenAI-compatible or Anthropic-compatible API endpoints. Use routing aliases such as
mwf/coding-auto so ciyuan_market can route to the best available coding
model without requiring developers to change tool configuration.
Generic OpenAI-compatible setup
Use this setup for Cursor, Codex, Hermes, OpenClaw, Continue, Aider, Cline, LangChain-based agents, LlamaIndex-based agents, and custom OpenAI-compatible agent runtimes.
export OPENAI_BASE_URL="https://api.ciyuan-market.com/api/v1"
export OPENAI_API_KEY="$CIYUAN_MARKET_API_KEY"
export OPENAI_MODEL="mwf/coding-auto"
Generic Anthropic-compatible setup
Use this setup for Claude-compatible clients and tools that expect Anthropic Messages format.
export ANTHROPIC_BASE_URL="https://api.ciyuan-market.com/api/anthropic"
export ANTHROPIC_API_KEY="$CIYUAN_MARKET_API_KEY"
export ANTHROPIC_MODEL="mwf/coding-auto"
Recommended agent models
| Use case | Recommended alias | Requirements |
|---|---|---|
| General coding | mwf/coding-auto | Tool calling, streaming, strong coding ability. |
| Fast coding chat | mwf/coding-fast | Low latency and streaming. |
| Large repo analysis | mwf/coding-long | Long context and stable output. |
| Cost-sensitive coding assistant | mwf/low-cost | Lower price and acceptable coding quality. |
| UI screenshot / vision coding | mwf/vision-chat | Vision input and text output. |
Cursor quick guide
Use the OpenAI-compatible endpoint.
Base URL: https://api.ciyuan-market.com/api/v1
API Key: CIYUAN_MARKET_API_KEY
Model: mwf/coding-auto
Recommended steps:
- Open Cursor settings.
- Add or enable OpenAI-compatible API key configuration.
- Set the OpenAI base URL override to
https://api.ciyuan-market.com/api/v1. - Add a custom model such as
mwf/coding-auto,mwf/coding-fast, ormwf/coding-long. - Use a model that supports streaming and tool calling for best agent behavior.
Troubleshooting:
| Issue | Suggested fix |
|---|---|
| Model not shown | Add the model name manually as a custom model. |
| Tool calling fails | Use a model with tool_calling: true in the Models page. |
| Streaming interrupted | Retry with backoff or use a routing alias with fallback. |
| 401 error | Check the API key and base URL. |
| 404 model error | Confirm the model is enabled for the account. |
Claude Code quick guide
Use the Anthropic-compatible gateway endpoint.
export ANTHROPIC_BASE_URL="https://api.ciyuan-market.com/api/anthropic"
export ANTHROPIC_API_KEY="$CIYUAN_MARKET_API_KEY"
export ANTHROPIC_MODEL="mwf/coding-auto"
ciyuan_market supports this Anthropic-compatible path for Claude Code and Anthropic SDK compatibility:
POST /api/v1/messages
Recommended requirements:
| Requirement | Reason |
|---|---|
| Anthropic Messages-compatible request shape | Claude Code expects Anthropic-style messages. |
| Streaming support | Claude Code relies on streaming UX. |
| Tool calling support | Required for agentic coding workflows. |
| Long context | Useful for repository-level tasks. |
| Stable fallback | Useful for long-running coding sessions. |
Codex quick guide
Use ciyuan_market as a custom OpenAI-compatible model provider.
Example provider configuration:
[model_providers.ciyuanmarket]
name = "ciyuan_market"
base_url = "https://api.ciyuan-market.com/api/v1"
env_key = "CIYUAN_MARKET_API_KEY"
wire_api = "responses"
model_provider = "ciyuanmarket"
model = "mwf/coding-auto"
Environment variable:
export CIYUAN_MARKET_API_KEY="br_xxx"
Recommended models:
| Model | Use case |
|---|---|
mwf/coding-auto | Default coding agent model. |
mwf/coding-long | Large repository context. |
mwf/coding-fast | Fast iteration and small changes. |
Troubleshooting:
| Issue | Suggested fix |
|---|---|
| Auth error | Confirm env_key points to CIYUAN_MARKET_API_KEY. |
| Model not found | Add the alias in ciyuan_market Console or use a direct model ID. |
| Responses API error | Use wire_api = "responses" only for models and endpoints
that support Responses. |
| Chat Completions-only model | Switch to a chat-compatible wire API if the client supports it. |
Hermes quick guide
Use the OpenAI-compatible endpoint unless your Hermes deployment is configured for another protocol.
export OPENAI_BASE_URL="https://api.ciyuan-market.com/api/v1"
export OPENAI_API_KEY="$CIYUAN_MARKET_API_KEY"
export OPENAI_MODEL="mwf/coding-auto"
Recommended model policy:
| Hermes workload | Model |
|---|---|
| General code generation | mwf/coding-auto |
| Low-latency task execution | mwf/coding-fast |
| Long-context repo scan | mwf/coding-long |
| Cost-sensitive background tasks | mwf/low-cost |
OpenClaw quick guide
Use the OpenAI-compatible endpoint for OpenAI-style agent runtime configuration.
export OPENAI_BASE_URL="https://api.ciyuan-market.com/api/v1"
export OPENAI_API_KEY="$CIYUAN_MARKET_API_KEY"
export OPENAI_MODEL="mwf/coding-auto"
If OpenClaw supports multiple providers, configure ciyuan_market as an OpenAI-compatible provider and use ciyuan_market routing aliases for model selection.
{
"provider": "openai-compatible",
"base_url": "https://api.ciyuan-market.com/api/v1",
"api_key_env": "CIYUAN_MARKET_API_KEY",
"model": "mwf/coding-auto"
}
Agent compatibility checklist
| Capability | Required for |
|---|---|
| Streaming | Good terminal/editor UX. |
| Tool calling | Agentic coding, file edits, command execution. |
| Long context | Large repositories and multi-file changes. |
| Structured outputs | Planning, task decomposition, automated workflows. |
| Vision input | UI screenshot analysis and design-to-code workflows. |
| Fallback | Production stability and long-running tasks. |
Using the Console
The ciyuan_market Console is the operational control plane for API access, model availability, routing policies, usage visibility, and billing administration. It gives account administrators a centralized view of keys, models, requests, credits, and account-level controls for production model traffic.
Managing API keys
Create, rotate, revoke, and label API keys from the console. Use separate keys for development, staging, production, and individual services so usage can be audited and isolated by environment or application.
| Practice | Description |
|---|---|
| Separate environments | Use different API keys for development, staging, and production traffic. |
| Use descriptive labels | Label keys by application, service, environment, or integration. |
| Rotate regularly | Rotate keys when access changes or credentials may have been exposed. |
| Avoid client-side exposure | Keep API keys on server-side systems only. Do not expose keys in browser or mobile client code. |
| Monitor key usage | Review request volume, credit consumption, and error patterns by key. |
Model list
Use the Models page to review models available to the account. Each model entry may include vendor, serving provider, modality, supported API families, context length, capability flags, availability status, and pricing information.
| Filter | Purpose |
|---|---|
| Vendor | Filter by model vendor such as OpenAI, Anthropic, Google, Qwen, DeepSeek, or other providers. |
| Provider | Filter by serving provider or cloud provider. |
| Modality | Filter by text, image, video, embedding, audio, or multimodal support. |
| Capability | Filter by streaming, tool calling, structured outputs, vision, prompt caching, or reasoning support. |
| Availability | Identify models that are currently available to the account. |
For production applications, verify model capabilities before enabling traffic. Some parameters and features are model-dependent and may not be supported across all API families.
Usage & logs
The Usage & Logs view provides operational visibility into API traffic. Teams can inspect request volume, selected models, resolved routing targets, credit consumption, latency, error codes, and request IDs.
- Troubleshoot failed requests.
- Identify high-cost workloads.
- Compare model usage across applications and environments.
- Validate routing and fallback behavior.
- Investigate latency or provider availability issues.
- Provide request IDs when contacting support.
Each API response includes or exposes a ciyuan_market request ID. Store this ID in your application logs to make production debugging and support escalation more efficient.
Fallback
Fallback is ciyuan_market's resilience mechanism. When the primary model or routing policy fails, the system automatically switches to a backup model to keep processing the request. This keeps your application responsive and minimizes the risk of service disruption.
Fallback acts like a safety net, keeping your application running smoothly even when a model failure, quota limit, or network fluctuation occurs.
Why fallback matters
In production, model services can run into a number of unpredictable issues:
- Model service failure: the upstream API becomes temporarily unavailable or times out.
- Performance fluctuation: high model load leads to slow or failed responses.
- Routing failure: all candidate models selected by smart routing become unavailable.
Fallback keeps your application available by providing a reliable backup path.
Core advantages
| Advantage | Description |
|---|---|
| High availability | Automatic failover keeps the service running and reduces the impact of outages. |
| Transparent switching | The system switches models automatically — no application code changes required. |
| Flexible configuration | Supports both per-request and account-level configuration for different use cases. |
| Cost optimization | Choose a more cost-effective model as the fallback to control emergency costs. |
| Centralized management | Configure once at the account level and it applies automatically to every request. |
Global fallback model configuration
ciyuan_market supports setting a global fallback model from the console backend. All requests automatically use this model as a backup when they fail.
How to configure it:
- Go to the ciyuan_market strategy settings page.
- Find the Default Fallback Model setting.
- Select your global fallback model from the dropdown list.
- Save the setting to apply it immediately.
Advantages of global configuration:
- No code changes required: configure once and it applies globally, with no need to repeat the setting on every request.
- Centralized management: manage the fallback policy in one place for easier adjustment and monitoring.
- Simplified maintenance: reduces code complexity and the chance of configuration errors.
- Flexible override: request-level fallback configuration takes priority and can override the global setting for specific scenarios.
Request-level fallback configuration
For specific business scenarios, you can specify a fallback model on an individual request to override the global configuration.
Specify the fallback model with the router.fallBackModels parameter:
{
"model": "claude-sonnet-4",
"messages": [
{
"role": "user",
"content": "Explain what quantum computing is"
}
],
"router": {
"fallBackModels": ["glm-5.2"]
}
}
Priority rules
When multiple fallback configurations are present, priority runs from highest to lowest:
- Request-level
router.fallBackModels: the fallback model specified on an individual request. - Global Default Fallback Model: the global fallback model configured in the console.
- No fallback: if neither is configured, the request returns an error on failure.
- If all fallback models fail, the system returns the failure reason from the last model attempted.
- When a fallback occurs, the response indicates the model actually used, making it easy to monitor and analyze.
Account administration
Depending on account type, the console may include account-level model enablement, reseller or distributor controls, billing configuration, and access settings. Administrators can use these controls to align model access, usage visibility, and billing responsibility with applications, customer accounts, or business units.
Production operations checklist
| Item | Recommendation |
|---|---|
| API keys | Use dedicated production keys with clear labels. |
| Models | Confirm model availability, pricing, context length, and required capabilities. |
| Routing | Configure routing aliases or fallback policies for critical workloads. |
| Logs | Ensure request IDs are captured in application logs. |
| Billing | Confirm wallet balance, plan status, and credit deduction rules. |
| Rate limits | Review account-level RPM, TPM, concurrency, and media task limits. |
| Alerts | Monitor usage growth, credit balance, errors, and provider availability. |
Billing & Credits
ciyuan_market uses a credit-based billing model across text, image, video, and other supported model workloads. Credits provide a unified unit for multi-model and multi-provider usage so teams can manage consumption consistently across modalities and API families.
Detailed model pricing is available on the Models page or through model metadata APIs. Pricing may vary by model, provider, modality, resolution, token type, output length, task duration, account type, and commercial agreement.
Top up & wallet
Accounts may add pay-as-you-go wallet credits for flexible usage. Wallet credits are used after monthly plan credits and resource packs have been consumed, unless a custom billing rule applies to the account.
Wallet credits do not expire unless otherwise specified in applicable commercial terms. Service fee is charged when recharging the pay-as-you-go wallet.
Monthly plans and resource packs
Each user or account can select one active monthly plan. Monthly plans provide a defined amount of usage capacity, commercial terms, and account-level access configuration for the billing period.
Users can also buy multiple resource packs for additional usage capacity. Resource packs can separate committed usage from pay-as-you-go wallet balance and are useful for high-volume text, image, video, or dedicated workload usage.
Deduction order
Unless custom billing rules are configured, credits are deducted in the following order:
| Priority | Credit source | Description |
|---|---|---|
| 1 | Monthly plan | Included monthly usage capacity is consumed first. |
| 2 | Resource packs | Additional purchased packs are consumed after monthly plan credits. |
| 3 | Pay-as-you-go wallet | Wallet balance is consumed after plan and resource pack credits. |
For accounts with custom commercial terms, deduction order, expiration rules, included usage, and pricing may differ. Account-specific rules are shown in the console or provided through the commercial agreement.
Custom pricing
Pricing can be customized for each user or account. Enterprise customers, reseller accounts, distributor accounts, and high-volume customers may be eligible for custom pricing. Contact sales for a quote.
Custom pricing can be configured by account, model, provider, modality, region, usage volume, or commercial agreement. When custom pricing is enabled, the console and billing APIs reflect account-specific pricing and deduction rules where available.
Pricing units
Different model modalities use different measurement units. ciyuan_market converts these units into credits according to the model’s pricing rules.
| Modality | Common pricing basis |
|---|---|
| Text | Input tokens, output tokens, cached read tokens, cached write tokens, reasoning tokens, or model-specific token categories. |
| Image | Model, resolution, number of generated images, input image usage, editing mode, or quality setting. |
| Video | Model, output resolution, generated seconds, aspect ratio, input image or video usage, and task type. |
| Embeddings | Input tokens or number of embedding records. |
| Audio | Input duration, output duration, transcription length, or model-specific audio units. |
Pricing units may vary by model. Always refer to the model detail page or pricing metadata before enabling a model in production.
Usage attribution
ciyuan_market usage can be reviewed by account, API key, model, modality, or time range. This allows teams to attribute cost to applications, environments, customers, or internal business units.
| Dimension | Description |
|---|---|
| API key | Group usage by application, service, or environment. |
| Model | Compare cost and volume by selected model. |
| Resolved model | Review the actual model used after routing or fallback. |
| Modality | Separate text, image, video, embedding, and audio usage. |
| Time range | Review daily, monthly, or custom reporting periods. |
| Metadata | Group usage by custom request metadata such as customer ID, tenant ID, user ID, or environment. |
Credit balance
Check how many credits are available across your account. The balance is split into three wallets that are deducted in order: the monthly plan allowance, purchased resource packs, and the pay-as-you-go wallet. A combined resource total (monthly plan + resource packs, excluding pay-as-you-go) is also available for tracking included usage separately from top-up spending.
To retrieve this programmatically, see
GET /v1/billing/balance in the API
Reference.
Usage details
Review a paginated, chronological list of individual usage records for reporting, monitoring, and internal cost allocation. Each record shows the model, model type (text, image, or video), the credits deducted, and a breakdown of which wallet each deduction was drawn from. Results can be filtered to a specific time range.
To retrieve this programmatically, see
GET /v1/usage in the API Reference.
Transaction history
Use transaction history to review credit movements, including top-ups, plan allocations, resource pack grants, usage deductions, adjustments, and administrative corrections.
To retrieve this programmatically, see
GET /v1/billing/transactions in the API
Reference.
Failed requests and refunds
Validation errors, authentication errors, and permission errors are generally not billed because no model execution occurs. Requests that reach an upstream model or generate partial output may consume credits depending on the model, provider, and response state.
For async image and video tasks, billing behavior depends on whether the task was accepted, started, completed, failed, or cancelled. The task detail response includes usage information when credits have been consumed.
Top-ups, monthly plans, resource packs, and consumed credits are non-refundable unless otherwise specified in the applicable commercial agreement or required by law.
API Reference
Common conventions
Base URL
All endpoints are served under the /v1 prefix.
Authentication
Calls to /v1/* endpoints use API Key authentication (not
JWT). The API Key is passed via the following header:
| Header | Format | Description |
|---|---|---|
Authorization | Bearer <api_key> | OpenAI-style. The Anthropic-compatible endpoint also accepts
x-api-key with anthropic-version: 2023-06-01. |
Missing or invalid keys return 401.
Balance pre-check
All model-calling endpoints run a balance pre-check before execution:
- Insufficient balance returns
Insufficient credit, mapped to:- OpenAI protocol: HTTP
400,code = insufficient_quota - Anthropic protocol: HTTP
402,type = billing_error
- OpenAI protocol: HTTP
- Some endpoints also estimate a minimum cost per model for a second pre-check.
POST https://api.ciyuan-market.com/api/v1/chat/completions
OpenAI Chat Completions-compatible endpoint. Supports streaming and non-streaming, tool calls, JSON mode, and multimodal input.
| Field | Type | Required | Description |
|---|---|---|---|
model | String | Yes | Model name. |
messages | Message[] | Yes | Conversation messages. |
stream | Boolean | No | Stream mode, default false. |
temperature | Double | No | Sampling temperature. |
max_tokens | Integer | No | Maximum output tokens. |
top_p | Double | No | Nucleus sampling. |
presence_penalty | Double | No | — |
frequency_penalty | Double | No | — |
tools | Tool[] | No | Tool definitions. |
tool_choice | String|Object | No | auto / none / required / specific
function. |
response_format | Object | No | {type, json_schema:{name,schema,strict}};
text/json_object/json_schema. |
parallel_tool_calls | Boolean | No | — |
metadata | Map | No | Pass-through metadata. |
Message fields:
| Field | Type | Description |
|---|---|---|
role | String | system / user / assistant /
tool. |
content | String|Array | Plain text or multimodal content block array
([{type:"text",text},{type:"image_url",image_url:{url}}]). |
tool_call_id | String | Links to the tool_calls when role=tool. |
tool_calls | ToolCall[] | Present when role=assistant makes tool calls. |
| Field | Type | Description |
|---|---|---|
type | String | Fixed function. |
function | Object | Function definition. |
function.name | String | Function name. |
function.description | String | Function description. |
function.parameters | Object | JSON Schema for inputs. |
curl --request POST \
--url https://api.ciyuan-market.com/api/v1/chat/completions \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"model": "glm-5.2",
"messages": [{"role": "user", "content": "Describe Hangzhou in one sentence."}],
"stream": false,
"temperature": 0.7
}'
{
"id": "chatcmpl-xxx",
"object": "chat.completion",
"created": 1721380000,
"model": "glm-5.2",
"choices": [
{
"index": 0,
"message": {"role": "assistant", "content": "Hangzhou is ..."},
"finish_reason": "stop"
}
],
"usage": {"prompt_tokens": 12, "completion_tokens": 18, "total_tokens": 30}
}
Response fields (non-streaming):
| Field | Type | Description |
|---|---|---|
id | String | Completion id. |
object | String | Fixed chat.completion. |
created | Long | Created timestamp (seconds). |
model | String | Model name. |
choices | Choice[] | {index, message:{role, content, tool_calls?}, finish_reason}. |
usage | Object | {prompt_tokens, completion_tokens, total_tokens}. |
| Field | Type | Description |
|---|---|---|
id | String | Tool call id. |
type | String | Fixed function. |
function | Object | Function call details. |
function.name | String | Function name. |
function.arguments | Object | Function arguments. |
Streaming response example:
data: {"object":"chat.completion.chunk","choices":[{"delta":{"role":"assistant","content":"..."}}]}
data: {"object":"chat.completion.chunk","choices":[{"delta":{"content":"..."}}]}
data: [DONE]
POST https://api.ciyuan-market.com/api/v1/responses
OpenAI Responses-compatible endpoint. Uses input instead of
messages, instructions instead of a system message, and a
text block instead of response_format.
| Field | Type | Required | Description |
|---|---|---|---|
model | String | Yes | Model name. |
input | String|Array | Yes | Plain string (user message) or message object array. |
instructions | String | No | System prompt. |
stream | Boolean | No | Default false. |
max_output_tokens | Integer | No | Maximum output tokens. |
temperature | Double | No | Default 1. |
top_p | Double | No | — |
tools | Tool[] | No | Top-level {type, name, description, parameters}. |
tool_choice | String|Object | No | auto/none/required/{type,name}. |
text | Object | No | {format:{type, name, schema, strict}};
text/json_object/json_schema. |
metadata | Map | No | — |
previous_response_id | String | No | Previous response id for multi-turn. |
parallel_tool_calls | Boolean | No | — |
curl --request POST \
--url https://api.ciyuan-market.com/api/v1/responses \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"model": "glm-5.2",
"input": "Describe Hangzhou in one sentence.",
"instructions": "Be concise.",
"stream": false
}'
{
"id": "resp_xxx",
"object": "response",
"model": "glm-5.2",
"status": "completed",
"created_at": 1721380000,
"output": [
{
"id": "msg_xxx",
"type": "message",
"role": "assistant",
"content": [{"type": "output_text", "text": "Hangzhou is ..."}],
"status": "completed"
}
],
"usage": {"input_tokens": 12, "output_tokens": 18, "total_tokens": 30}
}
Response fields (non-streaming):
| Field | Type | Description |
|---|---|---|
id | String | Response id. |
object | String | Fixed response. |
model | String | Model name. |
status | String | e.g. completed. |
created_at | Long | Created timestamp (seconds). |
output | Array | Output items. Message items:
{id, type:"message", role, content:[{type:"output_text",
text}], status}. Tool-call items:
{type:"function_call", id, name, call_id, arguments, status}. |
usage | Object | {input_tokens, output_tokens, total_tokens}. For Claude models,
input_tokens includes cache_read and
output_tokens includes cache_write. |
Streaming follows the Responses API events:
| Event | Description |
|---|---|
response.created | Start of the response stream. |
response.output_text.delta | Incremental text output update. |
response.completed | End of the response stream. |
POST https://api.ciyuan-market.com/api/v1/messages
Anthropic Messages-compatible endpoint. Accepts x-api-key and
anthropic-version: 2023-06-01 headers. Content blocks support
text, image, tool_use, tool_result,
thinking, and redacted_thinking.
| Field | Type | Required | JSON field | Description |
|---|---|---|---|---|
model | String | Yes | model | Model name. |
messages | Message[] | Yes | messages | Conversation messages. |
system | String|Array | No | system | System prompt, string or [{type,text}]. |
maxTokens | Integer | Yes | max_tokens | Maximum output tokens. |
stream | Boolean | No | stream | Streaming. |
temperature | Double | No | temperature | — |
topP | Double | No | top_p | — |
topK | Integer | No | top_k | — |
tools | Tool[] | No | tools | Tool definitions (input_schema). |
toolChoice | Object | No | tool_choice | — |
metadata | Map | No | metadata | — |
thinking | Object | No | thinking | Extended thinking config. |
stopSequences | Object | No | stop_sequences | — |
anthropicBeta | Object | No | anthropic_beta | Beta feature header. |
| Field | Type | Description |
|---|---|---|
role | String | Message role, e.g. user / assistant. |
content | String|ContentBlock[] | Plain text or an array of content blocks. |
| Field | Type | Description |
|---|---|---|
type | String | One of text, image, tool_use,
tool_result, thinking,
redacted_thinking. |
text | String | Present when type is text. |
source | Object | Present when type is image. |
Examples:
{ "type": "image", "source": { "type": "base64", "media_type": "...", "data": "..." } }
{ "type": "image", "source": { "type": "url", "url": "..." } }
| Field | Type | Description |
|---|---|---|
name | String | Function name. |
description | String | Function description. |
input_schema | Object | JSON Schema for inputs. |
cache_control | Object | Optional cache control. |
curl --request POST \
--url https://api.ciyuan-market.com/api/v1/messages \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY" \
--header "anthropic-version: 2023-06-01" \
--header "Content-Type: application/json" \
--data '{
"model": "claude-sonnet-4.6",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Describe Hangzhou in one sentence."}]
}'
{
"id": "msg_xxx",
"type": "message",
"role": "assistant",
"model": "claude-sonnet-4.6",
"content": [{"type": "text", "text": "Hangzhou is ..."}],
"stop_reason": "end_turn",
"usage": {"input_tokens": 12, "output_tokens": 18}
}
Response fields (non-streaming):
| Field | Type | Description |
|---|---|---|
id | String | Message id. |
type | String | Fixed message. |
role | String | Fixed assistant. |
model | String | Model name. |
content | ContentBlock[] | Response content blocks (e.g. {type:"text", text},
{type:"tool_use", ...}). |
stop_reason | String | e.g. end_turn, tool_use, max_tokens. |
usage | Object | {input_tokens, output_tokens}. |
| Event | Description |
|---|---|
message_start | Start of the message stream. |
content_block_start | Start of a new content block. |
content_block_delta | Incremental update for a content block. |
content_block_stop | End of a content block. |
message_delta | Incremental update for the message. |
message_stop | End of the message stream. |
GET https://api.ciyuan-market.com/api/v1/models
Returns all online, enabled API models.
curl --request GET \
--url https://api.ciyuan-market.com/api/v1/models \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY"
{
"object": "list",
"data": [
{
"id": "glm-5.2",
"object": "model",
"display_name": "glm-5.2",
"created": 1721380000,
"owned_by": "Zai",
"input_modalities": ["text", "image"],
"output_modalities": ["text"],
"context_length": 128000,
"description": "..."
}
]
}
Each model entry (data[]) fields:
| Field | Type | Description |
|---|---|---|
id | String | Model id. |
object | String | Fixed model. |
display_name | String | Display name. |
created | Long | Created timestamp (seconds). |
owned_by | String | Owner / vendor. |
input_modalities | String[] | e.g. ["text","image"]. |
output_modalities | String[] | e.g. ["text"]. |
context_length | Integer | Maximum context length. |
description | String | Model description. |
GET https://api.ciyuan-market.com/api/v1/models/{model}
Returns a single model with the same shape as a list entry. Returns HTTP 404 when the model does not exist.
curl --request GET \
--url https://api.ciyuan-market.com/api/v1/models/gpt-5.5 \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY"
Success response: a single model object with the same fields as a
/v1/models list entry.
When the model does not exist, returns HTTP 404:
{"error": {"message": "The model 'xxx' does not exist", "type": "invalid_request_error", "code": "invalid_model_error"}}
GET https://api.ciyuan-market.com/api/v1/image-models
Query the resolutions, ratios, and maximum counts supported by an image model before
calling /v1/image-generations. No authentication required.
| Field | Type | Description |
|---|---|---|
id | String | Model id. |
object | String | Fixed image_model. |
displayName | String | Display name. |
description | String | Model description. |
icon | String | Icon URL. |
created | Long | Created timestamp (seconds). |
maxCount | Integer | Max images per request. |
fileMax | Integer | Max reference images. When 0, image-to-image is not supported. |
resolutions | String[] | Supported resolutions, e.g.
["720p","1080p"]. |
ratios | String[] | Supported aspect ratios, e.g.
["1:1","3:2"]. |
curl --request GET \
--url https://api.ciyuan-market.com/api/v1/image-models \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY"
{
"object": "list",
"data": [
{
"id": "gpt-image-2",
"object": "image_model",
"displayName": "GPT Image 1",
"description": "...",
"icon": "...",
"created": 1721380000,
"maxCount": 4,
"fileMax": 10,
"resolutions": ["720p", "1080p"],
"ratios": ["1:1", "3:2"]
}
]
}
GET https://api.ciyuan-market.com/api/v1/video-models
Query the supported videoType values, duration range, resolutions, and
ratios for a video model before calling /v1/video-generations. No
authentication required.
| Field | Type | Description |
|---|---|---|
id | String | Model id. |
object | String | Fixed video_model. |
displayName | String | Display name. |
description | String | Model description. |
icon | String | Icon URL. |
created | Long | Created timestamp (seconds). |
allowedVideoTypes | VideoTypeOption[] | Supported videoType list. |
videoDurationMin | Integer | Minimum seconds per clip. |
videoDurationMax | Integer | Maximum seconds per clip. |
videoDurationSuggest | Integer[] | Recommended duration steps, e.g. [5,8,10]. |
resolutions | String[] | Supported resolutions. |
ratios | String[] | Supported aspect ratios. |
resolutionOptions | ResolutionOption[] | Structured resolution+ratio+size combos. |
fileMax | Integer | Max reference assets. |
VideoTypeOption fields:
| Field | Type | Description |
|---|---|---|
code | Integer | The videoType value to pass to
/v1/video-generations. |
name | String | Localized type name (text-to-video / image-to-video / ...). |
curl --request GET \
--url https://api.ciyuan-market.com/api/v1/video-models \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY"
{
"object": "list",
"data": [
{
"id": "sora-2",
"object": "video_model",
"displayName": "Sora 2",
"description": "...",
"icon": "...",
"created": 1721380000,
"allowedVideoTypes": [
{"code": 1, "name": "text-to-video"},
{"code": 2, "name": "image-to-video"},
{"code": 3, "name": "image-to-video (first/last frame)"}
],
"videoDurationMin": 5,
"videoDurationMax": 10,
"videoDurationSuggest": [5, 8, 10],
"resolutions": ["1080p", "720p"],
"ratios": ["16:9", "9:16"],
"fileMax": 5
}
]
}
Price tier fields
The four model query endpoints /v1/models,
/v1/models/{model}, /v1/image-models, and
/v1/video-models return the effective billing price for
the current caller (API key user), fully consistent with actual charges, and return
all price tiers of the model.
Field naming difference: /v1/models and
/v1/models/{model} use OpenAI-style snake_case (price_tiers);
/v1/image-models and /v1/video-models use camelCase
(priceTiers). The structures are identical.
price_tiers / priceTiers is an array; each element is a price
tier:
| Field | Type | Description |
|---|---|---|
outputPrice | decimal | Effective output unit price for the current caller |
cachePrice | decimal | Cache price (general models, used by the legacy billing formula) |
cacheReadPrice | decimal | Cache read unit price (Bedrock Claude only) |
cacheWritePrice | decimal | Cache write unit price (Bedrock Claude only) |
ratio | decimal | Billing multiplier. FIXED mode is 1; RATIO mode is the user/group multiplier |
mode | string | Pricing mode: RATIO / FIXED |
planId | string | Matched pricing plan ID, may be null |
The three model types share the same structure; only the descriptive field values differ. Non-applicable fields are null:
| Model type | UNIT | Effective description fields |
|---|---|---|
| Text | token | region / bandMin / bandMax |
| Image | image | resolution / clarity |
| Video | video | resolution / clarity |
Price meaning: the returned inputPrice / outputPrice /
cacheReadPrice / cacheWritePrice values are the final billing
unit prices for the current API key user after step-by-step resolution through the price
chain (chain)→ guidance → base price, consistent with actual charges. The unit price
seen by callers differs based on their pricing chain (reseller / distributor /
enterprise / user-level configuration).
Actual deduction = usage ÷ quantity × corresponding unit price × ratio. For per-second video billing: actual deduction = duration × outputPrice × ratio.
Boundary & exception handling (read-only endpoints will not return 500 due to price configuration issues)
| Scenario | Behavior |
|---|---|
| Single tier parse failure (pricing policy denies access, config missing) | Skip that tier, log a warning, and continue parsing remaining tiers |
| All tiers of a model fail to parse | Empty array [], model still returned normally |
| Model has no price configuration | Empty array [] |
| Price parsing throws an uncaught exception | Overall try-catch, return empty array, endpoint still returns 200 |
Response example (/v1/models, text model):
{
"object": "list",
"data": [
{
"id": "gpt-4o",
"object": "model",
"display_name": "gpt-4o",
"context_length": 128000,
"price_tiers": [
{
"region": "GLOBAL",
"bandMin": null,
"bandMax": null,
"resolution": null,
"clarity": null,
"unit": "token",
"quantity": 1000,
"description": "per 1k tokens",
"inputPrice": 0.0025,
"outputPrice": 0.01,
"cachePrice": 0.00125,
"cacheReadPrice": 0,
"cacheWritePrice": 0,
"ratio": 1,
"mode": "RATIO",
"planId": null
}
]
}
]
}
Response example (/v1/image-models, image model;
priceTiers structure is the same, unit is image):
{
"object": "list",
"data": [
{
"id": "dall-e-3",
"object": "image_model",
"displayName": "dall-e-3",
"resolutions": ["1024x1024", "1792x1024", "1024x1792"],
"priceTiers": [
{
"region": null,
"bandMin": null,
"bandMax": null,
"resolution": "1024x1024",
"clarity": "standard",
"unit": "image",
"quantity": 1,
"description": "per image",
"inputPrice": 0,
"outputPrice": 0.04,
"cachePrice": 0,
"cacheReadPrice": 0,
"cacheWritePrice": 0,
"ratio": 1,
"mode": "RATIO",
"planId": null
}
]
}
]
}
POST https://api.ciyuan-market.com/api/v1/image-generations
Asynchronously submit an image generation task. Returns a taskId
immediately; retrieve the result by polling
GET /v1/image-generations/{taskId} or via a
callbackUrl webhook.
The model, supported resolution / ratio values,
count upper limit, and reference-image upload limit (fileMax)
must be obtained from
GET /v1/image-models first. Only values
advertised by that model's spec are accepted.
| Field | Type | Required | Description |
|---|---|---|---|
text | String | Yes | Prompt. |
model | String | Yes | Model name. |
imageUrls | String[] | No | Reference image URLs (image-to-image). |
count | Integer | No | Number of images (≥0). |
resolution | String | No | Resolution (see /v1/image-models). |
ratio | String | No | Aspect ratio. |
callbackUrl | String | No | Task-level webhook URL. |
curl --request POST \
--url https://api.ciyuan-market.com/api/v1/image-generations \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"model": "seedream-4.5",
"text": "A cat drinking water by the river",
"count": 1,
"resolution": "2k",
"ratio": "1:1",
"imageUrls": []
}'
{
"code": 200,
"message": "image task is commit",
"data": {"taskId": "img_xxx"}
}
Error responses:
// Insufficient credit
{ "code": 500, "message": "Insufficient credit" }
// Model not found
{ "code": 404, "message": "Model not found: xxx" }
GET https://api.ciyuan-market.com/api/v1/image-generations/{taskId}
Poll an image generation task. status is pending /
success / failed. images is a JSON-stringified
array of image URLs; text carries any model-attached text description (e.g.
Gemini multimodal output), null otherwise.
curl --request GET \
--url https://api.ciyuan-market.com/api/v1/image-generations/img_xxx \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY"
{
"code": 200,
"message": "success",
"data": {
"taskId": "img_xxx",
"status": "success",
"errorMessage": null,
"images": "[\"https://.../1.png\"]",
"text": null
}
}
Response data fields:
| Field | Type | Description |
|---|---|---|
taskId | String | Task id. |
status | String | pending / success / failed. |
errorMessage | String | Failure reason, null on success. |
images | String | JSON-stringified array of image URLs, e.g.
"[\"https://.../1.png\"]". |
text | String | Model-attached text description (e.g. Gemini multimodal output);
null otherwise. |
Task not found:
{ "code": 500, "message": "task not found" }
If callbackUrl was supplied on submit, the server pushes the final
success / failed result via webhook with the same
data shape.
Complete example (submit + poll)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
public class ImageGenerationExample {
private static final String BASE = "https://api.ciyuan-market.com/api/v1";
private static final String API_KEY = System.getenv("CIYUAN_MARKET_API_KEY");
public static void main(String[] args) throws Exception {
HttpClient http = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10)).build();
// 1. Submit the task.
String body = "{"
+ "\"model\":\"seedream-4.5\","
+ "\"text\":\"A cat drinking water by the river\","
+ "\"count\":1,"
+ "\"resolution\":\"2k\","
+ "\"ratio\":\"1:1\","
+ "\"imageUrls\":[]"
+ "}";
HttpResponse<String> submit = http.send(
HttpRequest.newBuilder(URI.create(BASE + "/image-generations"))
.header("Authorization", "Bearer " + API_KEY)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body)).build(),
HttpResponse.BodyHandlers.ofString());
String taskId = extract(submit.body(), "taskId");
System.out.println("taskId = " + taskId);
// 2. Poll until terminal status.
String status = "pending";
while ("pending".equals(status)) {
Thread.sleep(15_000L);
HttpResponse<String> poll = http.send(
HttpRequest.newBuilder(URI.create(BASE + "/image-generations/" + taskId))
.header("Authorization", "Bearer " + API_KEY).GET().build(),
HttpResponse.BodyHandlers.ofString());
status = extract(poll.body(), "status");
System.out.println("status = " + status);
}
if (!"success".equals(status)) {
throw new RuntimeException("image generation failed: " + status);
}
// images is a JSON-stringified array of URLs.
String images = extract(pollResult(http, taskId), "images");
System.out.println("images = " + images);
}
// Minimal JSON field extractor — use Jackson/Gson in production.
private static String extract(String json, String field) {
int i = json.indexOf("\"" + field + "\":");
if (i < 0) return null;
i += field.length() + 3;
if (json.charAt(i) == '\"') {
int end = json.indexOf('\"', i + 1);
return json.substring(i + 1, end);
}
int end = i;
while (end < json.length() && "0123456789.".indexOf(json.charAt(end)) >= 0) end++;
return json.substring(i, end);
}
private static String pollResult(HttpClient http, String taskId) throws Exception {
return http.send(HttpRequest.newBuilder(URI.create(BASE + "/image-generations/" + taskId))
.header("Authorization", "Bearer " + API_KEY).GET().build(),
HttpResponse.BodyHandlers.ofString()).body();
}
}
import os
import time
import requests
BASE = "https://api.ciyuan-market.com/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['CIYUAN_MARKET_API_KEY']}"}
# 1. Submit the task.
resp = requests.post(
f"{BASE}/image-generations",
headers={**HEADERS, "Content-Type": "application/json"},
json={
"model": "seedream-4.5",
"text": "A cat drinking water by the river",
"count": 1,
"resolution": "2k",
"ratio": "1:1",
"imageUrls": [],
},
)
resp.raise_for_status()
task_id = resp.json()["data"]["taskId"]
print(f"taskId = {task_id}")
# 2. Poll until terminal status.
while True:
time.sleep(15)
poll = requests.get(f"{BASE}/image-generations/{task_id}", headers=HEADERS)
poll.raise_for_status()
data = poll.json()["data"]
status = data["status"]
print(f"status = {status}")
if status != "pending":
break
if status != "success":
raise RuntimeError(f"image generation failed: {data.get('errorMessage')}")
# images is a JSON-stringified array of URLs.
import json
images = json.loads(data["images"])
print(f"images = {images}")
POST https://api.ciyuan-market.com/api/v1/video-generations
Asynchronously submit a video generation task. Returns a taskId
immediately; retrieve the result by polling
GET /v1/video-generations/{taskId} or via a
callbackUrl webhook.
The model, allowed videoType values, duration range
(videoDurationMin/Max), supported resolution /
ratio, and reference-asset upload limit (fileMax) must be
obtained from GET /v1/video-models first. Only
videoType codes listed in that model's
allowedVideoTypes are accepted.
| Field | Type | Required | Description |
|---|---|---|---|
text | String | Yes | Prompt. |
model | String | Yes | Model name. |
videoType | Integer | Yes | 1 text-to-video / 2 image-to-video (first frame) / 3 image-to-video (first+last frame) / 4 image-to-video (reference) / 5 all reference. |
imageUrls | String[] | No | Image asset URLs. |
videoUrls | VideoUrl[]|String[] | No | Video asset URLs. |
audioUrls | String[] | No | Audio asset URLs. |
resolution | String | No | Resolution. |
ratio | String | No | Aspect ratio. |
duration | Long | No | Seconds (>0). |
callbackUrl | String | No | Task-level webhook URL. |
Examples for each videoType:
1. Text to video (videoType=1)
Generate a video from a text prompt only; no reference assets needed.
curl --request POST \
--url https://api.ciyuan-market.com/api/v1/video-generations \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"videoType": 1,
"text": "A cat jumping on a bed",
"resolution": "480p",
"ratio": "16:9",
"duration": 4,
"model": "seedance-2.0"
}'
2. Image to video - first frame (videoType=2)
Provide a single starting frame in imageUrls; the model generates a video
starting from that frame.
curl --request POST \
--url https://api.ciyuan-market.com/api/v1/video-generations \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"videoType": 2,
"text": "Happily shaking head",
"resolution": "480p",
"ratio": "16:9",
"duration": 4,
"model": "seedance-2.0",
"imageUrls": ["https://ciyuanmarket-flie.oss-accelerate.aliyuncs.com/test/first-frame.png"]
}'
3. Image to video - first and last frame (videoType=3)
Provide both the first and last frame in imageUrls (order:
[first, last]); the model generates a transition video between the two
frames.
curl --request POST \
--url https://api.ciyuan-market.com/api/v1/video-generations \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"videoType": 3,
"text": "Put on the hat",
"resolution": "480p",
"ratio": "16:9",
"duration": 4,
"model": "seedance-2.0",
"imageUrls": [
"https://ciyuanmarket-flie.oss-accelerate.aliyuncs.com/test/first-frame.png",
"https://ciyuanmarket-flie.oss-accelerate.aliyuncs.com/test/last-frame.png"
]
}'
4. Image to video - reference (videoType=4)
Provide one or more reference images in imageUrls; the model uses their
style/content as reference (not as a forced first/last frame) to generate the video.
curl --request POST \
--url https://api.ciyuan-market.com/api/v1/video-generations \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"videoType": 4,
"text": "Two cats playing together",
"resolution": "480p",
"ratio": "16:9",
"duration": 4,
"model": "kling-v3-omni-video",
"imageUrls": [
"https://ciyuanmarket-flie.oss-accelerate.aliyuncs.com/test/ref-1.png",
"https://ciyuanmarket-flie.oss-accelerate.aliyuncs.com/test/ref-2.png"
]
}'
5. All reference (videoType=5)
Mixed image / video / audio references. Reference assets by position in the prompt: the
1st entry in imageUrls is @图片 1, the 1st in
videoUrls is @视频 1, the 1st in audioUrls is
@音频 1. videoUrls also accepts plain URL strings.
curl --request POST \
--url https://api.ciyuan-market.com/api/v1/video-generations \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"videoType": 5,
"text": "Use the first-person framing of @视频 1 and @音频 1 as background music. First-person tea ad; start frame is @图片 1 ... end frame is @图片 2.",
"model": "seedance-2.0",
"imageUrls": [
"https://ark-project.tos-cn-beijing.volces.com/doc_image/r2v_tea_pic1.jpg",
"https://ark-project.tos-cn-beijing.volces.com/doc_image/r2v_tea_pic2.jpg"
],
"videoUrls": ["https://ark-project.tos-cn-beijing.volces.com/doc_video/r2v_tea_video1.mp4"],
"audioUrls": ["https://ark-project.tos-cn-beijing.volces.com/doc_audio/r2v_tea_audio1.mp3"],
"resolution": "1080p",
"ratio": "16:9",
"duration": 11
}'
Submit response (all five types):
{
"code": 200,
"message": "success",
"data": {"taskId": "vid_xxx"}
}
GET https://api.ciyuan-market.com/api/v1/video-generations/{taskId}
Poll a video generation task. status is pending /
success / failed; videoUrl is the generated video
URL and lastFrameUrl is the last-frame URL (image-to-video scenarios).
curl --request GET \
--url https://api.ciyuan-market.com/api/v1/video-generations/vid_xxx \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY"
{
"code": 200,
"message": "success",
"data": {
"status": "success",
"videoUrl": "https://.../out.mp4",
"lastFrameUrl": null,
"message": null
}
}
Response data fields:
| Field | Type | Description |
|---|---|---|
status | String | pending / success / failed. |
videoUrl | String | Generated video URL. |
lastFrameUrl | String | Last-frame URL (image-to-video scenarios); null otherwise. |
message | String | Failure reason, null on success. |
If callbackUrl was supplied on submit, the server pushes the final result
via webhook with the same data shape.
Complete example (submit + poll)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
public class VideoGenerationExample {
private static final String BASE = "https://api.ciyuan-market.com/api/v1";
private static final String API_KEY = System.getenv("CIYUAN_MARKET_API_KEY");
public static void main(String[] args) throws Exception {
HttpClient http = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10)).build();
// 1. Submit the task (videoType=1: text-to-video).
String body = "{"
+ "\"videoType\":1,"
+ "\"text\":\"A cat jumping on a bed\","
+ "\"resolution\":\"480p\","
+ "\"ratio\":\"16:9\","
+ "\"duration\":4,"
+ "\"model\":\"seedance-2.0\""
+ "}";
HttpResponse<String> submit = http.send(
HttpRequest.newBuilder(URI.create(BASE + "/video-generations"))
.header("Authorization", "Bearer " + API_KEY)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body)).build(),
HttpResponse.BodyHandlers.ofString());
String taskId = extract(submit.body(), "taskId");
System.out.println("taskId = " + taskId);
// 2. Poll until terminal status. Video tasks take longer — poll every 20s.
String status = "pending";
String lastBody = null;
while ("pending".equals(status)) {
Thread.sleep(20_000L);
HttpResponse<String> poll = http.send(
HttpRequest.newBuilder(URI.create(BASE + "/video-generations/" + taskId))
.header("Authorization", "Bearer " + API_KEY).GET().build(),
HttpResponse.BodyHandlers.ofString());
lastBody = poll.body();
status = extract(lastBody, "status");
System.out.println("status = " + status);
}
if (!"success".equals(status)) {
throw new RuntimeException("video generation failed: " + status);
}
String videoUrl = extract(lastBody, "videoUrl");
System.out.println("videoUrl = " + videoUrl);
}
// Minimal JSON field extractor — use Jackson/Gson in production.
private static String extract(String json, String field) {
int i = json.indexOf("\"" + field + "\":");
if (i < 0) return null;
i += field.length() + 3;
if (json.charAt(i) == '\"') {
int end = json.indexOf('\"', i + 1);
return json.substring(i + 1, end);
}
int end = i;
while (end < json.length() && "0123456789.".indexOf(json.charAt(end)) >= 0) end++;
return json.substring(i, end);
}
}
import os
import time
import requests
BASE = "https://api.ciyuan-market.com/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['CIYUAN_MARKET_API_KEY']}"}
# 1. Submit the task (videoType=1: text-to-video).
resp = requests.post(
f"{BASE}/video-generations",
headers={**HEADERS, "Content-Type": "application/json"},
json={
"videoType": 1,
"text": "A cat jumping on a bed",
"resolution": "480p",
"ratio": "16:9",
"duration": 4,
"model": "seedance-2.0",
},
)
resp.raise_for_status()
task_id = resp.json()["data"]["taskId"]
print(f"taskId = {task_id}")
# 2. Poll until terminal status. Video tasks take longer — poll every 20s.
while True:
time.sleep(20)
poll = requests.get(f"{BASE}/video-generations/{task_id}", headers=HEADERS)
poll.raise_for_status()
data = poll.json()["data"]
status = data["status"]
print(f"status = {status}")
if status != "pending":
break
if status != "success":
raise RuntimeError(f"video generation failed: {data.get('message')}")
print(f"videoUrl = {data['videoUrl']}")
if data.get("lastFrameUrl"):
print(f"lastFrameUrl = {data['lastFrameUrl']}")
GET https://api.ciyuan-market.com/api/v1/billing/balance
Returns the account balance split into three wallets: monthly plan, resource packs, and pay-as-you-go credit.
curl --request GET \
--url https://api.ciyuan-market.com/api/v1/billing/balance \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY"
{
"totalCredit": 128.50,
"totalResourceCredit": 30.00,
"wallets": {
"monthlyPlan": {"id": "pkg_xxx", "credit": 50.00, "name": "Monthly plan"},
"resourcePacks": [
{"id": "rp_xxx", "credit": 30.00, "name": "Video resource pack"}
],
"payAsYouGo": 48.50
}
}
Response fields:
| Field | Type | Description |
|---|---|---|
totalCredit | BigDecimal | Total balance. |
totalResourceCredit | BigDecimal | Sum of resource-pack balances. |
wallets.monthlyPlan | WalletDetail | Monthly plan (null if none). |
wallets.resourcePacks | WalletDetail[] | Resource pack list. |
wallets.payAsYouGo | BigDecimal | Pay-as-you-go balance. |
WalletDetailVO fields::
| Field | Type | Description |
|---|---|---|
id | String | Wallet id. |
credit | BigDecimal | Balance credits. |
name | String | Wallet name. |
GET https://api.ciyuan-market.com/api/v1/usage
Paginated model-call billing details, snapshoted by price
(priceSnapshotId), ordered by order creation time descending. Only normal
charge records (reason = model usage) are returned.
Query parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
page | Integer | No | 1 | Page number, 1-based. |
size | Integer | No | 20 | Page size (paginated by priceSnapshotId). |
startTime | LocalDateTime | No | — | Start time, format yyyy-MM-ddTHH:mm:ss, filters by snapshot
orderCreatedAt. |
endTime | LocalDateTime | No | — | End time, format yyyy-MM-ddTHH:mm:ss. |
curl --request GET \
--url "https://api.ciyuan-market.com/api/v1/usage?page=1&size=20&startTime=2026-07-01T00:00:00&endTime=2026-07-31T23:59:59" \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY"
Response wrapper:
{
"code": 0,
"message": "success",
"data": { ... }
}
| Field | Type | Description |
|---|---|---|
records | UsageDetailVO[] | Current page records. |
total | Long | Total count. |
current | Long | Current page. |
size | Long | Page size. |
pages | Long | Total pages. |
UsageDetailVO fields:
| Field | Type | Description |
|---|---|---|
priceSnapshotId | String | Price snapshot id. |
taskId | String | Task id. |
credit | BigDecimal | Charged amount. |
model | String | Model name. |
modelType | String | text / image / video. |
inputTokens | Long | Input tokens; null for image/video. |
outputTokens | Long | Output tokens. |
totalTokens | Long | Total tokens. |
cacheReadTokens | Long | Cache-read tokens. |
cacheWriteTokens | Long | Cache-write tokens. |
imageCount | Integer | Image count; set for image models. |
imageResolution | String | Image resolution, e.g. 720P. |
imageRatio | String | Image aspect ratio, e.g. 1:1. |
videoResolution | String | Video resolution, e.g. 1080p. |
videoRatio | String | Video aspect ratio, e.g. 16:9. |
videoDurationSec | Long | Video duration in seconds. |
orderCreatedAt | LocalDateTime | Order creation time (snapshot orderCreatedAt). |
creditDetails | CreditDetailItem[] | Order details under this snapshot (from credit_order_t). |
CreditDetailItem fields:
| Field | Type | Description |
|---|---|---|
credit | BigDecimal | Amount charged by this order. |
deductionSource | String | Deduction source (Balance / Monthly Package /
Resource Package). |
packageName | String | Package name; null if no package. |
Null-value convention: only the fields relevant to each modelType are
populated; the rest are null. text populates the token fields;
image populates imageCount/imageResolution/imageRatio;
video populates
videoResolution/videoRatio/videoDurationSec.
Response example:
{
"code": 200,
"message": "success",
"data": {
"records": [
{
"priceSnapshotId": "snap_9f3c1a2b",
"taskId": "task_5e8a1c33",
"credit": 0.0342,
"model": "glm-5.2",
"modelType": "text",
"inputTokens": 1280,
"outputTokens": 642,
"totalTokens": 1922,
"cacheReadTokens": 0,
"cacheWriteTokens": 0,
"imageCount": null,
"imageResolution": null,
"imageRatio": null,
"videoResolution": null,
"videoRatio": null,
"videoDurationSec": null,
"orderCreatedAt": "2026-07-18T14:23:11",
"creditDetails": [
{
"credit": 0.0342,
"deductionSource": "balance",
"packageName": ""
}
]
},
{
"priceSnapshotId": "snap_a12f77c0",
"taskId": "task_c71e44a2",
"credit": 1.8000,
"model": "seedance-2.0",
"modelType": "video",
"inputTokens": null,
"outputTokens": null,
"totalTokens": null,
"cacheReadTokens": null,
"cacheWriteTokens": null,
"imageCount": null,
"imageResolution": null,
"imageRatio": null,
"videoResolution": "1080p",
"videoRatio": "16:9",
"videoDurationSec": 8,
"orderCreatedAt": "2026-07-17T22:41:09",
"creditDetails": [
{
"credit": 1.5000,
"deductionSource": "Monthly Package",
"packageName": "基础月度套餐"
},
{
"credit": 0.3000,
"deductionSource": "Resource Package",
"packageName": "byteplus视频资源包"
}
]
}
],
"total": 128,
"current": 1,
"size": 20,
"pages": 7
}
}
GET https://api.ciyuan-market.com/api/v1/billing/transactions
Paginated list of the current user's paid (status=2) recharge
transactions, ordered by created_at descending.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
page | Integer | No | 1 | Page number. |
size | Integer | No | 20 | Page size. |
startTime | String | No | — | Start time, yyyy-MM-dd HH:mm:ss, inclusive. |
endTime | String | No | — | End time, yyyy-MM-dd HH:mm:ss, inclusive. |
curl --request GET \
--url "https://api.ciyuan-market.com/api/v1/billing/transactions?page=1&size=20&startTime=2026-07-01%2000:00:00&endTime=2026-07-31%2023:59:59" \
--header "Authorization: Bearer $CIYUAN_MARKET_API_KEY"
Response wrapper:
{
"code": 0,
"message": "success",
"data": { ... }
}
| Field | Type | Description |
|---|---|---|
records | TransactionVO[] | Current page transactions. |
total | Long | Total count. |
current | Long | Current page. |
size | Long | Page size. |
pages | Long | Total pages. |
TransactionVO fields:
| Field | Type | Description |
|---|---|---|
orderNo | String | Order number. |
thirdPartyOrderNo | String | Third-party order number. |
amount | BigDecimal | Order amount. |
actualAmount | BigDecimal | Actually paid amount. |
discount | BigDecimal | Discount amount. |
paymentMethod | String | Payment method (wechat / alipay / ustd /
stripe / wallyt etc.). |
TransactionVO fields:
| Field | Type | Description |
|---|---|---|
serviceFeeAmount | BigDecimal | Service fee amount. |
paymentChannel | String | Payment platform. |
source | String | Order source (recharge / package_purchase etc.). |
packageName | String | Package name (set for package purchases; null for plain
recharges). |
createdAt | LocalDateTime | Creation time. |
{
"code": 200,
"message": "success",
"data": {
"records": [
{
"orderNo": "R20260718abc123",
"thirdPartyOrderNo": "wx_pay_xxx",
"amount": 50.00,
"actualAmount": 48.50,
"discount": 1.50,
"paymentMethod": "wechat",
"serviceFeeAmount": 0.00,
"paymentChannel": "wechat",
"source": "recharge",
"packageName": null,
"createdAt": "2026-07-18T14:23:11"
}
],
"total": 28,
"current": 1,
"size": 20,
"pages": 2
}
}
Operational
Errors
ciyuan_market returns stable error codes so applications can handle retries, fallbacks, billing issues, and debugging consistently.
Provider-compatible endpoints try to preserve the original API family's error shape where possible. ciyuan_market-native endpoints use the ciyuan_market error object.
HTTP status and error code mapping
| HTTP status | Error type | Example codes | Retry |
|---|---|---|---|
| 400 | invalid_request_error | invalid_request, unsupported_parameter,
invalid_messages, invalid_image_url | No |
| 401 | authentication_error | missing_api_key, invalid_api_key | No |
| 402 | billing_error | insufficient_credits, payment_required,
quota_exceeded | No |
| 403 | permission_error | model_access_denied, endpoint_access_denied,
key_scope_denied | No |
| 404 | not_found_error | model_not_found, response_not_found,
task_not_found | No |
| 408 | timeout_error | gateway_timeout, provider_timeout | Yes |
| 409 | conflict_error | idempotency_conflict, task_already_cancelled | Depends |
| 422 | validation_error | schema_validation_failed, unsupported_modality | No |
| 429 | rate_limit_error | account_rpm_exceeded, account_tpm_exceeded,
provider_rate_limited | Yes |
| 500 | internal_error | internal_error | Yes |
| 502 | provider_error | provider_bad_gateway, provider_invalid_response | Yes |
| 503 | service_unavailable | model_unavailable, provider_unavailable,
insufficient_capacity | Yes |
| 504 | timeout_error | provider_timeout, gateway_timeout | Yes |
Common error codes
| Code | Meaning | Recommended action |
|---|---|---|
missing_api_key | No API key was provided. | Add the Authorization header. |
invalid_api_key | API key is invalid or revoked. | Create or rotate the API key. |
model_not_found | Model ID does not exist or is not enabled for the account. | Check the Models page or call GET /v1/models. |
model_access_denied | API key or account does not have access to the model. | Enable the model or contact admin. |
unsupported_parameter | Request includes a parameter unsupported by the selected endpoint or model. | Remove the parameter or choose a compatible model. |
unsupported_modality | Input or output modality is not supported by the selected model. | Choose a model that supports the modality. |
account_rpm_exceeded | Account requests per minute limit exceeded. | Retry with backoff or request higher limits. |
account_tpm_exceeded | Account tokens per minute limit exceeded. | Retry with backoff, reduce tokens, or request higher limits. |
provider_rate_limited | Upstream provider rate limited the request. | Retry or enable fallback. |
insufficient_credits | Account has insufficient credits. | Top up wallet, buy a pack, or upgrade plan. |
provider_timeout | Upstream provider did not respond in time. | Retry or enable fallback. |
model_unavailable | Model is temporarily unavailable. | Retry or use a routing alias. |
content_policy_error | Request or output was blocked by a safety policy. | Modify input or choose a suitable workflow. |
MCP
ciyuan_market MCP Guide
Wraps ciyuan_market (an OpenAI-compatible LLM gateway) as an MCP server so your AI tools can call ciyuan_market's chat, model, billing, image, and video endpoints directly.
Features
- 🤖 Multi-API chat: supports OpenAI Chat Completions, Anthropic Messages, and OpenAI Responses compatible endpoints
- 🖼️ Multimodal generation: besides text chat, supports image and video generation (text-to-, image-to-, first/last frame, reference asset) async tasks
- 🔍 Model & account lookup: list available models, model details, account balance, usage/billing details, and top-up transactions
- 🔑 Key passed via header: each call reads the API key from the request header, so one deployment can be shared by multiple accounts — the server never persists or caches any key
Quickstart
Use it in Claude Code (recommended). Add -s user to register it at user
scope (available in all your projects).
Step 1: Add the connection
claude mcp add --transport http ciyuanmarket https://api.ciyuan-market.com/mcp \
--header "X-Ciyuanmarket-Api-Key: <your ciyuan_market API key>" \
-s user
Step 2: Verify the connection
claude mcp list # should show ✓ Connected
claude mcp get ciyuanmarket # should show Scope: User config (available in all your projects)
Step 3: Start using it
You can ask Claude things like:
- "Use ciyuan_market to call claude-sonnet-5 and write a poem about autumn"
- "List the models available on my ciyuan_market account"
- "Check my ciyuan_market balance and recent usage"
- "Use ciyuan_market to generate a cyberpunk city-at-night image"
Claude will automatically call the matching MCP tool and return the result.
Using it with Claude Desktop
Add this to the mcpServers section:
{
"mcpServers": {
"ciyuanmarket": {
"type": "http",
"url": "https://api.ciyuan-market.com/mcp",
"headers": {
"X-Ciyuanmarket-Api-Key": "<your ciyuan_market API key>"
}
}
}
}
Using it with Codex CLI
Recommended: use env_http_headers to read the key from an environment
variable
Export the environment variable in your shell first:
export CIYUAN_MARKET_API_KEY=<your ciyuan_market API key>
Then in ~/.codex/config.toml:
[mcp_servers.ciyuanmarket]
url = "https://api.ciyuan-market.com/mcp"
env_http_headers = { "X-Ciyuanmarket-Api-Key" = "CIYUAN_MARKET_API_KEY" }
Alternative: use http_headers to write the key directly into the config
(handy if you don't want to manage a separate env var, but note the key is then stored
in plain text in the config file):
[mcp_servers.ciyuanmarket]
url = "https://api.ciyuan-market.com/mcp"
http_headers = { "X-Ciyuanmarket-Api-Key" = "<your ciyuan_market API key>" }
If adding it through the Codex settings UI:
- Type: HTTP / Streamable HTTP
- Name: ciyuanmarket
- URL:
https://api.ciyuan-market.com/mcp - Header name:
X-Ciyuanmarket-Api-Key - Header value: your ciyuan_market API key
Verify the connection
After starting Codex CLI, the /mcp command lists configured MCP servers
and their connection status — just confirm it loaded correctly. The usage pattern
matches Claude: Codex automatically picks the right tool.
If your config file already has other MCP servers, append this one at the same level. Fully quit and reopen Claude Desktop after editing.
Tools
This MCP server provides 14 tools, grouped into five categories:
1. Chat
1. chat_completion — Chat Completions
Sends a single chat request and returns the model's full reply (no streaming). Beyond
plain text, it also accepts images and video for multimodal understanding (model must
support the corresponding vision/video capability — check input_modalities via
list_models first) — change the message content from a string to an
array of content blocks mixing text with image_url / video_url.
| Parameter | Required | Description |
|---|---|---|
| model | ✅ | Model ID, e.g. "claude-sonnet-5" — check list_models first |
| messages | ✅ | Message list, each shaped like
{"role": "user"|"assistant"|"system", "content": "..."}; for
multimodal input, content is an array of content blocks (see Multimodal input
below) |
| temperature | ❌ | Sampling temperature — higher is more random |
| max_tokens | ❌ | Maximum tokens to generate |
Multimodal input (text / image / video)
Image input (URL):
{"role": "user", "content": [
{"type": "text", "text": "What's in this image?"},
{"type": "image_url", "image_url": {"url": "https://example.com/image.jpg"}}
]}
Image input (Base64):
{"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,<BASE64_STRING>"}}
Supported formats: PNG, JPEG, GIF (first frame only), WebP. Single image size limit 20MB.
Note: Base64-encoded large images produce very long strings and may fail due to an oversized request body; prefer passing images by URL.
The detail parameter (optional, set on the image_url object) controls
image processing fidelity: "auto" (default — model decides by image size) /
"low" (512x512 thumbnail, fast and cheap, good for simple classification) /
"high" (full resolution, good for reading small text / fine detail). A
single message's content array may hold multiple image_url blocks to pass several
images.
Video input (URL):
{"role": "user", "content": [
{"type": "text", "text": "Describe what happens in this video."},
{"type": "video_url", "video_url": {"url": "https://example.com/video.mp4"}}
]}
Video input (Base64):
{"type": "video_url", "video_url": {"url": "data:video/mp4;base64,<BASE64_STRING>"}}
Models supporting video input on ciyuan_market include select models from the Qwen, Doubao (dola-seed), Kimi, and MiniMax series — check input_modalities returned by list_models. The official OpenAI Chat Completions standard does not natively support video, but the ciyuan_market gateway supports it via the
{"type": "video_url", "video_url": {"url": "..."}}
extension format, consistent with the video_url format used by OpenRouter, NVIDIA NIM, vLLM, and other platforms.
2. create_message — Anthropic Messages compatible
Calls the Anthropic Messages compatible endpoint (no streaming). Content blocks support text, image, tool_use, tool_result, thinking, redacted_thinking. Images are passed via content blocks:
{"type": "image", "source": {...}}
| Parameter | Required | Description |
|---|---|---|
| model | ✅ | Model ID, e.g. "claude-sonnet-4.6" |
| messages | ✅ | Message list; content can be a string or an array of content blocks (text/image/tool_use/tool_result/thinking, etc.) |
| max_tokens | ✅ | Maximum output tokens |
| system | ❌ | System prompt, a string or [{"type": "text", "text": "..."}] |
| temperature / top_p / top_k | ❌ | Sampling parameters |
| tools | ❌ | Tool definitions, each shaped like
{"name", "description", "input_schema", ...} |
| tool_choice | ❌ | Tool selection strategy |
| thinking | ❌ | Extended thinking configuration |
| stop_sequences | ❌ | Custom stop sequences |
| metadata | ❌ | Additional metadata |
| anthropic_beta | ❌ | Beta feature identifier for the anthropic-beta header |
Multimodal input (text / image / video)
Image input supports three source types:
1. Base64-encoded (note: the data field is a plain Base64 string,
without the data: prefix);
media_type supports image/jpeg, image/png, image/gif, image/webp:
{"type": "image", "source": {
"type": "base64",
"media_type": "image/jpeg",
"data": "<BASE64_STRING>"
}}
2. URL reference:
{"type": "image", "source": {
"type": "url",
"url": "https://example.com/image.jpg"
}}
3. File ID (first upload the image via the Files API with
purpose="vision" to get a file_id):
{"type": "image", "source": {
"type": "file",
"file_id": "<file_id>"
}}
A single message's content array may hold multiple image blocks to pass several images.
Note: Base64-encoded large images produce very long strings and may fail due to an oversized request body; prefer passing images by URL.
Video input: the Anthropic Messages API does not support video files. For video understanding, first extract keyframes with ffmpeg or similar, then pass each frame as an image content block. For models that support video input on ciyuan_market (check input_modalities via list_models), use the chat_completion or create_response interface for native video support.
3. create_response — OpenAI Responses compatible
Uses input instead of messages,
instructions instead of a system message, and
text.format instead of response_format. Beyond plain text, it
also accepts images and video for multimodal understanding (model must support the
corresponding vision/video capability — check input_modalities via list_models) — set
input to an array of message objects whose content is an array of content
blocks mixing text with images/video.
| Parameter | Required | Description |
|---|---|---|
| model | ✅ | Model ID, e.g. "glm-5.2" |
| input | ✅ | A plain string (as one user message) or an array of message objects (used for multimodal input, see below) |
| instructions | ❌ | System prompt |
| max_output_tokens | ❌ | Maximum output tokens |
| temperature / top_p | ❌ | Sampling parameters |
| tools | ❌ | Tool definitions, top-level shape
{"type", "name", "description", "parameters"} |
| tool_choice | ❌ | "auto" / "none" / "required" or {"type", "name"} |
| text | ❌ | Output format config, e.g.
{"format": {"type": "text" | "json_object" | "json_schema", ...}} |
| previous_response_id | ❌ | Previous response ID for multi-turn conversations |
| parallel_tool_calls | ❌ | Whether to allow parallel tool calls |
| metadata | ❌ | Additional metadata |
Multimodal input (text / image / video)
Note: the Responses API uses content block types input_text /
input_image / input_video (not the text / image_url /
video_url of Chat Completions), and image_url / video_url are
bare strings, not nested objects.
Image input (URL):
[{"role": "user", "content": [
{"type": "input_text", "text": "What's in this image?"},
{"type": "input_image", "image_url": "https://example.com/image.jpg"}
]}]
Image input (Base64):
{"type": "input_image", "image_url": "data:image/jpeg;base64,<BASE64_STRING>"}
Supported formats: PNG, JPEG, GIF (first frame only), WebP. Single image size limit 20MB.
Note: Base64-encoded large images produce very long strings and may fail due to an oversized request body; prefer passing images by URL.
Image input (File ID):
{"type": "input_image", "file_id": "<file_id>"}
The file_id is obtained by uploading the image via the Files API with
purpose="vision".
The detail parameter (optional, set on the input_image object) controls
image processing fidelity: "auto" (default) / "low" (512x512
thumbnail, fast and cheap) / "high" (full resolution, for small text / fine
detail) / "original" (original resolution, only some newer models). A
single message's content array may hold multiple input_image blocks to pass several
images.
Video input (URL):
[{"role": "user", "content": [
{"type": "input_text", "text": "Describe what happens in this video."},
{"type": "input_video", "video_url": "https://example.com/video.mp4"}
]}]
Video input (Base64):
{"type": "input_video", "video_url": "data:video/mp4;base64,<BASE64_STRING>"}
Video input (File ID):
{"type": "input_video", "file_id": "<file_id>"}
Models supporting video input on ciyuan_market include select models from the Qwen, Doubao (dola-seed), Kimi, and MiniMax series — check input_modalities returned by list_models. The official OpenAI Responses API standard does not natively support video, but the ciyuan_market gateway supports it via the
{"type": "input_video", "video_url": "..."}
extension format, consistent with the input_video format used by BytePlus/Volcengine and other platforms.
2. Models & account
4. list_models — List available models
Returns the models available to the current account, with vendor, modality, capability,
and pricing metadata. No parameters. Each list entry includes a
price_tiers price tier list — the caller's effective billing price,
matching actual charges (see
Price tier field reference).
5. get_model — Get a single model's details
| Parameter | Required | Description |
|---|---|---|
| model | ✅ | Model ID, e.g. "gpt-5.5" — returns a clear error if it doesn't exist |
The response includes a price_tiers price tier list (see
Price tier field reference); returns 404 (no price
fields) when the model doesn't exist.
6. get_balance — Check account balance
Returns the current account's usage and balance. No parameters.
3. Billing
7. list_usage — Model usage/billing details
Paginated model usage billing details, sorted by order creation time descending. Only regular usage charges — no top-ups or adjustments.
| Parameter | Required | Description |
|---|---|---|
| page | ❌ | Page number, starting at 1, default 1 |
| size | ❌ | Page size, default 20 |
| start_time | ❌ | Start time, format "yyyy-MM-ddTHH:mm:ss" (e.g. "2026-07-01T00:00:00") |
| end_time | ❌ | End time, same format |
8. list_transactions — Top-up/package transactions
Paginated paid top-up / package purchase transactions, sorted by creation time descending.
| Parameter | Required | Description |
|---|---|---|
| page | ❌ | Page number, starting at 1, default 1 |
| size | ❌ | Page size, default 20 |
| start_time | ❌ | Start time, format "yyyy-MM-dd HH:mm:ss" (note: a space, not "T", between date and time) |
| end_time | ❌ | End time, same format |
4. Image generation
9. list_image_models — List image models
Returns supported image generation models, with resolution, aspect ratio, max image
count (maxCount), and max reference image count (fileMax). No parameters. Check this
before generating images — you can only pass values it publishes. Each list entry
includes a priceTiers price tier list (see
Price tier field reference).
10. create_image_generation — Submit an image generation task
Submits asynchronously and immediately returns a taskId; consumes account credit.
| Parameter | Required | Description |
|---|---|---|
| text | ✅ | Image generation prompt |
| model | ✅ | Model name, from the id returned by list_image_models |
| count | ❌ | Number of images to generate |
| resolution | ❌ | Resolution, from list_image_models' resolutions |
| ratio | ❌ | Aspect ratio, from list_image_models' ratios |
| image_urls | ❌ | Reference image URLs (image-to-image), count capped at that model's fileMax |
| callback_url | ❌ | Webhook called on completion; omit to poll instead |
11. get_image_generation — Poll an image task
| Parameter | Required | Description |
|---|---|---|
| task_id | ✅ | The taskId returned by create_image_generation |
Returns: status is pending / success / failed; images is a JSON string array of image URLs; text carries any extra model output (e.g. Gemini multimodal output).
5. Video generation
12. list_video_models — List video models
Returns supported video generation models, with allowedVideoTypes, duration range
(videoDurationMin/Max), resolution, aspect ratio, and reference asset limit (fileMax).
No parameters. Check this before generating video. Each list entry includes a
priceTiers price tier list (see
Price tier field reference).
13. create_video_generation — Submit a video generation task
Submits asynchronously and immediately returns a taskId; consumes account credit.
| Parameter | Required | Description |
|---|---|---|
| text | ✅ | Video generation prompt; when video_type=5, reference assets with "@Image N"/"@Video N"/"@Audio N" |
| model | ✅ | Model name, from the id returned by list_video_models |
| video_type | ✅ | Generation mode code (1-5, see below) — only values in that model's allowedVideoTypes are valid |
| image_urls | ❌ | Image asset URLs; meaning depends on video_type |
| video_urls | ❌ | Video asset URLs, only for video_type=5 |
| audio_urls | ❌ | Audio asset URLs, only for video_type=5 |
| resolution / ratio | ❌ | Resolution / aspect ratio, from list_video_models |
| duration | ❌ | Video duration in seconds, must be within videoDurationMin/Max |
| callback_url | ❌ | Webhook called on completion; omit to poll instead |
Meaning of video_type:
| Value | Mode | Asset requirement |
|---|---|---|
| 1 | Text-to-video | No asset needed |
| 2 | Image-to-video (first frame) | image_urls provides a single start frame |
| 3 | Image-to-video (first/last frame) | image_urls provides [first frame, last frame] in that order |
| 4 | Image-to-video (reference) | image_urls provides one or more style/content reference images |
| 5 | All references | Mix of image_urls/video_urls/audio_urls, referenced by position in text |
14. get_video_generation — Poll a video task
| Parameter | Required | Description |
|---|---|---|
| task_id | ✅ | The taskId returned by create_video_generation |
Price tier field reference
The outputs of these 4 model-query tools — list_models,
get_model, list_image_models, list_video_models —
return the caller's (API Key user's) effective billing price, which
matches actual charges exactly, and include all price tiers for the
model.
Naming difference: list_models / get_model follow OpenAI
snake_case (price_tiers); list_image_models /
list_video_models follow camelCase (priceTiers). Both have the
same structure.
price_tiers / priceTiers is an array; each element is a price
tier:
| Field | Type | Description |
|---|---|---|
region | string | Text model V2 tiering region, e.g. GLOBAL /
NON_GLOBAL / us-central1. Null for image/video
models |
bandMin | long | Text model input token band lower bound (inclusive); null = unbounded |
bandMax | long | Text model input token band upper bound (inclusive); null = unbounded |
resolution | string | Image/video resolution, e.g. 1080p / 4K. Null for
text models |
clarity | string | Clarity level |
unit | string | Billing unit: token (text) / image (image) /
video (video) |
quantity | integer | Unit quantity (e.g. per 1000 tokens, per 1 image) |
description | string | Price description |
inputPrice | decimal | Caller's effective input unit price |
outputPrice | decimal | Caller's effective output unit price |
cachePrice | decimal | Cache price (general models, legacy billing formula) |
cacheReadPrice | decimal | Cache read unit price (Bedrock Claude only) |
cacheWritePrice | decimal | Cache write unit price (Bedrock Claude only) |
ratio | decimal | Billing multiplier. 1 for FIXED mode; user/group
multiplier for RATIO mode |
mode | string | Pricing mode: RATIO / FIXED |
planId | string | Matched pricing plan id; may be null |
The three model types share one structure; only the description fields differ, and non-applicable fields are null:
| Model type | unit | Effective description fields |
|---|---|---|
| Text | token | region / bandMin / bandMax |
| Image | image | resolution / clarity |
| Video | video | resolution / clarity |
Pricing meaning: the returned inputPrice / outputPrice /
cacheReadPrice / cacheWritePrice, etc. are the final billing
unit prices for the current API Key user, resolved through the price
chain (chain) → guidance → base price, and match actual charges. The unit price a caller
sees varies by their pricing chain (reseller / distributor / enterprise / user-level
config).
Actual charge = usage ÷ quantity × unit price × ratio. For
per-second video billing, actual charge = duration ×
outputPrice × ratio.
Edge cases & error handling (a read-only endpoint never returns 500 due to price config):
| Scenario | Behavior |
|---|---|
| A single tier fails to resolve (pricing policy denies access, missing config) | Skip that tier, log a warn, continue resolving the rest |
| All tiers for a model fail to resolve | Empty array []; model still returned normally |
| Model has no price config at all | Empty array [] |
| Price resolution throws an uncaught exception | Caught overall, returns empty array; endpoint still 200 |
Response example (list_models, text model):
{
"object": "list",
"data": [
{
"id": "gpt-4o",
"object": "model",
"display_name": "gpt-4o",
"context_length": 128000,
"description": "...",
"price_tiers": [
{
"region": "GLOBAL",
"bandMin": null,
"bandMax": null,
"resolution": null,
"clarity": null,
"unit": "token",
"quantity": 1000,
"description": "per 1K tokens",
"inputPrice": 0.0025,
"outputPrice": 0.01,
"cachePrice": 0.00125,
"cacheReadPrice": 0,
"cacheWritePrice": 0,
"ratio": 1,
"mode": "RATIO",
"planId": null
}
]
}
]
}
Response example (list_image_models, image model;
priceTiers has the same structure, unit is
image):
{
"object": "list",
"data": [
{
"id": "dall-e-3",
"object": "image_model",
"displayName": "dall-e-3",
"resolutions": ["1024x1024", "1792x1024", "1024x1792"],
"priceTiers": [
{
"region": null,
"bandMin": null,
"bandMax": null,
"resolution": "1024x1024",
"clarity": "standard",
"unit": "image",
"quantity": 1,
"description": "per image",
"inputPrice": 0,
"outputPrice": 0.04,
"cachePrice": 0,
"cacheReadPrice": 0,
"cacheWritePrice": 0,
"ratio": 1,
"mode": "RATIO",
"planId": null
}
]
}
]
}
Examples
Example 1: a plain chat request
Ask: "Use ciyuan_market to call claude-sonnet-5 and ask what Python's GIL is"
The AI will call chat_completion with:
{
"model": "claude-sonnet-5",
"messages": [{"role": "user", "content": "What is Python's GIL?"}]
}
Example 2: tool use via the Anthropic Messages endpoint
Ask: "Use ciyuan_market's Messages endpoint and let the model decide whether to check the weather"
The AI will call create_message, passing a tools definition and
tool_choice; the response will include a tool_use content
block.
Example 3: list available models
Ask: "List the models on my ciyuan_market account"
The AI will call list_models, returning IDs, vendors, modalities, pricing,
and more for every available model.
Example 4: check balance and usage
Ask: "Check my ciyuan_market usage for this month"
The AI will call get_balance for the balance, then
list_usage (with start_time scoped to this month) for the
usage breakdown.
Example 5: generate an image
Ask: "Use ciyuan_market to generate a cyberpunk city-at-night image"
The AI will first call list_image_models to check specs, then
create_image_generation to get a taskId, then poll
get_image_generation for the image URL.
Example 6: text-to-video
Ask: "Use ciyuan_market to generate a 5-second video of a space nebula"
The AI will first call list_video_models to check specs, then
create_video_generation (video_type=1,
duration=5), and after getting a taskId, poll
get_video_generation.
FAQ
Tool call fails with "missing ciyuan_market API Key"
- You ran
claude mcp addwithout--header, or the key is wrong - If editing the JSON config directly, the
headersfield name is wrong (should beX-Ciyuanmarket-Api-Key) - Running locally without the
CIYUAN_MARKET_API_KEYenvironment variable set
Tool call fails with "ciyuan_market returned 401 unauthorized"
The API key itself is wrong or expired — regenerate it in the ciyuan_market console.
Claude isn't calling ciyuan_market tools — what now?
- Confirm the connection shows ✓ Connected via
claude mcp list - Check the connection status:
claude mcp get ciyuanmarket - Try being explicit: "Use ciyuan_market's
chat_completiontool to callclaude-sonnet-5…"
Image/video generation stays pending forever
- Poll image tasks with
get_image_generationand video tasks withget_video_generation— note that a running video task's status is "running", not "pending" - Generation takes time, usually a few to tens of seconds, longer for video
- If you passed a
callback_url, the task will call back on completion — no need to poll
list_image_models / list_video_models errors
Neither tool consumes credit itself — an error usually points to a key or network
issue. First confirm list_models works normally.
Notes
- Header name:MCP passes the key via
X-Ciyuanmarket-Api-Key. - Credit consumption:
chat_completion/create_message/create_response/create_image_generation/create_video_generationall consume account credit — checkget_balancefirst if you want to know the balance beforehand. - Check specs before generating:Image/video generation parameters like
model, resolution, ratio, count, duration, and video_type must only use values
published by
list_image_models/list_video_models, otherwise the call errors out. - No streaming:None of the three chat endpoints support streaming — each returns the full result at once.
- Stateless design:Every request is independent and no session is
stored; for multi-turn conversations use
create_response'sprevious_response_idor maintain history yourself inmessages.
Support
Get help with ciyuan_market
Find answers to common API, billing, routing, and integration questions. For production issues, send the request ID, API key label, endpoint, model, and timestamp so the team can trace the request quickly.
FAQ
Click a question to expand the answer.
Contact
Choose the best inbox for the request.
For incidents, rate limits, billing questions, production routing issues, SDK migration, provider compatibility, endpoint design questions, enterprise plans, committed usage, or custom provider routing requirements.












