# Inference API URL: https://creative-reasoning.com/docs/en/api-reference For new image and video integrations, use the [async task endpoints](/docs/en/media-tasks). They return a task ID first and reuse the corresponding generation parameters. Existing generation and editing endpoints remain supported. For field placement, model differences, and request examples, see [Image and video parameters](/docs/en/media-tasks#request-parameters). Optional fields in the schemas below are not supported by every model. The production API is `https://api.creative-reasoning.com`. Authenticate with `Authorization: Bearer API_KEY`, replacing `API_KEY` with a complete key copied from the [API Key page](https://creative-reasoning.com/console/keys). Full paths start with `/unified/v1`; use `https://api.creative-reasoning.com/unified/v1` as the SDK base URL. [Download the OpenAPI 3.1 contract (JSON)](https://creative-reasoning.com/docs-openapi/dataplane.en.json) for request fields, responses, and errors readable by developer tools and AI. # Embeddings and reranking URL: https://creative-reasoning.com/docs/en/embeddings-rerank ## Prepare an API Key The examples use the production API at `https://api.creative-reasoning.com`. Create or copy a complete API Key from the [API Key page](https://creative-reasoning.com/console/keys). Replace `API_KEY` in the request header with that complete key. Replace `YOUR_MODEL` in the examples with a model name from the [model catalog](https://creative-reasoning.com/models) that supports the operation on this page. ## Choose the endpoint Embeddings generate vectors for an input. Rerank orders candidate `documents` against a `query`. The operations require different model capabilities. ## Generate vectors ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/embeddings' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{"model":"YOUR_MODEL","input":["Hello world!","Hello Tezign!"]}' ``` In a successful response, `data[].index` is the input's zero-based position in the request array, and `data[].embedding` contains its vector. This float-vector example illustrates the structure only; the three values are illustrative and do not specify the vector length returned by your model: ```json { "object": "list", "model": "YOUR_MODEL", "data": [ {"object":"embedding","index":0,"embedding":[0.12,-0.04,0.87]}, {"object":"embedding","index":1,"embedding":[0.11,-0.05,0.86]} ] } ``` `input` is required and accepts text or a text array. Set optional fields such as `dimensions` and `encoding_format` only when supported by the model. Read the actual vector length and encoding from the result. See the [Embedding API](/docs/en/api-reference?operation=createUnifiedV1Embeddings) for the full fields. For a batch, preserve the mapping between each input and response `index`. Use the same model, dimension, and preprocessing method within one vector index. Models with multimodal embedding capability can mix text and images in one batch. An image may be a server-accessible URL or a complete Base64 payload; follow the model catalog example for supported fields and optional parameters. Never truncate Base64 with an ellipsis. Replace `YOUR_MULTIMODAL_MODEL` with a model supporting this input format, and replace the image URL and Base64 placeholder with your own image. ```json { "model": "YOUR_MULTIMODAL_MODEL", "input": [ { "text": "A sunset over the beach" }, { "image": "https://example.com/beach.jpg" }, { "image": "" } ], "dimensions": 512, "normalized": true } ``` ## Rerank candidates Choose an available Rerank model from the catalog. If none is available, contact support to enable one. A model that supports only embeddings cannot serve reranking requests. ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/rerank' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "YOUR_MODEL", "query": "What is the capital of France?", "documents": [ "Paris is the capital of France.", "Berlin is in Germany." ] }' ``` `model`, `query`, and `documents` are required. `top_n` can limit the number of results, and `return_documents` can request candidate content; check support for the selected model. This response illustrates the structure with example scores: ```json {"model":"YOUR_MODEL","results":[{"index":0,"relevance_score":0.96},{"index":1,"relevance_score":0.12}]} ``` Read the ranking in `results` order and use `index` to retrieve the original entry from `documents`. Treat `relevance_score` as the model's relevance score, not a probability. See the [Rerank API](/docs/en/api-reference?operation=createUnifiedV1Rerank) for the full fields. A response `index` refers to the original candidate position in the request, not a document ID. Use rerank scores only for ordering from the current model, not for comparisons across models. # Generate and edit images URL: https://creative-reasoning.com/docs/en/images-image-edit Image generation and editing return a task ID. Query that task and read the image when it completes. ## Prepare an API Key Create or copy a complete API Key from the [API Key page](https://creative-reasoning.com/console/keys). Replace `API_KEY` with the secret, not its prefix or API Key ID. Requests below use the production API at `https://api.creative-reasoning.com`. ## Generate an image ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/images/tasks' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "creative-reasoning-image-1.5", "prompt": "A blue ceramic cup on a white background", "n": 1, "size": "1024x1024", "quality": "low" }' ``` Initial acceptance returns HTTP `202`. This response structure example uses an illustrative ID. Save the actual response `id`; `pending` means queued, with no generated output yet. ```json { "id": "01a09ec9-7d00-7000-8000-000000000001", "status": "pending", "created_at": 1789370400, "model": "creative-reasoning-image-1.5", "poll_url": "/unified/v1/tasks/01a09ec9-7d00-7000-8000-000000000001" } ``` ## Query and read the result Replace `TASK_ID_FROM_SUBMIT_RESPONSE` with the response `id` and use the same API Key as the submission: ```bash curl 'https://api.creative-reasoning.com/unified/v1/tasks/TASK_ID_FROM_SUBMIT_RESPONSE' \ -H 'Authorization: Bearer API_KEY' ``` A query returning HTTP `200` still requires checking `status`. For `pending` or `processing`, keep waiting; for example, poll every five seconds with an overall deadline. Keep the ID if that deadline expires. For `failed`, read `error.code` and `error.message`. Read `data` only for `completed`. This completed-response structure example uses placeholders for media content and URL credentials: ```json { "id": "01a09ec9-7d00-7000-8000-000000000001", "status": "completed", "created_at": 1789370400, "model": "creative-reasoning-image-1.5", "completed_at": 1789370460, "data": [ { "b64_json": "BASE64_IMAGE_DATA" } ] } ``` For each `data` item, decode `b64_json` into an image file; first remove a `data:image/...;base64,` prefix if present. When `url` is provided, download the complete URL. `BASE64_IMAGE_DATA` is not an actual image. Terminal task bodies remain available for 24 hours; save the image to your own storage promptly. ## Edit an image Supply the input through the JSON `image` field. Replace `https://customer.example.com/assets/cup.png` with your own image URL directly accessible to CR, or use a Base64 Data URI. This endpoint does not accept multipart forms. ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/images/edit-tasks' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "creative-reasoning-image-1.5", "prompt": "Make the cup red while preserving the rest of the image", "n": 1, "size": "1024x1024", "quality": "low", "image": "https://customer.example.com/assets/cup.png" }' ``` Save the new `id` from the editing response and use the query request above to read its result. `image` can also be an array of image references for composition; a single-image edit can include `mask`. See [Image 1.5 parameters](/docs/en/media-tasks#creative-reasoning-image-15). ## Expand the canvas by direction Outpainting is available only for models that explicitly support `image_outpaint`. The `model` selects the operation and `expansion` supplies its parameters. Adding `expansion` does not enable outpainting on an ordinary image generation or editing model. Discover available models with your model API Key. Replace `API_KEY` with an API Key created in the [CR console](https://creative-reasoning.com), not a Management Token. ```bash curl 'https://api.creative-reasoning.com/unified/v1/models?capability=image_outpaint' \ -H 'Authorization: Bearer API_KEY' ``` Each `data[].id` is a model name accepted in requests. Its `data[].capabilities.image_outpaint` describes that model's expansion limits. An empty list means no outpainting model is available to this API Key; ask your administrator to check access and availability. Sign in to the [outpainting model guides](https://creative-reasoning.com/docs/en/models?type=image_outpaint), search for the returned model name and open its detailed page. That page provides parameters, complete requests, task queries, result interpretation, error recovery and billing guidance for its specific calling names. Use its outpainting example; do not substitute a model name from the ordinary generation or editing examples on this page. The directory shows marketplace models by default. If a name returned by discovery is absent, open `https://creative-reasoning.com/docs/en/models/calling/YOUR_MODEL` directly. Replace `YOUR_MODEL` with `data[].id`, encoded as a URL path segment; for example, encode `/` as `%2F`. The detailed page still requires sign-in and access for your current account. If access is denied, ask your administrator to check the permissions of your account and the team that owns the API Key. ## Select an editing region with a mask `creative-reasoning-image-1.5` supports masked editing. Prepare a PNG mask with the same pixel dimensions as the source image: use fully transparent pixels (Alpha = 0) for the region to edit and opaque pixels (Alpha = 255) for the region to preserve. Black and white colors alone, without transparency, do not select a region. The mask guides editing but does not guarantee pixel-exact preservation outside the selection. Replace both asset URLs below with your own source and mask URLs directly accessible to CR. The mask is not an output-background setting; do not put it inside `provider_options`. ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/images/edit-tasks' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "creative-reasoning-image-1.5", "image": "https://customer.example.com/assets/source.png", "mask": {"image_url": "https://customer.example.com/assets/mask.png"}, "prompt": "Remove the target in the transparent mask region and naturally reconstruct the background from the surrounding content. Do not add a replacement target. Preserve the content, composition, and lighting outside the mask as closely as possible." }' ``` Save the submission response `id` and query it with the same API Key using the steps above; HTTP `202` only confirms acceptance. The downloaded mask must be a valid transparent PNG matching the first source image dimensions. Each input file must not exceed 50 MiB, and the mask must not exceed 67,108,864 pixels. For invalid format, dimensions, or transparency, read the submission error or task `error.message`, correct the asset, and then resubmit. The mask object matches the `image_url` form of the OpenAI image editing JSON API. CR also retains its string shorthand: `"mask":"https://customer.example.com/assets/mask.png"`. Both accept a Base64 Data URI. `file_id`, mask arrays, and objects combining multiple reference fields are unsupported. The string shorthand is a compatibility format in the CR unified API. ## Adjust image parameters Use pixel dimensions such as `1024x1024` for `size`. `quality` accepts `low`, `medium`, or `high`. Sizes must meet side-length, ratio and total-pixel constraints in the [model parameter table](/docs/en/media-tasks#creative-reasoning-image-15). Recheck the supported range when changing models. ## Callbacks and recovery - Add your HTTPS `callback_url` at the top level to receive the same terminal result as a query. Deduplicate by task `id`; see [callback delivery](/docs/en/media-tasks#receive-notifications-at-callback_url). - For safe submission retries, add `Idempotency-Key: YOUR_UNIQUE_OPERATION_ID`. Generate and save this unique identifier for your business operation; it is not a credential. Retry with the same identifier and unchanged request body. - When you have a task ID, query it. If a submission without an idempotency key times out, do not blindly repeat POST: it may generate and charge twice. - For `401`, check the API Key. For query `404`, check the ID and original Key. For `failed`, read the error. `410 task_expired` means the result body has expired. See [task errors and idempotency](/docs/en/media-tasks#avoid-duplicate-generation-and-handle-errors). ## Compatibility endpoints Existing integrations can keep `/unified/v1/images/generations` and `/unified/v1/images/edits`, which may return an image directly or a task. See [compatibility response handling](/docs/en/media-tasks#image-generation-and-editing-compatibility-endpoints). After migrating to this guide’s endpoints, query the task returned by submission. ## Image and video skill To generate or edit images and videos through natural-language requests in Claude Code or Codex, install the [cr-media skill](/docs/en/integrations/cr-media). The guide covers plugin and `npx skills` installation, updates, API Key configuration, and local-image versus URL input requirements. # Call a text model URL: https://creative-reasoning.com/docs/en ## API Key authentication Get a complete API Key on the [API Key page](https://creative-reasoning.com/console/keys) and replace `API_KEY` in the examples. Authenticate with `Authorization: Bearer API_KEY`. Key prefixes, API Key IDs and Management Tokens cannot authenticate model calls. ## Send a request Choose a model below, then copy and run the cURL command. If the example contains `YOUR_MODEL`, replace it with a model name from the [model catalog](https://creative-reasoning.com/models) that supports Chat Completions. ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/chat/completions' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "YOUR_MODEL", "messages": [ { "role": "user", "content": "Hello" } ] }' ``` HTTP `200` means the request succeeded. The model output is in `choices[0].message.content`. See the [API reference](/docs/en/api-reference) for request and response fields. This response structure example shows only the fields needed to read the reply. The actual text will vary: ```json { "choices": [{ "index": 0, "message": {"role": "assistant", "content": "Hello! How can I help you?"}, "finish_reason": "stop" }] } ``` Visitors can view only listed models whose names start with `creative-reasoning`. Sign in to view other models according to your account permissions. Catalog visibility does not grant API Key access. Applications can use the [model discovery API](https://creative-reasoning.com/docs/en/api-reference#tag/llm/GET/unified/v1/models) to query text models and known context limits accessible with the current API Key. ## Streaming output Use `stream: true` to display the reply as it arrives. The cURL `-N` option displays received data without buffering: ```bash curl -N -X POST 'https://api.creative-reasoning.com/unified/v1/chat/completions' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "YOUR_MODEL", "messages": [{"role": "user", "content": "Hello"}], "stream": true }' ``` The response uses SSE. Parse the JSON in each `data:` field. `data: [DONE]` marks the end of the response and is not JSON. This event structure example includes only the relevant fields. A blank line separates events. One network read may contain a partial event or several events: ```text data: {"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]} data: {"choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]} data: {"choices":[{"index":0,"delta":{"content":"!"},"finish_reason":null}]} data: {"choices":[{"index":0,"delta":{},"finish_reason":"stop"}]} data: [DONE] ``` Append `delta.content` separately for each `choices[].index`; the example produces `Hello!`. Streaming text uses `delta.content`; `message.content` belongs to non-streaming responses. Role events, empty deltas and usage-only events may contain no text. Skip text concatenation for them while processing any other fields. See [tool calling](/docs/en#tool-calling) for tool-call deltas. `finish_reason: "stop"` indicates a normal end for that choice. `length` means the output was truncated at a limit; `tool_calls` requires handling a tool request; `content_filter` means content was filtered. Stop reading at `[DONE]`. An `error` event or disconnection before the end marker leaves an incomplete result. Follow [stream error recovery](/docs/en/troubleshooting#errors-during-a-stream); HTTP `200` or a closed connection alone does not establish successful completion. ## Tool calling Declare tools through Chat Completions `tools`. Replace `YOUR_MODEL` with a model that supports tool calling: ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/chat/completions' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "YOUR_MODEL", "messages": [{"role": "user", "content": "What is the weather in Singapore?"}], "tools": [{"type": "function", "function": { "name": "lookup_weather", "description": "Read a weather summary for a city.", "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]} }}] }' ``` Read `message.content` for a direct reply or `choices[].message.tool_calls` for tool requests. Parse and validate each `function.arguments` JSON string in your application. After execution, preserve the complete assistant message and append one `role: "tool"` message per call. The following result structure uses `TOOL_CALL_ID_FROM_RESPONSE` for that call's `tool_calls[].id`; replace `content` with the actual tool result string: ```json {"role":"tool","tool_call_id":"TOOL_CALL_ID_FROM_RESPONSE","content":"{\"city\":\"Singapore\",\"summary\":\"Warm with light rain\"}"} ``` Send the updated `messages` with the same `model` and `tools` until the model returns final text or your application's round/time limit is reached. For streaming, accumulate argument fragments by `choices[].index` and `delta.tool_calls[].index`. Parse and execute only complete arguments after the turn ends normally; never execute partial arguments after a disconnect. Your application runs tools and handles authorization and deduplication for operations with side effects. See [Chat Completions API](/docs/en/api-reference?operation=createUnifiedV1ChatCompletions) for field definitions. ## Continue a conversation with Responses Choose a model that supports Responses and use its name for `YOUR_MODEL`. Responses continues a conversation through a response ID and uses the same API Key authentication described above. ### Create the first response ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/responses' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "YOUR_MODEL", "input": "Hello" }' ``` Use the response's `id` to continue the conversation. To read the reply, find entries with `type: "message"` in `output`, then read `text` from their `content` entries with `type: "output_text"`. This response structure example shows only the relevant fields: ```json { "id": "resp_example", "output": [{ "type": "message", "role": "assistant", "content": [{"type": "output_text", "text": "Hello! How can I help you?"}] }] } ``` ### Continue with the response ID Replace `RESPONSE_ID_FROM_PREVIOUS_CALL` with the `id` from your actual response and continue with the same model. The `resp_example` value above illustrates the structure and cannot be used in a request. ```bash curl "https://api.creative-reasoning.com/unified/v1/responses" \ -H "Authorization: Bearer API_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"YOUR_MODEL","previous_response_id":"RESPONSE_ID_FROM_PREVIOUS_CALL","input":"Summarize the previous answer in one sentence."}' ``` Use `previous_response_id` only with the API Key that created the response. A different API Key receives a 404. ### Handle expired state For a 404, first check the model, `previous_response_id`, and API Key. If the state expired, reconstruct the input from application history instead of retrying that ID. ## Reasoning controls Chat Completions uses top-level `reasoning_effort`: ```json { "model": "YOUR_MODEL", "messages": [{"role": "user", "content": "Hello"}], "reasoning_effort": "low" } ``` Responses uses `reasoning.effort`: ```json { "model": "YOUR_MODEL", "input": "Hello", "reasoning": {"effort": "low"} } ``` CR accepts `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, and `max`. These are effort levels, not cross-model token budgets; a model may support only a subset. `none` requests disabled reasoning. Omitting the field preserves the model default. For a new integration, use the form shown for your endpoint. `low` does not specify a fixed token budget or response time. Input length, model load, and generated output also affect latency. An invalid level or type returns `400 invalid_reasoning_parameters`. A level known to be unsupported returns `400 unsupported_reasoning_parameters`. Some models validate the level in the model service and return a parameter error. See [error handling](/docs/en/troubleshooting#error-response-format). ## Authentication errors | Status | Meaning | Check | | --- | --- | --- | | `401` | The API Key is missing, malformed, invalid, or expired | Check the `Authorization` header and complete API Key | | `403` | Model permissions or balance/overdraft policy denied the request | Check the model name, API Key model permissions, and available quota | Correct authentication and permissions before retrying. See [errors and retries](/docs/en/troubleshooting) for other status codes and retry guidance. ## Store and rotate an API Key Load API Keys from a secret manager in server-side code or a controlled local environment. Keep secrets out of URLs, client bundles, Git, and logs. Use a Key prefix or API Key ID in diagnostic records. To rotate a Key, create a replacement, update the application, and send a minimal request. Disable the old Key after every application instance uses the replacement. ## Continue your integration - Configure a client with the [Codex, Claude Code, and SDK guides](/docs/en/integrations). - Check rates and costs with [request bills and effective prices](/docs/en/request-billing). - Resolve failed requests with [errors and retries](/docs/en/troubleshooting). ## Read with developer tools and AI The [documentation index](https://creative-reasoning.com/llms.txt) links to readable Markdown pages. The [complete guide text](https://creative-reasoning.com/llms-full.txt) contains public articles. The [model API OpenAPI](https://creative-reasoning.com/docs-openapi/dataplane.en.json) and [management API OpenAPI](https://creative-reasoning.com/docs-openapi/management.en.json) provide machine-readable fields, responses, and errors. Content requiring sign-in is excluded from these public exports. # Connect Claude Code URL: https://creative-reasoning.com/docs/en/integrations/claude-code Create or copy a complete API Key on the [API Key page](https://creative-reasoning.com/console/keys), then replace `API_KEY` with it. An API Key ID, key prefix, or Management Token cannot authenticate model calls. ## Configure Claude Code The command below works on macOS, Linux, and WSL. Replace `OPUS_MODEL`, `SONNET_MODEL`, and `HAIKU_MODEL` with names from the [model catalog](https://creative-reasoning.com/models) that support Anthropic Messages, streaming, and tool calls. All three values can use the same model. Replace `API_KEY` and the model names, then copy the entire block into your terminal. It creates or overwrites `~/.claude/settings.json`. Back up any existing custom settings first. ```bash mkdir -p ~/.claude && cat > ~/.claude/settings.json <<'EOF' { "env": { "ANTHROPIC_BASE_URL": "https://api.creative-reasoning.com", "ANTHROPIC_AUTH_TOKEN": "API_KEY", "ANTHROPIC_DEFAULT_OPUS_MODEL": "OPUS_MODEL", "ANTHROPIC_DEFAULT_SONNET_MODEL": "SONNET_MODEL", "ANTHROPIC_DEFAULT_HAIKU_MODEL": "HAIKU_MODEL", "CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS": "1" }, "model": "sonnet" } EOF ``` `sonnet` is a Claude Code client option that uses the model configured in `ANTHROPIC_DEFAULT_SONNET_MODEL`. To start with Opus instead, set `model` to `opus`. The API Key is saved in your user settings, so start Claude Code directly: ```bash claude ``` ## Start and verify 1. Start Claude Code, and run `/status` to confirm the selected model. 2. Complete a short task to verify streaming and one tool call. 3. If the request fails, follow [Errors and retries](/docs/en/troubleshooting) and retain the status, model name, and CR request ID. ## Claude Code configuration constraints - When connecting to CR, keep `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS` set to the string `"1"`. It disables experimental `anthropic-beta` headers and beta tool fields to avoid unsupported-field errors at the compatible endpoint. See [Claude Code environment variables](https://code.claude.com/docs/en/env-vars). - `settings.json` is standard JSON and cannot contain comments. - Set `ANTHROPIC_BASE_URL` to the HTTPS API Base URL without an API path. - Append `[1m]` only to `ANTHROPIC_DEFAULT_OPUS_MODEL` or `ANTHROPIC_DEFAULT_SONNET_MODEL`, and only when the model details explicitly list one-million-token context support. Do not append it to `ANTHROPIC_DEFAULT_HAIKU_MODEL`. ## Image and video skill To generate or edit images and videos through natural-language requests in Claude Code or Codex, install the [cr-media skill](/docs/en/integrations/cr-media). The guide covers plugin and `npx skills` installation, updates, API Key configuration, and local-image versus URL input requirements. # Connect Codex URL: https://creative-reasoning.com/docs/en/integrations/codex Create or copy a complete API Key on the [API Key page](https://creative-reasoning.com/console/keys), then replace `API_KEY` with it. An API Key ID, key prefix, or Management Token cannot authenticate model calls. ## Configure Codex Choose a model from the [model catalog](https://creative-reasoning.com/models) that supports the Responses API, streaming, and tool calls. Replace `YOUR_MODEL` with its name, then merge this configuration into `~/.codex/config.toml`: ```toml model = "YOUR_MODEL" model_provider = "creative_reasoning_router" [model_providers.creative_reasoning_router] name = "Creative Reasoning Router" base_url = "https://api.creative-reasoning.com" env_key = "CRR_API_KEY" wire_api = "responses" ``` This example uses the production gateway origin. Codex appends `/responses` to `base_url`; do not add that operation path yourself. `env_key` is the name of the environment variable. Set it and start Codex: ```bash export CRR_API_KEY="API_KEY" codex ``` ## Start and verify 1. Confirm that Codex shows the configured model. 2. Complete a short task and verify one tool call. 3. If the request fails, follow [Errors and retries](/docs/en/troubleshooting) and retain the status, model name, and CR request ID. ## Codex configuration constraints - Put `model` and `model_provider` before the first TOML table, and preserve existing configuration. - Use the gateway origin shown above for `base_url`, without an operation path. - Keep `wire_api = "responses"`. ## Image and video skill To generate or edit images and videos through natural-language requests in Claude Code or Codex, install the [cr-media skill](/docs/en/integrations/cr-media). The guide covers plugin and `npx skills` installation, updates, API Key configuration, and local-image versus URL input requirements. # Image and video skill URL: https://creative-reasoning.com/docs/en/integrations/cr-media [cr-skills](https://github.com/bmrlab/cr-skills) provides `cr-media` for image generation and editing, video generation, first/last-frame or reference-image input, and video editing, according to the selected model's capabilities. It includes scripts and model parameter notes. The scripts submit tasks, poll for results and download files. You can give the repository URL to your agent and ask it to install the skill using the README. Model coverage changes with skill updates; access still depends on your API Key permissions. Check the [model catalog](https://creative-reasoning.com/models) for available models. ## Install and update Choose one installation method. The scripts require Bash, `curl`, `jq`, `ffprobe` (from FFmpeg), `file` and `base64`. Use WSL on Windows to run the Bash scripts. ### Use npx skills With Node.js and npm installed, run this in your project directory: ```bash npx skills add https://github.com/bmrlab/cr-skills --skill cr-media ``` Select Claude Code or Codex when prompted, or add `--agent claude-code` or `--agent codex`. The default scope is the current project; add `-g` to use the skill across projects. This installs a standalone skill with its scripts and references. It is managed by `skills`, without registering a plugin in the client's marketplace. To update the project installation: ```bash npx skills update cr-media -p ``` For a global installation, use `npx skills update cr-media -g`. After installing or updating, open a new agent session in the corresponding project. ### Use the Claude Code plugin Run in your terminal: ```bash claude plugin marketplace add bmrlab/cr-skills claude plugin install cr-media@cr ``` Update with `claude plugin update cr-media@cr`, then restart Claude Code. You can also enable auto-update for the `cr` marketplace under Marketplaces in `/plugin`. ### Use the Codex plugin In a Codex CLI that supports plugin commands, run: ```bash codex plugin marketplace add bmrlab/cr-skills codex plugin add cr-media@cr ``` For later refreshes, the repository README specifies `codex plugin marketplace upgrade cr`; open a new Codex session afterward. If your client has no `codex plugin` command, use the `npx skills` method above. ## Configure an API Key Create or copy a complete API Key on the [API Key page](https://creative-reasoning.com/console/keys) and replace `API_KEY` below. API Key IDs, Key prefixes and Management Tokens cannot authenticate model calls. ```bash mkdir -p ~/.config/cr printf 'CR_API_KEY=%s\n' 'API_KEY' > ~/.config/cr/env chmod 600 ~/.config/cr/env ``` This writes or replaces the configuration file. The scripts first read the `CR_API_KEY` environment variable, then fall back to `~/.config/cr/env`. Requests go to `https://api.creative-reasoning.com`. Claude Code's `ANTHROPIC_AUTH_TOKEN` and other variables in your Codex text-model configuration are not automatically used as this skill's credential. ## Generate and read results Start a new agent session and request a task, for example: ```text Use cr-media to generate a blue ceramic cup on a white background. Save it to ./cr-output with the filename prefix cup. Check the model's supported sizes and parameters first. Return the file path, actual dimensions, format and task ID, and open the image to check its content. ``` For video, describe the scene, duration, aspect ratio, audio requirements and whether an input is a first frame or a reference image. The agent should select parameters from the bundled [image model notes](https://github.com/bmrlab/cr-skills/blob/main/plugins/cr-media/skills/cr-media/references/image-models.md) or [video model notes](https://github.com/bmrlab/cr-skills/blob/main/plugins/cr-media/skills/cr-media/references/video-models.md). `--dry-run` prints the request without submitting it. Actual generation is billed by model usage. The default output directory is `./cr-output` relative to the current directory; another directory can be specified. Check the summary and the actual files: | Result | What to read | | --- | --- | | Images | `files[].file` gives each local path; `size` and `mime` report detected dimensions and format. Open the images to check their content | | Video | `file` gives the local path. Check `duration_s`, `size`, `fps` and `audio`, then play the video or inspect frames | | Task record | `.json` stores requests and responses, where `name` is the chosen filename prefix. After a successful submission, read the task ID from `submit.id` | If the task completes but file download or decoding fails, keep the task ID and download from the original task result. If an image summary reports `size: "unknown"` or a non-image `mime`, inspect the file contents. Task completion alone does not establish that the downloaded file is usable. If processing continues, a wait times out or a session is interrupted, ask the agent to read the original task ID from the record and continue with `cr-image --resume` or `cr-video --resume`. Use the original API Key. Running the generation command again submits a new task. For a failed task, read `final.error`; for submission errors, inspect `submit`. See [asynchronous task recovery](/docs/en/media-tasks#avoid-duplicate-generation-and-handle-errors). ## Generate an image, then use it in a video Check the target video model's accepted image format first. The scripts convert local images into `data:image/...;base64,...`, which works only with models that accept Data URIs. File conversion alone does not establish model support. - If the target model accepts Data URIs, pass the generated local image to the agent as a first frame, last frame or reference image. - If the target model requires HTTP(S) URLs, provide an image address it can read directly. An accessible `data[].url` from image generation can be reused before it expires. If you only have a local file or `b64_json`, save the image to accessible storage you manage first. The skill does not provide image hosting or automatic uploads. - For `URL scheme must be HTTP(S)`, check the input format. Resubmitting the same Base64 input does not resolve this error. Consult the current model notes rather than applying one model's restriction to all image or video models. For direct HTTP integration, see [generate and edit images](/docs/en/images-image-edit) and [generate video](/docs/en/video-async). # Developer tools and SDKs URL: https://creative-reasoning.com/docs/en/integrations ## Choose a client The integration examples use these production addresses: | Client | Protocol | Client base URL | Guide | | --- | --- | --- | --- | | Codex | Responses | `https://api.creative-reasoning.com` | [Connect Codex](/docs/en/integrations/codex) | | Claude Code | Anthropic Messages | `https://api.creative-reasoning.com` | [Connect Claude Code](/docs/en/integrations/claude-code) | | Python or JavaScript application | OpenAI-compatible SDK | `https://api.creative-reasoning.com/unified/v1` | [Connect an SDK](/docs/en/integrations/sdk) | ## Image and video skill To generate or edit images and videos through natural-language requests in Claude Code or Codex, install the [cr-media skill](/docs/en/integrations/cr-media). The guide covers plugin and `npx skills` installation, updates, API Key configuration, and local-image versus URL input requirements. # SDK integration URL: https://creative-reasoning.com/docs/en/integrations/sdk ## Set environment variables ```bash export CR_API_KEY="API_KEY" export CR_MODEL="YOUR_MODEL" ``` Replace `API_KEY` with the complete API Key copied from the [API Key page](https://creative-reasoning.com/console/keys). Replace `YOUR_MODEL` with a model name from the [model catalog](https://creative-reasoning.com/models) that supports Chat Completions. The SDK examples use the production address `https://api.creative-reasoning.com/unified/v1`; the SDK appends the operation path. ## Python Install the OpenAI Python SDK: ```bash python -m pip install openai ``` ```python import os from openai import OpenAI client = OpenAI( api_key=os.environ["CR_API_KEY"], base_url="https://api.creative-reasoning.com/unified/v1", ) response = client.chat.completions.create( model=os.environ["CR_MODEL"], messages=[{"role": "user", "content": "Reply with one short sentence."}], ) print(response.choices[0].message.content) ``` ## JavaScript Install the OpenAI JavaScript SDK: ```bash npm install openai ``` ```javascript import OpenAI from "openai"; const { CR_API_KEY, CR_MODEL } = process.env; if (!CR_API_KEY || !CR_MODEL) { throw new Error("CR_API_KEY and CR_MODEL are required"); } const client = new OpenAI({ apiKey: CR_API_KEY, baseURL: "https://api.creative-reasoning.com/unified/v1", }); const response = await client.chat.completions.create({ model: CR_MODEL, messages: [{ role: "user", content: "Reply with one short sentence." }], }); console.log(response.choices[0].message.content); ``` For incremental output, see [text model calls](/docs/en#streaming-output). If a request fails, see [errors and retries](/docs/en/troubleshooting). ## Get model names and limits Use `client.models.list()` in Python or `await client.models.list()` in JavaScript. The list contains listed text models discoverable with the current API Key. CR context and output limits are extensions, and automatic use depends on the client implementation. See [model discovery API](https://creative-reasoning.com/docs/en/api-reference#tag/llm/GET/unified/v1/models) for the raw JSON fields and manual configuration guidance. # Manage API Keys and query usage URL: https://creative-reasoning.com/docs/en/manage-api-keys ## Credentials and permissions These requests use a management token, not a model API Key. Ask an administrator to grant the scope needed for each operation. Read, write, and usage aggregation scopes are independent; write permission does not imply read permission. | Operation | Required scope | | --- | --- | | List API Keys and query quota or budget state | `api_keys:read` | | Create or revoke API Keys and set budgets | `api_keys:write` | | Query historical usage summaries | `usage:aggregate` | API Key management uses a token bound to the target team. The `api_keys:write` scope also permits revealing complete keys and removing budgets; give it only to a trusted backend. Organization tokens cannot manage keys. Replace `YOUR_MANAGEMENT_TOKEN` with a complete management token authorized for the operation. ## Get the team code and API Key ID All monetary fields use the same **Credits (ℂ)** as the console and return exact decimal strings with up to six fractional digits. Successful responses identify the unit with `X-CRR-Credit-Unit: credits`. Summaries use `schema_version: 2`. 1. Open the target team in the [management console](https://creative-reasoning.com/). Click the code below its name to copy the code alone, such as `T-TU214G`, and use it for `TEAM_CODE`. This is a team code, not an organization code or team UUID. 2. Open the team's **API Key** tab. Find the target API Key and select **More → Copy API Key ID**. Replace `API_KEY_ID` with that UUID. This copies existing metadata without revealing the secret. **Copy API Key** is a separate sensitive action. Requests on this page use the production management service at `https://creative-reasoning.com`. A server can also list API Keys with a management token that has `api_keys:read`: ```bash curl \ -H "Authorization: Bearer YOUR_MANAGEMENT_TOKEN" \ "https://creative-reasoning.com/api/v1/management/teams/TEAM_CODE/api-keys" ``` HTTP 200 returns an array. Select the target item's `id` as `API_KEY_ID`; use `label` and `key_prefix` to identify it, not as substitutes for its ID. Listing returns no secret and needs no `api_keys:write`. The creation response returns the same resource ID. Do not create a new key to query an existing one. API Key ID is an attribute of the API Key, not a credential. Model calls use the API Key secret; management operations on this page use a management token in the header. Response `team_id` fields remain UUIDs and cannot substitute for `team_code` in machine paths. ## Create a service key Requires `api_keys:write`. If the service needs no overdraft, explicitly send `overdraft_enabled: false`. Omitting this field inherits the effective team and organization switches. Enabling overdraft without specifying a limit defaults to an unlimited key-level cap. ```bash curl \ -X POST \ -H "Authorization: Bearer YOUR_MANAGEMENT_TOKEN" \ -H 'Content-Type: application/json' \ -d '{"label":"batch-worker","overdraft_enabled":false}' \ "https://creative-reasoning.com/api/v1/management/teams/TEAM_CODE/api-keys" ``` Save `id` and `key` from the HTTP 201 response. Use `id` for `API_KEY_ID`, the existing API Key resource UUID. This ID is not a credential and cannot authenticate model calls. Store `key`, the API Key secret, in secret storage for model calls. Continue to use the management token for the management operations below. ## Set a periodic spending budget Set the budget before giving the key to the service. Key creation and budget configuration are separate operations. If budget configuration fails, do not start the workload with that key. To keep the existing starting time, omit `starts_at`. Creation defaults to the request time; updates preserve the existing value. Explicitly changing this field changes the spending range. ```bash curl \ -X PUT \ -H "Authorization: Bearer YOUR_MANAGEMENT_TOKEN" \ -H 'Content-Type: application/json' \ -d '{"amount":"1000","window_days":7,"is_enabled":true}' \ "https://creative-reasoning.com/api/v1/management/teams/TEAM_CODE/api-keys/API_KEY_ID/budgets/windowed" ``` Check `amount`, `window_days`, and `starts_at` in the HTTP 200 response. Monetary inputs and outputs use Credits (ℂ). This example sets a budget of `1000 ℂ` for a fixed seven-day period. Budget `amount` and key `overdraft_limit` must be multiples of `0.000005 ℂ`, at most `49999999999999.999995 ℂ`. Inputs outside these range or precision limits return 400 rather than rounding. For an all-time budget, use `budgets/all_time` and omit `window_days`. To display spending, remaining quota, and reset time, request the independent `api_keys:read` scope and query remaining quota and reset time below. Write permission does not include read permission. Successful configuration does not guarantee that every model request already uses the new policy. ## Query remaining quota and reset time Requires `api_keys:read`. ```bash curl \ -H "Authorization: Bearer YOUR_MANAGEMENT_TOKEN" \ "https://creative-reasoning.com/api/v1/management/teams/TEAM_CODE/api-keys/API_KEY_ID/quota" ``` Read `available_credits` and `overdraft.remaining_credits` from the HTTP 200 response. For spending and remaining budget in the current period, read `budgets.windowed.used_credits` and `remaining_credits`. For the next reset time, read `resets_at`. Display the result with these boundaries: - Quota fields use Credits, not model token counts. Do not add balance, remaining overdraft, and remaining budget into one spendable total. These fields do not guarantee model invocation access. - `all_time` is a budget from `starts_at` with no automatic reset. `windowed` resets every N days from that time. Some fields are `null` when absent, disabled, or not started; do not display them as zero. Resetting adds no credit and erases no debt. - The snapshot is eventually consistent. Keep `observed_at` for display and allow recent spending to appear later. Do not use the response as a synchronous admission check. For budget states, unlimited overdraft, and null definitions, see the [Management API](/docs/en/management-api). ## Query historical token usage Historical reports require the independent `usage:aggregate` scope. An administrator can explicitly grant it to the same token or issue a separate reporting token. `api_keys:read` does not imply this permission. Use RFC3339 values for `start` and `end`. This example uses `2026-08-31T16:00:00Z` and `2026-09-01T16:00:00Z` for September 1 in Shanghai. `Z` means UTC; explicit offsets such as `+08:00` also work. The interval is `[start, end)`, with an exclusive end. ```bash curl --get \ -H "Authorization: Bearer YOUR_MANAGEMENT_TOKEN" \ --data-urlencode "api_key_id=API_KEY_ID" \ --data-urlencode "start=2026-08-31T16:00:00Z" \ --data-urlencode "end=2026-09-01T16:00:00Z" \ --data-urlencode "timezone=Asia/Shanghai" \ "https://creative-reasoning.com/api/v1/management/usage/summary" ``` `timezone` interprets bare dates and controls time buckets; it does not override an RFC3339 offset. Unix seconds and milliseconds are not accepted. Prefer RFC3339 with `Z` or an offset in programs. With `YYYY-MM-DD`, `end` includes that entire local date instead. For total spending in the time range, read `totals.credits.after_discount` in Credits. For example, `"105.21352"` means spending of `105.21352 ℂ`, not tokens or CNY. With grouping, top-level `totals` still cover the entire filter window, not just the current page. For token usage, read the integer strings in `totals.tokens.input` and `totals.tokens.output`. Do not add token dimensions that can overlap. These counts come from finalized text bills, not complete model usage. Budgets use accounting time, which can differ from the historical request window. To query only embedding calls, add `--data-urlencode "request_type=embedding"`. Finalized embedding bills contribute to this token view. A missing billing dimension does not prove that actual consumption was zero. To inspect one call, save `x-cr-usage-id` from the model response and call the [single-call usage endpoint](/docs/en/management-api?operation=getManagementRequestUsage) with a token that has `usage:read`. ## Revoke a retired key Stop the workload before revoking its key. Revocation does not cancel completed requests or historical charges. ```bash curl \ -X DELETE \ -H "Authorization: Bearer YOUR_MANAGEMENT_TOKEN" \ "https://creative-reasoning.com/api/v1/management/teams/TEAM_CODE/api-keys/API_KEY_ID" ``` HTTP 204 confirms revocation and has no response body. Revoking the API Key does not revoke its management token. When the service no longer needs management access, ask an administrator to revoke that token separately. If creation times out, ask an administrator with read access to check the result before retrying. See the [Management API](/docs/en/management-api) for key lookup, updates, Reveal, budget removal, and token creation, updates, and rotation. ## View and configure keys in the console Select the target team on the [API Key console page](https://creative-reasoning.com/console/keys) and find a key by label or prefix. **Settings** contains labels, overdraft, and spending budgets; **More** contains usage, Copy API Key ID, and revocation. Users can manage only their own keys; other operations depend on account permissions. Use **Save settings** for labels and overdraft, and **Save budget** separately for each budget. A budget-loading failure does not mean that no budget exists; retry before editing. Revocation is irreversible and does not remove historical charges. ## Handle rejected requests Check the HTTP status and `Content-Type` before parsing an error. Parse `application/json` as an object with an `error` string. Treat `text/plain` as diagnostic text, not a stable error code. For JSON requests, fix malformed syntax after 400, field types or missing required fields after 422, and `Content-Type` after 415. Reduce an oversized body after 413. A 400 can also indicate an invalid UUID path or business rule. Do not retry these requests unchanged. Quota and summary use 422 differently; follow the response definition for the operation you called. For 401, check credential type, expiry, and revocation; do not switch automatically to an API Key or JWT. For 403, check the required scope. For 404, check object ownership and retry only recently submitted calls of your own. For 422, narrow the summary query; contact an administrator if quota queries keep exceeding their limit. For 429 or 503, follow `Retry-After` with a retry deadline. # Management API URL: https://creative-reasoning.com/docs/en/management-api The management API base URL is `https://creative-reasoning.com/api/v1/management`. Use the [CR console](https://creative-reasoning.com) to manage teams, API Keys, and management tokens. This page and the [OpenAPI JSON](/docs-openapi/management.en.json) are readable without signing in. Business APIs still require a management token or administrator login JWT. For integration workflows, see [Manage API Keys and query usage](/docs/en/manage-api-keys) and [Query request bills and prices](/docs/en/request-billing). [Download the OpenAPI 3.1 contract (JSON)](https://creative-reasoning.com/docs-openapi/management.en.json) for request fields, responses, and errors readable by developer tools and AI. # Media task reference URL: https://creative-reasoning.com/docs/en/media-tasks This reference covers model parameters, task queries, result fields, callbacks and idempotency. For a complete first call, follow [Generate and edit images](/docs/en/images-image-edit) or [Generate videos](/docs/en/video-async). ## Prepare an API Key The examples use the production API at `https://api.creative-reasoning.com`. Create or copy a complete API Key from the [API Key page](https://creative-reasoning.com/console/keys). Replace `API_KEY` in the request header with that complete key. ## Choose an endpoint | Operation | Method and path | | --- | --- | | Image generation | `POST /unified/v1/images/tasks` | | JSON image editing | `POST /unified/v1/images/edit-tasks` | | Video generation | `POST /unified/v1/videos/tasks` | | Read an existing task | `GET /unified/v1/tasks/{task_id}` | | Wait for an existing task, up to 30 seconds | `GET /unified/v1/tasks/{task_id}/wait` | The submission endpoints reuse [image and video parameters](/docs/en/media-tasks#request-parameters). Supported sizes, durations, reference images, quality settings, and extensions still depend on the model. Editing accepts JSON, not multipart uploads. ## Submit an image task The following is a minimal submission. `Idempotency-Key` is optional. To prevent duplicate generation when retrying the same operation, add the header as described later on this page. ```bash curl "https://api.creative-reasoning.com/unified/v1/images/tasks" \ -H "Authorization: Bearer API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "creative-reasoning-image-1.5", "prompt": "A blue ceramic cup on a white background", "n": 1, "size": "1024x1024", "quality": "low" }' ``` Initial acceptance returns `202 Accepted` without waiting for generation. Save `id` and `poll_url`. The `Location` header also contains the query path. `poll_url` is relative; append it to `https://api.creative-reasoning.com` to form the complete query URL. ```json { "id": "01a09ec9-7d00-7000-8000-000000000001", "status": "pending", "created_at": 1789370400, "model": "creative-reasoning-image-1.5", "poll_url": "/unified/v1/tasks/01a09ec9-7d00-7000-8000-000000000001" } ``` `202` means accepted, not generated successfully. Some model-specific errors are discovered only during execution and produce a `failed` task. ## Submit a video or edit task For video, send the request to `/unified/v1/videos/tasks`. Continue using `model`, `content`, and supported model parameters. For example: ```json { "model": "creative-reasoning-video-1.0", "content": [{"type": "text", "text": "Sunset over the sea"}], "duration": 4, "resolution": "480p", "aspect_ratio": "16:9" } ``` For editing, send JSON to `/unified/v1/images/edit-tasks` with an `image` input and, where supported, a `mask`. Check [model parameter differences](/docs/en/media-tasks#request-parameters) before reusing a parameter combination with another model. ### Request a last frame Choose a model from the [model catalog](https://creative-reasoning.com/models) that supports last-frame output with four-second, 720p, 16:9 video. Replace `YOUR_VIDEO_MODEL` with its model name. This request generates one video and requests its last frame. Put `return_last_frame` inside `provider_options`, using underscore-separated field names. This is a generated output, separate from an input image supplied with `content[].role: "last_frame"`. ```bash curl "https://api.creative-reasoning.com/unified/v1/videos/tasks" \ -H "Authorization: Bearer API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "YOUR_VIDEO_MODEL", "content": [{"type": "text", "text": "A blue ceramic cup sits on a wooden table in sunlight. The camera slowly moves forward."}], "duration": 4, "resolution": "720p", "aspect_ratio": "16:9", "provider_options": {"return_last_frame": true} }' ``` Save the returned `id` and follow the query steps on this page. To receive a completion notification, also add your own `callback_url` at the request's top level. Requesting a last frame does not add another video to `data`; check whether `last_frame_url` is present when reading the result. ## Request parameters ### Shared parameters All endpoints use `Authorization: Bearer API_KEY` and `Content-Type: application/json`. | Field | Type | Scope and rules | | --- | --- | --- | | `model` | string, required | A model name from the [model catalog](/models). Changing the model can invalidate the previous parameter combination | | `callback_url` | string, optional | Terminal notification destination for image generation, JSON image editing, and video generation. Top-level only, subject to the [HTTPS callback rules](/docs/en/media-tasks#prepare-the-callback-url) | | `provider_options` | object, optional | Extensions supported by the selected model. Arbitrary fields do not necessarily take effect. Extensions are not portable across models | Parameters with shared fields belong at the top level. For example, video duration uses `duration`, and aspect ratio uses `aspect_ratio`. Model features without shared fields use `provider_options`. For example, models with audio controls can use `provider_options.generate_audio`. Duplicate parameters are not portable: some models prefer the shared field, while others reject conflicting values. `callback_url` at any depth inside `provider_options` returns `400 reserved_parameter`. Adding `callback_url` does not change the model's generation parameters or supported inputs. ### Image parameters These fields apply to image generation and editing task endpoints and the image compatibility endpoints below. Editing accepts JSON, not multipart forms. | Field | Type | Meaning | | --- | --- | --- | | `prompt` | string, required | Generation or editing description | | `image` | string or array, task-dependent | Reference or editing images. URL, base64, array support, and image counts depend on the model | | `mask` | string or `{ "image_url": string }`, optional | Inpainting mask, only for models with mask editing support; `file_id` is unsupported | | `n` | integer, optional | Image count. Batch generation and count limits depend on the model | | `size` | string, optional | Image size. Pixel sizes, resolution tiers, and aspect ratios are distinct formats, with no automatic conversion across models | | `quality` | string, optional | Model-specific quality or resolution tier | | `aspect_ratio` | string, optional | Aspect ratio, only for models that support it. Not a universal substitute for `size` | | `negative_prompt` | string, optional | Negative description, supported by some models | | `seed` | integer, optional | Random seed, with model-specific limits. Does not guarantee identical output | | `output_format` | string, optional | Output file format, supported by some models | | `response_format` | string, optional | Result representation, supported by some models. Consumers need to handle both `data[].url` and `data[].b64_json` | | `user` | string, optional | Compatibility field, not used for CR authentication or task ownership | For example, `1024x1024`, `1024*1024`, `1K`, and `16:9` are not interchangeable. The API's example value for `size` is not a default accepted by every model. #### creative-reasoning-image-1.5 See the [model integration guide](/docs/en/models/creative-reasoning-image-1.5) for recommended invocation IDs, complete parameters, image-size limits and result handling. Sign-in is required. Start with one minimal example, then use its parameter table to adjust `size`, `quality`, `image` or `mask`. After submission, query the existing task and save the returned image. ### Video parameters These fields apply to `POST /unified/v1/videos/tasks` and `POST /unified/v1/videos/generations`. | Field | Type | Meaning | | --- | --- | --- | | `content` | array, required | Text and media items, described below. Text-to-video uses `content[].text`, not a top-level `prompt` | | `duration` | integer, optional | Duration in seconds. Allowed values and defaults depend on the model. CR does not accept string durations or `-1` | | `resolution` | string, optional | Resolution tier, such as `480p` or `720p` for some models. Tiers and letter case depend on the model | | `aspect_ratio` | string, optional or conditionally required | Aspect ratio, such as `16:9`. Some text-to-video models require it. Some image-to-video models reject it and follow the input image | | `size` | string, optional | Pixel size for some models, distinct from `resolution`. Omitted unless explicitly supported | | `fps` | integer, optional | Frame rate, supported by some models | | `seed` | integer, optional | Random seed, with model-specific limits | | `negative_prompt` | string, optional | Negative description, supported by some models | These are request settings. Read actual output properties from the [video result fields](/docs/en/media-tasks#read-video-result-fields). Result `duration` and `fps` may contain fractions; omitted output fields do not inherit request values. To request an output last-frame image on a supported model, use `provider_options.return_last_frame: true`; see the [complete request example](/docs/en/media-tasks#request-a-last-frame). #### Content types and roles | `type` | Content field | `role` | Purpose | | --- | --- | --- | --- | | `text` | `text` | Omitted | Generation description | | `image_url` | `image_url.url` | `first_frame` | First frame | | `image_url` | `image_url.url` | `last_frame` | Last frame, only for models that support first and last frames | | `image_url` | `image_url.url` | `reference_image` | Reference image, distinct from a first frame | | `video_url` | `video_url.url` | `reference_video` | Reference video, supported by some models | | `input_audio` | `input_audio.url` | `reference_audio` | Reference audio, supported by some models | The following `content` structure includes a first frame. Its image URL is a placeholder for a reachable asset. The selected model must support first-frame input: ```json [ {"type": "text", "text": "The camera slowly moves forward"}, { "type": "image_url", "role": "first_frame", "image_url": {"url": "https://customer.example.com/assets/first-frame.png"} } ] ``` Reference images need an explicit `role: "reference_image"`. An image without a role can be treated as a first frame. Valid JSON does not establish support for the media types, counts, or combinations. The `creative-reasoning-video-1.0` text-to-video example above contains text only, without reference images, videos, or audio. Its optional boolean `provider_options.generate_audio` controls generated sound, not reference audio input. Check model support before changing duration, resolution, or extensions. #### Video model support These settings apply to `creative-reasoning-video-1.0`, `creative-reasoning-video-1.0-i2v`, and `creative-reasoning-video-1.0-r2v`: | Parameter | Values | When omitted | | --- | --- | --- | | `duration` | Integer from 4 to 15, in seconds | 5 | | `resolution` | Use `480p`, `720p`, or `1080p` | `720p` | | `aspect_ratio` | `16:9`, `9:16`, `1:1`, `4:3`, `3:4`, `21:9`, `adaptive` | `adaptive` | | `provider_options.generate_audio` | Boolean; `true` generates audio, `false` produces silent video | `true` | Put `resolution` at the top level; do not use the image `quality` field. With `adaptive`, text-to-video uses the prompt, image-to-video uses the first frame, and reference-to-video prioritizes reference video, then images. Read actual output properties from the response. | Model | Inputs | | --- | --- | | `creative-reasoning-video-1.0` | Text only; no image, reference video, or reference audio | | `creative-reasoning-video-1.0-i2v` | One `first_frame`, optionally followed by one `last_frame`; no reference video or audio | | `creative-reasoning-video-1.0-r2v` | Up to 9 `reference_image` items, 3 `reference_video` items and 3 `reference_audio` items. Audio cannot be the only media input: include at least one image or video | Input images use JPEG, PNG or WebP, at most 30 MB each, 300–6000 pixels per dimension and a width-to-height ratio of 0.4–2.5. Reference videos use MP4 or MOV, 2–15 seconds and at most 50 MB each, with no more than 15 seconds total. Reference audio uses WAV or MP3, 2–15 seconds and at most 15 MB each, with no more than 15 seconds total. Use complete asset URLs accessible to CR. `role: "last_frame"` supplies an input frame; it does not request `last_frame_url` output. Inputs, duration and resolution can affect usage; use model pricing and the call's billing details for costs. #### creative-reasoning-video-1.0 This model generates video from text. Describe the scene and motion in a `text` item inside `content` and use the settings above. See [Generate videos](/docs/en/video-async) for the complete submission, query and download workflow. #### creative-reasoning-video-1.0-i2v This model generates video from a first-frame image. The example uses one image with `role: "first_frame"`, `duration: 4`, `resolution: "480p"`, and `aspect_ratio: "16:9"`. No `provider_options` are needed. The example uses a publicly accessible cat image. ```json { "model": "creative-reasoning-video-1.0-i2v", "content": [ { "type": "text", "text": "白色长毛猫在绿色草地上缓慢向镜头走来,尾巴轻轻摆动,阳光柔和,固定镜头,保持图片中猫的外观。" }, { "type": "image_url", "image_url": { "url": "https://cdn.translate.alibaba.com/r/wanx-demo-1.png" }, "role": "first_frame" } ], "duration": 4, "resolution": "480p", "aspect_ratio": "16:9" } ``` To use another image, supply a URL directly accessible to CR and update the prompt. Check model support for other input counts or media combinations. `resolution` selects a tier; read actual dimensions and duration from the result. #### creative-reasoning-video-1.0-r2v This model uses a reference image to guide video generation. The example uses one image with `role: "reference_image"`, `duration: 4`, `resolution: "480p"`, and `aspect_ratio: "16:9"`. No `provider_options` are needed. The image needs the explicit reference role. The example uses a publicly accessible cat image. ```json { "model": "creative-reasoning-video-1.0-r2v", "content": [ { "type": "text", "text": "白色长毛猫在绿色草地上缓慢向镜头走来,尾巴轻轻摆动,阳光柔和,固定镜头,保持图片中猫的外观。" }, { "type": "image_url", "image_url": { "url": "https://cdn.translate.alibaba.com/r/wanx-demo-1.png" }, "role": "reference_image" } ], "duration": 4, "resolution": "480p", "aspect_ratio": "16:9" } ``` To use another image, supply a URL directly accessible to CR and update the prompt. Check model support for other input counts or media combinations. `resolution` selects a tier; read actual dimensions and duration from the result. Unsupported fields can be ignored or cause the request or task to fail. HTTP `2xx` means the request was accepted. It does not prove that every optional field took effect. An asynchronous task can still return `failed` later. ## Query or wait for a result Use the same API Key that submitted the task. A different API Key receives `404`, even within the same team. Replace `TASK_ID_FROM_SUBMIT_RESPONSE` with the submission response's `id`, then query that task: ```bash curl "https://api.creative-reasoning.com/unified/v1/tasks/TASK_ID_FROM_SUBMIT_RESPONSE" \ -H "Authorization: Bearer API_KEY" ``` A successful query returns `200` and a task object. Handle its `status`: | status | Client action | | --- | --- | | `pending`, `processing` | Query again or wait for notification; do not submit another generation | | `completed` | Read image or video results from `data` | | `failed` | Read `error.code` and `error.message` | To reduce short polling, call `/unified/v1/tasks/TASK_ID_FROM_SUBMIT_RESPONSE/wait`. It waits up to 30 seconds. If generation is unfinished, it returns `200` and the current task state. You can wait again for the same ID. Waiting timeouts, disconnects, and repeated reads do not cancel or regenerate the task. A failed generation also returns `200` with `status: failed`; HTTP status alone does not indicate generation success. Terminal response bodies are retained for 24 hours after completion, then return `410 task_expired`. Save results promptly; download links have their own validity period. For video models that support last-frame output, set `provider_options.return_last_frame: true` when submitting the task. When the model returns a last frame, the successful result includes its image download URL in `data[].last_frame_url`; otherwise, the field is omitted. Task queries, wait responses, and completion callbacks contain the same field. See [download links and their lifetime](/docs/en/media-tasks#download-and-save-results). ## Read image usage Some image models combine input and output usage into billing tokens, shown as “Combined usage” in prices and request details. If a unified response includes `usage.billing.tokenhub_tokens`, its value is the billing quantity for this request. For example: ```json { "usage": { "billing": {"tokenhub_tokens": 3763} } } ``` This quantity combines input and output usage for the generation or edit. Apply the matching billing-token rate to calculate the charge. It does not represent native text input or image output tokens. These responses do not provide enough information to reconstruct input, output, or cached token counts. Clients that read those fields must allow them to be absent. Continue reading images from `data[].url` or `data[].b64_json`. Use the matching rate in the [model catalog](/models); see [image billing items](/docs/en/request-billing#image-billing-items) and [charge calculation examples](/docs/en/request-billing#charge-examples). Usage has the same meaning in synchronous results and completed async tasks. ## Read video result fields Each `data[]` item represents one video, including its optional last frame. Field meanings are uniform, but availability varies by model. Unreported or invalid optional metadata is omitted; requested settings do not substitute for generated-result metadata. Clients must accept additional optional fields. Older results may omit `type`. | Field | Meaning | | --- | --- | | `type`, `url` | Standard results use `type: video`; `url` downloads the video | | `last_frame_url` | This video's last-frame image link, omitted when unavailable | | `duration` | Generated-video duration in seconds, including fractions; not task processing time | | `width`, `height`, `size` | Pixel dimensions; complete dimensions produce a size such as `1280x720` | | `resolution` | Reported tier, such as `720p`; not inferred from dimensions | | `aspect_ratio` | Reported concrete ratio, or reduced width-to-height ratio; never `adaptive` | | `fps`, `frame_count` | Frame rate and reported total frames; fractional FPS is supported and total frames are not estimated | | `has_audio` | Whether the video contains audio; `false` is retained and unknown is omitted | | `format`, `seed` | Reported container format and actual seed; format is not inferred from the URL, and unknown or random placeholder seeds are omitted | | `extensions` | Registered output-specific fields, omitted when unavailable | Task-level `tools` reports tool execution once per task, without repeating it for each video. For example: ```json { "tools": [{"type": "web_search", "calls": 2}] } ``` `calls` is a nonnegative integer; explicit `0` is retained. If a tool is reported without a count, `calls` is omitted. Unreported tools are omitted. Enabling search in a request does not prove it ran. These statistics are informational and excluded from charge calculation; the meaning of `usage` is unchanged. Task-level `extensions` contains only registered task fields. No extension fields are currently defined, so the object is omitted. Queries, wait responses, completion callbacks and callback retries return the same saved terminal body, including identical download links. Image URL, Base64 and multiple-image result shapes remain unchanged. ### Successful response example This complete task object includes a last frame. `OPAQUE_VIDEO_TOKEN` and `OPAQUE_FRAME_TOKEN` are placeholders; use the full URLs from the actual response. The example shows selected optional fields, whose availability varies by generation. ```json { "id": "01a09ec9-7d00-7000-8000-000000000002", "status": "completed", "model": "YOUR_VIDEO_MODEL", "created_at": 1789370400, "completed_at": 1789370640, "data": [{ "type": "video", "url": "https://api.creative-reasoning.com/_cr/v1/media/video/01a09ec9-7d00-7000-8000-000000000002/OPAQUE_VIDEO_TOKEN", "last_frame_url": "https://api.creative-reasoning.com/_cr/v1/media/video/01a09ec9-7d00-7000-8000-000000000002/OPAQUE_FRAME_TOKEN", "duration": 4, "resolution": "720p", "aspect_ratio": "16:9", "has_audio": false, "seed": 0 }], "usage": {"output": {"video_tokens": 87300}} } ``` ### Handle optional fields Preserve valid `false`, `0`, and fractional values. Missing fields mean unreported values; do not default them to no audio, zero tool calls, or request settings. GET, wait, and callbacks use the same field meanings. Ignore unrecognized additions and allow older results to omit `type`. ## Download and save results Use `data[].url` directly to play or download the video. Do not parse or construct this URL. `OPAQUE_VIDEO_TOKEN` in the example is a placeholder. A link lasts at most 24 hours from issuance, and can stop working earlier if the upstream file expires. Download the video to your storage if you need to keep it. For models that support last-frame output, set `return_last_frame: true` in the submission's `provider_options`. When the model returns a last frame, `data[].last_frame_url` contains its image download URL; otherwise, the field is omitted. Task queries and completion callbacks contain the same URL. Last-frame links follow the same access and expiry rules as video links. Use the complete returned URL directly. See [video result fields](/docs/en/media-tasks#read-video-result-fields) for video specifications, audio presence and task-level tool statistics. Fields have the same meaning in queries and callbacks; availability varies by model. CR streams the video without redirecting to the provider. Downloads support `GET`, `HEAD`, and a single `Range`, without a CR API Key. Treat the link as an access credential: keep it out of public logs and do not share it with unrelated parties. Expired or modified links return `404`. Callback retries, administrator redelivery, and later task queries reuse the saved body. They do not extend the download link's lifetime. A failed download does not change the generation status or charge another generation fee. For images, download `data[].url` or read `data[].b64_json`. Image URLs may also expire; promptly save required output to your own storage. ## Receive notifications at callback_url Add this optional top-level field to any task submission: ```json { "callback_url": "https://customer.example.com/webhooks/cr-media?token=your-random-token" } ``` This fragment is not a complete generation request: include `model` and generation parameters. Follow the [HTTPS callback rules](/docs/en/media-tasks#prepare-the-callback-url). Do not put `callback_url` in `provider_options`. CR sends only `completed` or `failed`. The callback body is byte-for-byte identical to the saved terminal GET response, without an event wrapper. Successful results contain `data` and available `usage`; see the video response example above. Image results retain the model-supported `url` or `b64_json`. ### Prepare the callback URL Provide an HTTPS endpoint that accepts a `POST` without a CR API Key. The URL must meet these requirements: - Use an absolute HTTPS URL whose UTF-8 representation is no longer than 2,048 bytes. - You can include a path and query, but not user information or a fragment. - Every address in the DNS response must be publicly routable. - The URL cannot point to the CR API itself. Do not use localhost, a private IP address, or an endpoint that depends on HTTP redirects in production. To identify the caller, put a random token in the query and compare it at the receiver. Do not write the full callback URL to logs. ### Receive the terminal state A failed callback has `status: "failed"` and includes `error`. A cancelled task uses `error.code: "task_cancelled"`. Failed callbacks do not contain `data` or `usage`. `error.code` says why the task failed, using CR's own vocabulary — a cancelled task uses `task_cancelled`, and an unclassified failure uses `task_failed`. CR never returns a model provider's error text, code, or identifiers, so these values are the same for every model. See [error codes](/docs/en/troubleshooting#error-response-format) for the full set and how to branch on it safely. Each delivery relies only on these standard headers: | Header | Purpose | | --- | --- | | `content-type` | Always `application/json` | | `user-agent` | Always `CR-Webhook/1.0` | Parse the JSON normally. You do not need to retain the raw body. ### Prevent duplicate processing A network timeout can cause the same terminal result to arrive more than once. Use the CR task `id` in the body as the idempotency key. Add a unique constraint for the task `id` when you save results. If you already processed the task, return `2xx` again. Save the result before you return `2xx`. If processing takes longer, write the result to a queue or database first, then process it asynchronously. ### Handle retries After the first delivery fails, CR retries up to three times. Retries run 1, 2, and 4 seconds after each failure. Every attempt for the task uses the same body. - Any `2xx` means that delivery succeeded. - Any non-`2xx`, connection error, TLS error, or timeout triggers a retry. - CR does not follow a `3xx` response. CR waits no more than 10 seconds for each response. A callback delivery failure does not change the generation task status or charge it again. To reconcile a task, send a `GET` to the submission response `poll_url`. The poll endpoint and the callback return the same terminal body. ## Avoid duplicate generation and handle errors These rules apply to `/unified/v1/images/tasks`, `/unified/v1/images/edit-tasks`, and `/unified/v1/videos/tasks`. To retry these submissions safely, add the optional `Idempotency-Key` header. Its value is a unique business operation identifier that you generate. It is not an API Key and does not authenticate the request. Replace `YOUR_UNIQUE_OPERATION_ID` below with this operation's unique identifier, such as a UUID saved in your business record. Reuse the identifier and request body when retrying the same operation; use a new identifier for a new operation: ```http Idempotency-Key: YOUR_UNIQUE_OPERATION_ID ``` The identifier accepts 1–256 printable non-whitespace ASCII characters. It is scoped to the API Key, operation, and endpoint; it does not deduplicate across image/video operations or across old and new endpoints. - Same key and request: returns the same task. A terminal replay can return `200`, still with a task object. - Accepted task: while the submitting API Key remains valid, the same key and request can recover the task even if the model no longer accepts new generation requests. - Same key, changed request: returns `409 idempotency_conflict` without creating a second task. Changing the callback destination also changes the request. - Timeout, disconnect, or `503`: does not prove the task was not accepted. If you set an idempotency header, retry with the same key and request. Query if you already have the ID. Without the header, do not blindly repeat the POST: it can generate another result. - Each API Key can have up to 128 unfinished tasks. Additional submissions return `429 task_capacity_exceeded`. - When concurrent waiting is full, `/wait` returns `429 task_wait_capacity_exceeded`; use the ordinary GET query. - `400 invalid_parameter`: check the request, including any unsupported `response_mode` field. Task records remain until 30 days after termination for idempotency checks; this does not extend the 24-hour result retention. Do not reuse one idempotency key indefinitely. Without this header, each POST creates a new task. Execution is limited to 24 hours. If submission cannot be confirmed, CR does not blindly regenerate. It can eventually return `submission_unknown`, without charging the customer for that task. Failed generation is not charged. Successful generation is charged even if the customer's callback endpoint is unavailable. ## Compatibility endpoints Compatibility endpoints do not provide the task endpoints’ idempotent submission guarantee. Query the original task when you have its ID; after a submission timeout without an ID, first confirm whether the request was accepted. The existing `/unified/v1/images/generations`, `/unified/v1/images/edits`, and `/unified/v1/videos/generations` endpoints remain supported and are not deprecated. Existing image endpoints retain their model-specific inline or task response; video submissions still return tasks. Migration requires changing both the submission path and result handling, not just the URL. ### Image generation and editing compatibility endpoints Replace `YOUR_MODEL` with a model name from the [model catalog](https://creative-reasoning.com/models) that supports the image operation. #### Generate an image Check [image parameters and model examples](/docs/en/media-tasks#image-parameters) for `size`, `quality`, and input limits before sending a request. A generic example does not establish support for every optional field. ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/images/generations' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "YOUR_MODEL", "prompt": "A blue ceramic cup on a white background" }' ``` #### Edit an image ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/images/edits' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "YOUR_MODEL", "prompt": "Change the background to light gray", "image": "https://example.invalid/replace-with-your-image.png" }' ``` The editing endpoint accepts JSON, not multipart uploads. Replace the sample URL with an image that CR can reach. Confirm that the model supports editing, then check formats, arrays, and masks in [image parameters](/docs/en/media-tasks#image-parameters). Successful text-to-image generation does not establish editing support. #### Handle the response Read `data` directly from a synchronous response. Poll only `pending` or `processing` tasks with the API Key that submitted them. Set a polling interval and an overall deadline. Keep the task ID if the deadline expires so you can check it later. Handle accepted requests according to the model's native behavior and whether you supplied a callback URL: | Request | Submission response | Next action | | --- | --- | --- | | Synchronous image, without `callback_url` | Returns `data` directly | Save the image without polling | | Asynchronous image, without `callback_url` | Returns a CR `id` and `pending`; `poll_url` can be absent | Query the task with its CR `id` | | With `callback_url` | Returns a CR `id`, `pending`, and `poll_url` | Receive the terminal callback and query the same task if needed | If an asynchronous image response omits `poll_url`, query `GET /unified/v1/images/generations/{id}` with the CR `id` from the submission. Do not repeat POST to retrieve the result. Image editing tasks use the same query path. #### Receive image callbacks Both generation and JSON editing accept a top-level `callback_url`. Without this field, existing synchronous or asynchronous behavior stays unchanged. Do not put it in `provider_options`; CR rejects that with `400 reserved_parameter`. A callback request returns `status: "pending"`, a CR task `id`, and `poll_url`. Image editing tasks also use `/unified/v1/images/generations/{task_id}` for polling. Synchronous models still generate during the POST, then save the result and queue the notification. Adding a callback does not make the POST return immediately or generate the image again. See the callback section above for the result format, URL validation, and delivery retries. `503 callback_unavailable` means CR could not register or persist the callback. If persistence fails after the provider accepts the request, generation may already have started. Do not resubmit unconditionally. ### Video generation compatibility endpoint Video generation uses asynchronous tasks, not a synchronous POST that waits for the finished video. Without `callback_url`, the submission still returns a CR `id` and `poll_url`. Poll that URL with the API Key that submitted the task until it is `completed` or `failed`. Do not submit another generation request to check progress. This example uses the text-to-video example parameters for `creative-reasoning-video-1.0`. Replace the callback URL with your receiver and keep `callback_url` at the top level. Before changing models, check [video parameters and model differences](/docs/en/media-tasks#video-parameters). Duration, resolution, and aspect ratio are not portable across all models. ```bash curl "https://api.creative-reasoning.com/unified/v1/videos/generations" \ -H "Authorization: Bearer API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "creative-reasoning-video-1.0", "content": [{"type": "text", "text": "sunset over the sea"}], "duration": 4, "resolution": "480p", "aspect_ratio": "16:9", "callback_url": "https://customer.example.com/webhooks/cr-video" }' ``` Do not put `callback_url` in `provider_options`. The name is reserved at every depth of `provider_options`, and the service returns `400 reserved_parameter`. Store the response `id` and `poll_url`. The `id` is the same in the submission response, poll response, and callback body: ```json { "id": "0199c9e6-9381-7f30-9aa0-0df86dca6cdf", "status": "pending", "created_at": 1788912000, "model": "creative-reasoning-video-1.0", "poll_url": "/unified/v1/videos/generations/0199c9e6-9381-7f30-9aa0-0df86dca6cdf" } ``` `503 callback_unavailable` means the callback service is unavailable. It can occur before or after task acceptance. A `503` alone therefore does not prove that no task was created. Do not automatically retry POST; retain the request ID and contact support to confirm whether a task was created. `503 media_unavailable` means the video download service is unavailable. Removing `callback_url` does not resolve it; contact support before submitting again. # Query request bills and effective prices URL: https://creative-reasoning.com/docs/en/request-billing ## Estimate request costs Check the selected model’s rates and billing units in the [model catalog](https://creative-reasoning.com/models). Use catalog rates for estimates and recorded request charges for billing reconciliation. ### Image billing items Image models can bill input and output tokens separately or combine them as “Combined usage”. “Image output” represents native output-image tokens. “Combined usage” represents multiple types of usage converted into billing tokens under the model's rules. For `usage.billing.tokenhub_tokens`, use the matching combined-usage rate without adding input or output token charges. See [generate and edit images](/docs/en/media-tasks#read-image-usage) for a usage example. ### Combined usage and charges The “Combined usage” label applies to any integrated model that uses this form of metering. Video models priced per second, per video, or per native output token retain those units. A shared label does not make all models follow the same billing rules. Catalog rates use Credits (ℂ). Check the quantity unit shown for each item. For a rate per million billing tokens: ```text Charge (ℂ) = actual billing tokens / 1,000,000 × rate (ℂ per million billing tokens) ``` The response quantity already includes the model's conversion. Do not multiply it by conversion factors again. Factors can differ between models, so native image or video output rates do not apply to this quantity. Applicable discounts and settlement precision affect the final amount. Use the actual charge in request details and keep `x-cr-usage-id` to look up the bill. ### Charge examples Public list prices and these calculation examples are available without signing in. The rates below are hypothetical and illustrate the arithmetic. Check the selected model's current rate, unit, and supported specifications in the [model catalog](https://creative-reasoning.com/models). | Billing method | Assumed rates and usage | Estimated charge before discounts | | --- | --- | --- | | Combined billing tokens | 56 ℂ per million billing tokens; 3,763 tokens | `3763 ÷ 1000000 × 56 = 0.210728 ℂ`, approximately ¥0.042146 | | Video output seconds | No-reference-video tier: 4 ℂ per second; 5 billable output seconds | `5 × 4 = 20 ℂ`, or ¥4 | | Video input and output seconds | Reference-video tier: 2 ℂ per input second and 3 ℂ per output second; 5 billable input seconds and 10 billable output seconds | `5 × 2 + 10 × 3 = 40 ℂ`, or ¥8 | | Per video | 25 ℂ per video at the selected specification; 1 billable video | `1 × 25 = 25 ℂ`, or ¥5 | RMB equivalents use `1 ℂ = ¥0.20`. If the applicable discount charges 80% of list price, a 20 ℂ estimate becomes `20 × 80% = 16 ℂ`, or ¥3.20. Settlement precision also affects the final amount. Use the request bill for the recorded charge. “Billed by generation specification” means selecting the price tier that matches the request, such as its resolution, input type, and use of reference video, then applying that tier's billing unit to actual usage. With reference video, both input and output rates must come from the reference-video tier. The no-reference output rate does not apply. Per-second billing uses the model's reported billable duration, which may include minimum-duration or rounding rules; the file's playback duration alone may not determine the charge. Size, quality, prompt, reference images, and cache hits can also affect image usage. A request-cost sample only represents its stated conditions. Public examples help estimate a budget. To retrieve your actual charge, retain the usage ID and use an authorized management token as described below. ## From a model call to its bill Model calls and management queries use different credentials. `API_KEY` invokes a model; `YOUR_MANAGEMENT_TOKEN` queries billing. The management token needs `usage:read`. A model API Key cannot authenticate to the management API. Model requests use the production API at `https://api.creative-reasoning.com`; management queries use `https://creative-reasoning.com`. Copy a complete API Key from the [API Key page](https://creative-reasoning.com/console/keys) and use it for `API_KEY` below. Replace `YOUR_MODEL` with a model name from the [model catalog](https://creative-reasoning.com/models) that supports Chat Completions. Ask an administrator for a management token authorized to read the target team's billing, then use its complete value for `YOUR_MANAGEMENT_TOKEN`. First, invoke the model and retain `x-cr-usage-id` from the response headers. This example uses `--include` to display headers; production clients should read the header from the response object: ```bash curl -i \ -H "Authorization: Bearer API_KEY" \ -H 'Content-Type: application/json' \ -d '{"model":"YOUR_MODEL","messages":[{"role":"user","content":"Hello"}]}' \ "https://api.creative-reasoning.com/unified/v1/chat/completions" ``` The response contains two IDs with different purposes: ```http x-cr-request-id: 018f1000-0000-7000-8000-000000000004 x-cr-usage-id: 018f1000-0000-7000-8000-000000000004 ``` `x-cr-request-id` identifies this HTTP attempt for diagnostics. `x-cr-usage-id` identifies its bill. They normally match for synchronous inference. Each asynchronous poll and supported idempotent retry has a new request ID but retains the original usage ID. Store the task ID separately for generation-status lookup. Billing clients only need the usage ID; do not replace it with a poll request ID. Receiving a usage ID does not imply that billing is final or immediately queryable. Repeating an ordinary inference call does not automatically make it idempotent. For streaming calls, read these IDs from the initial response headers and continue consuming the stream. Next, replace `USAGE_ID` with the UUID from the `x-cr-usage-id` response header and query with the management token. ```bash curl \ -H "Authorization: Bearer YOUR_MANAGEMENT_TOKEN" \ "https://creative-reasoning.com/api/v1/management/usage/USAGE_ID" ``` Check `billing_status` first. For `pending`, follow `Retry-After` with a retry deadline. `credits` is null, not a zero charge. For `final`, read `credits.after_discount` as the recorded charge. Final billing does not prove generation succeeded; check the model response or task status separately. A new call can briefly return 404. Retry only a recently submitted call of your own; missing and inaccessible records also return 404. ## Read usage and charges Amounts use Credits (ℂ), the same unit as the console. A successful response identifies this unit with `X-CRR-Credit-Unit: credits`. For a call with 9 input tokens, 14 output tokens, and no organization discount: ```json { "usage_id": "018f1000-0000-7000-8000-000000000004", "billing_status": "final", "created_at": "2026-09-16T13:52:56.621Z", "usage_items": [ { "name": "input:prompt_tokens", "usage": 9 }, { "name": "output:completion_tokens", "usage": 14 } ], "credits": { "before_discount": "0.00553", "after_discount": "0.00553" } } ``` - `usage_items` contains quantities for each billing dimension, such as input and output token counts. - `credits.before_discount` is the charge at list price. - `credits.after_discount` is the final charge after the organization discount and is the amount to use for this call. - `created_at` is the billing record's creation time, not the time billing became final. - To display savings, subtract the final charge from the list-price charge using decimal arithmetic. The receipt contains only these five top-level fields. In this example, `"0.00553"` means a charge of `0.00553 ℂ`, equivalent to `¥0.001106` at `1 ℂ = ¥0.20`. Amounts are decimal strings. Use decimal arithmetic for charge calculations to preserve precision. ## Check a batch Put up to 100 usage UUIDs in `usage_ids`. This example sends the same ID twice to show that duplicates are preserved: ```bash curl \ -X POST \ -H "Authorization: Bearer YOUR_MANAGEMENT_TOKEN" \ -H 'Content-Type: application/json' \ -d '{"usage_ids":["USAGE_ID","USAGE_ID"]}' \ "https://creative-reasoning.com/api/v1/management/usage/batch" ``` HTTP 200 returns `items` in input order. It does not mean that every item was found or finalized. Check each item's `lookup_status`: `not_found` has null `usage`; for `found`, check `usage.billing_status` next. Batches have no per-item `Retry-After` header, so configure bounded backoff in your client. An invalid UUID rejects the entire batch. Valid IDs outside the token's scope and missing IDs both return `not_found`. Team tokens query their team; organization tokens query their organization. Duplicate IDs still consume rate-limit units. For a rejected batch, check `Content-Type` before parsing the error. A 400 JSON error indicates an invalid UUID or batch size. Malformed JSON returns 400 plain text. Wrong field types, unknown fields, or a missing `usage_ids` return 422 plain text. Set `Content-Type: application/json` after 415 and reduce an oversized body after 413. Correct the request before resending. Plain-text wording is not a stable error code. ## Get prices before a call Request the independent `pricing:read` scope. Open the target team in the [management console](https://creative-reasoning.com/), click the code below its name, and replace `TEAM_CODE` with the copied value, such as `T-TU214G`. Use the team code, not the team UUID: ```bash curl \ -H "Authorization: Bearer YOUR_MANAGEMENT_TOKEN" \ "https://creative-reasoning.com/api/v1/management/teams/TEAM_CODE/models/pricing" ``` Read `effective_pricing` to display current organization prices. `pricing` contains list prices. `discount: 7500` means charging 75% of the list price, not a 75% reduction. Prices use Credits per one billing unit; preserve decimal strings and tier structures. Multiply token unit prices by 1,000,000 for Credits per million tokens. A tier's `up_to` is its quantity limit for that billing dimension. Do not recalculate historical bills from current prices. Listing a model does not grant a key permission to invoke it. Use the bill lookup for historical charges and [Query API Key quota and usage](/docs/en/manage-api-keys#query-remaining-quota-and-reset-time) for time-range summaries. See the [Management API](/docs/en/management-api) for complete request and response fields and permission requirements. # Errors and retries URL: https://creative-reasoning.com/docs/en/troubleshooting ## Identify the request Keep the request time and time zone, HTTP method and path, model name, API Key prefix or ID, HTTP status, and `x-cr-request-id`. For async tasks, keep the task `id` too. Each poll has a separate request ID; the response header always identifies the current HTTP request. Keep only the redacted payload excerpts needed for diagnosis. Do not send an `Authorization` header, a complete API Key, customer input, or a private media URL in a ticket or chat. JSON HTTP errors include a top-level `request_id`, alongside `error`, matching the `x-cr-request-id` response header. A failed async task also includes a top-level `request_id`, but it identifies the original submission. The saved result stays unchanged across polls, idempotent replays, and callbacks. The current poll's ID remains in the response header. These are CR identifiers, not the model service's request IDs. Saving only the nested `error` object discards `request_id`. Existing saved task results are not rewritten to add this field; clients must accept its absence. Stream error events retain their existing protocol. Read their correlation IDs from the response headers. If the response includes `x-cr-usage-id`, save it to [look up the bill](/docs/en/request-billing). A poll's request ID can change and cannot replace the original usage ID. A disconnected call is not necessarily free. Check `billing_status: "final"` and `credits.after_discount` for the final charge. ## Investigate by stage | Symptom | First checks | | --- | --- | | Connection or TLS failure | API Base URL, DNS, certificate, proxy, and egress | | 400 or parameter validation failure | Required fields, request body, and model capability | | 401 | Bearer header, complete API Key, expiry, and disabled status | | 403 or access denied | Model access policies for the API Key, team, or organization, plus allowance state | | 404 | Operation path, model name, `previous_response_id` or task ID, and the API Key used | | 429 or selected 5xx | Rate limits, concurrency, error details, and bounded backoff | | Interrupted SSE | Read timeout, proxy buffering, cancellation, and service-side stream errors | | Long-running task | Task ID, polling interval, terminal-state handling, and overall deadline | ## Error response format This page describes model-call errors. Management operations use a separate error contract in the [Management API reference](/docs/en/management-api). CR uses the same `error` object for model-call HTTP errors and terminal async task failures. An immediate HTTP error also includes a top-level `request_id` that mirrors the `x-cr-request-id` response header: ```json { "error": { "type": "invalid_request_error", "code": "content_policy_violation", "message": "The request was rejected by a content safety filter" }, "request_id": "0199c9e6-9381-7f30-9aa0-0df86dca6cdf" } ``` Branch on `error.code`. Treat `error.type` as a coarse grouping. Except for the context-limit marker documented below, `error.message` is human-readable text that can change. Do not depend on its full wording. For async tasks, check `status` first: `completed` means success and `failed` means failure. Stop polling on `failed`, then use `error.code` to choose a message or next action. Do not require `error.code == "task_failed"` to end a task. GET and callback return the same terminal body. Its `id` is the task ID; a failed task's `request_id` identifies the original submission, not the current poll. ## Errors from the model Model failures in HTTP error responses and terminal async task errors use the CR codes below. CR defines their error code, category, and message, and omits model provider identifiers. See [errors during a stream](#errors-during-a-stream) for failures after streaming has started. Recognized failures include actionable details in `error.message`: the rejected field, a missing schema type, a media size limit, or a context token limit. `error.param` identifies the field when CR can determine it safely. Error messages omit supplier identities, service addresses, credentials, and raw request content. Unknown diagnostics keep a general message; support can investigate with `request_id`. | `error.code` | `error.type` | Meaning | What to do | | --- | --- | --- | --- | | `content_policy_violation` | `invalid_request_error` | Input or generated output failed a content safety check | Follow the error message to adjust the input or generation options; do not retry the same request indefinitely | | `invalid_parameter` | `invalid_request_error` | A parameter was invalid or unsupported for this model | Check the parameter against [media parameters](/docs/en/media-tasks#request-parameters) for this model | | `input_too_large` | `invalid_request_error` | Input exceeds a size or token limit, including image and text token counts, image dimensions, and input video size | Shorten the input, resize images, compress video, or split the request | | `unsupported_capability` | `invalid_request_error` | This model does not support the requested operation or input type | Use a supported operation or input format, or choose a model that supports it | | `upstream_rate_limited` | `rate_limit_error` | Rate limited | Retry with backoff | | `quota_exceeded` | `upstream_error` | The model's capacity is exhausted | Contact your administrator; retrying will not help | | `model_unavailable` | `overloaded_error` | The model is temporarily unavailable or offline | Use bounded retries with backoff; if unavailable persistently, contact your administrator or choose another model. An offline model needs service restoration or a route change | | `request_timeout` | `timeout_error` | The model did not respond in time | Retry; consider a smaller request | | `upstream_request_failed` | `upstream_error` | The request failed without a more specific reason | Retry once; if it persists, contact support with your request ID | A model service can report an offline model with HTTP `400`. CR preserves that HTTP status but classifies the error as `model_unavailable`, not `invalid_parameter`. Do not interpret every `400` as a request to change generation parameters, and do not retry indefinitely. Offline-model messages do not promise recovery after a short wait. ### Copyright checks on generated audio When CR recognizes a copyright restriction on generated audio, `error.code` remains `content_policy_violation` and `error.message` explains that the generated audio may be subject to copyright restrictions. This does not establish that the caller supplied infringing audio. Automatically generated music or other audio can fail a check even when the request contains no audio input. Try disabling audio generation or, if the model supports reference audio, using audio you own or are authorized to use. See [video generation parameters](/docs/en/media-tasks#request-parameters) for the request format. These changes do not guarantee that other content safety checks will pass. If the rejection appears incorrect, contact support with the task `id` and `request_id`. Stop polling an async task once its status is `failed`, and do not retry generation indefinitely. ### Context limits and client recovery Recognized context-window failures retain `error.type: "invalid_request_error"` and `error.code: "input_too_large"`. Their message starts with `prompt is too long` so compatible clients can recognize the failure. When both counts are available, CR includes the input token count and the limit: ```json { "error": { "type": "invalid_request_error", "code": "input_too_large", "message": "prompt is too long: 1045171 tokens > 1000000 maximum; shorten or compact the conversation and retry" }, "request_id": "0199c9e6-9381-7f30-9aa0-0df86dca6cdf" } ``` CR supplies the explanation without model-service identifiers or raw diagnostic text. Image, video, and HTTP body size errors do not use this context-limit marker. Automatic compaction still depends on the client's version, settings, and conversation state. CR does not compact conversation history. If Claude Code cannot recover automatically, `/compact` is the manual recovery command. See [Claude Code gateway troubleshooting](https://code.claude.com/docs/en/llm-gateway-connect#troubleshoot-gateway-errors). Changing `max_tokens` does not remove history already included in the request. ### Async task failures Terminal async tasks (`status: "failed"`) use the same codes, with two differences: | `error.code` | Meaning | | --- | --- | | `task_cancelled` | The task was cancelled | | `task_failed` | The task failed without a more specific reason — the task-shaped equivalent of `upstream_request_failed` | Clients must tolerate new error codes. Handle an unknown code as a generic failure; `status: "failed"` still ends the task. A temporary error on a GET request does not mean the generation task failed. Keep the task ID and retry the query rather than automatically submitting another generation request, which can generate and charge twice. ## Errors from the gateway These come from CR itself, before or instead of a model call. Local media validation failures use `invalid_parameter` and retain a safe, actionable reason. `error.param` identifies the request field, such as `content[1].image_url.url`, `image[0]`, or `provider_options.image_urls[0]`. For example, a model that accepts only HTTP(S) media URLs rejects a data URL with this error object: ```json { "error": { "type": "invalid_request_error", "code": "invalid_parameter", "message": "content[1].image_url.url: URL scheme must be HTTP(S) (url_kind=data); expected an HTTP(S) media URL", "param": "content[1].image_url.url" }, "request_id": "01a09ec9-7d00-7000-8000-000000000001" } ``` These errors do not echo URLs, signed query parameters, credentials, prompts, or Base64 data. Raw model-service errors still go through CR classification rather than direct forwarding. `param` can be omitted when CR cannot safely identify the field. Local validation can also move an accepted async task from `202` to `failed`; stop polling and correct the parameters. | `error.code` | HTTP | Meaning | | --- | --- | --- | | `invalid_api_key` | 401 | The API Key is missing, malformed, or revoked | | `insufficient_balance` | 402 | The API Key has insufficient balance for the request | | `model_access_denied` | 403 | A policy denies this key access to the model | | `model_not_found` | 404 | No such model | | `model_disabled` | 404 | The model exists but is disabled | | `task_not_found` | 404 | No such task, or it belongs to another key | | `no_routes_available` | 503 | The model has no usable route | | `provider_unavailable` | 502 | CR could not build a request for the model's route | | `missing_model` | 400 | The request body has no `model` | | `invalid_body` | 400 | The body is not valid JSON or form data | | `conflicting_reasoning_parameters` | 400 | Different reasoning levels were specified, or extension controls conflict with the standard level; keep one standard form for the endpoint | | `invalid_reasoning_parameters` | 400 | The standard reasoning level has an invalid value or type | | `unsupported_reasoning_parameters` | 400 | All available routes for the selected model explicitly reject the requested standard reasoning level | | `unsupported_content_type` | 400 | The content type is not supported on this path | | `payload_too_large` | 413 | The request body exceeds the maximum size | | `reserved_parameter` | 400 | A reserved name such as `callback_url` was placed in `provider_options` | | `invalid_callback_url` | 400 | `callback_url` is not an acceptable HTTPS destination | | `callback_unavailable` | 503 | CR could not register or persist the callback | | `media_unavailable` | 503 | The media download service is unavailable | | `endpoint_not_available` | 501 | This model is not served on this endpoint | | `request_rebuild_failed` | 500 | CR could not prepare the upstream request | | `router_loop_detected` | 508 | A semantic-router request was already routed | ## Errors during a stream Once a streaming response has returned `200`, CR cannot change the status. If the connection is still writable, a later failure arrives as an error event in the stream. If the client or proxy has disconnected, the failure may only be recorded on the server because the client can no longer receive the event. Before forwarding a complete error event, CR replaces the model's error category, code, and message with the CR codes above. It removes diagnostic URLs, request IDs, and debug fields. Successful output before the error is preserved; billing still uses the valid usage received. The error shape follows the API: Chat Completions and Anthropic Messages use `error.code`; a Responses `error` event uses top-level `code`, and a `response.failed` event uses `response.error.code`. All of these events indicate a failed stream. Stream errors generated by CR and failure records on the server use the following codes: | `error.code` | Meaning | | --- | --- | | `upstream_stream_idle_timeout` | The model sent no data for too long | | `upstream_stream_deadline_exceeded` | The stream exceeded its total time limit | | `upstream_stream_read_error` | The stream stopped unexpectedly | | `downstream_stream_write_error` | CR could not write to the client stream, for example because the client or proxy disconnected. This is a downstream connection failure, not proof of a model failure | | `upstream_stream_incomplete` | The stream ended before its terminal event | | `upstream_stream_error` | Server record for a model error event; the client event uses the classified CR reason codes above | | `upstream_sse_line_too_large` | A single event exceeded the size limit | Treat a stream that ends without its terminal event as failed even if you received partial content. Do not mark partial content as a complete result. Usage may have accrued before the interruption; use the request's bill for its final charge. ## Retry with limits Retry only temporary network failures, 429 responses, and selected 5xx responses. Use exponential backoff with jitter, and set an attempt limit and business deadline. Fix authentication, access, and parameter errors before retrying them. A timeout on a generation POST does not prove that no task was created. Resubmitting can create a duplicate task and another charge. ## Contact support If the problem remains, give the information from **Identify the request** to your team administrator or CR support, and reproduce it with the smallest redacted input. # Generate videos URL: https://creative-reasoning.com/docs/en/video-async Video generation returns a task ID. Query that task and read the video URL when it completes. ## Prepare an API Key Create or copy a complete API Key from the [API Key page](https://creative-reasoning.com/console/keys). Replace `API_KEY` with the secret, not its prefix or API Key ID. Requests below use the production API at `https://api.creative-reasoning.com`. ## Submit a video task ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/videos/tasks' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "creative-reasoning-video-1.0", "content": [ { "type": "text", "text": "Sunset over the sea, with a slow forward camera movement" } ], "duration": 4, "resolution": "480p", "aspect_ratio": "16:9" }' ``` Initial acceptance returns HTTP `202`. This response structure example uses an illustrative ID. Save the actual response `id`; `pending` means queued, with no generated output yet. ```json { "id": "01a09ec9-7d00-7000-8000-000000000001", "status": "pending", "created_at": 1789370400, "model": "creative-reasoning-video-1.0", "poll_url": "/unified/v1/tasks/01a09ec9-7d00-7000-8000-000000000001" } ``` ## Query and read the result Replace `TASK_ID_FROM_SUBMIT_RESPONSE` with the response `id` and use the same API Key as the submission: ```bash curl 'https://api.creative-reasoning.com/unified/v1/tasks/TASK_ID_FROM_SUBMIT_RESPONSE' \ -H 'Authorization: Bearer API_KEY' ``` A query returning HTTP `200` still requires checking `status`. For `pending` or `processing`, keep waiting; for example, poll every five seconds with an overall deadline. Keep the ID if that deadline expires. For `failed`, read `error.code` and `error.message`. Read `data` only for `completed`. This completed-response structure example uses placeholders for media content and URL credentials: ```json { "id": "01a09ec9-7d00-7000-8000-000000000001", "status": "completed", "created_at": 1789370400, "model": "creative-reasoning-video-1.0", "completed_at": 1789370460, "data": [ { "type": "video", "url": "https://api.creative-reasoning.com/_cr/v1/media/video/01a09ec9-7d00-7000-8000-000000000001/OPAQUE_VIDEO_TOKEN" } ] } ``` Play or download the complete `data[].url`; do not parse or reconstruct it. `OPAQUE_VIDEO_TOKEN` is illustrative. Real video links last up to 24 hours from generation, or less if the source expires sooner. Downloads need no API Key because the URL carries its own credential. Save the file to your storage promptly. ## Use a first frame or reference image Choose `creative-reasoning-video-1.0-i2v` and add a first-frame image to `content`. This example uses a public sample image; replace it with your own accessible URL when integrating: ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/videos/tasks' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "creative-reasoning-video-1.0-i2v", "content": [ { "type": "text", "text": "白色长毛猫在绿色草地上缓慢向镜头走来,尾巴轻轻摆动,阳光柔和,固定镜头,保持图片中猫的外观。" }, { "type": "image_url", "image_url": { "url": "https://cdn.translate.alibaba.com/r/wanx-demo-1.png" }, "role": "first_frame" } ], "duration": 4, "resolution": "480p", "aspect_ratio": "16:9" }' ``` For reference-guided generation, change `model` to `creative-reasoning-video-1.0-r2v` and the image `role` to `reference_image`. Both requests use the submission, query and result handling above. See [video model parameters](/docs/en/media-tasks#video-model-support) for input counts and formats. ## Adjust video parameters These three models accept integer `duration` values from 4 to 15 seconds and `resolution` values of `480p`, `720p`, and `1080p`. `aspect_ratio` supports landscape, portrait, square and automatic ratios. See the [parameter table](/docs/en/media-tasks#video-model-support) for exact choices, defaults and model differences. Media inputs depend on the model; changing the name alone does not make every input supported. Read actual dimensions, duration and audio status from the [result fields](/docs/en/media-tasks#read-video-result-fields); do not substitute requested values for missing output fields. ## Callbacks and recovery - Add your HTTPS `callback_url` at the top level to receive the same terminal result as a query. Deduplicate by task `id`; see [callback delivery](/docs/en/media-tasks#receive-notifications-at-callback_url). - For safe submission retries, add `Idempotency-Key: YOUR_UNIQUE_OPERATION_ID`. Generate and save this unique identifier for your business operation; it is not a credential. Retry with the same identifier and unchanged request body. - When you have a task ID, query it. If a submission without an idempotency key times out, do not blindly repeat POST: it may generate and charge twice. - For `401`, check the API Key. For query `404`, check the ID and original Key. For `failed`, read the error. `410 task_expired` means the result body has expired. See [task errors and idempotency](/docs/en/media-tasks#avoid-duplicate-generation-and-handle-errors). ## Compatibility endpoints Existing integrations can keep `/unified/v1/videos/generations`, which also returns an asynchronous task but uses a different query path. See the [video compatibility endpoint](/docs/en/media-tasks#video-generation-compatibility-endpoint). Old and new submission endpoints do not share idempotency keys. ## Image and video skill To generate or edit images and videos through natural-language requests in Claude Code or Codex, install the [cr-media skill](/docs/en/integrations/cr-media). The guide covers plugin and `npx skills` installation, updates, API Key configuration, and local-image versus URL input requirements. # 模型调用 API URL: https://creative-reasoning.com/docs/zh/api-reference 新接入图片与视频推荐使用[异步任务接口](/docs/zh/media-tasks)。新接口先返回任务 ID,生成参数仍使用本页对应字段;旧生成与编辑接口继续兼容。 图片和视频的字段位置、模型差异及请求示例见[图片与视频参数](/docs/zh/media-tasks#请求参数)。下方契约中的可选字段不表示每个模型均支持。 生产 API 地址为 `https://api.creative-reasoning.com`。请求使用 `Authorization: Bearer API_KEY`,将 `API_KEY` 替换为从 [API Key 页面](https://creative-reasoning.com/console/keys)复制的完整密钥。完整路径以 `/unified/v1` 开头;SDK 的 base URL 使用 `https://api.creative-reasoning.com/unified/v1`。 [下载 OpenAPI 3.1 契约(JSON)](https://creative-reasoning.com/docs-openapi/dataplane.zh.json)。包含请求参数、响应结构与错误定义,可供开发工具和 AI 直接读取。 # Embedding 与 Rerank URL: https://creative-reasoning.com/docs/zh/embeddings-rerank ## 准备 API Key 本页示例使用生产 API `https://api.creative-reasoning.com`。在 [API Key 页面](https://creative-reasoning.com/console/keys)创建或复制完整 API Key,将请求头中的 `API_KEY` 替换为完整密钥即可。 将示例中的 `YOUR_MODEL` 替换为[模型目录](https://creative-reasoning.com/models)中支持本页操作的模型名称。 ## 选择接口 Embedding 为输入生成向量。Rerank 根据 `query` 重排候选 `documents`。两者需要不同的模型能力。 ## 生成向量 ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/embeddings' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{"model":"YOUR_MODEL","input":["Hello world!","Hello Tezign!"]}' ``` 成功响应中,`data[].index` 是输入在请求数组中的位置,从 `0` 开始;`data[].embedding` 是对应向量。下面仅示意浮点向量的结构,三个数值不代表模型的实际维度或真实计算结果: ```json { "object": "list", "model": "YOUR_MODEL", "data": [ {"object":"embedding","index":0,"embedding":[0.12,-0.04,0.87]}, {"object":"embedding","index":1,"embedding":[0.11,-0.05,0.86]} ] } ``` `input` 必填,可以是单个文本或文本数组。只有模型明确支持时才设置 `dimensions`、`encoding_format` 等可选字段;向量长度和编码以实际响应为准。完整字段见 [Embedding API](/docs/zh/api-reference?operation=createUnifiedV1Embeddings)。 批量调用时,保留输入与响应 `index` 的对应关系。同一个向量索引使用相同的模型、维度和预处理方式。 支持多模态 Embedding 的模型可在同一批次混合文本与图片。图片既可以使用服务端可访问的 URL,也可以使用完整 Base64;具体字段及可选参数以模型目录中的调用示例为准。图片 Base64 不要使用省略号截断。 将 `YOUR_MULTIMODAL_MODEL` 替换为支持该输入格式的模型名称;图片 URL 和 Base64 均替换为你自己的可用图片。 ```json { "model": "YOUR_MULTIMODAL_MODEL", "input": [ { "text": "海滩上的日落" }, { "image": "https://example.com/beach.jpg" }, { "image": "<完整的 Base64 图片>" } ], "dimensions": 512, "normalized": true } ``` ## 重新排序 先从模型目录确认可用的 Rerank 模型;没有可用项时联系支持开通。仅支持 Embedding 的模型不能用于 Rerank。 ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/rerank' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "YOUR_MODEL", "query": "What is the capital of France?", "documents": [ "Paris is the capital of France.", "Berlin is in Germany." ] }' ``` `model`、`query` 和 `documents` 必填。`top_n` 可限制返回条数,`return_documents` 可请求携带候选正文;具体支持情况见所选模型。下面是响应结构示例,分数为示意值: ```json {"model":"YOUR_MODEL","results":[{"index":0,"relevance_score":0.96},{"index":1,"relevance_score":0.12}]} ``` 按 `results` 中的顺序读取重排结果,通过 `index` 回查原始 `documents`。`relevance_score` 是模型给出的相关性分数,不应当作概率。完整字段见 [Rerank API](/docs/zh/api-reference?operation=createUnifiedV1Rerank)。 响应中的 `index` 指向请求中的原始候选位置,不是文档 ID。Rerank 分数只用于当前模型的排序,不用于跨模型比较。 # 生成与编辑图片 URL: https://creative-reasoning.com/docs/zh/images-image-edit 图片生成和编辑都返回任务 ID。提交后查询同一任务,完成后读取图像。 ## 准备 API Key 在 [API Key 页面](https://creative-reasoning.com/console/keys)创建或复制完整 API Key,将 `API_KEY` 替换为密钥。不要使用 Key 前缀或 API Key ID。以下请求使用生产 API `https://api.creative-reasoning.com`。 ## 生成图像 ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/images/tasks' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "creative-reasoning-image-1.5", "prompt": "白色背景上的蓝色陶瓷杯", "n": 1, "size": "1024x1024", "quality": "low" }' ``` 首次受理返回 HTTP `202`。下面是响应结构示例,ID 为示意值。保存实际响应的 `id`;`pending` 表示等待执行,还没有生成结果。 ```json { "id": "01a09ec9-7d00-7000-8000-000000000001", "status": "pending", "created_at": 1789370400, "model": "creative-reasoning-image-1.5", "poll_url": "/unified/v1/tasks/01a09ec9-7d00-7000-8000-000000000001" } ``` ## 查询并读取结果 用响应中的 `id` 替换 `TASK_ID_FROM_SUBMIT_RESPONSE`,并使用提交时的同一 API Key: ```bash curl 'https://api.creative-reasoning.com/unified/v1/tasks/TASK_ID_FROM_SUBMIT_RESPONSE' \ -H 'Authorization: Bearer API_KEY' ``` 查询返回 HTTP `200` 时,仍需判断 `status`。`pending`、`processing` 表示继续等待,可每隔 5 秒查询一次并设置总等待上限;到期后保留 ID,稍后继续查询。`failed` 表示生成失败,读取 `error.code` 和 `error.message`。只有 `completed` 才读取 `data`。 下面是完成响应的结构示例,媒体内容及 URL 凭证均为占位值: ```json { "id": "01a09ec9-7d00-7000-8000-000000000001", "status": "completed", "created_at": 1789370400, "model": "creative-reasoning-image-1.5", "completed_at": 1789370460, "data": [ { "b64_json": "BASE64_IMAGE_DATA" } ] } ``` 逐项读取 `data`:有 `b64_json` 时 Base64 解码成图片文件;若包含 `data:image/...;base64,` 前缀,先去掉前缀。有 `url` 时使用完整链接下载。`BASE64_IMAGE_DATA` 不是可解码的图片。任务终态正文保留 24 小时,及时保存图片到自己的存储。 ## 编辑图像 下面通过 JSON 的 `image` 提供待编辑图片。把 `https://customer.example.com/assets/cup.png` 换成你自己的、CR 可直接访问的图片 URL;也可使用 Base64 Data URI。接口不接收 multipart 表单。 ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/images/edit-tasks' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "creative-reasoning-image-1.5", "prompt": "将杯子改为红色,保持其余画面不变", "n": 1, "size": "1024x1024", "quality": "low", "image": "https://customer.example.com/assets/cup.png" }' ``` 保存这次编辑响应的新 `id`,用上面的查询请求读取编辑结果。`image` 也可以是图片地址数组,用于多图合成;单图局部编辑可提供 `mask`。详细取值见 [Image 1.5 参数](/docs/zh/media-tasks#creative-reasoning-image-15)。 ## 按方向扩展画布 扩图只适用于明确支持 `image_outpaint` 的模型。`model` 决定操作,`expansion` 描述扩展范围;普通图片生成或编辑模型不会因为传入 `expansion` 而获得扩图能力。 先用自己的模型调用 API Key 查询可用模型。把 `API_KEY` 换成在 [CR 控制台](https://creative-reasoning.com) 创建的 API Key;它不是 Management Token。 ```bash curl 'https://api.creative-reasoning.com/unified/v1/models?capability=image_outpaint' \ -H 'Authorization: Bearer API_KEY' ``` 响应 `data[].id` 是可用于调用的模型名称,`data[].capabilities.image_outpaint` 给出该模型的扩图参数边界。空列表表示当前 API Key 没有可用扩图模型,请联系管理员确认权限与可用性。 取得模型名称后,登录[扩图模型接入文档](https://creative-reasoning.com/docs/zh/models?type=image_outpaint),按该名称查找并打开对应模型的详细页。该页提供绑定到具体调用名称的参数表、完整请求、任务查询、结果解释、错误处理与计费说明。使用其中的扩图示例,不要直接替换成本页普通图片生成或编辑示例中的模型名称。 目录默认只展示模型广场中的模型。如果发现接口返回的名称不在目录中,可直接打开 `https://creative-reasoning.com/docs/zh/models/calling/YOUR_MODEL`。将 `YOUR_MODEL` 替换为 `data[].id`,并按 URL 路径段编码,例如将 `/` 编码为 `%2F`。详细页仍需登录,并按当前账号权限展示;若无法访问,请联系管理员核对账号与 API Key 所属团队的权限。 ## 用蒙版指定编辑区域 `creative-reasoning-image-1.5` 支持蒙版编辑。准备与原图像素宽高相同的 PNG 蒙版:需要修改的区域设为完全透明(Alpha = 0),保留区域设为不透明(Alpha = 255)。只有黑白颜色、没有透明区域的图片不能表示这一选区。蒙版引导模型编辑,但不保证蒙版外像素逐点不变。 把下面两个素材 URL 替换为你自己的、CR 可直接访问的原图与蒙版地址。蒙版不是生成图片的透明背景设置,也不要放进 `provider_options`。 ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/images/edit-tasks' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "creative-reasoning-image-1.5", "image": "https://customer.example.com/assets/source.png", "mask": {"image_url": "https://customer.example.com/assets/mask.png"}, "prompt": "移除蒙版透明区域内的目标,并根据周围内容自然补全背景。不要添加替代目标,尽量保持蒙版外的内容、构图和光线不变。" }' ``` 保存提交响应的 `id`,按本页查询步骤使用同一 API Key 获取任务结果;HTTP `202` 仅表示受理。下载后的蒙版必须是有效的透明 PNG,宽高与第一张原图相同;素材每个不超过 50 MiB,蒙版不超过 67,108,864 像素。格式、尺寸或透明选区不正确时,读取提交错误或任务 `error.message`,修正素材后再提交。 `mask` 的对象形式与 OpenAI 图片编辑 JSON 接口的 `image_url` 形式一致。CR 也保留字符串简写:`"mask":"https://customer.example.com/assets/mask.png"`。两者均可使用 Base64 Data URI;不支持 `file_id`、蒙版数组或同时混用多个引用字段。字符串简写是 CR 统一接口的兼容格式。 ## 调整图片参数 `size` 使用像 `1024x1024` 这样的像素尺寸;`quality` 可选择 `low`、`medium`、`high`。修改尺寸时同时满足边长、比例和像素总数限制,见[完整模型参数表](/docs/zh/media-tasks#creative-reasoning-image-15)。更换模型时重新核对其支持范围。 ## 回调与失败恢复 - 可在提交正文顶层添加自己的 HTTPS `callback_url`。收到的终态与查询结果相同;以任务 `id` 去重。地址约束和重投规则见[回调说明](/docs/zh/media-tasks#使用-callback_url-接收通知)。 - 需要安全重试提交时,添加 `Idempotency-Key: YOUR_UNIQUE_OPERATION_ID`。这是调用方为本次业务操作生成并保存的唯一编号,不是密钥。相同操作重试必须复用该编号和原请求正文。 - 已有任务 ID 时查询原任务。没有幂等键且提交超时时,不要盲目重发 POST,以免重复生成和计费。 - `401` 检查 API Key;`404` 查询时检查 ID 和是否使用原 Key;`failed` 读取错误原因;`410 task_expired` 表示结果正文已过期。完整恢复规则见[任务错误与幂等提交](/docs/zh/media-tasks#避免重复生成与处理错误)。 ## 兼容接口 已有接入可继续使用 `/unified/v1/images/generations` 和 `/unified/v1/images/edits`。它们可能直接返回图片,也可能返回任务;详情见[兼容响应处理](/docs/zh/media-tasks#图片生成与编辑兼容接口)。迁移到本页接口后,提交先返回任务,必须按上文查询结果。 ## 图片与视频 Skill 需要让 Claude Code 或 Codex 用自然语言生成、编辑图片和视频时,安装 [cr-media Skill](/docs/zh/integrations/cr-media)。该指南包含插件与 `npx skills` 安装、升级、API Key 配置,以及本地参考图和 URL 的使用限制。 # 调用文本模型 URL: https://creative-reasoning.com/docs/zh ## API Key 认证 在 [API Key 页面](https://creative-reasoning.com/console/keys)获取完整 API Key,替换示例中的 `API_KEY`。请求头使用 `Authorization: Bearer API_KEY`;Key 前缀、API Key ID 和 Management Token 不能作为模型调用凭据。 ## 发送请求 在下方选择模型,复制并运行 cURL。若示例包含 `YOUR_MODEL`,将它替换为[模型目录](https://creative-reasoning.com/models)中支持 Chat Completions 的模型名称。 ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/chat/completions' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "YOUR_MODEL", "messages": [ { "role": "user", "content": "Hello" } ] }' ``` HTTP `200` 表示请求成功;模型输出位于 `choices[0].message.content`。请求字段与响应结构见[API 参考](/docs/zh/api-reference)。 下面是响应结构示例,仅展示读取回复需要的字段,文本内容以实际返回为准: ```json { "choices": [{ "index": 0, "message": {"role": "assistant", "content": "Hello! How can I help you?"}, "finish_reason": "stop" }] } ``` 游客的模型目录只展示名称以 `creative-reasoning` 开头且已上架的系列模型;其他模型需登录后按账号权限查看。目录可见不代表 API Key 有调用权限。程序可通过[模型发现接口](https://creative-reasoning.com/docs/zh/api-reference#tag/llm/GET/unified/v1/models)查询当前 API Key 可访问的文本模型及已知上下文上限。 ## 流式输出 需要逐段显示回复时,使用 `stream: true`。cURL 的 `-N` 让终端及时显示收到的数据: ```bash curl -N -X POST 'https://api.creative-reasoning.com/unified/v1/chat/completions' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "YOUR_MODEL", "messages": [{"role": "user", "content": "Hello"}], "stream": true }' ``` 响应使用 SSE。逐条解析 `data:` 中的 JSON。`data: [DONE]` 表示响应结束,不是 JSON。 下面是只保留相关字段的事件结构示例。事件之间由空行分隔,一次网络读取可能只包含半个事件,也可能包含多个事件: ```text data: {"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]} data: {"choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]} data: {"choices":[{"index":0,"delta":{"content":"!"},"finish_reason":null}]} data: {"choices":[{"index":0,"delta":{},"finish_reason":"stop"}]} data: [DONE] ``` 按 `choices[].index` 分别累加 `delta.content`,上例得到 `Hello!`。流式文本使用 `delta.content`;`message.content` 用于非流式响应。角色事件、空 `delta`、仅包含用量的事件可能没有文本,应跳过文本追加,继续处理事件中的其他字段。工具调用增量见[工具调用](/docs/zh#工具调用)。 `finish_reason: "stop"` 表示该条回复正常结束;`length` 表示输出达到限制,应将内容视为截断;`tool_calls` 表示需要处理工具请求;`content_filter` 表示内容被过滤。收到 `[DONE]` 后结束读取。出现 `error` 事件或连接在结束标记前断开时,将已收片段视为不完整结果,按[流式错误处理](/docs/zh/troubleshooting#流式过程中的错误)恢复,不要把 HTTP `200` 或连接关闭本身当作成功完成。 ## 工具调用 Chat Completions 使用 `tools` 声明工具。选择支持工具调用的模型,将 `YOUR_MODEL` 替换为其名称: ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/chat/completions' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "YOUR_MODEL", "messages": [{"role": "user", "content": "What is the weather in Singapore?"}], "tools": [{"type": "function", "function": { "name": "lookup_weather", "description": "Read a weather summary for a city.", "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]} }}] }' ``` 模型直接回复时读取 `message.content`;请求工具时读取 `choices[].message.tool_calls`。应用解析并校验 `function.arguments` 中的 JSON 字符串,执行后保留完整 assistant 消息,再为每项调用追加一条 `role: "tool"` 消息。以下是需要追加的结果结构,将 `TOOL_CALL_ID_FROM_RESPONSE` 替换为该项的 `tool_calls[].id`,`content` 替换为实际工具结果字符串: ```json {"role":"tool","tool_call_id":"TOOL_CALL_ID_FROM_RESPONSE","content":"{\"city\":\"Singapore\",\"summary\":\"Warm with light rain\"}"} ``` 使用相同的 `model`、`tools` 和补全后的 `messages` 再次请求,直到返回最终文本或达到应用设置的轮数与时间上限。流式调用按 `choices[].index` 和 `delta.tool_calls[].index` 累积参数片段;收到完整参数并确认该轮正常结束后才解析和执行,连接中断时不执行半截参数。工具由应用执行;有副作用的操作由应用负责授权与去重。字段定义见 [Chat Completions API](/docs/zh/api-reference?operation=createUnifiedV1ChatCompletions)。 ## 使用 Responses 继续对话 选择支持 Responses 的模型,将它的名称用于 `YOUR_MODEL`。Responses 通过响应 ID 继续对话,认证仍使用本页的 API Key。 ### 创建第一个响应 ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/responses' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "YOUR_MODEL", "input": "Hello" }' ``` 成功响应中的 `id` 用于继续对话。文本回复位于 `output` 数组中 `type: "message"` 的条目内,再读取其 `content` 中 `type: "output_text"` 的 `text`。以下为响应结构示例,仅展示相关字段: ```json { "id": "resp_example", "output": [{ "type": "message", "role": "assistant", "content": [{"type": "output_text", "text": "Hello! How can I help you?"}] }] } ``` ### 使用响应 ID 继续对话 将 `RESPONSE_ID_FROM_PREVIOUS_CALL` 替换为上一条真实响应的 `id`,使用相同模型继续对话。上面的 `resp_example` 仅用于说明结构,不能用于请求。 ```bash curl "https://api.creative-reasoning.com/unified/v1/responses" \ -H "Authorization: Bearer API_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"YOUR_MODEL","previous_response_id":"RESPONSE_ID_FROM_PREVIOUS_CALL","input":"Summarize the previous answer in one sentence."}' ``` `previous_response_id` 只能与创建该响应的 API Key 一起使用。换用其他 API Key 会返回 404。 ### 处理过期状态 收到 404 时,先检查模型、`previous_response_id` 和 API Key。如果状态已过期,使用应用保存的历史重新构建输入,不要继续重试该 ID。 ## 统一推理参数 Chat Completions 使用顶层 `reasoning_effort`: ```json { "model": "YOUR_MODEL", "messages": [{"role": "user", "content": "你好"}], "reasoning_effort": "low" } ``` Responses 使用 `reasoning.effort`: ```json { "model": "YOUR_MODEL", "input": "你好", "reasoning": {"effort": "low"} } ``` CR 接受 `none`、`minimal`、`low`、`medium`、`high`、`xhigh` 和 `max`。它们是强度档位,不是跨模型统一的 token 数;模型可能只支持其中一部分。`none` 表示请求关闭推理,省略字段则保留模型默认行为。 新接入按所用接口选择上面的一种写法。`low` 不代表固定 token 数,也不保证固定响应时间。输入长度、模型负载和实际生成量都会影响耗时。 非法档位或类型返回 `400 invalid_reasoning_parameters`。已确认不支持的档位返回 `400 unsupported_reasoning_parameters`;部分模型由模型服务校验并返回参数错误。错误处理见[错误说明](/docs/zh/troubleshooting#错误响应格式)。 ## 认证错误 | 状态码 | 含义 | 检查项 | | --- | --- | --- | | `401` | API Key 缺失、格式错误、无效或已过期 | 检查 `Authorization` 请求头和完整的 API Key | | `403` | 请求被模型权限或余额/透支策略拒绝 | 检查模型名称、API Key 的模型权限和可用额度 | 修正认证和权限后再重试。其他状态码和重试方式见[错误处理与重试](/docs/zh/troubleshooting)。 ## 保存与轮换 API Key 在服务端或受控本地环境中通过密钥管理系统加载 API Key,不将密钥放入 URL、客户端包、Git 或日志。排障记录使用 Key 前缀或 API Key ID。 轮换时创建新 API Key,更新应用并发送一个最小请求。确认所有应用实例均使用新 Key 后,再停用旧 Key。 ## 继续接入 - 需要配置客户端,查看 [Codex、Claude Code 和 SDK 接入](/docs/zh/integrations)。 - 需要核对单价或费用,查看[调用账单与有效价格](/docs/zh/request-billing)。 - 请求失败时,按[错误处理与重试](/docs/zh/troubleshooting)处理。 ## 供开发工具与 AI 读取 [文档索引](https://creative-reasoning.com/llms.txt)列出可直接读取的 Markdown 页面;[完整指南](https://creative-reasoning.com/llms-full.txt)包含公开正文。[模型调用 OpenAPI](https://creative-reasoning.com/docs-openapi/dataplane.zh.json)和[管理 API OpenAPI](https://creative-reasoning.com/docs-openapi/management.zh.json)提供机器可读的参数、响应和错误定义。需登录的内容不进入这些公开导出。 # Claude Code 接入 URL: https://creative-reasoning.com/docs/zh/integrations/claude-code 在 [API Key 页面](https://creative-reasoning.com/console/keys)创建或复制完整 API Key,用它替换本页的 `API_KEY`。API Key ID、前缀和管理 Token 不能用于模型调用。 ## 配置 Claude Code 下面的命令适用于 macOS、Linux 和 WSL。将 `OPUS_MODEL`、`SONNET_MODEL`、`HAIKU_MODEL` 替换为[模型目录](https://creative-reasoning.com/models)中支持 Anthropic Messages、流式输出和工具调用的模型名称;三项可以使用同一个模型。 替换 `API_KEY` 和模型名称后,复制整段到终端执行。命令会创建或覆盖 `~/.claude/settings.json`;如果已有自定义配置,请先备份。 ```bash mkdir -p ~/.claude && cat > ~/.claude/settings.json <<'EOF' { "env": { "ANTHROPIC_BASE_URL": "https://api.creative-reasoning.com", "ANTHROPIC_AUTH_TOKEN": "API_KEY", "ANTHROPIC_DEFAULT_OPUS_MODEL": "OPUS_MODEL", "ANTHROPIC_DEFAULT_SONNET_MODEL": "SONNET_MODEL", "ANTHROPIC_DEFAULT_HAIKU_MODEL": "HAIKU_MODEL", "CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS": "1" }, "model": "sonnet" } EOF ``` `sonnet` 是 Claude Code 的客户端选项,使用 `ANTHROPIC_DEFAULT_SONNET_MODEL` 配置的模型。需要默认使用 Opus 时,将 `model` 改为 `opus`。API Key 已写入用户配置,启动时直接运行: ```bash claude ``` ## 启动并验证 1. 启动 Claude Code,然后运行 `/status`,确认当前模型。 2. 完成一个短任务,验证流式输出和一次工具调用。 3. 如果请求失败,按[错误处理与重试](/docs/zh/troubleshooting)保留状态码、模型名称和 CR 请求 ID。 ## Claude Code 配置约束 - 接入 CR 时,保留 `CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS` 为字符串 `"1"`。它关闭实验性的 `anthropic-beta` 请求头及 beta 工具字段,避免兼容入口拒绝不支持的字段。详见 [Claude Code 环境变量说明](https://code.claude.com/docs/en/env-vars)。 - `settings.json` 是标准 JSON,不能包含注释。 - `ANTHROPIC_BASE_URL` 只填写 HTTPS API Base URL,不追加 API 路径。 - 只有模型详情明确支持 1M 上下文时,才可在 `ANTHROPIC_DEFAULT_OPUS_MODEL` 或 `ANTHROPIC_DEFAULT_SONNET_MODEL` 的值后追加 `[1m]`;不要用于 `ANTHROPIC_DEFAULT_HAIKU_MODEL`。 ## 图片与视频 Skill 需要让 Claude Code 或 Codex 用自然语言生成、编辑图片和视频时,安装 [cr-media Skill](/docs/zh/integrations/cr-media)。该指南包含插件与 `npx skills` 安装、升级、API Key 配置,以及本地参考图和 URL 的使用限制。 # Codex 接入 URL: https://creative-reasoning.com/docs/zh/integrations/codex 在 [API Key 页面](https://creative-reasoning.com/console/keys)创建或复制完整 API Key,用它替换本页的 `API_KEY`。API Key ID、前缀和管理 Token 不能用于模型调用。 ## 配置 Codex 从[模型目录](https://creative-reasoning.com/models)选择支持 Responses API、流式输出和工具调用的模型,将其名称填入 `YOUR_MODEL`,再将以下内容合并到用户配置 `~/.codex/config.toml`: ```toml model = "YOUR_MODEL" model_provider = "creative_reasoning_router" [model_providers.creative_reasoning_router] name = "Creative Reasoning Router" base_url = "https://api.creative-reasoning.com" env_key = "CRR_API_KEY" wire_api = "responses" ``` 本页使用生产网关根地址。Codex 会在 `base_url` 后追加 `/responses`,不需要手动添加该操作路径。 `env_key` 是环境变量名称。设置该变量并启动 Codex: ```bash export CRR_API_KEY="API_KEY" codex ``` ## 启动并验证 1. 确认 Codex 显示配置的模型。 2. 完成一个短任务,并验证一次工具调用。 3. 如果请求失败,按[错误处理与重试](/docs/zh/troubleshooting)保留状态码、模型名称和 CR 请求 ID。 ## Codex 配置约束 - 将 `model` 和 `model_provider` 放在第一个 TOML 表之前,并保留已有配置。 - `base_url` 使用本页示例的根地址,不包含具体操作路径。 - 保持 `wire_api = "responses"`。 ## 图片与视频 Skill 需要让 Claude Code 或 Codex 用自然语言生成、编辑图片和视频时,安装 [cr-media Skill](/docs/zh/integrations/cr-media)。该指南包含插件与 `npx skills` 安装、升级、API Key 配置,以及本地参考图和 URL 的使用限制。 # 图片与视频 Skill URL: https://creative-reasoning.com/docs/zh/integrations/cr-media [cr-skills](https://github.com/bmrlab/cr-skills) 提供 `cr-media`,让 Agent 按模型能力生成或编辑图片、生成视频、使用首尾帧或参考图,以及编辑视频。它包含调用脚本和模型参数说明,脚本负责提交任务、轮询与下载。 你可以直接把仓库链接发给自己的 Agent,让它按 README 安装。模型支持范围随 Skill 版本更新;实际可调用的模型仍取决于 API Key 权限,可在[模型目录](https://creative-reasoning.com/models)查看。 ## 安装与升级 以下方式选一种即可。脚本运行需要 Bash、`curl`、`jq`、`ffprobe`(来自 FFmpeg)、`file` 和 `base64`;仓库提供的是 Bash 脚本,Windows 请在 WSL 中使用。 ### 使用 npx skills 本机已安装 Node.js 和 npm 时,在项目目录运行: ```bash npx skills add https://github.com/bmrlab/cr-skills --skill cr-media ``` 按提示选择 Claude Code 或 Codex,也可添加 `--agent claude-code` 或 `--agent codex` 指定客户端。默认安装到当前项目;需要在所有项目中使用时添加 `-g`。 此方式安装独立 Skill,包含脚本和参考资料。它由 `skills` 管理,不登记到客户端的插件市场。更新当前项目中的 Skill: ```bash npx skills update cr-media -p ``` 全局安装使用 `npx skills update cr-media -g`。安装或更新后,在相应项目中打开新的 Agent 会话。 ### 使用 Claude Code 插件 在终端运行: ```bash claude plugin marketplace add bmrlab/cr-skills claude plugin install cr-media@cr ``` 之后用 `claude plugin update cr-media@cr` 更新,再重启 Claude Code。也可在 `/plugin` 的 Marketplaces 中为 `cr` 开启自动更新。 ### 使用 Codex 插件 在支持插件命令的 Codex CLI 中运行: ```bash codex plugin marketplace add bmrlab/cr-skills codex plugin add cr-media@cr ``` 之后按仓库 README 使用 `codex plugin marketplace upgrade cr` 刷新,并打开新的 Codex 会话。若客户端没有 `codex plugin` 命令,使用上面的 `npx skills` 方式。 ## 配置 API Key 在 [API Key 页面](https://creative-reasoning.com/console/keys)创建或复制完整 API Key,替换下面的 `API_KEY`。API Key ID、Key 前缀和 Management Token 不能用于模型调用。 ```bash mkdir -p ~/.config/cr printf 'CR_API_KEY=%s\n' 'API_KEY' > ~/.config/cr/env chmod 600 ~/.config/cr/env ``` 命令会写入或覆盖该配置文件。脚本优先读取环境变量 `CR_API_KEY`,未设置时读取 `~/.config/cr/env`,请求发往 `https://api.creative-reasoning.com`。Claude Code 的 `ANTHROPIC_AUTH_TOKEN` 和 Codex 文本模型配置中的其他变量不会自动作为此 Skill 的密钥。 ## 生成与读取结果 在 Agent 的新会话中提出任务,例如: ```text 使用 cr-media 生成一张白色背景上的蓝色陶瓷杯图片,保存到 ./cr-output, 文件名前缀为 cup。先核对模型支持的尺寸和参数,完成后给出文件路径、 实际尺寸、格式和任务 ID,并打开图片检查内容。 ``` 生成视频时,说明画面、时长、比例、是否需要声音,以及使用首帧还是参考图。Agent 应根据 Skill 随附的[图片模型说明](https://github.com/bmrlab/cr-skills/blob/main/plugins/cr-media/skills/cr-media/references/image-models.md)或[视频模型说明](https://github.com/bmrlab/cr-skills/blob/main/plugins/cr-media/skills/cr-media/references/video-models.md)选取参数。`--dry-run` 只打印请求,不提交生成;正式生成按模型实际用量计费。 脚本默认将结果保存到当前目录下的 `./cr-output`,也可指定其他目录。完成后核对摘要与实际文件: | 结果 | 读取方式 | | --- | --- | | 图片 | `files[].file` 是本地文件路径,`size` 和 `mime` 是检测到的尺寸与格式;打开图片确认内容 | | 视频 | `file` 是本地文件路径,`duration_s`、`size`、`fps`、`audio` 用于核对成片;播放或抽帧确认内容 | | 任务记录 | `.json` 保存请求与响应,`name` 是指定的文件名前缀;提交成功后可从 `submit.id` 取得任务 ID | 若任务完成但文件下载或解码失败,保留任务 ID,从原任务结果重新下载。图片摘要的 `size` 为 `unknown`,或 `mime` 不是图片类型时,先检查文件内容,不能仅凭任务完成判断文件可用。 任务仍在处理、等待超时或会话中断时,让 Agent 从记录中读取原任务 ID,使用 `cr-image --resume` 或 `cr-video --resume` 继续查询。恢复时使用原 API Key;不要把重新运行生成命令当成继续等待。任务失败时读取记录中的 `final.error`;提交报错查看 `submit`。具体状态和恢复规则见[异步任务说明](/docs/zh/media-tasks#避免重复生成与处理错误)。 ## 先生成图片,再生成视频 先确认目标视频模型的图片输入格式。脚本会把本地图片转换成 `data:image/...;base64,...`,但只有接受 Data URI 的模型才能直接使用;脚本能转换文件不代表模型支持该格式。 - 目标模型接受 Data URI 时,可以把刚生成的本地图片交给 Agent,作为首帧、尾帧或参考图。 - 目标模型仅接受 HTTP(S) URL 时,提供它可直接读取的图片地址。如果生图响应已有可用的 `data[].url`,可在有效期内复用;如果只有本地文件或 `b64_json`,需要先将图片保存到自己管理的可访问存储。Skill 不提供图床或自动上传服务。 - 出现 `URL scheme must be HTTP(S)` 时,检查输入格式;反复提交同一份 Base64 无法解决该错误。具体支持范围查看当前模型说明,不将某个模型的限制推广到所有图片或视频模型。 直接通过 HTTP 接入时,参见[生成与编辑图片](/docs/zh/images-image-edit)和[生成视频](/docs/zh/video-async)。 # 开发工具与 SDK URL: https://creative-reasoning.com/docs/zh/integrations ## 选择客户端 以下是各接入示例使用的生产地址: | 使用方式 | 协议 | 客户端 Base URL | 接入说明 | | --- | --- | --- | --- | | Codex | Responses | `https://api.creative-reasoning.com` | [Codex 接入](/docs/zh/integrations/codex) | | Claude Code | Anthropic Messages | `https://api.creative-reasoning.com` | [Claude Code 接入](/docs/zh/integrations/claude-code) | | Python/JavaScript 应用 | OpenAI 兼容 SDK | `https://api.creative-reasoning.com/unified/v1` | [SDK 接入](/docs/zh/integrations/sdk) | ## 图片与视频 Skill 需要让 Claude Code 或 Codex 用自然语言生成、编辑图片和视频时,安装 [cr-media Skill](/docs/zh/integrations/cr-media)。该指南包含插件与 `npx skills` 安装、升级、API Key 配置,以及本地参考图和 URL 的使用限制。 # SDK 接入 URL: https://creative-reasoning.com/docs/zh/integrations/sdk ## 设置环境变量 ```bash export CR_API_KEY="API_KEY" export CR_MODEL="YOUR_MODEL" ``` 将 `API_KEY` 替换为从 [API Key 页面](https://creative-reasoning.com/console/keys)复制的完整 API Key,将 `YOUR_MODEL` 替换为[模型目录](https://creative-reasoning.com/models)中支持 Chat Completions 的模型名称。Python 的 `base_url` 和 JavaScript 的 `baseURL` 已填写生产地址 `https://api.creative-reasoning.com/unified/v1`,SDK 会追加操作路径。 ## Python 安装 OpenAI Python SDK: ```bash python -m pip install openai ``` ```python import os from openai import OpenAI client = OpenAI( api_key=os.environ["CR_API_KEY"], base_url="https://api.creative-reasoning.com/unified/v1", ) response = client.chat.completions.create( model=os.environ["CR_MODEL"], messages=[{"role": "user", "content": "Reply with one short sentence."}], ) print(response.choices[0].message.content) ``` ## JavaScript 安装 OpenAI JavaScript SDK: ```bash npm install openai ``` ```javascript import OpenAI from "openai"; const { CR_API_KEY, CR_MODEL } = process.env; if (!CR_API_KEY || !CR_MODEL) { throw new Error("CR_API_KEY and CR_MODEL are required"); } const client = new OpenAI({ apiKey: CR_API_KEY, baseURL: "https://api.creative-reasoning.com/unified/v1", }); const response = await client.chat.completions.create({ model: CR_MODEL, messages: [{ role: "user", content: "Reply with one short sentence." }], }); console.log(response.choices[0].message.content); ``` 需要增量结果时,查看[文本模型调用](/docs/zh#流式输出)。请求失败时,查看[错误处理与重试](/docs/zh/troubleshooting)。 ## 获取模型名称和上限 Python 使用 `client.models.list()`,JavaScript 使用 `await client.models.list()`。列表只包含当前 API Key 可发现的已上架文本模型。CR 的上下文与输出上限属于扩展字段;客户端是否自动使用它们取决于实现。原始 JSON 字段及手动配置说明见[模型发现 API](https://creative-reasoning.com/docs/zh/api-reference#tag/llm/GET/unified/v1/models)。 # 管理 API Key 与查询用量 URL: https://creative-reasoning.com/docs/zh/manage-api-keys ## 凭据与权限 本页请求使用管理 Token,不能用模型 API Key 代替。请管理员按操作授予所需 scope;读、写和用量汇总权限相互独立,写权限不隐含读权限。 | 操作 | 所需 scope | | --- | --- | | 列出 API Key、查询额度和预算状态 | `api_keys:read` | | 创建或撤销 API Key、设置预算 | `api_keys:write` | | 查询历史用量汇总 | `usage:aggregate` | API Key 管理使用绑定目标团队的管理 Token。`api_keys:write` 还允许读取完整密钥和移除预算限制,只交给可信后端。组织 Token 不能管理 Key。将 `YOUR_MANAGEMENT_TOKEN` 替换为具有当前操作权限的完整管理 Token。 ## 取得团队编号和 API Key ID 本页金额统一使用与控制台一致的 **Credits(ℂ)**,以精确十进制字符串返回,最多六位小数。成功响应通过 `X-CRR-Credit-Unit: credits` 标明金额单位;汇总响应的 `schema_version` 为 `2`。 1. 在[管理控制台](https://creative-reasoning.com/)打开目标团队,点击团队名称下方的编号,复制纯编号,例如 `T-TU214G`。替换请求路径中的 `TEAM_CODE`。这是团队编号,不是组织编号,也不是团队 UUID。 2. 打开该团队的 **API Key** 页签,找到目标 API Key,选择 **更多 → 复制 API Key ID**。用该 UUID 替换请求中的 `API_KEY_ID`。该按钮只复制已有资源 ID,不读取密钥明文;**复制 API Key** 是另一项敏感操作。 本页请求使用生产管理服务 `https://creative-reasoning.com`。服务端也可以用具有 `api_keys:read` 的管理 Token 列出 API Key: ```bash curl \ -H "Authorization: Bearer YOUR_MANAGEMENT_TOKEN" \ "https://creative-reasoning.com/api/v1/management/teams/TEAM_CODE/api-keys" ``` HTTP 200 返回数组。选择目标项的 `id` 作为 `API_KEY_ID`,用 `label` 和 `key_prefix` 辅助辨认;不要拿前缀代替 ID。列表不返回密钥明文,也不需要 `api_keys:write`。创建响应的 `id` 是同一个资源 ID,无需创建新 Key 来查询旧 Key。 API Key ID 只是 API Key 的属性,不能调用模型。模型调用使用 API Key 明文;本页管理操作使用请求头中的管理 Token。响应中的 `team_id` 仍是团队 UUID,不能放回要求 `team_code` 的路径。 ## 创建服务专用 Key 需要 `api_keys:write`。 若服务不需要预支,显式发送 `overdraft_enabled: false`。省略该字段会继承团队和组织的有效预支开关;启用预支而未指定上限时,Key 级上限默认为无限。 ```bash curl \ -X POST \ -H "Authorization: Bearer YOUR_MANAGEMENT_TOKEN" \ -H 'Content-Type: application/json' \ -d '{"label":"batch-worker","overdraft_enabled":false}' \ "https://creative-reasoning.com/api/v1/management/teams/TEAM_CODE/api-keys" ``` 在 HTTP 201 响应中保存 `id` 和 `key`。`id` 是 API Key ID(UUID),用它替换后续请求中的 `API_KEY_ID`;它不是凭据,不能调用模型。`key` 是 API Key 明文,存入秘密管理系统供服务调用模型。以下管理操作继续使用管理 Token。 ## 设置周期消费预算 在把 Key 交给服务前设置预算。创建 Key 和设置预算是两次独立操作;预算请求失败时,不要启动该 Key 的工作负载。 不改变起算点时,不发送 `starts_at`。首次设置默认从请求时刻起算,更新时保留原起算点。显式修改该字段会重新选择消费统计范围。 ```bash curl \ -X PUT \ -H "Authorization: Bearer YOUR_MANAGEMENT_TOKEN" \ -H 'Content-Type: application/json' \ -d '{"amount":"1000","window_days":7,"is_enabled":true}' \ "https://creative-reasoning.com/api/v1/management/teams/TEAM_CODE/api-keys/API_KEY_ID/budgets/windowed" ``` 核对 HTTP 200 响应中的 `amount`、`window_days` 和 `starts_at`。金额输入和输出均使用 Credits(ℂ);本例设置的预算为 `1000 ℂ`,周期为固定 7 天。预算 `amount` 和 Key 的 `overdraft_limit` 必须是 `0.000005 ℂ` 的整数倍,最大 `49999999999999.999995 ℂ`;超出范围或精度要求的输入返回 400,不自动舍入。总额预算改用 `budgets/all_time`,并省略 `window_days`。 若要展示已用、剩余和下次重置时间,另外申请独立的 `api_keys:read`,按下节查询剩余额度与重置时间。写权限不包含读权限。预算配置成功不代表策略已同步到所有模型请求。 ## 查询剩余额度与重置时间 需要 `api_keys:read`。 ```bash curl \ -H "Authorization: Bearer YOUR_MANAGEMENT_TOKEN" \ "https://creative-reasoning.com/api/v1/management/teams/TEAM_CODE/api-keys/API_KEY_ID/quota" ``` 从 HTTP 200 响应中读取 `available_credits`,以及 `overdraft.remaining_credits`。查看本周期消费和余额时,读取 `budgets.windowed.used_credits` 和 `remaining_credits`;查看重置时间时,读取 `resets_at`。 按以下边界展示查询结果: - 额度字段的单位是 Credits,不是模型 token 数。余额、预支余量、预算余额不可相加为一个可消费总额,也不能据此判定一定可调用。 - `all_time` 是自 `starts_at` 起的总额预算,不自动重置;`windowed` 是从该时刻起每 N 天重置的周期预算。未配置、停用或未开始时部分字段为 `null`,不要显示为零。重置不充值,也不清除预支欠款。 - 快照采用最终一致性。保留 `observed_at` 供展示,允许近期消费稍后出现。不要把查询结果作为同步放行依据。 字段状态、无限预支和空值的完整定义见[管理 API](/docs/zh/management-api)。 ## 查询历史 token 用量 查询历史报表需要独立的 `usage:aggregate`。可由管理员为同一个 Token 明确授予,或签发另一个仅有该 scope 的 Token;`api_keys:read` 不隐含此权限。 请求中的 `start` 与 `end` 使用 RFC3339 时间。下面示例使用 `2026-08-31T16:00:00Z` 和 `2026-09-01T16:00:00Z`,表示上海时间 9 月 1 日全天。`Z` 表示 UTC,也可写显式偏移 `+08:00`。区间为 `[start, end)`,结束时刻不计入。 ```bash curl --get \ -H "Authorization: Bearer YOUR_MANAGEMENT_TOKEN" \ --data-urlencode "api_key_id=API_KEY_ID" \ --data-urlencode "start=2026-08-31T16:00:00Z" \ --data-urlencode "end=2026-09-01T16:00:00Z" \ --data-urlencode "timezone=Asia/Shanghai" \ "https://creative-reasoning.com/api/v1/management/usage/summary" ``` `timezone` 解释裸日期并决定时间分桶,不会重新解释 RFC3339 中的偏移。接口不接受 Unix 秒或毫秒数字。推荐程序始终发送带 `Z` 或偏移的 RFC3339;若使用 `YYYY-MM-DD`,`end` 会包含该日期全天,与精确时间的排他上界不同。 查看该时间段的总消费,读取 `totals.credits.after_discount`,单位为 Credits。例如 `"105.21352"` 表示消费 `105.21352 ℂ`,不是 token 数或人民币金额。分组时顶层 `totals` 仍覆盖整个过滤窗口,不是当前页之和。 查看 token 用量,读取 `totals.tokens.input`、`totals.tokens.output` 中各维度的整数字符串。不要把可能重叠的 token 维度相加。这些数值来自已完成文本账单,不代表完整模型用量;预算采用消费记账时间,与历史请求区间不一定一致。 仅查 embedding 时增加 `--data-urlencode "request_type=embedding"`。embedding 的已落定账单计入该 token 视图;缺失的计费维度不代表真实消耗为零。 若需要核对一次调用,保存模型响应中的 `x-cr-usage-id`,使用具有 `usage:read` 的 Token 调用[单条查账接口](/docs/zh/management-api?operation=getManagementRequestUsage)。 ## 服务下线后撤销 Key 先停止工作负载,再撤销 Key。撤销不取消已执行的请求或历史费用。 ```bash curl \ -X DELETE \ -H "Authorization: Bearer YOUR_MANAGEMENT_TOKEN" \ "https://creative-reasoning.com/api/v1/management/teams/TEAM_CODE/api-keys/API_KEY_ID" ``` HTTP 204 表示撤销成功,响应无正文。撤销 Key 不会撤销管理 Token;服务不再需要管理权限时,请管理员另行撤销该 Token。 若创建请求超时,先让有读权限的管理员核对结果,不要盲目重发。其余 Key 查询、修改、Reveal、预算删除及 Token 创建、修改、轮换方式见[管理 API](/docs/zh/management-api)。 ## 在控制台查看和设置 在[控制台 API Key 页面](https://creative-reasoning.com/console/keys)选择目标团队,按标签或前缀找到 Key。**设置**用于标签、透支和消费预算;**更多**提供查看用量、复制 API Key ID 和撤销操作。普通用户只能管理自己的 Key,其他操作按账号权限开放。 标签与透支使用 **保存设置**,每项预算分别使用 **保存预算**。加载预算失败不代表未设置预算;请先重试,再修改配置。撤销不可恢复,也不会删除历史费用。 ## 处理被拒绝的请求 先检查 HTTP 状态码和 `Content-Type`,再解析错误。将 `application/json` 解析为包含 `error` 字符串的对象。将 `text/plain` 视为诊断文本,不作为稳定错误码。 对于 JSON 请求,遇到 400 时修正语法,遇到 422 时修正字段类型或补齐必填字段,遇到 415 时修正 `Content-Type`。遇到 413 时缩小请求体。400 也可能表示 UUID 路径或业务规则无效。不要原样重试这些请求。额度与汇总的 422 含义不同,应按所调用操作的响应定义处理。 遇到 401,检查凭据类型、有效期和撤销状态;不要自动切换成 API Key 或 JWT。遇到 403,核对所需 scope。遇到 404,核对对象归属,仅对自己刚提交的调用做有限重试。遇到 422,缩小汇总范围;额度查询持续超限时联系管理员。遇到 429 或 503,按 `Retry-After` 退避并设置重试截止时间。 # 管理 API URL: https://creative-reasoning.com/docs/zh/management-api 管理 API 地址为 `https://creative-reasoning.com/api/v1/management`。在 [CR 控制台](https://creative-reasoning.com)管理团队、API Key 和管理 Token。 文档与 [OpenAPI JSON](/docs-openapi/management.zh.json) 可匿名阅读,业务接口仍要求管理 Token 或管理员登录 JWT。接入流程见[管理 API Key 与查询用量](/docs/zh/manage-api-keys)、[查询调用账单与价格](/docs/zh/request-billing)。 [下载 OpenAPI 3.1 契约(JSON)](https://creative-reasoning.com/docs-openapi/management.zh.json)。包含请求参数、响应结构与错误定义,可供开发工具和 AI 直接读取。 # 媒体任务参考 URL: https://creative-reasoning.com/docs/zh/media-tasks 本页集中说明模型参数、任务查询、结果字段、回调及幂等规则。首次接入请按[生成与编辑图片](/docs/zh/images-image-edit)或[生成视频](/docs/zh/video-async)完成一次调用。 ## 准备 API Key 本页示例使用生产 API `https://api.creative-reasoning.com`。在 [API Key 页面](https://creative-reasoning.com/console/keys)创建或复制完整 API Key,将请求头中的 `API_KEY` 替换为完整密钥即可。 ## 选择提交接口 | 操作 | 方法与路径 | | --- | --- | | 图片生成 | `POST /unified/v1/images/tasks` | | JSON 图片编辑 | `POST /unified/v1/images/edit-tasks` | | 视频生成 | `POST /unified/v1/videos/tasks` | | 查询已有任务 | `GET /unified/v1/tasks/{task_id}` | | 等待已有任务,最多 30 秒 | `GET /unified/v1/tasks/{task_id}/wait` | 三个提交接口复用[图片与视频参数](/docs/zh/media-tasks#请求参数)。模型支持的尺寸、时长、参考图、质量及扩展参数没有改变。图片编辑只接收 JSON,不接收 multipart。 ## 提交图片任务 下面是最小提交示例。需要避免重试造成重复生成时,按本页后文添加可选的 `Idempotency-Key` 请求头。 ```bash curl "https://api.creative-reasoning.com/unified/v1/images/tasks" \ -H "Authorization: Bearer API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "creative-reasoning-image-1.5", "prompt": "白色背景上的蓝色陶瓷杯", "n": 1, "size": "1024x1024", "quality": "low" }' ``` 首次受理返回 `202 Accepted`,不等待生成完成。保存 `id` 和 `poll_url`;响应的 `Location` 也包含查询路径。`poll_url` 是相对路径,拼在 `https://api.creative-reasoning.com` 后得到完整查询地址。 ```json { "id": "01a09ec9-7d00-7000-8000-000000000001", "status": "pending", "created_at": 1789370400, "model": "creative-reasoning-image-1.5", "poll_url": "/unified/v1/tasks/01a09ec9-7d00-7000-8000-000000000001" } ``` `202` 表示任务已被受理,不代表生成成功。部分模型参数错误只能在执行时发现,此时任务会进入 `failed`。 ## 提交视频或编辑任务 视频将请求发到 `/unified/v1/videos/tasks`,正文仍使用 `model`、`content` 和该模型支持的参数。例如: ```json { "model": "creative-reasoning-video-1.0", "content": [{"type": "text", "text": "海边日落"}], "duration": 4, "resolution": "480p", "aspect_ratio": "16:9" } ``` 编辑将 JSON 请求发到 `/unified/v1/images/edit-tasks`,通过 `image` 提供素材,并按模型能力选用 `mask`。不要把上述视频参数直接用于其他模型,先核对[参数差异](/docs/zh/media-tasks#请求参数)。 ### 请求视频尾帧 在[模型目录](https://creative-reasoning.com/models)选择支持输出尾帧及 4 秒、720p、16:9 参数组合的模型,将 `YOUR_VIDEO_MODEL` 替换为该模型名称。下面请求一个视频及其尾帧。`return_last_frame` 放在 `provider_options` 中;字段名使用下划线。这里的尾帧是生成结果,与通过 `content[].role: "last_frame"` 提供的输入图片不同。 ```bash curl "https://api.creative-reasoning.com/unified/v1/videos/tasks" \ -H "Authorization: Bearer API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "YOUR_VIDEO_MODEL", "content": [{"type": "text", "text": "一只蓝色陶瓷杯放在木桌上,阳光照在杯身上,镜头缓慢向前推进。"}], "duration": 4, "resolution": "720p", "aspect_ratio": "16:9", "provider_options": {"return_last_frame": true} }' ``` 保存返回的 `id`,按本页的查询步骤获取结果。需要完成通知时,再在请求顶层加入自己的 `callback_url`。请求尾帧不增加 `data` 中的视频数量;读取时仍需检查 `last_frame_url` 是否存在。 ## 请求参数 ### 通用参数 所有接口使用 `Authorization: Bearer API_KEY` 和 `Content-Type: application/json`。 | 字段 | 类型 | 适用范围与规则 | | --- | --- | --- | | `model` | string,必填 | [模型目录](/models)中的模型名称。更换模型后,原参数组合不保证仍有效 | | `callback_url` | string,可选 | 图片生成、JSON 图片编辑和视频生成的终态通知地址。只放在请求顶层,必须满足 [HTTPS 回调规则](/docs/zh/media-tasks#准备回调地址) | | `provider_options` | object,可选 | 所选模型支持的扩展参数。不是任意字段都会生效,不应复制其他模型的扩展参数 | 有通用字段的参数放在顶层。例如视频时长使用 `duration`,宽高比使用 `aspect_ratio`。没有通用字段的模型能力才使用 `provider_options`,例如支持声音控制的模型使用 `provider_options.generate_audio`。不要在两处重复指定同一参数:有的模型采用通用字段,有的模型会拒绝冲突值。 `provider_options` 任意深度出现 `callback_url` 都返回 `400 reserved_parameter`。增加 `callback_url` 不改变模型支持的生成参数,也不会让不支持某种输入的模型获得该能力。 ### 图片参数 适用于图片任务接口 `POST /unified/v1/images/tasks`、`POST /unified/v1/images/edit-tasks`,以及兼容接口 `POST /unified/v1/images/generations`、`POST /unified/v1/images/edits`。编辑接口只接受 JSON,不接受 multipart 表单。 | 字段 | 类型 | 说明 | | --- | --- | --- | | `prompt` | string,必填 | 生成或编辑描述 | | `image` | string 或 array,按任务提供 | 参考图或待编辑图。URL、base64、数组和图片数量是否受支持,取决于模型 | | `mask` | string 或 `{ "image_url": string }`,可选 | 局部编辑蒙版,仅适用于支持蒙版编辑的模型;不支持 `file_id` | | `n` | integer,可选 | 图片数量。不是每个模型都支持批量生成,也没有统一的数量上限 | | `size` | string,可选 | 尺寸。像素尺寸、分辨率档位和宽高比不是同一种格式,不会跨模型自动换算 | | `quality` | string,可选 | 图片质量或清晰度档位,取值由模型定义 | | `aspect_ratio` | string,可选 | 宽高比,仅适用于支持该字段的模型。不是 `size` 的通用替代项 | | `negative_prompt` | string,可选 | 负向描述,仅部分模型支持 | | `seed` | integer,可选 | 随机种子,支持范围由模型定义,不保证输出完全可复现 | | `output_format` | string,可选 | 输出文件格式,仅部分模型支持 | | `response_format` | string,可选 | 结果表示方式,仅部分模型支持。接收结果时同时处理 `data[].url` 和 `data[].b64_json` | | `user` | string,可选 | 兼容字段,不作为 CR 认证或任务归属依据 | 例如 `1024x1024`、`1024*1024`、`1K` 和 `16:9` 不能互换。接口中的 `size` 示例值不是每个模型都接受的默认值。 #### creative-reasoning-image-1.5 生成、编辑的推荐调用 ID、完整参数、尺寸限制及返回说明,统一见[该模型的接入文档](/docs/zh/models/creative-reasoning-image-1.5)。该页面登录后可见。 先运行其中一个最小示例,再按同页参数表调整 `size`、`quality`、`image` 或 `mask`。提交完成后,继续查询原任务并保存实际返回的图片。 ### 视频参数 适用于 `POST /unified/v1/videos/tasks` 和 `POST /unified/v1/videos/generations`。 | 字段 | 类型 | 说明 | | --- | --- | --- | | `content` | array,必填 | 文本和媒体输入项,结构见下表。文生视频使用 `content[].text`,不是顶层 `prompt` | | `duration` | integer,可选 | 秒数。合法时长和默认值由模型决定。CR 不接受字符串秒数或 `-1` | | `resolution` | string,可选 | 分辨率档位,例如某些模型使用 `480p`、`720p`。大小写和档位由模型决定 | | `aspect_ratio` | string,可选或条件必填 | 宽高比,例如 `16:9`。部分文生视频必须填写,部分图生视频禁止填写并跟随输入图 | | `size` | string,可选 | 部分模型的像素尺寸参数,不等同于 `resolution`。没有明确支持时省略 | | `fps` | integer,可选 | 帧率,仅部分模型支持 | | `seed` | integer,可选 | 随机种子,范围由模型决定 | | `negative_prompt` | string,可选 | 负向描述,仅部分模型支持 | 以上是请求设置。实际成片属性以[视频结果字段](/docs/zh/media-tasks#读取视频结果字段)为准,结果中的 `duration` 和 `fps` 可以是小数;结果缺失的字段不继承请求值。支持输出尾帧的模型可使用 `provider_options.return_last_frame: true`,见[完整请求示例](/docs/zh/media-tasks#请求视频尾帧)。 #### content 输入类型与角色 | `type` | 内容字段 | `role` | 用途 | | --- | --- | --- | --- | | `text` | `text` | 不填写 | 生成描述 | | `image_url` | `image_url.url` | `first_frame` | 首帧图 | | `image_url` | `image_url.url` | `last_frame` | 尾帧图,仅支持首尾帧的模型可用 | | `image_url` | `image_url.url` | `reference_image` | 参考图,不等同于首帧图 | | `video_url` | `video_url.url` | `reference_video` | 参考视频,仅部分模型支持 | | `input_audio` | `input_audio.url` | `reference_audio` | 参考音频,仅部分模型支持 | 带首帧的 `content` 结构如下。图片 URL 需要替换为可访问的素材地址,所选模型必须支持首帧输入: ```json [ {"type": "text", "text": "镜头缓慢向前推进"}, { "type": "image_url", "role": "first_frame", "image_url": {"url": "https://customer.example.com/assets/first-frame.png"} } ] ``` 参考图应显式填写 `role: "reference_image"`。省略 `role` 可能被当作首帧。JSON 结构合法不代表该模型支持这些媒体类型、数量或组合。 上面的 `creative-reasoning-video-1.0` 文生视频示例只包含文字,不传参考图片、视频或音频。`provider_options.generate_audio` 是可选布尔值,用于控制生成声音,不是输入参考音频。时长、分辨率和声音开关的取值见下面的模型支持表。 #### 视频模型支持范围 以下设置适用于 `creative-reasoning-video-1.0`、`creative-reasoning-video-1.0-i2v` 和 `creative-reasoning-video-1.0-r2v`: | 参数 | 取值 | 省略时 | | --- | --- | --- | | `duration` | 4–15 的整数,单位秒 | 5 | | `resolution` | 可使用 `480p`、`720p`、`1080p` | `720p` | | `aspect_ratio` | `16:9`、`9:16`、`1:1`、`4:3`、`3:4`、`21:9`、`adaptive` | `adaptive` | | `provider_options.generate_audio` | 布尔值;`true` 生成声音,`false` 生成无声视频 | `true` | `resolution` 放在请求顶层,不使用图片的 `quality` 字段。`adaptive` 在文生视频中按提示词选择比例,在首帧模型中参考首帧,在参考模型中优先参考视频、其次图片。实际成片属性仍以返回结果为准。 | 模型 | 输入要求 | | --- | --- | | `creative-reasoning-video-1.0` | 只使用文本;不传图片、参考视频或参考音频 | | `creative-reasoning-video-1.0-i2v` | 一张 `first_frame`;可再加一张 `last_frame`。不传参考视频、音频 | | `creative-reasoning-video-1.0-r2v` | 最多 9 张 `reference_image`、3 条 `reference_video`、3 条 `reference_audio`。音频不能单独输入,至少同时有一张图或一条视频 | 输入图片使用 JPEG、PNG 或 WebP;单张不超过 30 MB,宽高各为 300–6000 像素,宽高比在 0.4–2.5 之间。参考视频使用 MP4 或 MOV,单条 2–15 秒且不超过 50 MB,所有参考视频总时长不超过 15 秒;参考音频使用 WAV 或 MP3,单条 2–15 秒且不超过 15 MB,总时长不超过 15 秒。使用 CR 可访问的完整素材 URL。 `role: "last_frame"` 表示输入尾帧,不代表返回 `last_frame_url`。输入素材、时长和分辨率会影响用量,费用以模型价格及调用明细为准。 #### creative-reasoning-video-1.0 该模型从文字生成视频。用 `content` 中的 `text` 描述画面和动作,参数取值见上表。完整的提交、查询及下载步骤见[生成视频](/docs/zh/video-async)。 #### creative-reasoning-video-1.0-i2v 该模型使用首帧图片生成视频。示例使用一张图片、`role: "first_frame"`、`duration: 4`、`resolution: "480p"` 和 `aspect_ratio: "16:9"` ,不需要 `provider_options`。示例使用一张可公开访问的白猫图片。 ```json { "model": "creative-reasoning-video-1.0-i2v", "content": [ { "type": "text", "text": "白色长毛猫在绿色草地上缓慢向镜头走来,尾巴轻轻摆动,阳光柔和,固定镜头,保持图片中猫的外观。" }, { "type": "image_url", "image_url": { "url": "https://cdn.translate.alibaba.com/r/wanx-demo-1.png" }, "role": "first_frame" } ], "duration": 4, "resolution": "480p", "aspect_ratio": "16:9" } ``` 替换图片时使用 CR 可直接访问的 URL,并同步修改提示词。其他输入数量和媒体组合见[视频模型支持范围](/docs/zh/media-tasks#视频模型支持范围)。`resolution` 选择档位,实际宽高和时长以生成结果为准。 #### creative-reasoning-video-1.0-r2v 该模型使用参考图片引导视频生成。示例使用一张图片、`role: "reference_image"`、`duration: 4`、`resolution: "480p"` 和 `aspect_ratio: "16:9"` ,不需要 `provider_options`。图片必须显式标注参考角色。示例使用一张可公开访问的白猫图片。 ```json { "model": "creative-reasoning-video-1.0-r2v", "content": [ { "type": "text", "text": "白色长毛猫在绿色草地上缓慢向镜头走来,尾巴轻轻摆动,阳光柔和,固定镜头,保持图片中猫的外观。" }, { "type": "image_url", "image_url": { "url": "https://cdn.translate.alibaba.com/r/wanx-demo-1.png" }, "role": "reference_image" } ], "duration": 4, "resolution": "480p", "aspect_ratio": "16:9" } ``` 替换图片时使用 CR 可直接访问的 URL,并同步修改提示词。其他输入数量和媒体组合见[视频模型支持范围](/docs/zh/media-tasks#视频模型支持范围)。`resolution` 选择档位,实际宽高和时长以生成结果为准。 未支持的字段可能被忽略,也可能导致请求或任务失败。HTTP `2xx` 只表示请求已被接受,不证明所有可选参数都生效;异步任务仍可能在之后返回 `failed`。 ## 查询或等待结果 使用提交任务时的同一 API Key。用另一把 API Key 查询会返回 `404`,即使两把 Key 属于同一个团队。将 `TASK_ID_FROM_SUBMIT_RESPONSE` 替换为提交响应中的 `id`,再查询该任务: ```bash curl "https://api.creative-reasoning.com/unified/v1/tasks/TASK_ID_FROM_SUBMIT_RESPONSE" \ -H "Authorization: Bearer API_KEY" ``` 查询成功返回 `200` 和任务对象。根据 `status` 处理: | status | 调用方处理 | | --- | --- | | `pending`、`processing` | 继续查询或等待通知,不重新提交生成 | | `completed` | 读取 `data` 中的图片或视频结果 | | `failed` | 读取 `error.code` 和 `error.message` | 希望少做短间隔轮询时,调用 `/unified/v1/tasks/TASK_ID_FROM_SUBMIT_RESPONSE/wait`。它最多等待 30 秒;仍未完成时,返回 `200` 和当前状态。可以再次等待同一个 ID。等待超时、客户端断开或重复查询不会取消任务,也不会重新生成。 支持返回尾帧的视频模型可在提交时设置 `provider_options.return_last_frame: true`。模型返回尾帧时,成功结果的 `data[].last_frame_url` 提供尾帧图片下载链接;未返回时省略该字段。任务查询、等待结果和完成回调中的字段一致。链接的使用与有效期见[下载视频及尾帧](/docs/zh/media-tasks#下载与保存结果)。 生成失败同样通过 `200` 返回任务对象,使用 `status: failed` 表示;不要只看 HTTP 状态判断生成是否成功。终态正文从完成时起保留 24 小时,过期返回 `410 task_expired`。及时保存结果,下载链接还有自身的有效期。 ## 读取图像用量 部分图像模型将输入与输出用量合并为计费 Token,在价格表和调用明细中显示为“综合用量”。若统一响应包含 `usage.billing.tokenhub_tokens`,该值就是本次请求的计费用量,例如: ```json { "usage": { "billing": {"tokenhub_tokens": 3763} } } ``` 该数量是本次生成或编辑的输入与输出综合计费用量,使用对应的计费 Token 单价计算费用。它不代表原厂文本输入或图片输出 Token。此类响应不提供可还原的输入、输出和缓存分项;读取这些分项的客户端应允许字段缺失。图片仍从 `data[].url` 或 `data[].b64_json` 读取。 单价以[模型目录](/models)的对应计费项为准,参见[图像计费项](/docs/zh/request-billing#图像计费项)和[费用计算示例](/docs/zh/request-billing#费用示例)。同步结果与异步任务的完成结果使用相同的用量含义。 ## 读取视频结果字段 每个 `data[]` 元素对应一个视频,尾帧属于同一元素。以下字段含义统一,可用字段因模型而异;模型未报告或字段无效时省略,不用请求设置代替生成结果。客户端须允许新增可选字段,历史结果可以缺少 `type`。 | 字段 | 含义 | | --- | --- | | `type`、`url` | 标准结果的 `type` 为 `video`;`url` 是视频下载链接 | | `last_frame_url` | 该视频的尾帧图片链接;没有尾帧时省略 | | `duration` | 成片时长,单位秒,保留小数;不是任务耗时 | | `width`、`height`、`size` | 像素宽高;完整宽高生成 `1280x720` 形式的 `size` | | `resolution` | 报告的分辨率档位,如 `720p`,不根据尺寸推断 | | `aspect_ratio` | 报告的具体比例,或宽高约分得到的比例;不返回 `adaptive` | | `fps`、`frame_count` | 帧率和报告的总帧数;帧率支持小数,不估算总帧数 | | `has_audio` | 成片是否含音频;保留 `false`,未知时省略 | | `format`、`seed` | 报告的容器格式及实际种子;不根据 URL 推断格式,未知或随机种子占位值省略 | | `extensions` | 已定义的产物特有字段;无可用扩展时省略 | 任务顶层 `tools` 提供工具执行统计,各视频中不重复。例如: ```json { "tools": [{"type": "web_search", "calls": 2}] } ``` `calls` 为非负整数,明确返回 `0` 时保留;只报告工具、没有次数时省略 `calls`。没有工具信息时省略 `tools`,请求开启搜索不代表实际调用。统计仅提供执行信息,不参与费用计算,`usage` 的含义不变。任务级 `extensions` 仅承载已定义的任务信息,当前没有已定义扩展字段,响应省略此对象。 查询、wait、完成回调及回调重试返回同一份保存的终态,包含相同下载链接。图片的 URL、Base64 和多图返回形态保持不变。 ### 成功响应示例 下面展示包含尾帧的完整任务对象。下载链接中的 `OPAQUE_VIDEO_TOKEN` 和 `OPAQUE_FRAME_TOKEN` 是占位符,实际使用时保留响应中的完整 URL。示例只展示部分可选字段,不代表每次生成都会返回这些字段。 ```json { "id": "01a09ec9-7d00-7000-8000-000000000002", "status": "completed", "model": "YOUR_VIDEO_MODEL", "created_at": 1789370400, "completed_at": 1789370640, "data": [{ "type": "video", "url": "https://api.creative-reasoning.com/_cr/v1/media/video/01a09ec9-7d00-7000-8000-000000000002/OPAQUE_VIDEO_TOKEN", "last_frame_url": "https://api.creative-reasoning.com/_cr/v1/media/video/01a09ec9-7d00-7000-8000-000000000002/OPAQUE_FRAME_TOKEN", "duration": 4, "resolution": "720p", "aspect_ratio": "16:9", "has_audio": false, "seed": 0 }], "usage": {"output": {"video_tokens": 87300}} } ``` ### 兼容可选字段 读取结果时保留有效的 `false`、`0` 和小数。字段缺失表示未报告,不能默认成无音频、零次工具调用或请求中设置的值。GET、wait 和完成回调中的字段含义相同;忽略未识别的新增字段,并允许历史结果缺少 `type`。 ## 下载与保存结果 直接使用 `data[].url` 播放或下载视频,不要解析或拼接 URL。示例中的 `OPAQUE_VIDEO_TOKEN` 仅为占位符。真实链接自生成起最多有效 24 小时;如果源文件提前过期,链接也会提前失效。需要长期保存时,请及时下载到自己的存储。 对于支持返回尾帧的模型,在提交请求的 `provider_options` 中设置 `return_last_frame: true`。模型返回尾帧时,`data[].last_frame_url` 是尾帧图片的下载链接;未返回时省略该字段。任务查询和完成回调中的链接一致。尾帧链接与视频链接遵循相同的访问和过期规则,请直接使用返回的完整 URL。 视频规格、音频状态及任务级工具统计见[视频结果字段](/docs/zh/media-tasks#读取视频结果字段)。同一字段在查询和回调中的含义一致,可用字段因模型而异。 CR 流式转发视频,不跳转到供应商地址。下载支持 `GET`、`HEAD` 和单段 `Range`,无需附加 CR API Key。链接本身包含访问凭证,请勿写入公开日志或发给无关人员。过期或被篡改的链接返回 `404`。 回调重试、管理员重新投递和后续查询使用同一份已保存正文,不延长其中下载链接的有效期。下载失败不改变生成状态,也不会再次收取生成费用。 图片从 `data[].url` 下载或读取 `data[].b64_json`。图片链接也可能过期,需要长期保存的结果请及时下载到自己的存储。 ## 使用 callback_url 接收通知 需要通知时,在任一提交正文顶层加入 `callback_url`: ```json { "callback_url": "https://customer.example.com/webhooks/cr-media?token=your-random-token" } ``` 这只是追加字段的示例,提交时仍需提供 `model` 和生成参数。回调地址遵循[HTTPS 回调规则](/docs/zh/media-tasks#准备回调地址),不能放入 `provider_options`。 CR 只发送 `completed` 或 `failed`。回调正文与该任务保存的终态 GET 响应逐字节一致,没有事件外层。成功结果包含 `data` 和可用的 `usage`;视频结构见本页成功响应示例,图片保留模型支持的 `url` 或 `b64_json`。 ### 准备回调地址 提供一个无需 CR API Key 即可接收 `POST` 的 HTTPS 地址。该地址需要满足以下规则: - 使用绝对 HTTPS URL,UTF-8 编码后不超过 2048 字节。 - 可以包含 path 和 query,但不能包含 userinfo 或 fragment。 - 域名的全部 DNS 地址都必须是公网地址。 - 不能指向 CR API 本身。 生产环境不要使用 localhost、IP 内网地址或依赖 HTTP 重定向的地址。如需校验调用方,可以在 query 中放置随机 token,并在接收端比对。不要把完整回调 URL 写入日志。 ### 接收终态 失败回调的 `status` 是 `failed`,并包含 `error`。取消的任务使用 `error.code: "task_cancelled"`。失败回调不包含 `data` 或 `usage`。 `error.code` 用 CR 自己的词汇说明失败原因:取消为 `task_cancelled`,未归类的失败为 `task_failed`。CR 不会返回模型供应商的错误文案、错误码或标识,因此这些取值对所有模型一致。完整集合与安全的分支写法见[错误码](/docs/zh/troubleshooting#错误响应格式)。 每次投递只依赖以下标准请求头: | 请求头 | 用途 | | --- | --- | | `content-type` | 固定为 `application/json` | | `user-agent` | 固定为 `CR-Webhook/1.0` | 正常解析 JSON 即可,不需要保留原始正文。 ### 防止重复处理 网络超时可能导致同一个终态被重复发送。使用正文中的 CR 任务 `id` 作为幂等键。保存结果时,为任务 `id` 建立唯一约束;如果该任务已经处理,直接返回 `2xx`。 先保存结果,再返回 `2xx`。如果业务处理时间较长,先把结果写入队列或数据库,再异步处理。 ### 处理重试 CR 首次投递失败后,最多再重试 3 次。重试分别安排在失败后的 1、2、4 秒。同一任务的每次投递使用相同正文。 - 任意 `2xx` 表示投递成功。 - 非 `2xx`、连接错误、TLS 错误和超时会触发重试。 - `3xx` 不会跳转。 CR 等待单次响应的时间不超过 10 秒。 回调投递失败不改变生成任务状态,也不重复计费。需要对账时,使用提交响应中的 `poll_url` 查询任务。查询接口和回调返回相同的终态正文。 ## 避免重复生成与处理错误 以下规则适用于 `/unified/v1/images/tasks`、`/unified/v1/images/edit-tasks` 和 `/unified/v1/videos/tasks`。需要安全重试这些提交请求时,添加可选的 `Idempotency-Key` 请求头。它是由你生成的业务操作唯一标识,不是 API Key,也不参与认证。将下面的 `YOUR_UNIQUE_OPERATION_ID` 替换为本次操作的唯一编号,例如保存在业务记录中的 UUID;同一操作重试时复用该值和请求正文,新操作使用新值: ```http Idempotency-Key: YOUR_UNIQUE_OPERATION_ID ``` 标识长度为 1–256 个不含空白的可打印 ASCII 字符。它只在同一 API Key、同一操作、同一接口范围内复用任务;不跨图片/视频或新旧提交接口去重。 - 相同键和相同请求:返回同一任务;任务已终态时 POST 可返回 `200`,但正文仍是任务对象。 - 已受理任务:只要提交时的 API Key 仍有效,可以用相同键和请求恢复任务,即使该模型已不再接受新的生成请求。 - 相同键、不同请求:返回 `409 idempotency_conflict`,不创建第二个任务。修改 callback 地址也属于请求变更。 - 超时、断网或 `503`:不表示任务一定未受理。已设置幂等头时,以相同键和相同请求重试;已经拿到 ID 时直接查询。未设置幂等头时,不要盲目重发 POST,以免重复生成。 - 每把 API Key 最多同时保留 128 个未完成任务。达到限制返回 `429 task_capacity_exceeded`,稍后重试。 - 等待连接达到上限时,`/wait` 返回 `429 task_wait_capacity_exceeded`,改用普通 GET 查询。 - `400 invalid_parameter`:检查请求,尤其不要在新接口传 `response_mode`。 任务记录保留到终态后的 30 天,用于幂等识别;这不延长结果正文的 24 小时有效期。不要永久重复使用同一个幂等键。不带该 Header 的每次 POST 都是新的生成任务。 任务最长执行 24 小时。无法确认提交结果时,CR 不会盲目再次生成;最终可能返回 `submission_unknown`,该任务不向客户扣费。生成终态失败不扣生成费用;生成成功但客户回调不通,仍按成功生成计费。 ## 兼容接口 兼容接口不提供上述任务接口的幂等提交保证。已拿到任务 ID 时查询原任务;提交超时且没有 ID 时,先确认是否已经受理。 旧的 `/unified/v1/images/generations`、`/unified/v1/images/edits` 和 `/unified/v1/videos/generations` 继续支持,尚未废弃。旧图片接口仍按所选模型保留同步结果或任务响应,旧视频接口仍返回任务。迁移时需要同时修改提交路径和结果处理代码,不能只替换 URL 后继续直接读取 `data`。 ### 图片生成与编辑兼容接口 将 `YOUR_MODEL` 替换为[模型目录](https://creative-reasoning.com/models)中支持相应图片操作的模型名称。 #### 生成图像 先按[图片参数与模型示例](/docs/zh/media-tasks#图片参数)确认 `size`、`quality` 和输入限制,再运行请求。通用示例不代表所有可选参数都受支持。 ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/images/generations' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "YOUR_MODEL", "prompt": "A blue ceramic cup on a white background" }' ``` #### 编辑图像 ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/images/edits' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "YOUR_MODEL", "prompt": "Change the background to light gray", "image": "https://example.invalid/replace-with-your-image.png" }' ``` 编辑接口使用 JSON,不接收 multipart 上传。将示例 URL 替换为 CR 服务可访问的图像。先确认所选模型支持编辑,再按[图片参数](/docs/zh/media-tasks#图片参数)核对格式、数组和 `mask` 支持;文生图通过不代表编辑也可用。 #### 处理响应 同步响应直接读取 `data`。只轮询 `pending` 或 `processing` 任务,并使用提交任务的 API Key。轮询时设置间隔和总等待上限;到期后保留任务 ID,稍后继续查询。 根据模型的原生行为和是否传入回调地址,处理已受理的请求: | 请求方式 | 提交响应 | 后续处理 | | --- | --- | --- | | 同步图片,不传 `callback_url` | 直接返回 `data` | 保存图片,不轮询 | | 异步图片,不传 `callback_url` | 返回 CR `id` 和 `pending`,可以没有 `poll_url` | 使用 CR `id` 查询任务 | | 传入 `callback_url` | 返回 CR `id`、`pending` 和 `poll_url` | 接收终态回调,必要时查询同一任务 | 异步图片响应没有 `poll_url` 时,查询 `GET /unified/v1/images/generations/{id}`,将 `{id}` 替换为提交响应中的 CR `id`。不要重新 POST 来查询结果。图片编辑任务也使用这条查询路径。 #### 接收图片回调 生成和 JSON 编辑接口都支持顶层 `callback_url`。不传该字段时,原有同步或异步行为不变。不要把它放进 `provider_options`,否则返回 `400 reserved_parameter`。 带回调的请求返回 `status: "pending"`、CR 任务 `id` 和 `poll_url`。图片编辑任务也使用 `/unified/v1/images/generations/{task_id}` 查询。同步模型仍在本次 POST 内完成生成,然后保存结果并排队通知;添加回调不代表 POST 会立即返回,也不会再次调用模型。 回调格式、地址校验和重投规则见本页的回调说明。 `503 callback_unavailable` 表示回调无法登记或保存;如果错误发生在模型服务接受请求之后,生成可能已经开始,不要无条件重新提交。 ### 视频生成兼容接口 视频接口使用异步任务,不提供等待出片后直接返回媒体的同步 POST。不传 `callback_url` 时,提交响应仍返回 CR `id` 和 `poll_url`。使用提交任务的 API Key 轮询该地址,直到 `completed` 或 `failed`,不要重复提交生成请求。 以下示例使用 `creative-reasoning-video-1.0` 的文生视频示例参数。将回调 URL 换为你的接收地址,并把 `callback_url` 放在请求顶层。更换模型前,核对[视频参数与模型差异](/docs/zh/media-tasks#视频参数),不要沿用另一模型的时长、清晰度或宽高比。 ```bash curl "https://api.creative-reasoning.com/unified/v1/videos/generations" \ -H "Authorization: Bearer API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "creative-reasoning-video-1.0", "content": [{"type": "text", "text": "海边日落"}], "duration": 4, "resolution": "480p", "aspect_ratio": "16:9", "callback_url": "https://customer.example.com/webhooks/cr-video" }' ``` 不要把 `callback_url` 放入 `provider_options`。该名称在 `provider_options` 的任意深度都是保留参数,服务会返回 `400 reserved_parameter`。 保存响应中的 `id` 和 `poll_url`。`id` 在提交响应、查询响应和回调正文中保持一致: ```json { "id": "0199c9e6-9381-7f30-9aa0-0df86dca6cdf", "status": "pending", "created_at": 1788912000, "model": "creative-reasoning-video-1.0", "poll_url": "/unified/v1/videos/generations/0199c9e6-9381-7f30-9aa0-0df86dca6cdf" } ``` `503 callback_unavailable` 表示回调服务暂不可用,可能发生在任务受理前或受理后。不能仅凭 `503` 判断任务未创建。收到该错误时,不要自动重发 POST;保留请求 ID,联系支持确认任务是否已创建。`503 media_unavailable` 表示视频下载服务暂不可用,删除 `callback_url` 无法解决;请联系支持后再提交。 # 查询调用账单与有效价格 URL: https://creative-reasoning.com/docs/zh/request-billing ## 估算调用费用 在[模型目录](https://creative-reasoning.com/models)查看所选模型的单价和计费单位。目录报价与调用后的实际扣费分别用于预算估算和账单核对。 ### 图像计费项 图像模型可以按输入、输出 Token 分项计费,也可以合并为“综合用量”。分项计费中的“图像输出”只代表输出图像的原厂 Token;“综合用量”使用计费 Token,代表按照模型规则折算的多种用量。 若响应中的用量为 `usage.billing.tokenhub_tokens`,使用“综合用量”对应的单价,不再叠加输入或输出 Token 费用。用量字段示例见[生成与编辑图像](/docs/zh/media-tasks#读取图像用量)。 ### 综合用量与费用 “综合用量”不限定图片。任何已接入综合计量的模型都使用这一展示方式。视频模型如果按秒、条或原厂输出 Token 计价,仍按对应的单位结算;显示名称通用不代表所有模型采用同一计费规则。 目录单价以 Credits(ℂ)表示,注意每项标明的数量单位。按百万计费 Token 报价时: ```text 费用(ℂ)= 实际计费 Token 数量 ÷ 1,000,000 × 单价(ℂ / 百万计费 Token) ``` 计费 Token 已按该模型的规则折算,使用响应中的数量即可,不需要再次乘换算系数。不同模型的系数可能不同,不能直接套用原厂图片或视频输出 Token 单价。最终金额还受适用折扣和结算精度影响,以调用明细的实际扣费为准。保留 `x-cr-usage-id` 可查询该次请求的账单。 ### 费用示例 无需登录即可查看公开单价和下面的计算方法。以下假设单价仅用于演示算法;选择具体模型时,请在[模型目录](https://creative-reasoning.com/models)核对当前单价、单位和适用规格。 | 计费方式 | 假设单价与用量 | 估算费用(未计折扣) | | --- | --- | --- | | 综合计费 Token | 56 ℂ / 百万计费 Token;用量 3,763 | `3763 ÷ 1000000 × 56 = 0.210728 ℂ`,约 ¥0.042146 | | 视频按输出秒数计费 | 无参考视频档位:4 ℂ / 秒;输出计费 5 秒 | `5 × 4 = 20 ℂ`,即 ¥4 | | 视频输入、输出分别按秒计费 | 有参考视频档位:输入 2 ℂ / 秒,输出 3 ℂ / 秒;输入计费 5 秒,输出计费 10 秒 | `5 × 2 + 10 × 3 = 40 ℂ`,即 ¥8 | | 视频按条计费 | 所选规格 25 ℂ / 条;计费 1 条 | `1 × 25 = 25 ℂ`,即 ¥5 | 人民币等值按 `1 ℂ = ¥0.20` 换算。若适用折扣为 80%,20 ℂ 的标价对应 `20 × 80% = 16 ℂ`,即 ¥3.20。实际扣费还取决于结算精度,以调用账单为准。 “按生成规格计费”表示需要先选择与请求匹配的价格档位,例如分辨率、输入类型以及是否使用参考视频,再按该档位的计费单位和实际用量计算。使用参考视频时,输入、输出都应匹配参考视频档位,不能把无参考视频的输出单价直接套入。按秒计费使用模型返回的计费时长,计费时长可能包含最低时长或取整规则,不能只用文件播放时长推算。 尺寸、质量、提示词、参考图和缓存命中情况也可能影响图片用量。一次请求的费用只能作为对应条件下的样本。公开示例用于预算;查询自己的实际扣费,请按下文保存用量 ID,并使用有权限的管理 Token 查账。 ## 从模型调用到查账 模型调用和管理查询使用两种不同凭据:`API_KEY` 调用模型,`YOUR_MANAGEMENT_TOKEN` 查询账单。管理 Token 必须具有 `usage:read`,不能拿模型 API Key 调用管理接口。 模型请求使用生产 API `https://api.creative-reasoning.com`,管理查询使用 `https://creative-reasoning.com`。在 [API Key 页面](https://creative-reasoning.com/console/keys)复制完整 API Key,填入下方的 `API_KEY`;将 `YOUR_MODEL` 替换为[模型目录](https://creative-reasoning.com/models)中支持 Chat Completions 的模型名称。向管理员申请有权查询目标团队账单的管理 Token,将其完整值填入 `YOUR_MANAGEMENT_TOKEN`。 第一步,调用模型并保存响应头中的 `x-cr-usage-id`。下面使用 `--include` 显示响应头;正式客户端应直接从响应对象读取该字段: ```bash curl -i \ -H "Authorization: Bearer API_KEY" \ -H 'Content-Type: application/json' \ -d '{"model":"YOUR_MODEL","messages":[{"role":"user","content":"Hello"}]}' \ "https://api.creative-reasoning.com/unified/v1/chat/completions" ``` 响应会包含两个用途不同的 ID: ```http x-cr-request-id: 018f1000-0000-7000-8000-000000000004 x-cr-usage-id: 018f1000-0000-7000-8000-000000000004 ``` `x-cr-request-id` 标识这一次 HTTP 请求,用于排障;`x-cr-usage-id` 标识账单记录,用于查账。同步推理请求中两者通常相同。异步任务的每次轮询、以及受支持的幂等重试都有新的 request ID,但 usage ID 仍指向原始账单;任务 ID 用于查询生成状态。业务查账只需保存 usage ID,不要用轮询的 request ID 替代它。拿到 usage ID 不代表账单立即可查或计费已完成;普通推理重发不因此获得幂等保证。 流式调用也从初始响应头读取这两个 ID,并继续读取流中的结果。 第二步,将下方的 `USAGE_ID` 替换为响应头 `x-cr-usage-id` 中的 UUID,再使用管理 Token 查询。 ```bash curl \ -H "Authorization: Bearer YOUR_MANAGEMENT_TOKEN" \ "https://creative-reasoning.com/api/v1/management/usage/USAGE_ID" ``` 先检查 `billing_status`。为 `pending` 时,按 `Retry-After` 有限重试;此时 `credits` 为 null,不是零费用。为 `final` 时,读取 `credits.after_discount` 作为已记录费用。`final` 不代表生成成功,执行结果需从模型响应或任务查询核对。 新调用可能短暂返回 404。仅对自己刚提交的调用有限重试;不存在和无权访问也返回 404。 ## 读取费用和用量 金额单位为 Credits(ℂ),与控制台一致。成功响应通过 `X-CRR-Credit-Unit: credits` 标明该单位。以 9 个输入 token、14 个输出 token、无组织折扣的调用为例: ```json { "usage_id": "018f1000-0000-7000-8000-000000000004", "billing_status": "final", "created_at": "2026-09-16T13:52:56.621Z", "usage_items": [ { "name": "input:prompt_tokens", "usage": 9 }, { "name": "output:completion_tokens", "usage": 14 } ], "credits": { "before_discount": "0.00553", "after_discount": "0.00553" } } ``` - `usage_items` 是各计费维度的实际数量,例如输入和输出 token 数。 - `credits.before_discount` 是按公开标价计算的 Credits。 - `credits.after_discount` 是应用组织折扣后的最终 Credits,也是本次调用应读取的消费金额。 - `created_at` 是账单记录的创建时间,不表示计费完成时间。 - 如需展示优惠金额,使用十进制运算计算折前与折后的差值。查账响应只返回上述五个顶层字段。 本例的 `"0.00553"` 表示消费 `0.00553 ℂ`,按 `1 ℂ = ¥0.20` 对应 `¥0.001106`。金额是十进制字符串,计算费用时使用十进制运算以保留精度。 ## 批量核对调用 把最多 100 个用量 UUID 放入 `usage_ids`。下面使用同一个 ID 两次,展示重复项保持不变的行为: ```bash curl \ -X POST \ -H "Authorization: Bearer YOUR_MANAGEMENT_TOKEN" \ -H 'Content-Type: application/json' \ -d '{"usage_ids":["USAGE_ID","USAGE_ID"]}' \ "https://creative-reasoning.com/api/v1/management/usage/batch" ``` HTTP 200 返回按输入顺序排列的 `items`,不代表每项均已查到或计费完成。对每项先检查 `lookup_status`:`not_found` 的 `usage` 为 null;`found` 时继续检查 `usage.billing_status`。批量响应没有逐项的 `Retry-After` 头,客户端需自行设置有截止时间的退避。 非法 UUID 会拒绝整批。合法但不在 Token 范围内的 ID 与不存在的 ID 均为 `not_found`。团队 Token 只查本团队,组织 Token 只查本组织;重复 ID 也消耗限流单位。 批量请求被拒绝时,先检查 `Content-Type`。400 JSON 错误表示 UUID 或批量大小无效。JSON 语法错误返回 400 纯文本;字段类型错误、未知字段或缺少 `usage_ids` 返回 422 纯文本。遇到 415,设置 `Content-Type: application/json`;遇到 413,缩小请求体。修正请求后再发送,不将纯文本措辞当作稳定错误码。 ## 查询调用前的有效价格 另外申请独立的 `pricing:read`。在[管理控制台](https://creative-reasoning.com/)打开目标团队,点击团队名称下方的编号,用复制值替换 `TEAM_CODE`,例如 `T-TU214G`,不是团队 UUID: ```bash curl \ -H "Authorization: Bearer YOUR_MANAGEMENT_TOKEN" \ "https://creative-reasoning.com/api/v1/management/teams/TEAM_CODE/models/pricing" ``` 读取 `effective_pricing` 展示当前组织折后单价。`pricing` 是标价;`discount: 7500` 表示收取标价的 75%,不是减免 75%。单价单位为 Credits/单个计费单位,保留十进制字符串及阶梯结构。每百万 token 的 Credits 单价等于接口单价乘以 1,000,000;阶梯 `up_to` 表示对应计费维度的数量上限。 当前价格不能用于重算历史账单,模型在价格列表中也不代表某个 Key 有调用权。历史费用使用上面的查账结果,区间统计按[查询 API Key 额度与用量](/docs/zh/manage-api-keys#查询剩余额度与重置时间)操作。 完整请求、响应字段和权限要求见[管理 API](/docs/zh/management-api)。 # 错误处理与重试 URL: https://creative-reasoning.com/docs/zh/troubleshooting ## 定位请求 保留请求时间和时区、HTTP 方法和路径、模型名称、API Key 前缀或 ID、HTTP 状态以及 `x-cr-request-id`;异步任务还要保存任务 `id`。每次轮询有独立的请求 ID,响应头始终标识当前 HTTP 请求。 请求和响应正文只保留脱敏后的必要片段。不要在工单或聊天中发送 `Authorization` Header、完整 API Key、客户输入或私有媒体 URL。 JSON HTTP 错误响应在顶层返回 `request_id`,与 `error` 并列,且与响应头 `x-cr-request-id` 一致。失败的异步任务也在顶层返回 `request_id`,但指向最初提交任务的请求。保存的结果不会随着轮询、幂等重试或回调改变;查询请求自身的 ID 仍从响应头读取。这些是 CR 标识,不是模型服务的原始 request ID。客户端如果只保存嵌套的 `error` 对象,会丢失 `request_id`。 旧任务已保存的终态正文不会补写新字段,客户端应兼容字段缺失。流内错误事件沿用原协议,关联 ID 从响应头读取。 响应含有 `x-cr-usage-id` 时也应保存,用它[查询本次调用的账单](/docs/zh/request-billing)。轮询请求的 request ID 可以变化,不能替代原始 usage ID。连接中断不代表免费,最终费用以账单的 `billing_status: "final"` 和 `credits.after_discount` 为准。 ## 按阶段排查 | 现象 | 优先检查 | | --- | --- | | 无法连接、TLS 错误 | API Base URL、DNS、证书、代理及网络出口 | | 400 或参数校验失败 | 必填字段、请求体和模型能力 | | 401 | Bearer Header、完整 API Key、有效期与停用状态 | | 403 或访问被拒绝 | API Key、团队或组织的模型访问策略,以及额度状态 | | 404 | 接口路径、模型名称、`previous_response_id` 或任务 ID,以及所用 API Key | | 429 或部分 5xx | 限流、并发、错误信息与有界退避 | | SSE 中断 | 读取超时、代理缓冲、客户端取消与服务端流错误 | | 任务长时间未结束 | 任务 ID、轮询间隔、终态处理和总体等待上限 | ## 错误响应格式 本页描述模型调用接口的错误。管理接口使用独立的错误格式,见[管理 API](/docs/zh/management-api)。 模型调用的 HTTP 错误响应和异步任务终态使用相同的 `error` 对象。即时 HTTP 错误还会在 顶层返回 `request_id`,它与响应头 `x-cr-request-id` 相同: ```json { "error": { "type": "invalid_request_error", "code": "content_policy_violation", "message": "The request was rejected by a content safety filter" }, "request_id": "0199c9e6-9381-7f30-9aa0-0df86dca6cdf" } ``` 请按 `error.code` 做分支。`error.type` 只作粗分类。除下文约定的上下文超限标识外,`error.message` 是可调整的可读文案,不要依赖完整措辞。 异步任务先按 `status` 判断是否结束:`completed` 为成功,`failed` 为失败。收到 `failed` 后停止轮询,再用 `error.code` 决定如何提示或处理;不要只在 `error.code == "task_failed"` 时才结束任务。GET 和 callback 使用同一份终态正文。其中的 `id` 是任务 ID;失败任务的 `request_id` 标识最初提交任务的请求,而非当前轮询。 ## 来自模型的错误 HTTP 错误响应和异步任务终态中的模型失败使用下列 CR 错误码。错误码、错误类别和文案均由 CR 定义,不包含模型供应商的标识。流开始后的失败见[流式过程中的错误](#流式过程中的错误)。 已识别的错误会在 `error.message` 中提供纠错信息,例如被拒绝的字段、缺少的 schema 类型、素材大小上限或上下文 token 上限。能安全确定字段时,另有 `error.param`。错误说明不包含供应商身份、服务地址、凭据或原始请求内容。尚未识别的诊断保留通用说明,可通过 `request_id` 联系支持排查。 | `error.code` | `error.type` | 含义 | 处理方式 | | --- | --- | --- | --- | | `content_policy_violation` | `invalid_request_error` | 输入或生成结果未通过内容安全审核 | 按错误说明调整输入或生成选项;不要无限原样重试 | | `invalid_parameter` | `invalid_request_error` | 参数非法,或该模型不支持 | 对照[媒体参数](/docs/zh/media-tasks#请求参数)核对该模型的参数 | | `input_too_large` | `invalid_request_error` | 输入大小或 token 总量超限,包括图文 token 总量、图片尺寸和输入视频大小 | 缩短输入、调整图片尺寸、压缩视频或拆分请求 | | `unsupported_capability` | `invalid_request_error` | 该模型不支持本次操作或输入类型 | 使用模型支持的操作或输入格式,或换用支持该能力的模型 | | `upstream_rate_limited` | `rate_limit_error` | 触发限流 | 退避后重试 | | `quota_exceeded` | `upstream_error` | 该模型容量已耗尽 | 联系管理员;重试无效 | | `model_unavailable` | `overloaded_error` | 模型暂时不可用或已离线 | 可有限退避重试;持续不可用时联系管理员或选择其他模型,离线模型需要恢复服务或更换路由 | | `request_timeout` | `timeout_error` | 模型未在时限内响应 | 重试;可考虑减小请求 | | `upstream_request_failed` | `upstream_error` | 请求失败,未提供更具体的原因 | 重试一次;持续出现请带上请求 ID 联系支持 | 模型服务可能用 HTTP `400` 报告模型离线。CR 保留该 HTTP 状态,但将错误归为 `model_unavailable`,而不是 `invalid_parameter`。不要仅凭 `400` 要求调用方修改生成参数,也不要无限重试。离线错误的提示不承诺模型会在短时间内恢复。 ### 生成音频的版权审核失败 如果识别到生成音频的版权限制,`error.code` 仍为 `content_policy_violation`,`error.message` 会明确说明生成的音频可能触及版权限制。这不代表调用方上传了侵权音频;没有音频输入时,自动生成的音乐等内容也可能未通过审核。 可尝试关闭音频生成,或在模型支持参考音频时使用自有或已获授权的音频。具体写法见[视频生成参数](/docs/zh/media-tasks#请求参数)。这些调整不保证通过其他内容安全审核。如认为审核有误,请保留任务 `id` 和 `request_id` 联系支持。异步任务已返回 `failed` 时应停止轮询,不要无限重试生成。 ### 上下文超限与客户端恢复 已识别的上下文窗口超限保留 `error.type: "invalid_request_error"` 和 `error.code: "input_too_large"`。文案以 `prompt is too long` 开头,供兼容客户端识别。如果能够取得实际输入 token 数和上限,CR 会同时返回这两个数字: ```json { "error": { "type": "invalid_request_error", "code": "input_too_large", "message": "prompt is too long: 1045171 tokens > 1000000 maximum; shorten or compact the conversation and retry" }, "request_id": "0199c9e6-9381-7f30-9aa0-0df86dca6cdf" } ``` CR 生成上述说明,不返回模型服务标识或原始诊断文案。图片、视频和 HTTP 请求体大小超限不使用这个上下文标识。 是否自动压缩仍取决于客户端版本、配置和会话状态,CR 不代替客户端压缩历史。如果 Claude Code 无法自动恢复,可使用 `/compact` 手动压缩,详见 [Claude Code 网关排障说明](https://code.claude.com/docs/en/llm-gateway-connect#troubleshoot-gateway-errors)。修改 `max_tokens` 不会删除已经包含在请求中的历史消息。 ### 异步任务失败 异步任务终态(`status: "failed"`)使用同一套错误码,另有两个: | `error.code` | 含义 | | --- | --- | | `task_cancelled` | 任务被取消 | | `task_failed` | 任务失败,未提供更具体的原因,等价于任务侧的 `upstream_request_failed` | 客户端应兼容新增错误码。无法识别的错误码按通用失败处理,不影响 `status: "failed"` 的终态判断。查询请求暂时失败不代表生成任务失败;保留任务 ID 重试查询,不要自动重新提交生成请求,以免重复生成和计费。 ## 来自网关的错误 这些错误由 CR 自身产生,发生在调用模型之前,或替代了模型调用。 本地媒体参数校验失败使用 `invalid_parameter`,并保留可安全公开的原因。`error.param` 指向请求中的字段,例如 `content[1].image_url.url`、`image[0]` 或 `provider_options.image_urls[0]`。例如,只接受 HTTP(S) 媒体 URL 的模型收到 data URL 时,错误对象如下: ```json { "error": { "type": "invalid_request_error", "code": "invalid_parameter", "message": "content[1].image_url.url: URL scheme must be HTTP(S) (url_kind=data); expected an HTTP(S) media URL", "param": "content[1].image_url.url" }, "request_id": "01a09ec9-7d00-7000-8000-000000000001" } ``` 这类错误不回显原始 URL、签名参数、凭据、提示词或 Base64 内容。模型服务的错误只返回 CR 归类后的原因;无法安全确定具体字段时,`param` 可以省略。异步任务在收到 `202` 后也可能因本地参数校验变为 `failed`,应停止轮询并修正参数。 | `error.code` | HTTP | 含义 | | --- | --- | --- | | `invalid_api_key` | 401 | API Key 缺失、格式错误或已吊销 | | `insufficient_balance` | 402 | API Key 余额不足以支撑本次请求 | | `model_access_denied` | 403 | 策略禁止该 Key 访问此模型 | | `model_not_found` | 404 | 模型不存在 | | `model_disabled` | 404 | 模型存在但已停用 | | `task_not_found` | 404 | 任务不存在,或不属于该 Key | | `no_routes_available` | 503 | 该模型没有可用路由 | | `provider_unavailable` | 502 | CR 无法为该模型的路由构造请求 | | `missing_model` | 400 | 请求体缺少 `model` | | `invalid_body` | 400 | 请求体不是合法的 JSON 或表单 | | `conflicting_reasoning_parameters` | 400 | 重复指定了不同的推理档位,或扩展参数与标准档位冲突;按接口保留一种标准写法 | | `invalid_reasoning_parameters` | 400 | 标准推理档位的值或类型非法 | | `unsupported_reasoning_parameters` | 400 | 所选模型的可用线路均明确不支持请求中的标准推理档位 | | `unsupported_content_type` | 400 | 该路径不支持此 content type | | `payload_too_large` | 413 | 请求体超过大小上限 | | `reserved_parameter` | 400 | `provider_options` 中出现了 `callback_url` 等保留名 | | `invalid_callback_url` | 400 | `callback_url` 不是可接受的 HTTPS 地址 | | `callback_unavailable` | 503 | CR 无法登记或持久化回调 | | `media_unavailable` | 503 | 媒体下载服务暂不可用 | | `endpoint_not_available` | 501 | 该模型不在此接口上提供 | | `request_rebuild_failed` | 500 | CR 无法准备模型请求 | | `router_loop_detected` | 508 | 语义路由请求已被路由过一次 | ## 流式过程中的错误 流式响应一旦返回 `200`,CR 无法再改变状态码。连接仍可写入时,之后发生的失败会以流内的错误事件返回。客户端或代理已断开连接时,错误可能只记录在服务端,客户端无法再收到错误事件。 CR 在转发完整错误事件前,将模型的错误类别、错误码和文案替换为上方的 CR 错误码,不转发其诊断 URL、request ID 或调试字段。错误事件之前的正常输出保留;用量仍按已收到的有效用量结算。 事件结构随接口保持兼容:Chat Completions 和 Anthropic Messages 从 `error.code` 读取原因;Responses 的 `error` 事件从顶层 `code` 读取,`response.failed` 事件从 `response.error.code` 读取。所有这些事件都表示该流失败。 CR 生成的流式错误及服务端失败记录使用以下错误码: | `error.code` | 含义 | | --- | --- | | `upstream_stream_idle_timeout` | 模型长时间未发送数据 | | `upstream_stream_deadline_exceeded` | 流超过总时长限制 | | `upstream_stream_read_error` | 流意外中断 | | `downstream_stream_write_error` | CR 向客户端写入流失败,例如客户端或代理断开连接;这是下游连接失败,不代表模型失败 | | `upstream_stream_incomplete` | 流在终止事件之前结束 | | `upstream_stream_error` | 服务端记录模型以错误结束了该流;客户事件使用上方归类后的 CR 原因码 | | `upstream_sse_line_too_large` | 单个事件超过大小上限 | 流在缺少终止事件的情况下结束时,即使已收到部分内容也应视为失败,不要将部分内容标记为完整结果。中断前可能已经产生用量,最终费用以本次调用的账单为准。 ## 有界重试 只对临时网络错误、429 和部分 5xx 进行有限重试。使用指数退避和随机抖动,并设置最大次数和业务截止时间。先修正认证、权限和参数错误,不要自动重试。 生成类 POST 超时不能证明任务未创建。直接重新提交可能创建重复任务并再次计费。 ## 联系支持 如果问题仍未解决,向团队管理员或 CR 服务支持提供“定位请求”中的信息,并使用最小的脱敏输入复现问题。 # 生成视频 URL: https://creative-reasoning.com/docs/zh/video-async 视频生成返回任务 ID。提交后查询同一任务,完成后读取视频下载链接。 ## 准备 API Key 在 [API Key 页面](https://creative-reasoning.com/console/keys)创建或复制完整 API Key,将 `API_KEY` 替换为密钥。不要使用 Key 前缀或 API Key ID。以下请求使用生产 API `https://api.creative-reasoning.com`。 ## 提交视频任务 ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/videos/tasks' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "creative-reasoning-video-1.0", "content": [ { "type": "text", "text": "海边日落,镜头缓慢向前推进" } ], "duration": 4, "resolution": "480p", "aspect_ratio": "16:9" }' ``` 首次受理返回 HTTP `202`。下面是响应结构示例,ID 为示意值。保存实际响应的 `id`;`pending` 表示等待执行,还没有生成结果。 ```json { "id": "01a09ec9-7d00-7000-8000-000000000001", "status": "pending", "created_at": 1789370400, "model": "creative-reasoning-video-1.0", "poll_url": "/unified/v1/tasks/01a09ec9-7d00-7000-8000-000000000001" } ``` ## 查询并读取结果 用响应中的 `id` 替换 `TASK_ID_FROM_SUBMIT_RESPONSE`,并使用提交时的同一 API Key: ```bash curl 'https://api.creative-reasoning.com/unified/v1/tasks/TASK_ID_FROM_SUBMIT_RESPONSE' \ -H 'Authorization: Bearer API_KEY' ``` 查询返回 HTTP `200` 时,仍需判断 `status`。`pending`、`processing` 表示继续等待,可每隔 5 秒查询一次并设置总等待上限;到期后保留 ID,稍后继续查询。`failed` 表示生成失败,读取 `error.code` 和 `error.message`。只有 `completed` 才读取 `data`。 下面是完成响应的结构示例,媒体内容及 URL 凭证均为占位值: ```json { "id": "01a09ec9-7d00-7000-8000-000000000001", "status": "completed", "created_at": 1789370400, "model": "creative-reasoning-video-1.0", "completed_at": 1789370460, "data": [ { "type": "video", "url": "https://api.creative-reasoning.com/_cr/v1/media/video/01a09ec9-7d00-7000-8000-000000000001/OPAQUE_VIDEO_TOKEN" } ] } ``` 使用 `data[].url` 的完整链接播放或下载,不要解析或重新拼接 URL。`OPAQUE_VIDEO_TOKEN` 为示意值。真实视频链接自生成起最多有效 24 小时,源文件提前过期时也会提前失效;下载不需要附加 API Key。链接本身包含访问凭证,请及时保存到自己的存储。 ## 使用首帧或参考图 选择 `creative-reasoning-video-1.0-i2v`,并在 `content` 中加入首帧图片。示例使用公开示例图片,实际接入时换成你自己的可访问 URL: ```bash curl -X POST 'https://api.creative-reasoning.com/unified/v1/videos/tasks' \ -H 'Authorization: Bearer API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "model": "creative-reasoning-video-1.0-i2v", "content": [ { "type": "text", "text": "白色长毛猫在绿色草地上缓慢向镜头走来,尾巴轻轻摆动,阳光柔和,固定镜头,保持图片中猫的外观。" }, { "type": "image_url", "image_url": { "url": "https://cdn.translate.alibaba.com/r/wanx-demo-1.png" }, "role": "first_frame" } ], "duration": 4, "resolution": "480p", "aspect_ratio": "16:9" }' ``` 改用参考图引导时,将 `model` 改为 `creative-reasoning-video-1.0-r2v`,图片 `role` 改为 `reference_image`。这两种请求都按上面的提交、查询和结果处理流程完成。首帧、尾帧和参考图的数量及格式见[视频模型参数](/docs/zh/media-tasks#视频模型支持范围)。 ## 调整视频参数 这三个模型的 `duration` 接受 4–15 秒整数;`resolution` 可使用 `480p`、`720p`、`1080p`;`aspect_ratio` 支持横屏、竖屏、方形及自动比例。完整取值、默认值和模型差异见[参数表](/docs/zh/media-tasks#视频模型支持范围)。输入素材类型由模型决定,不能只更改模型名称后照搬全部媒体输入。实际宽高、时长与声音状态从[结果字段](/docs/zh/media-tasks#读取视频结果字段)读取,缺失时不要用请求值代替。 ## 回调与失败恢复 - 可在提交正文顶层添加自己的 HTTPS `callback_url`。收到的终态与查询结果相同;以任务 `id` 去重。地址约束和重投规则见[回调说明](/docs/zh/media-tasks#使用-callback_url-接收通知)。 - 需要安全重试提交时,添加 `Idempotency-Key: YOUR_UNIQUE_OPERATION_ID`。这是调用方为本次业务操作生成并保存的唯一编号,不是密钥。相同操作重试必须复用该编号和原请求正文。 - 已有任务 ID 时查询原任务。没有幂等键且提交超时时,不要盲目重发 POST,以免重复生成和计费。 - `401` 检查 API Key;`404` 查询时检查 ID 和是否使用原 Key;`failed` 读取错误原因;`410 task_expired` 表示结果正文已过期。完整恢复规则见[任务错误与幂等提交](/docs/zh/media-tasks#避免重复生成与处理错误)。 ## 兼容接口 已有接入可继续使用 `/unified/v1/videos/generations`;该接口也返回异步任务,查询路径与本页不同。详情见[视频兼容接口](/docs/zh/media-tasks#视频生成兼容接口)。新旧提交接口不共享幂等键。 ## 图片与视频 Skill 需要让 Claude Code 或 Codex 用自然语言生成、编辑图片和视频时,安装 [cr-media Skill](/docs/zh/integrations/cr-media)。该指南包含插件与 `npx skills` 安装、升级、API Key 配置,以及本地参考图和 URL 的使用限制。