Send an Image via URL
On this page
The simplest method
Sending an image via URL is the most direct way to use the Vision API: you provide the address of a publicly accessible image, and Mistral downloads it for analysis. Your request stays lightweight—a few hundred bytes—since it carries only a link.
Prioritize this method when your images are already hosted on a CDN, cloud storage, or website, or when you’re working with public web images. A team that already stores product visuals on a CDN can start analyzing them without changing their infrastructure.
Message format
A multimodal message with an image URL follows this structure:
message = {
"role": "user",
"content": [
{
"type": "text",
"text": "Your question about the image"
},
{
"type": "image_url",
"image_url": "https://example.com/my-image.jpg"
}
]
}
The image_url field accepts any HTTP or HTTPS URL pointing to a valid image file in JPEG, PNG, GIF, or WebP format.
Complete Python example
Here is a complete, ready-to-run script that analyzes a public image from Wikimedia, assuming your API key is set in the environment:
from mistralai.client import Mistral
import os
# Initialize the client
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
# Public image to analyze
url_image = "https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/Camponotus_flavomarginatus_ant.jpg/800px-Camponotus_flavomarginatus_ant.jpg"
# Call the Vision API
response = client.chat.complete(
model="mistral-small-latest",
messages=[
{
"role": "user",
"content": [
{
"type": "text",
"text": "Describe precisely what you see in this image."
},
{
"type": "image_url",
"image_url": url_image
}
]
}
]
)
print(response.choices[0].message.content)
Note that we pass the key via os.environ rather than hardcoding it. This is the only acceptable approach once the script leaves your local machine.
Adding a system prompt
The response above will be correct but generic—“a black ant on a blurry background.” A system message changes the nature of the analysis by assigning a role to the model before it views the image:
response = client.chat.complete(
model="mistral-small-latest",
messages=[
{
"role": "system",
"content": "You are an entomology expert. Analyze insect images with scientific precision, identifying the species, family, and visible morphological characteristics."
},
{
"role": "user",
"content": [
{"type": "text", "text": "Identify this insect."},
{"type": "image_url", "image_url": url_image}
]
}
]
)
With this framing, the same image yields a taxonomic identification and a morphological description. The system prompt guides how the model analyzes the image—a powerful lever for obtaining specialized responses at the cost of just a few dozen tokens.
URL requirements
The API must be able to download the image without any context from your session. This leads to four requirements: the URL must be publicly accessible (no pages behind authentication); it must point directly to the file, not to an HTML page containing the image; the format must be supported (JPEG, PNG, GIF where only the first frame is read, or WebP); and the size must remain reasonable, under 20 MB.
The most common confusion involves share links. A Google Drive or Dropbox link “shared with everyone” returns an HTML page, not an image file: the call fails, or the model describes a web interface. The best practice is to verify the Content-Type before sending:
import requests
def verify_image_url(url):
"""Verify that a URL points to an accessible image."""
try:
response = requests.head(url, timeout=5, allow_redirects=True)
content_type = response.headers.get("Content-Type", "")
if response.status_code == 200 and "image" in content_type:
size = int(response.headers.get("Content-Length", 0))
print(f"Image accessible: {content_type}, {size / 1024:.0f} KB")
return True
else:
print(f"Issue: status={response.status_code}, type={content_type}")
return False
except requests.RequestException as e:
print(f"Connection error: {e}")
return False
verify_image_url("https://example.com/photo.jpg")
A HEAD request is sufficient: it retrieves headers without downloading the file.
Images from cloud storage
This public accessibility requirement seems incompatible with confidential documents. The solution lies in pre-signed URLs: if your images are in an S3 bucket, Google Cloud Storage, or Azure Blob, you generate a temporary address that grants access to a single object for a duration you specify.
import boto3
s3 = boto3.client("s3")
# Generate a pre-signed URL valid for 1 hour
presigned_url = s3.generate_presigned_url(
"get_object",
Params={"Bucket": "my-bucket", "Key": "images/invoice.png"},
ExpiresIn=3600
)
# Use this URL with the Vision API
response = client.chat.complete(
model="mistral-small-latest",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "Extract the total amount from this invoice."},
{"type": "image_url", "image_url": presigned_url}
]
}
]
)
Your bucket remains private, the URL expires after the specified delay, and you retain the lightweight nature of the request. Set ExpiresIn as short as possible: a few minutes are more than enough for an API call.
Error handling
A call that depends on a remote download can fail for reasons beyond your control—the image was deleted, the URL expired, or the hosting server is unavailable. In production, never let the raw exception bubble up to the user:
from mistralai.client import Mistral
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
try:
response = client.chat.complete(
model="mistral-small-latest",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "Describe this image."},
{"type": "image_url", "image_url": "https://example.com/image.jpg"}
]
}
]
)
print(response.choices[0].message.content)
except Exception as e:
print(f"Error: {e}")
Test your error handling with a deliberately invalid URL before deploying: this is the most frequent scenario and the one least often tested.
Key takeaways
- Sending via URL is the simplest method—a public URL is all you need
- The message
contentfield is an array containingtextandimage_urlelements - The URL must point directly to an accessible image file
- Pre-signed URLs allow you to use private images securely
- Always add a system prompt to guide the model’s analysis