> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apimart.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# qwen3.8-max Integration Guide

>  - OpenAI-compatible: chat/completions and Responses
- Built-in tools only on Responses; thinking cannot be disabled
- Implicit/explicit context cache; PDF on chat endpoint only
- Billing = token fees + per-call tool fees 

OpenAI SDK compatible: swap `base_url` and `api_key`. Model name is fixed **`qwen3.8-max`**.

```python theme={null}
from openai import OpenAI

client = OpenAI(
    api_key="<your APIMart key>",
    base_url="https://api.apimart.ai/v1",
)

resp = client.chat.completions.create(
    model="qwen3.8-max",
    messages=[{"role": "user", "content": "Describe Hangzhou in one sentence"}],
    stream=False,  # must set explicitly — see below
)
print(resp.choices[0].message.content)
```

Related APIs:

* [Chat Completions](/es/api-reference/texts/general/chat-completions)
* [OpenAI Responses](/es/api-reference/texts/openai/responses)
* [Model pricing API](/es/api-reference/texts/qwen3.8-max/pricing)

## Three easy pitfalls

### 1. `/v1/chat/completions` defaults to **streaming** if `stream` is omitted

```python theme={null}
# Omitting stream → SSE; parsing as non-stream fails
client.chat.completions.create(model="qwen3.8-max", messages=[...])

# Non-stream requires explicit False
client.chat.completions.create(
    model="qwen3.8-max",
    messages=[...],
    stream=False,
)
```

This is **opposite** to OpenAI’s default (omit = non-stream). Easy to miss when porting SDK code.

### 2. Built-in tools work only on `/v1/responses`

`/v1/chat/completions` does **not** support built-in tools (they are ignored with **no error**). For web search, code interpreter, text-to-image search, or image-to-image search, use the [Responses API](/es/api-reference/texts/openai/responses).

### 3. Wrong tool names fail silently

Invalid tool names are accepted quietly. **`t2i_search` / `i2i_search` on pricing pages are not valid tool names**:

| Name you may see          | Actual tool type       |
| ------------------------- | ---------------------- |
| `t2i_search` (pricing UI) | **`web_search_image`** |
| `i2i_search` (pricing UI) | **`image_search`**     |

## Built-in tools (Responses)

Declare in `/v1/responses` `tools` as `{"type": "<name>"}`.

| Tool               | Purpose                                                     | Constraints                                             |
| ------------------ | ----------------------------------------------------------- | ------------------------------------------------------- |
| `web_search`       | Search the web and cite                                     | —                                                       |
| `web_extractor`    | Fetch page body by URL                                      | **Must be declared with `web_search`**; alone → **400** |
| `code_interpreter` | Run code in a sandbox                                       | —                                                       |
| `web_search_image` | **Text→image search** (existing web images, not generation) | —                                                       |
| `image_search`     | **Image→image search**                                      | Provide an image in `input`; slower — prefer streaming  |

### Web search

```python theme={null}
resp = client.responses.create(
    model="qwen3.8-max",
    input="One sentence about Shanghai weather tomorrow",
    tools=[{"type": "web_search"}],
    max_output_tokens=600,
)
```

### Web extract

```python theme={null}
resp = client.responses.create(
    model="qwen3.8-max",
    input="Fetch https://example.com and summarize the first screen",
    tools=[
        {"type": "web_search"},
        {"type": "web_extractor"},  # missing web_search → 400
    ],
)
```

Typical error text:

```text theme={null}
The web_extractor tool must be executed with web_search tool.
```

### Image search

```python theme={null}
resp = client.responses.create(
    model="qwen3.8-max",
    input=[{
        "role": "user",
        "content": [
            {"type": "input_image", "image_url": "https://example.com/your.jpg"},
            {"type": "input_text", "text": "Find similar images"},
        ],
    }],
    tools=[{"type": "image_search"}],
    stream=True,  # recommended: this tool is noticeably slower
)
```

### Confirm a tool was called

Trust **`usage.x_tools`** (billing source of truth):

```json theme={null}
{
  "output": [
    { "type": "reasoning" },
    { "type": "web_search_call" },
    {
      "type": "message",
      "content": [{ "type": "output_text", "text": "..." }]
    }
  ],
  "usage": {
    "input_tokens": 2528,
    "output_tokens": 362,
    "output_tokens_details": { "reasoning_tokens": 280 },
    "x_tools": { "web_search": { "count": 1 } }
  }
}
```

**Tools declared but not invoked are free** — they do not appear in `x_tools`.

## Thinking (reasoning)

**Thinking cannot be turned off.** Every request reasons before answering:

* Thinking tokens bill as **output**, via `output_tokens_details.reasoning_tokens`
* Responses: `reasoning` items in `output`; chat stream: `delta.reasoning_content`
* `enable_thinking: false` is ignored in stream mode; non-stream is degraded — **not recommended**

Output token usage with thinking is often much higher. Cap cost with `max_output_tokens`.

## Context cache

Reuse long prompts to cut input cost.

### Implicit cache (automatic)

Repeated requests with the same prefix may hit cache from the second call; hits bill at cache rates (\~1/8 of normal input). Hit size is block-rounded; **full hit is not guaranteed**.

### Explicit cache

Mark content with `cache_control`:

```python theme={null}
client.chat.completions.create(
    model="qwen3.8-max",
    messages=[
        {
            "role": "system",
            "content": [
                {
                    "type": "text",
                    "text": "<long fixed context>",
                    "cache_control": {"type": "ephemeral"},
                }
            ],
        },
        {"role": "user", "content": "Answer based on the context above"},
    ],
    stream=False,
)
```

| Item              | Notes                                     |
| ----------------- | ----------------------------------------- |
| Min cache content | **≥ 1024 tokens**                         |
| TTL               | **5 minutes**                             |
| Cache create      | Slightly more expensive than normal input |
| Explicit hit      | Usually cheaper than implicit hit         |

Response distinction:

```json theme={null}
// create
"prompt_tokens_details": {
  "cache_creation_input_tokens": 1482,
  "cache_type": "ephemeral",
  "cached_tokens": 0
}

// hit
"prompt_tokens_details": {
  "cache_creation_input_tokens": 0,
  "cache_type": "ephemeral",
  "cached_tokens": 1482
}
```

Implicit hits typically only set `cached_tokens` (may omit `cache_type: "ephemeral"`).

## PDF understanding

Supported **only** on `/v1/chat/completions`. Responses **silently ignores** PDFs (no error).

```python theme={null}
client.chat.completions.create(
    model="qwen3.8-max",
    messages=[{
        "role": "user",
        "content": [
            {
                "type": "file",
                "file": {"file_url": "https://example.com/doc.pdf"},
            },
            # or base64:
            # {"type": "file", "file": {"file_data": "data:application/pdf;base64,...", "filename": "doc.pdf"}}
            {"type": "text", "text": "What is this document about?"},
        ],
    }],
    stream=False,
)
```

* PDFs are understood as images and bill as **image input tokens** (\~letter \~2082 tok/page, A4 \~2147 tok/page order of magnitude); **no extra parse fee**
* `fileid://` is **invalid** here (other-model mechanism) and treated as plain text

## Billing model

Total = **token fees** + **per-call tool fees** (independent).

| Item           | How billed                                                    |
| -------------- | ------------------------------------------------------------- |
| Input          | Per token; cache hits use cache rates                         |
| Output         | Per token; **thinking counts as output**                      |
| Built-in tools | Actual calls in `usage.x_tools` (often priced per 1000 calls) |

Fetch unit prices via the [pricing API](/es/api-reference/texts/qwen3.8-max/pricing):

```http theme={null}
GET /api/pricing/model?model=qwen3.8-max
```

Read `data.pricing.effective_rates` (includes group discount) and `data.pricing.extras.tools`.

## Limits

| Item               | Value                                    |
| ------------------ | ---------------------------------------- |
| Max input          | 983,616 tokens (\~1M)                    |
| Max output         | 131,072 tokens                           |
| Cache read / write | Supported / supported                    |
| Multimodal input   | Images, video, etc. (e.g. `input_image`) |

## FAQ

**Q: I passed `tools` but nothing ran?**\
① Use `/v1/responses`; ② correct tool names (not `t2i_search`); ③ check `usage.x_tools` — missing means not invoked and not billed.

**Q: `web_extractor` returns 400?**\
Declare it together with `web_search`.

**Q: Non-stream is slow?**\
Tool calls (especially `image_search`) take longer. Prefer streaming when timeouts matter.

**Q: Can I disable thinking to save money?**\
No. Cap with `max_output_tokens`, or switch to a model that allows disabling thinking.

**Q: How do I check usage?**

```http theme={null}
GET /v1/dashboard/billing/usage
GET /v1/dashboard/billing/subscription
```
