Integration guides · 2026-10-17

Moondream 3.1 API: base64 images, reasoning and pricing

Call Moondream 3.1 as moondream/moondream3.1-9b-a2b through an OpenAI-compatible API: base64 images, 32,000-token context, reasoning: true and pricing.

Simple diagram: an image and a question go to https://llmtr.com/v1, the box reads Moondream 3.1, and a text answer returns to the application.

Short answer: send the image as a base64 data URL

LLMTR is a gateway that gives access to language models from different providers through one OpenAI-compatible API. You call Moondream 3.1 there with the model id moondream/moondream3.1-9b-a2b on the /v1/chat/completions endpoint at https://llmtr.com/v1. The model takes text and images and returns text; you send the image inside the message as an image_url part that carries a base64 data URL.

Moondream 3.1 is a small vision-language model that Moondream built for understanding images: 9 billion parameters in total, 2 billion of them active per token. The LLMTR catalog lists it for visual question answering, captions, reading text in images (OCR) and visual reasoning. Moondream's model page gives 7 July 2026 as the release date of 3.1 and notes that OCR and prompts give better results in English and Latin scripts. On LLMTR the context window is 32,000 tokens.

How do you use the Moondream 3.1 API?

Create an API key on LLMTR and keep it in the LLMTR_API_KEY environment variable. Set the OpenAI client's base_url to https://llmtr.com/v1 and pass moondream/moondream3.1-9b-a2b as the model. The Python example below reads a local photo of a shelf, encodes it as base64 and sends it with the data:image/png;base64, prefix; it asks the same question first with reasoning off and then with reasoning on.

An image address that starts with https:// is not accepted on this model: LLMTR refuses the request with 400 unsupported_input before it is sent to the provider. Always read the image on your side and embed it in the request. Text-only requests without an image are accepted as well. Moondream's model page is built around one image per call and describes multiple images as experimental, so build your requests around a single image. If you want to ask a second question about the same image, send the earlier messages again with the image, because Chat Completions is stateless.

The answer arrives in choices[0].message.content and the token counts in usage; the number of tokens the image takes shows up in usage.prompt_tokens. The provider states a maximum of 4,096 output tokens per response. For long answers, look at finish_reason: if it is length, the answer was cut at the max_tokens limit.

An OpenAI Python SDK example that sends a local image to moondream/moondream3.1-9b-a2b as a base64 data URL and asks the same question with reasoning off and on.

import base64
import os

from openai import OpenAI

client = OpenAI(base_url="https://llmtr.com/v1", api_key=os.environ["LLMTR_API_KEY"])

with open("shelf.png", "rb") as f:
    image_b64 = base64.b64encode(f.read()).decode("ascii")

messages = [
    {
        "role": "user",
        "content": [
            {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{image_b64}"}},
            {"type": "text", "text": "How many bottles are on the top shelf? Answer with a number."},
        ],
    }
]

response = client.chat.completions.create(
    model="moondream/moondream3.1-9b-a2b",
    messages=messages,
    max_tokens=256,
)
print(response.choices[0].message.content)
print(response.usage)

# Same question with reasoning turned on
response = client.chat.completions.create(
    model="moondream/moondream3.1-9b-a2b",
    messages=messages,
    max_tokens=512,
    extra_body={"reasoning": True},
)
message = response.choices[0].message
print(message.content)
print(getattr(message, "reasoning_content", None))
print(response.usage)

Moondream 3.1 pricing and the cost of a request

Moondream 3.1 is a paid model billed per token: 1M tokens cost $0.30 for input and $2.50 for output. The image is billed at the input price as part of the prompt. Tokens produced while reasoning is on are counted in completion_tokens and billed at the output price. There is no cache price for this row. The number of tokens an image takes can vary with its size and content; when you plan a budget, look at usage.prompt_tokens on a few samples of your own images.

A worked example: a request with a 1,000-token prompt, image included, and a 200-token answer costs (1,000 x $0.30 + 200 x $2.50) / 1M = $0.0008. When you ask the same question with reasoning on, the answer gets longer and the difference shows up at the output price; work out the real amount from the usage values in each response. Requests that LLMTR refuses are not charged.

moondream/moondream3.1-9b-a2b on LLMTR, as of 17 October 2026
PropertyValue
Model idmoondream/moondream3.1-9b-a2b
Endpoint/v1/chat/completions
Context window32,000 tokens
Input price$0.30 per 1M tokens
Output price$2.50 per 1M tokens
Inputtext, image (base64 data URL only)
Outputtext
Reasoningoff by default; turned on with reasoning: true or :think
Not supportedtool calling, response_format, stop sequences, reasoning_effort

Turning reasoning on: reasoning: true or :think

Reasoning is off by default. For questions that need a closer look, add "reasoning": true to the request body or append :think to the model id (moondream/moondream3.1-9b-a2b:think). In the OpenAI Python SDK this field goes in extra_body; the second request in the example does exactly that. "reasoning": false and :fast keep reasoning off. Rather than turning reasoning on for every request, turn it on for questions that involve counting, comparing or looking at several details; leaving it off for short descriptions and one-word answers keeps the output bill small, because no trace tokens are produced.

The reasoning field takes true or false; if you send an object such as {"enabled": true}, the request returns 400. reasoning_effort is not supported on this model and returns 400 as well.

With reasoning on, the trace arrives separately from the answer: in message.reasoning_content in a non-streamed response, and in choices[].delta.reasoning_content chunks in a stream. Moondream's model page notes that reasoning traces are not guaranteed to be faithful to the answer; take the answer from message.content and use the trace for inspection only.

Unsupported fields and parameters

Moondream 3.1 offers no tool calling, no JSON output mode and no stop sequences; Moondream's model page also says the model does no tool use. LLMTR refuses the fields that would change the answer with 400 invalid_request before sending them to the provider: a non-empty tools array, a response_format of type json_object or json_schema, and a non-empty stop. The error message tells you what to do: remove the tools, describe the format you want in the prompt, cut the answer at your own delimiter or limit its length with max_tokens.

Empty forms that change nothing about the answer are removed from the request and listed in the response's llmtr_dropped_parameters field: an empty tools array, a tool_choice with no tools, a response_format of type {"type": "text"} and an empty stop. seed and include_reasoning are removed too; turn reasoning on with reasoning. temperature, top_p, presence_penalty, frequency_penalty and user are accepted. stream: true is supported; if you send include_usage: true in stream_options, usage arrives in the last chunk.

Getting started and the data note

Step 1: create an account at llmtr.com and top up your balance under Dashboard > Billing. Step 2: create a key under Dashboard > API Keys; the raw key is shown only once, so keep it in the LLMTR_API_KEY environment variable. Step 3: run the example with your own image. Each request is deducted from your balance at the catalog price in effect when it is processed.

The data note on the model card reads: this model is served through a third-party provider. The preview release of the same family, moondream/moondream3-preview, is in the catalog too; the comparison article in this series explains how the two differ.

Call Moondream 3.1 through LLMTR

Top up your balance, create an API key and send the first request with a base64 image to https://llmtr.com/v1 using moondream/moondream3.1-9b-a2b.

  1. Account and balance. Create an account at llmtr.com and top up your balance under Dashboard > Billing.
  2. API key. Create a key under Dashboard > API Keys and keep it in the LLMTR_API_KEY environment variable.
  3. First request. Set base_url to https://llmtr.com/v1, turn the image into a base64 data URL and send it with moondream/moondream3.1-9b-a2b as the model.

Frequently asked questions

How much does the Moondream 3.1 API cost?

On LLMTR, $0.30 for input and $2.50 for output per 1M tokens. Images are billed at the input price and reasoning tokens at the output price.

Can I send an https image URL to Moondream 3.1?

No. This model accepts images only as base64 data URLs; if you send an https address, LLMTR refuses the request with 400. Read the file and send it with a prefix such as data:image/png;base64,.

How do I turn on reasoning in Moondream 3.1?

Add "reasoning": true to the request body or use the model id moondream/moondream3.1-9b-a2b:think. Reasoning is off by default; reasoning_effort is not supported.

Related posts