Three roles
- system — a separate top-level
system parameter, not an element of the messages array. Sets instructions and behavior.
- user — the user's turns.
- assistant — the model's replies. You add these back into history for the next turn.
const res = await client.messages.create({
model: "claude-sonnet-4-5",
max_tokens: 1024,
system: "You are a concise technical assistant. Get to the point.",
messages: [
{ role: "user", content: "What is idempotency?" },
],
});
content can be a string or an array of blocks
The short form is a string. The full form is an array of blocks (needed for images, documents, caching):
messages: [
{
role: "user",
content: [
{ type: "text", text: "What's in the picture?" },
{
type: "image",
source: { type: "base64", media_type: "image/png", data: "<base64>" },
},
],
},
];
Multi-turn conversation
The Messages API is stateless — the server does not remember history. You pass the whole array on every request:
const history = [
{ role: "user", content: "My name is Max." },
{ role: "assistant", content: "Nice to meet you, Max." },
{ role: "user", content: "What's my name?" }, // the model answers "Max"
];
Rules: messages alternate user/assistant, the first is always user, the last is usually user. Two user messages in a row are not allowed.
Prefilling the assistant's reply
You can "start" the model's reply by appending an assistant message at the end — Claude continues from there. Useful for strict JSON: prefilling { forces it to emit an object immediately.