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

# Vision and image generation

> Use gpt-5.4 to understand images or grok-imagine-image to generate images from prompts.

Moxus AI supports image understanding, image generation, and image editing. Input formats, sizes, output counts, and response formats vary by model. This page uses `gpt-5.4` for image understanding and `grok-imagine-image` for image generation.

<Columns cols={2}>
  <Card title="Image understanding" icon="scan-eye" href="#image-understanding">
    Send a public image URL or read a local file and pass it as Base64 data.
  </Card>

  <Card title="Image generation" icon="wand-sparkles" href="#image-generation">
    Generate an image from a prompt and save the returned Base64 data locally.
  </Card>

  <Card title="Image editing" icon="image-plus" href="#image-editing">
    Edit an existing image when the selected model supports it.
  </Card>

  <Card title="Prompting tips" icon="text-cursor-input" href="#prompting-tips">
    Describe the subject, style, composition, and constraints.
  </Card>
</Columns>

<Tip>
  If you are still tuning a prompt, choose an image generation model in the web Conversation page and generate a test image there first. After the model and prompt are confirmed, use the API examples on this page from external code.
</Tip>

<span id="image-understanding" />

## Image understanding

Image understanding uses the OpenAI-compatible `chat/completions` endpoint. You can pass a public image URL or encode a local image as Base64 and send it as a `data:` URI. The examples use `gpt-5.4`.

### Use a local image

Local-image examples read the file, convert it to Base64, then send it in the request. In the Python example, `IMAGE_PATH = "photo.jpg"` means that the image is in the same project folder as the Python file and its name must match exactly, including extension and letter case. Use a full local path when the image is elsewhere. The Node.js example uses `const IMAGE_PATH = "photo.png"`; put the image in the same project folder as the `.mjs` file and run the command from that folder. Change both `IMAGE_PATH` and `IMAGE_MIME_TYPE` when the filename or format differs.

<Info>
  For Python and Node.js dependency installation, running examples, and environment troubleshooting, see [FAQ](/en/overview/faq).
</Info>

<CodeGroup>
  ```bash cURL theme={null}
  # This example uses a public image URL. For a local image, use the Python or Node.js example.
  curl https://moxus.cloud/v1/chat/completions \
    -H "Authorization: Bearer sk-your-key" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "gpt-5.4",
      "messages": [
        {
          "role": "user",
          "content": [
            {"type": "text", "text": "Describe this image and list the key details."},
            {
              "type": "image_url",
              "image_url": {
                "url": "https://example.com/photo.jpg"
              }
            }
          ]
        }
      ]
    }'
  ```

  ```python Python theme={null}
  # base64 is a Python standard library module used to turn a local image into text for JSON.
  import base64
  import httpx
  from openai import OpenAI

  # Replace only these values: your API key and the local image filename or full path.
  API_KEY = "sk-your-key"
  IMAGE_PATH = "photo.jpg"
  # Use image/jpeg for JPEG files. Change this to image/png for PNG files.
  IMAGE_MIME_TYPE = "image/jpeg"

  client = OpenAI(
      api_key=API_KEY,
      base_url="https://moxus.cloud/v1",
      # Connect directly to Moxus AI without reading system or terminal proxy variables.
      http_client=httpx.Client(trust_env=False, timeout=60.0),
  )

  # Read the local image file and encode it as a Base64 string.
  # "rb" means read in binary mode, which is required for image files.
  with open(IMAGE_PATH, "rb") as image_file:
      image_base64 = base64.b64encode(image_file.read()).decode("utf-8")

  response = client.chat.completions.create(
      model="gpt-5.4",
      messages=[
          {
              "role": "user",
              "content": [
                  {"type": "text", "text": "Describe this image and list the key details."},
                  {
                      "type": "image_url",
                      "image_url": {
                          # This prefix tells the model that the remaining value is Base64 image data.
                          "url": f"data:{IMAGE_MIME_TYPE};base64,{image_base64}",
                      },
                  },
              ],
          }
      ],
  )

  print(response.choices[0].message.content)
  ```

  ```javascript Node.js theme={null}
  import OpenAI from "openai";

  // readFileSync is a Node.js standard library method for reading the local image file.
  import { readFileSync } from "node:fs";

  // Put photo.png in the same project folder as the .mjs file. Change both values when the filename or format differs.
  const API_KEY = "sk-your-key";
  const IMAGE_PATH = "photo.png";
  const IMAGE_MIME_TYPE = "image/png";

  const client = new OpenAI({
    apiKey: API_KEY,
    baseURL: "https://moxus.cloud/v1",
  });

  // Convert the local image into a Base64 string so it can be sent in JSON.
  const imageBase64 = readFileSync(IMAGE_PATH).toString("base64");

  const response = await client.chat.completions.create({
    model: "gpt-5.4",
    messages: [
      {
        role: "user",
        content: [
          { type: "text", text: "Describe this image and list the key details." },
          {
            type: "image_url",
            image_url: {
              // This prefix tells the model that the remaining value is Base64 image data.
              url: `data:${IMAGE_MIME_TYPE};base64,${imageBase64}`,
            },
          },
        ],
      },
    ],
  });

  console.log(response.choices[0].message.content);
  ```
</CodeGroup>

<span id="image-generation" />

## Image generation

Image generation uses the OpenAI-compatible `/v1/images/generations` endpoint. The examples use `grok-imagine-image`. Support for size, output count, and response format varies by model, so confirm the model name and pricing in Model Square before integrating.

<CodeGroup>
  ```bash cURL theme={null}
  # prompt describes the image. size and n support depends on the selected image model.
  curl https://moxus.cloud/v1/images/generations \
    -H "Authorization: Bearer sk-your-key" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "grok-imagine-image",
      "prompt": "A clean product mockup of a smart desk lamp on a white table, soft studio lighting",
      "n": 1,
      "size": "1024x1024"
    }'
  ```

  ```python Python theme={null}
  # base64 is a Python standard library module used to decode the returned image data.
  import base64
  import httpx
  from openai import OpenAI

  client = OpenAI(
      api_key="sk-your-key",
      base_url="https://moxus.cloud/v1",
      # Connect directly to Moxus AI without reading system or terminal proxy variables.
      http_client=httpx.Client(trust_env=False, timeout=60.0),
  )

  response = client.images.generate(
      model="grok-imagine-image",
      prompt="A clean product mockup of a smart desk lamp on a white table, soft studio lighting",
      n=1,
      size="1024x1024",
      response_format="b64_json",
  )

  # With response_format="b64_json", the generated image is returned in the b64_json field.
  image_base64 = response.data[0].b64_json

  # Decode the Base64 string and write it as a local PNG file.
  with open("generated-image.png", "wb") as image_file:
      image_file.write(base64.b64decode(image_base64))

  print("Saved image to generated-image.png")
  ```

  ```javascript Node.js theme={null}
  import OpenAI from "openai";

  // writeFileSync is a Node.js standard library method for writing the image file.
  import { writeFileSync } from "node:fs";

  const client = new OpenAI({
    apiKey: "sk-your-key",
    baseURL: "https://moxus.cloud/v1",
  });

  const response = await client.images.generate({
    model: "grok-imagine-image",
    prompt: "A clean product mockup of a smart desk lamp on a white table, soft studio lighting",
    n: 1,
    size: "1024x1024",
    response_format: "b64_json",
  });

  // With response_format: "b64_json", the generated image is returned in the b64_json field.
  const imageBase64 = response.data[0].b64_json;

  // Buffer.from(..., "base64") converts the Base64 string back to image bytes.
  writeFileSync("generated-image.png", Buffer.from(imageBase64, "base64"));

  console.log("Saved image to generated-image.png");
  ```
</CodeGroup>

<span id="image-editing" />

## Image editing

Use image editing to modify an existing image, such as replacing a background, changing a local area, or adjusting the overall style. The endpoint, file upload format, and parameters depend on the selected model. Confirm that the model supports image editing in Model Square before calling it.

<span id="prompting-tips" />

## Prompting tips

* Describe the subject, style, composition, lighting, color palette, and background.
* State the intended use and constraints, such as aspect ratio or elements to keep or avoid.
* Combine image understanding with [structured output](/en/guide/structured-output) when downstream code needs stable fields.

## Billing notes

* Image understanding usually counts image input as tokens. Larger or more detailed images consume more tokens.
* Image generation and editing may be billed per image, by size, or by model-specific units.

See [models and pricing](/en/overview/models-and-pricing) for current prices.

## Notes

* Use only models marked as supporting the required capability in Model Square.
* Large images can consume more tokens or be rejected; compress them when necessary.
* Image URLs must be publicly accessible.

## Next steps
