Roles: system, developer, user, and assistant
On this page
The four message roles
Every message sent to the Chat Completions endpoint includes a role field that determines how the Grok model interprets it. Understanding these roles is essential for structuring your conversations and getting quality responses.
The xAI API recognizes four roles: system, developer, user, and assistant. Each has a specific position and usage within the messages array.
The system (or developer) role
The system message comes first in the messages array. It defines the model’s overall behavior for the entire conversation: tone, response format, limits, personality, language, and so on.
{
"role": "system",
"content": "You are a cybersecurity expert. Always respond in English, concisely and technically. If you do not know the answer, state it clearly."
}
The developer role is an alias for system. The two are interchangeable in the xAI API. OpenAI introduced developer to better reflect the intent: these are the developer’s instructions, not the “system’s”.
Best practices for the system message
- Be specific: “Respond in 3 sentences maximum” is more effective than “Be concise”
- Define the format: specify if you expect JSON, Markdown, or bulleted lists
- Set limits: indicate what the model must not do
- Provide context: give business context (“You are an assistant for a veterinary clinic”)
The user role
user messages represent the end user’s input. These are the questions, requests, or instructions sent by the person interacting with your application.
{
"role": "user",
"content": "What are the 3 most common web vulnerabilities?"
}
A user message can appear anywhere in the conversation after the system message. In a multi-turn conversation, you typically alternate between user and assistant messages.
The assistant role
assistant messages represent the model’s previous responses. When you send back a conversation history, every response from Grok is tagged with this role.
{
"role": "assistant",
"content": "The three most common web vulnerabilities are:\n1. SQL Injection\n2. Cross-Site Scripting (XSS)\n3. Broken Authentication"
}
You can also use the assistant role for few-shot prompting: injecting examples of desired responses before the actual user message.
{
"messages": [
{"role": "system", "content": "Classify the sentiment: positive, negative, or neutral."},
{"role": "user", "content": "I love this product!"},
{"role": "assistant", "content": "positive"},
{"role": "user", "content": "Customer service is deplorable."},
{"role": "assistant", "content": "negative"},
{"role": "user", "content": "The delivery arrived yesterday."}
]
}
In this example, the first two user/assistant exchanges serve as a demonstration. The model understands the expected format and will apply the same logic to the third message.
Complete request structure
Here is a typical request combining all three roles in a multi-turn conversation:
{
"model": "grok-4.20-0309-reasoning",
"messages": [
{
"role": "system",
"content": "You are a teaching assistant specialized in mathematics. Explain concepts step by step."
},
{
"role": "user",
"content": "What is a derivative?"
},
{
"role": "assistant",
"content": "A derivative measures the instantaneous rate of change of a function..."
},
{
"role": "user",
"content": "Give me a concrete example."
}
]
}
The order is always the same: system first, then alternating user/assistant, with the last message obligatorily user (this is the question the model must answer).
Key takeaways
- system/developer: developer instructions, always first, defines overall behavior
- user: end user messages, trigger response generation
- assistant: previous model responses, useful for history and few-shot prompting
- The
systemanddeveloperroles are interchangeable in the xAI API - The last message in the array must be a
usermessage