Migrating Between Mistral SDK Versions
On this page
Lesson rewritten November 2, 2026. The previous version referred to “moving from V1 to V2,” which was actually the transition from the legacy 0.x client to version 1.0 in August 2024. Since then, the Python SDK has seen two more major releases: 2.0 in March 2026 and 3.0 in September 2026. This lesson reconstructs the full history based on official migration guides and release notes. Updated November 3, 2026: Fixed the TypeScript streaming loop, which previously passed
string | ContentChunk[]content directly toprocess.stdout.write, causing failures in strict mode.
Why this lesson matters
You will encounter this material in two scenarios: you are resuming a project written some time ago that refuses to start after a dependency update, or you are following an online tutorial whose examples no longer work. In both cases, ask the same first question: for which SDK generation was this code written? Almost always, a single line tells you: the import statement.
Four generations in two years
| Generation | Python (mistralai) | TypeScript (@mistralai/mistralai) | Distinguishing code feature |
|---|---|---|---|
| 0.x | up to 0.4.2 (July 2024) | up to 0.5.0 (June 2024) | MistralClient, flat methods: client.chat(...) |
| 1.x | 1.0.0 (Aug 7, 2024) → 1.9.11 (Oct 2025) | from Aug 2024 | from mistralai import Mistral, chained methods: client.chat.complete(...) |
| 2.x | 2.0.0 (Mar 10, 2026) | 2.0.0 (Mar 18, 2026) | Python: from mistralai.client import Mistral; TypeScript: ES modules only |
| 3.x | 3.0.0 (Sep 28, 2026), 3.7.0 as of Nov 1, 2026 | 3.0 (Oct 2026), 3.5.0 today | Python: httpx2 HTTP client |
In TypeScript, the import import { Mistral } from '@mistralai/mistralai' has not changed since 1.x. In Python, it has changed twice: that is where most breakages occur.
From 0.x to 1.x: the Mistral client and chained methods
Version 1.0 replaced the two clients, MistralClient (synchronous) and MistralAsyncClient (asynchronous), with a single class, Mistral. It also replaced flat methods with namespaces: chat groups conversation operations, and you go one level deeper to reach complete(). Messages, which were previously written using the ChatMessage class, are now written as dictionaries or using the UserMessage, SystemMessage, AssistantMessage, and ToolMessage classes.
# 0.x (legacy)
from mistralai.client import MistralClient
from mistralai.models.chat_completion import ChatMessage
client = MistralClient(api_key="...")
response = client.chat(
model="mistral-small-latest",
messages=[ChatMessage(role="user", content="Hello")],
)
# 1.x
from mistralai import Mistral
client = Mistral(api_key="...")
response = client.chat.complete(
model="mistral-small-latest",
messages=[{"role": "user", "content": "Hello"}],
)
Streaming follows the same logic, with a trap that often costs half an hour of debugging: the received fragment is now wrapped, and its content is read through an intermediate .data level. Legacy 0.x code copied as-is raises an AttributeError on the first fragment.
# 0.x
for chunk in client.chat_stream(model=..., messages=...):
print(chunk.choices[0].delta.content)
# 1.x and later
for chunk in client.chat.stream(model=..., messages=...):
print(chunk.data.choices[0].delta.content)
The official 1.0 guide provides the full table. The most frequent mappings are:
| 0.x | 1.x and later |
|---|---|
client.chat / client.chat_stream | client.chat.complete / client.chat.stream |
client.completions (FIM) | client.fim.complete |
client.embeddings(model=..., input=[...]) | client.embeddings.create(model=..., inputs=[...]) |
client.list_models() | client.models.list() |
client.files.create(...) | client.files.upload(...) |
client.jobs.create(...) | client.fine_tuning.jobs.create(...) |
MistralAsyncClient and its methods | _async variants: client.chat.complete_async, client.chat.stream_async… |
From 1.x to 2.x: everything moves under mistralai.client
Version 2.0 did not touch method names: client.chat.complete remains client.chat.complete. It changed the address of everything else. The SDK became a namespace package (PEP 420), and all imports migrated from mistralai to mistralai.client:
# 1.x
from mistralai import Mistral
from mistralai.models import UserMessage, SDKError
# 2.x and later
from mistralai.client import Mistral
from mistralai.client.models import UserMessage
from mistralai.client.errors import SDKError
Note the third line: error classes no longer live among models but in mistralai.client.errors, with MistralError as the common base (from which SDKError and HTTPValidationError inherit).
Cloud provider clients joined the same namespace. In 1.x, they were shipped with the mistralai package but in separate modules, mistralai_azure and mistralai_gcp:
# 1.x
from mistralai_azure import MistralAzure
client = MistralAzure(azure_endpoint="https://your-endpoint.inference.ai.azure.com", azure_api_key="your-azure-key")
from mistralai_gcp import MistralGoogleCloud
client = MistralGoogleCloud(region="europe-west4", project_id="my-project")
# 2.x and later
from mistralai.azure.client import MistralAzure
client = MistralAzure(server_url="https://your-endpoint.inference.ai.azure.com", api_key="your-azure-key")
from mistralai.gcp.client import MistralGCP # pip install "mistralai[gcp]"
client = MistralGCP(region="europe-west4", project_id="my-project")
Three other changes in 2.0 may affect you. The minimum version is now Python 3.10 (1.9.11 accepted Python 3.9). 42 types were renamed according to a regular convention: {Verb}{Entity}Request for requests and {Verb}{Entity}Response for responses. The only renaming visible in common code is Tools, which became ConversationRequestTool. Finally, enumerations now accept unknown values, so a new value added by the API no longer crashes an older SDK version.
From 2.x to 3.x: httpx2 and built-in tools
Version 3.0, released September 28, 2026, changes neither imports nor common methods. However, three points can break a project:
- The HTTP client becomes
httpx2. If you pass your own client to the SDK (parametersclient=orasync_client=, for example for a proxy or common headers), it must be anhttpx2client; raw transport requests, responses, and errors are alsohttpx2types. - Built-in tools leave chat completions.
client.chat.completeandclient.agents.completeno longer accept theweb_search,web_search_premium, andcode_interpretertools: they are used via the Conversations API (client.beta.conversations) or an agent. The Mistral documentation explains why: chat completion responses cannot carry the references these tools return. - The
mcpandagentsextras now rely on MCP 2.2.
Version 3.0 also adds service account token authentication: Mistral() reads the token from the file specified by the MISTRAL_SA_TOKEN_PATH environment variable.
What about TypeScript?
Moving from the legacy JavaScript 0.x client to the TypeScript SDK 1.x mirrors the Python transition almost exactly. The import changes from a default export to a named export, the constructor takes a configuration object, and methods become chained:
// 0.x (legacy)
import MistralClient from '@mistralai/mistralai';
const client = new MistralClient(process.env.MISTRAL_API_KEY);
const response = await client.chat({
model: 'mistral-small-latest',
messages: [{ role: 'user', content: 'Hello' }],
});
// 1.x and later
import { Mistral } from '@mistralai/mistralai';
const client = new Mistral({ apiKey: process.env.MISTRAL_API_KEY });
const response = await client.chat.complete({
model: 'mistral-small-latest',
messages: [{ role: 'user', content: 'Hello' }],
});
Streaming moves from client.chatStream(...) to client.chat.stream(...), and, as in Python, content is read via chunk.data:
const stream = await client.chat.stream({
model: 'mistral-small-latest',
messages: [{ role: 'user', content: 'Hello' }],
});
for await (const chunk of stream) {
const content = chunk.data.choices[0]?.delta.content;
// content can also be a list of fragments: we only write text
if (typeof content === 'string') process.stdout.write(content);
}
TypeScript 2.0 (March 18, 2026) kept these imports, but the SDK is now published as ES modules only: a require('@mistralai/mistralai') in CommonJS no longer works. Runtime validation moves to Zod v4, which only affects projects that import schemas directly from the SDK. And cloud clients live in separate packages: @mistralai/mistralai-azure (MistralAzure) and @mistralai/mistralai-gcp (MistralGCP, formerly MistralGoogleCloud).
Conducting the migration
On a real project, proceed in a defined order rather than fixing errors as they appear. Start by identifying the code generation via its imports, then update the package (pip install --upgrade mistralai or npm install @mistralai/mistralai@latest): as long as the old version is installed, you are fixing blindly. Then proceed as follows:
- Search for old imports:
MistralClient,from mistralai import,from mistralai.models import,mistralai_azure,mistralai_gcp,require('@mistralai/mistralai') - Replace them according to the mappings in this lesson, do not forget errors, which move to
mistralai.client.errors - Update calls: chained methods, plural
inputsfor embeddings,.datain streaming loops - Move built-in tools (
web_search,code_interpreter) from chat completions to the Conversations API
Finally, test each endpoint you use, one by one: chat, embeddings, and streaming each have their own changes, and a project that starts does not necessarily call all three correctly.
If you cannot migrate immediately
None of these versions offer a transition mode or compatibility aliases. If a production freeze prevents you from migrating, explicitly pin the version in your dependencies; otherwise, the next installation will fetch the latest version and break the application:
# Python: stay on 1.x
pip install "mistralai<2"
# Python: stay on 2.x
pip install "mistralai>=2,<3"
# npm: stay on 1.x
npm install @mistralai/mistralai@1
Treat this pinning as a reprieve: new features arrive only in the current version.
Official sources: 0.x → 1.0 migration guide · Python 2.0.0 release notes · Python 3.0.0 release notes · TypeScript 2.0.0 release notes · Version history on PyPI · Websearch — built-in tools
Key takeaways
- Identify code generation by its import:
MistralClient(0.x),from mistralai import Mistral(1.x),from mistralai.client import Mistral(2.x and 3.x) - 1.0 (Aug 2024) introduced the
Mistralclient, chained methods, and the streaming.datalevel - 2.0 (Mar 2026) moved all Python imports under
mistralai.client, errors undermistralai.client.errors, and raised the minimum to Python 3.10 - 3.0 (Sep 2026) switches to
httpx2and reservesweb_searchandcode_interpreterfor the Conversations API and agents - In TypeScript, the import has not changed since 1.x, but 2.0 accepts only ES modules