Guide · Images with Qwen3 VL

Read an image with Qwen3 VL

4 steps · about 2 minutes

  1. Get a free key

    Sign in with Google at synap.linkrra.com — no card. Your key starts with sk-pool-.

  2. Pick the vision model

    qwen/qwen3-vl-30b-a3b-instruct is the model on this fleet that reads images. Everything else about the request is ordinary chat.

    MODEL = "qwen/qwen3-vl-30b-a3b-instruct"
  3. Send the image as base64

    The standard OpenAI content array, with an image_url part. A data URL always works, whatever your network allows.

    import base64
    
    b64 = base64.b64encode(open("photo.png", "rb").read()).decode()
    
    r = client.chat.completions.create(
        model=MODEL,
        messages=[{"role": "user", "content": [
            {"type": "text", "text": "What is in this image?"},
            {"type": "image_url",
             "image_url": {"url": f"data:image/png;base64,{b64}"}},
        ]}],
    )
    print(r.choices[0].message.content)
    const b64 = fs.readFileSync("photo.png").toString("base64");
    
    const r = await client.chat.completions.create({
      model: MODEL,
      messages: [{ role: "user", content: [
        { type: "text", text: "What is in this image?" },
        { type: "image_url",
          image_url: { url: `data:image/png;base64,${b64}` } },
      ]}],
    });
    console.log(r.choices[0].message.content);
  4. Or pass a public URL

    We fetch it for you. Some hosts refuse a server-side fetch, so fall back to base64 if it comes back as an error — see the notes.

    {"type": "image_url",
     "image_url": {"url": "https://example.com/photo.png"}}
Notes, prices and limits

The standard OpenAI content array with an image part. Recommended model: qwen/qwen3-vl-30b-a3b-instruct — $0.14 in and $0.55 out per 1M tokens, 65,536-token context.

Run live against this API with openai 2.48.0 and openai 7.47.0, including reading text inside the image: it returned the string painted into the test picture verbatim.

A remote https:// URL is fetched by us, server-side, and some hosts refuse that fetch. The refusal surfaces as a generic 422 — {"error":{"message":"Inference backend error.","type":"upstream_error"}} — which does not say the host blocked it. Base64 has no such dependency, which is why it comes first above and the URL comes after it.

Images count as input tokens, so a large picture costs more than a short prompt. Resize before sending if you are sending many.

One catalogue bug to know about if you build a client on it: /v1/models?format=openrouter reports this model’s input modalities as text only, although image input demonstrably works. Gating an upload button on that field will wrongly hide it. Use the capability field until it is fixed.

On the free tier: every request counts input and output against 100,000 free tokens a day, and answers stop at 4,096 output tokens. Coding agents send long prompts, so the free tier covers a short session; credits cover the rest.

Field names from the OpenAI image-input guide, run against this API, checked 2026-11-03 20:20 UTC. Prices refresh from /v1/models when this page loads.