Skip to main content

Configuration

'mistral' => [
    'api_key' => env('MISTRAL_API_KEY', ''),
    'url' => env('MISTRAL_URL', 'https://api.mistral.ai/v1'),
],

Reasoning Models

Mistral’s Magistral models support advanced reasoning capabilities where the model thinks through problems before responding.

Using Reasoning Models

Simply specify a reasoning model when making your request. The thinking process is automatically included in the response:
use Prism\Prism\Facades\Prism;

$response = Prism::text()
    ->using('mistral', 'magistral-medium-latest')
    ->withPrompt('What is the capital of France?')
    ->asText();

// Access the final answer
echo $response->text;
// "The capital of France is Paris."

// Access the reasoning process
echo $response->additionalContent['thinking'];
// "Okay, the user asked about the capital of France. I know that the capital of France is Paris..."

Accessing Thinking Content

You can access the thinking content via the additionalContent property on either the Response or the relevant Step. On the Response (easiest when not using tools):
$response = Prism::text()
    ->using('mistral', 'magistral-medium-latest')
    ->withPrompt('What is the meaning of life in popular fiction?')
    ->asText();

// Get the reasoning process
$thinking = $response->additionalContent['thinking'];

// Get the final answer
$answer = $response->text;
On the Step (necessary when using tools, as reasoning happens before tool calls):
$tools = [
    Tool::as('search')
        ->for('Search for current information')
        ->withStringParameter('query', 'The search query')
        ->using(fn (string $query): string => 'The Tigers game is at 3pm'),
];

$response = Prism::text()
    ->using('mistral', 'magistral-medium-latest')
    ->withTools($tools)
    ->withMaxSteps(3)
    ->withPrompt('What time is the Tigers game today?')
    ->asText();

// Access thinking from the first step
$thinking = $response->steps->first()->additionalContent['thinking'];

Understanding the Response Structure

Reasoning models return content in a structured format with two types of blocks:
  1. Thinking blocks - The model’s internal reasoning process (stored in additionalContent['thinking'])
  2. Text blocks - The final self-contained answer (stored in text)
Prism automatically separates these for you, making both easily accessible.

Streaming

Mistral supports streaming responses in real-time:
return Prism::text()
    ->using('mistral', 'mistral-large-latest')
    ->withPrompt(request('message'))
    ->asEventStreamResponse();
For complete streaming documentation, see Streaming Output.

Audio Processing

Mistral provides advanced speech-to-text capabilities through their Voxtral models, offering state-of-the-art transcription accuracy with native multilingual support.

Speech-to-Text

Mistral’s Voxtral models deliver exceptional speech recognition performance, outperforming industry standards like Whisper large-v3.

Basic STT Usage

use Prism\Prism\ValueObjects\Media\Audio;

$audioFile = Audio::fromPath('/path/to/recording.mp3');

$response = Prism::audio()
    ->using('mistral', 'voxtral-mini-2507')
    ->withInput($audioFile)
    ->asText();

echo "Transcription: " . $response->text;

Model Selection Guide

// For production transcription with highest accuracy
$response = Prism::audio()
    ->using('mistral', 'voxtral-small-latest')
    ->withInput($audioFile)
    ->asText();

// For efficient transcription and edge deployment
$response = Prism::audio()
    ->using('mistral', 'voxtral-mini-latest')
    ->withInput($audioFile)
    ->asText();

// For optimized transcription-only service
$response = Prism::audio()
    ->using('mistral', 'voxtral-mini-2507')
    ->withInput($audioFile)
    ->asText();

Language Detection and Specification

$response = Prism::audio()
    ->using('mistral', 'voxtral-mini-2507')
    ->withInput($audioFile)
    ->withProviderOptions([
        'language' => 'en',           // ISO-639-1 code (optional)
        'temperature' => 0.0,         // Lower for more deterministic results
    ])
    ->asText();

// Multilingual support - single model handles multiple languages
$response = Prism::audio()
    ->using('mistral', 'voxtral-mini-2507')
    ->withInput($multilingualAudioFile)
    ->withProviderOptions([
        // Auto-detection works well for mixed-language content
        'temperature' => 0.1,
    ])
    ->asText();

Timestamps and Segmentation

$response = Prism::audio()
    ->using('mistral', 'voxtral-mini-2507')
    ->withInput($audioFile)
    ->withProviderOptions([
        'timestamp_granularities' => ['segment'], // word, segment
        'response_format' => 'json',
    ])
    ->asText();

// Access segment information with timestamps
$segments = $response->additionalContent['segments'] ?? [];
foreach ($segments as $segment) {
    echo "Text: " . $segment['text'] . "\n";
    echo "Start: " . $segment['start'] . "s\n";
    echo "End: " . $segment['end'] . "s\n";
}

Context and Prompts

$response = Prism::audio()
    ->using('mistral', 'voxtral-mini-2507')
    ->withInput($audioFile)
    ->withProviderOptions([
        'prompt' => 'This is a medical consultation discussing patient symptoms and treatment options.',
        'language' => 'en',
        'temperature' => 0.0,         // Deterministic for medical content
    ])
    ->asText();

Long-form Audio Processing

Voxtral handles extended audio without chunking:
// Process up to 30 minutes of audio in a single request
$longAudioFile = Audio::fromPath('/path/to/long_meeting.wav');

$response = Prism::audio()
    ->using('mistral', 'voxtral-small-latest')
    ->withInput($longAudioFile)
    ->withProviderOptions([
        'timestamp_granularities' => ['segment'],
        'language' => 'en',
    ])
    ->asText();

echo "Full transcription: " . $response->text;

// Access usage information
if ($response->usage) {
    echo "Audio duration: " . $response->usage->promptTokens . " tokens\n";
    echo "Total tokens: " . $response->usage->totalTokens . "\n";
}

Documents

The text generation part of the exposed Facade only allows documents to be passed in through via URL. See the Documents page on how to do that.

OCR

Mistral provides an OCR endpoint which can be used to extract text from documents. This OCR endpoint can be used like this:
use Prism\Prism\Enums\Provider;
use Prism\Prism\Facades\Prism;
use Prism\Prism\ValueObjects\Media\Document;
use Prism\Prism\Providers\Mistral\Mistral;
use Prism\Prism\Providers\Mistral\ValueObjects\OCRResponse;

/** @var Mistral $provider */
$provider = Prism::provider(Provider::Mistral);

/** @var OCRResponse $ocrResponse */
$ocrResponse = $provider->ocr(
    'mistral-ocr-latest',
    Document::fromUrl('https://prismphp.com/storage/prism-text-generation.pdf')
);

/**
 * Just need the full text of all the pages combined? Use the toText() method.
 */
$text = $ocrResponse->toText();
The OCR endpoint response time can vary depending on the size of the document. We recommend doing this in the background like a queue with a longer timeout.

Build docs developers (and LLMs) love