Skip to content

The safe_prompt Parameter in the Mistral API

8 min read · updated August 11, 2026

safe_prompt is a boolean that silently prepends a system message to your conversation. It is one of the few parameters in this API that changes your prompt rather than the sampling of it, and knowing the exact string it adds is the difference between reasoning about your context and guessing at it.

What the flag does

In Mistral’s chat completions reference the parameter is a boolean with a default of false, documented as “whether to inject a safety prompt before all conversations”.

curl https://api.mistral.ai/v1/chat/completions \
  -H "Authorization: Bearer $MISTRAL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mistral-large-2512",
    "messages": [{"role": "user", "content": "What is the best French cheese?"}],
    "safe_prompt": true
  }'

There is no model-side mechanism here and no classifier. The flag is a convenience for something you could do yourself: it prepends a system message to the array before the request is rendered into a prompt. The model then behaves as it would have behaved had you written that message. That is the whole implementation, and understanding it predicts every property below.

The exact text it injects

Mistral’s documentation for the feature gives the injected system prompt verbatim:

Always assist with care, respect, and truth. Respond with utmost
utility yet securely. Avoid harmful, unethical, prejudiced, or
negative content. Ensure replies promote fairness and positivity.

Four sentences, roughly thirty-five words. Mistral’s own description of the evaluation behind it is that a set of adversarial prompts deliberately asking for excluded content was assembled, and that with this system prompt in place the models declined all of them. That is Mistral’s reported result on Mistral’s chosen set, and it is the right way to read it — not as a general guarantee, but as a claim about a specific evaluation.

Notice what the text is and is not. It is generic value language. It names no categories, defines no thresholds, and gives the model no way to distinguish a medical question from a request for malware. It steers a distribution; it does not classify anything.

The wording also carries assumptions that will not suit every application, and they are worth reading as instructions rather than as sentiment because that is how the model receives them. “Respond with utmost utility yet securely” asks for a trade-off with no stated tiebreak. “Avoid... negative content” is doing a lot of unspecified work — a truthful answer that a proposal will not work, or that a test result is bad, is negative content by any plain reading. And “ensure replies promote fairness and positivity” is a standing instruction to editorialise, applied to every response including the ones where the user wanted a number. If you have ever wondered why an assistant softens a straightforward technical judgement, a prompt of roughly this shape somewhere in the stack is one of the more common explanations.

What it costs you

Because it is an ordinary system message, everything true of your own system prompt is true of it, and the consequences are all mundane and all worth stating.

  • You pay for it, on every call. Thirty-five words is somewhere around forty to fifty tokens depending on the tokenizer version. Trivial per request, and not trivial as a fixed line on ten million requests.
  • It occupies the top of your context. If you already have a system message, you now have two competing sets of instructions in the position your model treats as most authoritative. “Ensure replies promote fairness and positivity” is not obviously compatible with “report the failure bluntly and do not soften it”.
  • It changes tone, not only refusals. This is the effect people do not anticipate. A prompt asking for positivity nudges output toward hedging and warmth across every response, not only the sensitive ones. If your assistant started adding caveats to factual answers, check whether this flag is set somewhere in a shared client wrapper.
  • It shifts the false-positive rate. Steering a model away from “harmful” content with no definition of the term will decline some legitimate requests — security research, clinical questions, historical description of violence. There is no threshold to tune, because there is no classifier.

Finding out whether it is on

Because the default is false, nobody gets this behaviour by accident from the API itself. What does happen is that a wrapper somewhere sets it — a shared client factory, a framework integration, a configuration file copied from an example — and then every team using that wrapper has a system message they did not write and cannot see in their own code.

There is no field in the response that tells you. The completion looks identical either way, and usage.prompt_tokens is the only place the difference shows up at all: an injected system prompt is real tokens and they are counted. So the reliable check is a differential one. Send the same trivial request twice, once with the flag explicitly false and once with it explicitly true, and compare prompt_tokens:

# same messages, same model, only the flag differs
"safe_prompt": false   ->  usage.prompt_tokens = N
"safe_prompt": true    ->  usage.prompt_tokens = N + (length of the safety prompt)

The delta is the injected message, and it tells you both that the feature is doing what the documentation says and exactly what it costs on your model’s tokenizer. Compare that against a request from your actual application to see which of the two your production path is producing.

Two related things to look for while you are there. Some SDKs surface the parameter as required rather than optional, which means it is being serialised into every request whether you set it or not — the value is false, so nothing is injected, but it makes the field appear in logs and invites the assumption that somebody chose it. And if you route through anything that rewrites requests, confirm the flag survives the rewrite in the state you set it.

It is deprecated

The page documenting safe_prompt now sits under Mistral’s deprecated resources and states that the feature is deprecated, with Custom Guardrails recommended in its place for control over moderation categories and thresholds. The parameter is still listed in the API reference, so existing requests are not going to start erroring today, but it is not the mechanism Mistral is building on.

Deprecated is not removed, and the gap between the two is where quiet breakage lives. If safe_prompt is load-bearing in your application, treat its removal as a scheduled event rather than a surprise and check the API reference for the version you pin.

What to do instead

The successor is configurable rather than binary. Mistral’s current guardrailing documentation covers a Moderation API — a classification endpoint that scores content against categories — and request-level guardrail rules with per-category thresholds, exposed through the guardrails parameter on the chat endpoint. That is a genuinely different design: a classifier with a score you can threshold and log, rather than a sentence in the prompt whose effect you can only infer from output.

The architectural point generalises past this one flag. A prompt-based guardrail and a classifier-based one fail differently. The prompt version cannot be audited — you cannot ask it why a response was softened — and cannot be tuned, because there is no dial. A classifier produces a score per category, which you can threshold per use case, record against the request, and review when someone reports a false positive. If you need to explain a decline to a user or a regulator, only one of those two gives you anything to explain it with.

If you are keeping a prompt-level rule anyway, write it yourself in your own system message rather than setting the flag. You will know it is there, it will be in version control, you can word it for your domain instead of accepting generic language, and it will not disappear when the parameter is finally removed. See how Mistral handles the system role for where to put it.