This guide is for customer developers implementing model and search APIs.
This guide is for customer developers implementing model and search APIs. Customers provide service endpoints, model IDs and optional API keys conforming to this protocol; QwenWork makes the calls.
Call direction: QwenWork → Customer service; responses travel in the opposite direction. Implement only the capabilities you need. Example domains, model IDs, content and request identifiers may be replaced; field names, structure, status values and event names must remain unchanged.
Read by capability: Chat · Asynchronous tasks · Images · Video · Music · Realtime speech recognition · Search.
Protocol names are not sent in request bodies. model is the actual model ID; search requests do not send model.
Implement requests and responses for each capability according to its chapter. Explicitly reject unsupported parameters.
Customers provide complete call URLs. Asynchronous images and video also require a complete query URL containing {task_id}. For example:
All three correlation headers share the Forward external user ID switch; no separate session or turn switch is needed. Primary-model Agent chat sends each available field independently and omits missing fields. Specialized models and search services forward only the external user ID.
Process these headers as specified. Customer services should allow unused additional headers. Asynchronous endpoints do not need to recognize or validate an asynchronous marker header.
API keys are optional throughout. Correlation headers do not replace authentication. Web search userId/requestId retain their request-body semantics.
Synchronous success returns final results. Asynchronous submission returns a task ID, and a successful query returns output assets. Use the specified fields and nesting without additional response wrappers.
Return downloadable absolute URLs for output assets, with valid, nonempty files in the correct format. Download requests do not carry the API Bearer token. If authentication is required, provide signed URLs with sufficient validity.
Input images support the agreed URLs or Data URIs. Customer services must be able to fetch the URLs or decode the Data URIs.
QwenWork sends POST to the complete configured endpoint:
For stream=true, return Content-Type: text/event-stream and send SSE records, with a blank line after each data: record:
Visual understanding uses the same POST endpoint, with images passed as message content blocks:
The primary-model connectivity preflight sends a short request to the Chat endpoint. Support the following field combination:
Task IDs may contain letters, digits, -, _, . and :, with at most 200 characters; they must not be just . or ... Query response IDs must match the request. Completed tasks must not return to a processing state. Known tasks must remain queryable throughout the agreed retention period, including after customer-service restarts.
Example task failure:
Sync and Async share the request structure below. Sync must return images in the same response; Async must provide submission and query endpoints.
Text-to-image POST request:
Output PNG; editing accepts 1–3 input images. Supported sizes: 1024*1024, 1536*1024, 1024*1536, 2048*2048, 2048*1152, and automatic sizing with size omitted. Confirm support before integration.
Return HTTP 200 and Content-Type: application/json to the same POST:
Submit the same request body to the Async endpoint, which first returns a task:
Use the asynchronous submission and query flow from section 4. Basic request:
input.media determines the generation mode; no separate operation is sent:
The following fields are sent only when specified; otherwise they are omitted. Confirm support before integration. Do not silently ignore valid values; return a parameter error for unsupported ones.
Send POST to the complete music endpoint and return the audio URL in the same HTTP response:
Both interfaces perform bidirectional streaming recognition: audio is sent continuously while transcription results are received. Select audio encoding and control events according to the endpoint.
The endpoint is /api-ws/v1/inference. The model ID is in the message body; the URL has no query.
The endpoint is /api-ws/v1/realtime. The URL carries ?model=<model ID>. The handshake also includes OpenAI-Beta: realtime=v1.
The customer service returns session.created; QwenWork sends configuration and waits for session.updated:
Both search types use POST / JSON with optional keys. Their request and response structures are shown below.
The basic request is below. Actual requests may also include the extension fields in the table. Empty strings, nulls or empty arrays indicate unspecified conditions and may be ignored.
Optional extensions
Extension fields may be sent with empty values. Apply nonempty filters. Explicitly reject unsupported or conflicting conditions; do not return unfiltered results as success.
Successful response:
The customer service receives only the search query:
402 is the fixed business code for insufficient quota; 429 indicates request rate limiting only. Other names are suggestions. Existing stable business codes may be retained if their meanings are documented with the API. HTTP semantics must match the response structures below. 429/503 may carry Retry-After, but this does not guarantee a caller retry. A generation timeout or lost response may occur after task creation and must not trigger duplicate generation.
When insufficient quota prevents a new request, return HTTP 402 with the business code in the endpoint's error structure. Do not retry it as transient rate limiting until quota is restored.
After SSE / WebSocket establishment, return an error event; the handshake or response status cannot be changed. Asynchronous task queries and search business errors may remain HTTP 200, using 402 in the appropriate field to indicate insufficient quota.
Rejected chat request (HTTP 402):
For non-2xx responses, error.code, error.type and error.message are nonempty strings; error.param is optional:
Use non-2xx for failed submissions or synchronous requests. code and message are nonempty strings; request_id supports troubleshooting:
Use non-2xx for failures before the handshake. After connection establishment, return errors through the corresponding events.
Binary audio interface: header.error_code and header.error_message are nonempty strings; task_id matches the request.
HTTP 200 business errors must contain an integer errorCode and a nonempty string errorMsg. Prefer values corresponding to the HTTP status table above, or use agreed nonzero integer business codes.
Web search failure:
For each capability, provide the protocol name, model ID (except search), complete endpoint, authentication method, and a query endpoint for asynchronous images/video. Explicitly specify Sync or Async for images, and the endpoint and audio encoding (binary or Base64) for ASR.
Also document supported input types, image counts/sizes, video modes/durations, asset access, output URL validity, task retention, timeouts and concurrency limits. Deliver credentials separately; do not put them in examples or integration logs.
Validate actual generation separately from protocol parsing: correct JSON does not prove usable images, video or audio. For successful calls, record request identifiers, HTTP status, task state and asset validation results. Avoid storing credentials or original user content.
1. Protocol and endpoint inventory
| Capability | Integration contract | Method / transport | Completion response from the customer service |
|---|---|---|---|
| Primary model, visual understanding and speech text polishing | Chat Completions | POST; JSON or SSE | choices[].message or choices[].delta |
| Synchronous image generation/editing | QwenWork Image Sync | POST; JSON | Returns output.choices[].message.content[].image in the same response |
| Asynchronous image generation/editing | QwenWork Image Async | POST submission + GET query | Submission returns a task ID; a successful query returns an image list |
| Video generation | QwenWork Video | POST submission + GET query | Submission returns a task ID; a successful query returns output.video_url |
| Music generation | QwenWork Music | POST; JSON | Returns output.audio.url in the same response; MP3 audio |
| Realtime ASR | QwenWork Realtime | WebSocket | Bidirectional streaming; binary or Base64 audio, see section 8 |
| Web search | QwenWork Search | POST; JSON | pageItems |
| Image search | QwenWork Search | POST; JSON | imageItems |
2. Common connection conventions
2.1 Endpoint and protocol selection
Customers provide complete call URLs. Asynchronous images and video also require a complete query URL containing {task_id}. For example:
| Contract | Example call endpoint | Example query endpoint |
|---|---|---|
| Chat Completions | https://service.example/chat/completions | None |
| QwenWork Image Sync | https://service.example/images/generate | None |
| QwenWork Image Async | https://service.example/images/jobs | https://service.example/images/jobs/\{task\_id\} |
| QwenWork Video | https://service.example/videos/jobs | https://service.example/videos/jobs/\{task\_id\} |
| QwenWork Music | https://service.example/music/generate | None |
| QwenWork Realtime, binary audio | wss://service.example/api-ws/v1/inference | None |
| QwenWork Realtime, Base64 audio | wss://service.example/api-ws/v1/realtime | None |
| Web / image search | https://service.example/search/web / https://service.example/search/images | None |
- Explicitly choose Sync or Async for images. Both support custom paths. Sync has no query endpoint; Async requires one.
- ASR paths must retain the /api-ws/v1/inference or /api-ws/v1/realtime suffix; a gateway prefix may be added.
- K8S supports HTTP(S), WS(S), cluster domains, private IPs and custom ports. The URL must be reachable from the QwenWork service network. TLS requires a valid certificate chain.
- HTTP endpoints must not include a query, fragment or URL credentials. Section 8 describes the ASR model query exception. Endpoints must respond directly without redirects. /v1 is not automatically appended to complete endpoints.
2.2 Headers and authentication
| Header | Sent when | Requirement |
|---|---|---|
| Content-Type: application/json | HTTP JSON requests | Parse as UTF-8 JSON |
| Authorization: Bearer <API Key> | An API key is configured | Validate the agreed integration key |
| No Authorization | No API key is configured | Provide the agreed keyless endpoint; no placeholder key is required |
| OpenAI-Beta: realtime=v1 | Base64 audio ASR handshake | See section 8.2 |
| X-QwenWork-External-User-Id | External user ID forwarding is enabled and the ID is available | User correlation identifier |
| X-QwenWork-Session-Id | External user ID forwarding is enabled for primary-model Agent chat and the session ID is available | Session correlation identifier |
| X-QwenWork-Turn-Id | External user ID forwarding is enabled for primary-model Agent chat and the turn ID is available | Turn correlation identifier |
2.3 Success, failure and file results
Synchronous success returns final results. Asynchronous submission returns a task ID, and a successful query returns output assets. Use the specified fields and nesting without additional response wrappers.
Return downloadable absolute URLs for output assets, with valid, nonempty files in the correct format. Download requests do not carry the API Bearer token. If authentication is required, provide signed URLs with sufficient validity.
Input images support the agreed URLs or Data URIs. Customer services must be able to fetch the URLs or decode the Data URIs.
3. Chat Completions: primary models, visual understanding and speech text polishing
3.1 Standard request and response
QwenWork sends POST to the complete configured endpoint:
The customer service returns:
model is the actual model ID. Preserve the order of system, user, assistant and tool entries in messages. Message content may be a string or an array of content blocks.
3.2 Streaming output and tool calls
For stream=true, return Content-Type: text/event-stream and send SSE records, with a blank line after each data: record:
Agent models must also support tools, tool_choice, assistant tool_calls and tool-role tool_call_id. Return streaming tool calls through delta.tool_calls, distinguishing tools with stable index/id values. function.arguments is a JSON string that may arrive in concatenable segments. Use finish_reason: "tool_calls" when tool calls are complete.
Support stream_options.include_usage=true and return usage before the stream ends. Do not fabricate zero usage when it is unknown. Agree on reasoning and other extension parameters separately.
Example tool request:
Example response when the model requests a tool call:
The next request includes this assistant message and a tool result such as {"role":"tool","tool_call_id":"call-001","content":"已发货"}. Preserve their association; do not rewrite tool results as unrelated ordinary user text.
3.3 Image input
Visual understanding uses the same POST endpoint, with images passed as message content blocks:
Images may also be Data URIs; process them according to the agreed input formats. Speech text polishing uses plain-text messages and returns improved text.
3.4 Integration preflight request
The primary-model connectivity preflight sends a short request to the Chat endpoint. Support the following field combination:
The preflight includes enable_thinking=false. Accept this field and disable reasoning.
4. Shared asynchronous task flow for images and video
The endpoint protocol determines asynchronous submission; no additional header is needed to enable it. Customer services accept submission requests directly and return a task ID.
Submission and queries use the same optional API key from model configuration. Queries use an agreed complete URL, such as https://media.example/tasks/\{task\_id\}. The placeholder must occur exactly once and occupy an entire path segment. Do not specify a different query server through the submission response.
Successful submission returns 2xx JSON; 202 + Location is not required:
A query while processing returns:
| output.task_status | State reported by the customer service |
|---|---|
| PENDING | Accepted and waiting to execute |
| RUNNING | Executing |
| SUCCEEDED | Succeeded; query results must include downloadable assets |
| FAILED | Execution failed; return output.code/message |
| CANCELED | Canceled |
| UNKNOWN | Task absent, expired or in an indeterminate state |
A lost submission response does not mean the task was not created. Treat the result as unknown; do not depend on QwenWork resending the generation POST. Queries can continue checking the original task.
5. QwenWork Image Sync / Async: image generation and editing
5.1 Differences between the two contracts
| Item | QwenWork Image Sync | QwenWork Image Async |
|---|---|---|
| Request body | model/input/parameters from section 5.2 | Same |
| First HTTP response | Final image results | output.task_id/task_status |
| Subsequent query | None | GET the configured query endpoint |
| Final image field | output.choices[].message.content[].image | Same field in the successful query response |
5.2 Shared request body
Text-to-image POST request:
For image editing, reference images precede the text; the same endpoint accepts:
| Field | Type / requirement | Constraint |
|---|---|---|
| model | required string | Agreed actual model ID |
| input.messages | required array, one user message | Read content here, not from the top-level Chat messages field |
| content[].text | nonempty string | Prompt, at most 2500 characters |
| content[].image | supplied for editing, one image per item | Accept URLs / agreed Data URIs and preserve reference order |
| parameters.n | required integer | Requested count, 1–4 |
| parameters.size | optional string | Width*height; omit for automatic sizing rather than sending auto |
| parameters.watermark | required boolean | Honor the watermark requirement; clarify unsupported behavior during integration |
5.3 Sync success and failure responses
Return HTTP 200 and Content-Type: application/json to the same POST:
QwenWork reads output.choices[].message.content[].image in order. Return one image item per image; type is optional. Return at least one valid image and no more than the requested n, with URLs immediately downloadable. Sync does not require task_id/task_status, and their presence does not start polling.
Use non-2xx statuses for failure, such as HTTP 400 for unsupported parameters:
Missing images, invalid URLs or undownloadable files are not successful generation. The Sync endpoint and intermediate gateways must allow the full generation duration. A generation timeout leaves the result unknown; do not automatically resubmit.
5.4 Async submission and query responses
Submit the same request body to the Async endpoint, which first returns a task:
Then poll as described in section 4. GET response for a successful task:
Use the fixed task-status enumeration from section 4. Queries must return the same task_id, and SUCCEEDED queries must contain images. Even if submission immediately returns SUCCEEDED, subsequent queries must retrieve final assets. Do not substitute the submission response for a query endpoint.
6. QwenWork Video: video generation
Use the asynchronous submission and query flow from section 4. Basic request:
6.1 Basic parameters
| Field | Type | Requirement |
|---|---|---|
| model | string | Actual model ID |
| input.prompt | string | Nonempty prompt, at most 2500 characters |
| input.media | optional array | Reference images, formatted as shown below |
| parameters.duration | optional integer | Duration, 4–15 seconds |
| parameters.resolution | optional string | 480P, 720P, 1080P |
| parameters.watermark | boolean | Whether to add a watermark |
| parameters.prompt_extend | boolean | Always sent as false; accept this value without requiring prompt expansion |
| Mode | media contents |
|---|---|
| Text-to-video | Omitted |
| Image-to-video | [{"type":"first_frame","url":"https://assets.example/first.png"\}\] |
| First and last frames | One first_frame and one last_frame, each with a url |
| Multiple reference images | Multiple reference_image items, each with a url |
6.2 Optional extensions
The following fields are sent only when specified; otherwise they are omitted. Confirm support before integration. Do not silently ignore valid values; return a parameter error for unsupported ones.
| Field | Type | Meaning |
|---|---|---|
| parameters.ratio | string | Aspect ratio: adaptive, 16:9, 4:3, 1:1, 3:4, 9:16 |
| parameters.audio | boolean | true generates an audio track; false does not |
| parameters.seed | integer | Random seed, 0–2147483647 |
6.3 Successful query
video_url must point to a downloadable MP4. See sections 4 and 10 for failure states and formats.
7. QwenWork Music: music generation
Send POST to the complete music endpoint and return the audio URL in the same HTTP response:
| Field | Type | Constraint |
|---|---|---|
| model | string | Actual model ID |
| input.prompt | string | Nonempty music description, at most 2000 characters |
| input.lyrics | optional string | Lyrics, at most 20000 characters; use them when supplied |
| input.is_instrumental | optional boolean | true generates instrumental music; do not provide lyrics in this case |
| input.format | string | Fixed at mp3 |
| input.enable_aigc_watermark | boolean | Whether to add a watermark |
Return output.audio.url in the same HTTP response. audio.id is only an audio identifier; there is no task query. The endpoint and gateways must support long generation requests.
8. QwenWork Realtime: realtime speech recognition
Both interfaces perform bidirectional streaming recognition: audio is sent continuously while transcription results are received. Select audio encoding and control events according to the endpoint.
8.1 Realtime streaming ASR (binary audio)
The endpoint is /api-ws/v1/inference. The model ID is in the message body; the URL has no query.
- Complete the WebSocket handshake, including a Bearer header if a key is configured.
- QwenWork sends run-task; the customer service responds with task-started.
- QwenWork starts sending PCM16, mono, 16 kHz binary audio frames; the customer service continuously returns recognition results.
- QwenWork sends finish-task; the customer service returns remaining results and task-finished.
Customer-service ready message:
Recognition result:
sentence_id identifies sentences starting at 1. Text with sentence_end=false may be revised by later results for the same sentence; only true marks final text. usage.duration is cumulative task usage, not a per-sentence amount to sum. A sentence ending does not end the task.
Finish message and acknowledgement:
On task failure, send header.event: "task-failed" with the same task_id, header.error_code and header.error_message. Disconnecting does not replace a normal finish event.
8.2 Realtime streaming ASR (Base64 audio)
The endpoint is /api-ws/v1/realtime. The URL carries ?model=<model ID>. The handshake also includes OpenAI-Beta: realtime=v1.
The customer service returns session.created; QwenWork sends configuration and waits for session.updated:
Audio is sent in JSON text frames; audio is the Base64 encoding of PCM bytes:
The customer service returns preview text through conversation.item.input_audio_transcription.text and final text in transcript of conversation.item.input_audio_transcription.completed. Use item_id to correlate the same transcription. QwenWork finally sends session.finish; the customer service sends session.finished and ends the session. Use the native error event for errors.
Minimal server event examples; send each JSON object as a separate WebSocket text message:
QwenWork finish request and server acknowledgement:
See section 10.3 for error formats for both realtime speech interfaces.
9. QwenWork Search: web and image search
Both search types use POST / JSON with optional keys. Their request and response structures are shown below.
9.1 Web search
The basic request is below. Actual requests may also include the extension fields in the table. Empty strings, nulls or empty arrays indicate unspecified conditions and may be ignored.
Basic fields
| Field | Type | Meaning |
|---|---|---|
| query | string | Nonempty search query |
| count | integer or null | Requested result count |
| contents | object or null | mainText, markdownText and summary are booleans specifying the requested body formats or summary |
| Field | Type | Meaning |
|---|---|---|
| timeRange | string | OneDay, OneWeek, OneMonth, OneYear, NoLimit or empty: past day, week, month, year, or unrestricted time |
| site | string | Restrict to a site |
| allowed_domains | string[] or null | Allowed domains |
| blockSites, blocked_domains | string[] or null | Excluded sites or domains; accept both |
| category, recency | string | Category or time extensions; agree on nonempty value semantics separately |
| userId, requestId | string | Optional correlation identifiers, not authentication credentials |
pageItems is an ordered array. Return body text and summaries according to contents. Optional result fields include mainText, summary, publishedTime, hostname and hostLogo. Omit unknown fields. Return {"pageItems":[]} for empty results. The default timeout is 3 seconds. See section 10.4 for errors.
9.2 Image search
The customer service receives only the search query:
Successful response:
imageUrl points to an accessible image file. Width and height may be omitted or null. Return {"imageItems":[]} for no results. Requests do not send count.
On success, omit errorCode/errorMsg; do not return errorCode=0. The default timeout is 5 seconds, with a 4 MiB response-body limit. See section 10.4 for errors.
10. Error codes and failure responses
Common requirements
- Error codes must be stable, nonempty and suitable for programmatic handling. Messages must be nonempty and readable, without credentials or stack traces.
- Reject unaccepted requests with an appropriate non-2xx status. Report failures of accepted asynchronous tasks through task queries.
- Search business errors may use HTTP 200 but must include error fields. Other endpoints must not merely append error text to ordinary success responses.
- Do not hide failures with empty results, empty assets or success states.
| Scenario | HTTP status | Suggested code (string) |
|---|---|---|
| Invalid or unsupported parameter | 400 | InvalidParameter / UnsupportedParameter |
| Missing or invalid key | 401 | Unauthorized |
| Insufficient quota | 402 | "402" (fixed business code) |
| Access denied | 403 | Forbidden |
| Model or task not found | 404 | ModelNotFound / TaskNotFound |
| Request body too large | 413 | PayloadTooLarge |
| Request rate or concurrency limit | 429 | RateLimitExceeded |
| Internal service error | 500 | InternalError |
| Service temporarily unavailable | 503 | ServiceUnavailable |
| Dependency timeout | 504 | Timeout |
Insufficient quota: 402
When insufficient quota prevents a new request, return HTTP 402 with the business code in the endpoint's error structure. Do not retry it as transient rate limiting until quota is restored.
| Response scenario | Error field | Value |
|---|---|---|
| Chat request / SSE error event | error.code | string: "402" |
| Failed image, video or music request | code | string: "402" |
| Failed accepted asynchronous task | output.code, with output.task_status=FAILED | string: "402" |
| Binary audio ASR failure event | header.error_code | string: "402" |
| Base64 audio ASR failure event | error.code | string: "402" |
| Web / image search business failure | errorCode | integer: 402 |
Web search business failure (HTTP 200):
10.1 Chat APIs
For non-2xx responses, error.code, error.type and error.message are nonempty strings; error.param is optional:
After SSE starts, the HTTP status cannot change. Send the same error object and end the stream without a normal completion result:
10.2 Images, video and music
Use non-2xx for failed submissions or synchronous requests. code and message are nonempty strings; request_id supports troubleshooting:
When an accepted asynchronous task fails, GET queries return HTTP 200 with the same task_id and errors inside output:
Use CANCELED for cancellation. Use UNKNOWN for indeterminate or expired tasks, never SUCCEEDED. If the query request itself fails, use non-2xx with top-level code/message. A nonexistent task may explicitly return 404 / TaskNotFound.
10.3 Realtime speech recognition
Use non-2xx for failures before the handshake. After connection establishment, return errors through the corresponding events.
Binary audio interface: header.error_code and header.error_message are nonempty strings; task_id matches the request.
Base64 audio interface: error.code, error.type and error.message are nonempty strings.
Do not substitute normal finish events for failure events.
10.4 Web and image search
HTTP 200 business errors must contain an integer errorCode and a nonempty string errorMsg. Prefer values corresponding to the HTTP status table above, or use agreed nonzero integer business codes.
Web search failure:
Image search failure:
On success, omit errorCode/errorMsg; do not use errorCode: 0. Actual empty results are still successful and return only an empty result array. Non-2xx indicates request failure and may include {"code":"ServiceUnavailable","message":"Search service unavailable."}.
11. Integration testing and delivery requirements
11.1 Deliver endpoint details
For each capability, provide the protocol name, model ID (except search), complete endpoint, authentication method, and a query endpoint for asynchronous images/video. Explicitly specify Sync or Async for images, and the endpoint and audio encoding (binary or Base64) for ASR.
Also document supported input types, image counts/sizes, video modes/durations, asset access, output URL validity, task retention, timeouts and concurrency limits. Deliver credentials separately; do not put them in examples or integration logs.
11.2 Minimum protocol acceptance cases
| API | Required cases |
|---|---|
| Chat Completions | JSON, normal SSE completion, usage, tool-call IDs and arguments deltas; VL also validates image content blocks |
| Image Sync | Text-to-image, editing and multi-image responses; actual images in the same POST response with no subsequent query |
| Image Async | Submission, processing queries, successful images, failure and querying the original task after an instance restart |
| Video | Input mapping for each enabled mode, task states and downloadable MP4 |
| Music | model, prompt, optional lyrics, watermark and playable MP3 in the same response |
| ASR | Handshake, readiness event, audio encoding, interim/final text, normal completion and failure events |
| WebSearch | All fields/nulls, normal results, empty results, non-2xx and business errors |
| ImageSearch | query-only, imageItems, empty results and errorCode=0 recognized as failure |
| Common behavior | Agreed keyed/keyless access, invalid credentials, invalid parameters, timeouts, invalid assets and expired URLs |
11.3 Common issues
| Symptom | Check first |
|---|---|
| HTTP 200 but generation is considered failed | Required result fields, an unexpected generic data wrapper and downloadable asset URLs |
| Synchronous image generation never produces a result | Whether final images are returned and the gateway times out early |
| Asynchronous task cannot be found | Stable task_id, correct GET path substitution and querying the same task across instances |
| Image editing produces incorrect content | Ordered image content blocks and request parsing from input.messages |
| Image search reports success but produces an error | errorCode=0 or incorrect result fields such as pageItems/data |
| ASR has no transcription or cannot finish | Mixed binary/Base64 encoding, missing readiness or task-finished/session.finished events |