> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/openai/openai-python/llms.txt
> Use this file to discover all available pages before exploring further.

# Chat Completions

> Create chat completions with the OpenAI API

## Create Chat Completion

Creates a model response for the given chat conversation.

```python theme={null}
client.chat.completions.create(
    model="gpt-5.2",
    messages=[
        {"role": "developer", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What is recursion?"}
    ]
)
```

### Parameters

<ParamField path="messages" type="array" required>
  A list of messages comprising the conversation so far. Depending on the model you use, different message types (modalities) are supported, like text, images, and audio.

  See [Message Format](#message-format) below for details.
</ParamField>

<ParamField path="model" type="string" required>
  Model ID used to generate the response, like `gpt-4o` or `o3`. OpenAI offers a wide range of models with different capabilities, performance characteristics, and price points. Refer to the [model guide](https://platform.openai.com/docs/models) to browse and compare available models.
</ParamField>

<ParamField path="temperature" type="float" default="1.0">
  What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. We generally recommend altering this or `top_p` but not both.
</ParamField>

<ParamField path="max_completion_tokens" type="integer">
  An upper bound for the number of tokens that can be generated for a completion, including visible output tokens and reasoning tokens.
</ParamField>

<ParamField path="max_tokens" type="integer">
  **Deprecated** in favor of `max_completion_tokens`. The maximum number of tokens that can be generated in the chat completion. This value is not compatible with o-series models.
</ParamField>

<ParamField path="n" type="integer" default="1">
  How many chat completion choices to generate for each input message. Note that you will be charged based on the number of generated tokens across all of the choices. Keep `n` as `1` to minimize costs.
</ParamField>

<ParamField path="stream" type="boolean" default="false">
  If set to true, the model response data will be streamed to the client as it is generated using server-sent events. See [Streaming](/api/chat/streaming) for more information.
</ParamField>

<ParamField path="stop" type="string | array">
  Up to 4 sequences where the API will stop generating further tokens. The returned text will not contain the stop sequence. Not supported with latest reasoning models `o3` and `o4-mini`.
</ParamField>

<ParamField path="presence_penalty" type="float" default="0">
  Number between -2.0 and 2.0. Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics.
</ParamField>

<ParamField path="frequency_penalty" type="float" default="0">
  Number between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim.
</ParamField>

<ParamField path="logit_bias" type="object">
  Modify the likelihood of specified tokens appearing in the completion. Accepts a JSON object that maps tokens (specified by their token ID in the tokenizer) to an associated bias value from -100 to 100.
</ParamField>

<ParamField path="logprobs" type="boolean" default="false">
  Whether to return log probabilities of the output tokens or not. If true, returns the log probabilities of each output token returned in the `content` of `message`.
</ParamField>

<ParamField path="top_logprobs" type="integer">
  An integer between 0 and 20 specifying the number of most likely tokens to return at each token position, each with an associated log probability. `logprobs` must be set to `true` if this parameter is used.
</ParamField>

<ParamField path="top_p" type="float" default="1.0">
  An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top\_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered.

  We generally recommend altering this or `temperature` but not both.
</ParamField>

<ParamField path="seed" type="integer">
  This feature is in Beta. If specified, our system will make a best effort to sample deterministically, such that repeated requests with the same `seed` and parameters should return the same result. Determinism is not guaranteed.
</ParamField>

<ParamField path="tools" type="array">
  A list of tools the model may call. You can provide either custom tools or function tools. See [Function Calling](#function-calling) below.
</ParamField>

<ParamField path="tool_choice" type="string | object">
  Controls which (if any) tool is called by the model. `none` means the model will not call any tool and instead generates a message. `auto` means the model can pick between generating a message or calling one or more tools. `required` means the model must call one or more tools.

  Specifying a particular tool via `{"type": "function", "function": {"name": "my_function"}}` forces the model to call that tool.

  `none` is the default when no tools are present. `auto` is the default if tools are present.
</ParamField>

<ParamField path="parallel_tool_calls" type="boolean" default="true">
  Whether to enable parallel function calling during tool use.
</ParamField>

<ParamField path="response_format" type="object">
  An object specifying the format that the model must output.

  Setting to `{"type": "json_schema", "json_schema": {...}}` enables Structured Outputs which ensures the model will match your supplied JSON schema.

  Setting to `{"type": "json_object"}` enables the older JSON mode, which ensures the message the model generates is valid JSON.
</ParamField>

<ParamField path="reasoning_effort" type="string">
  Constrains effort on reasoning for reasoning models. Currently supported values are `none`, `minimal`, `low`, `medium`, `high`, and `xhigh`.

  * `gpt-5.1` defaults to `none`, which does not perform reasoning. The supported reasoning values for `gpt-5.1` are `none`, `low`, `medium`, and `high`.
  * All models before `gpt-5.1` default to `medium` reasoning effort.
  * The `gpt-5-pro` model defaults to (and only supports) `high` reasoning effort.
  * `xhigh` is supported for all models after `gpt-5.1-codex-max`.
</ParamField>

<ParamField path="user" type="string">
  **Deprecated** - being replaced by `safety_identifier` and `prompt_cache_key`. A stable identifier for your end-users.
</ParamField>

<ParamField path="metadata" type="object">
  Set of 16 key-value pairs that can be attached to an object. Keys are strings with a maximum length of 64 characters. Values are strings with a maximum length of 512 characters.
</ParamField>

<ParamField path="store" type="boolean">
  Whether or not to store the output of this chat completion request for use in model distillation or evals products. Supports text and image inputs. Note: image inputs over 8MB will be dropped.
</ParamField>

### Response

Returns a `ChatCompletion` object.

```python theme={null}
{
    "id": "chatcmpl-123",
    "object": "chat.completion",
    "created": 1677652288,
    "model": "gpt-5.2",
    "choices": [
        {
            "index": 0,
            "message": {
                "role": "assistant",
                "content": "Recursion is when a function calls itself..."
            },
            "finish_reason": "stop"
        }
    ],
    "usage": {
        "prompt_tokens": 20,
        "completion_tokens": 50,
        "total_tokens": 70
    }
}
```

<ResponseField name="id" type="string">
  A unique identifier for the chat completion.
</ResponseField>

<ResponseField name="object" type="string">
  The object type, which is always `chat.completion`.
</ResponseField>

<ResponseField name="created" type="integer">
  The Unix timestamp (in seconds) of when the chat completion was created.
</ResponseField>

<ResponseField name="model" type="string">
  The model used for the chat completion.
</ResponseField>

<ResponseField name="choices" type="array">
  A list of chat completion choices. Can be more than one if `n` is greater than 1.

  <Expandable title="Choice object">
    <ResponseField name="index" type="integer">
      The index of the choice in the list of choices.
    </ResponseField>

    <ResponseField name="message" type="object">
      A chat completion message generated by the model.

      <Expandable title="Message object">
        <ResponseField name="role" type="string">
          The role of the author of this message (e.g., `assistant`).
        </ResponseField>

        <ResponseField name="content" type="string">
          The contents of the message.
        </ResponseField>

        <ResponseField name="tool_calls" type="array">
          The tool calls generated by the model, such as function calls.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="finish_reason" type="string">
      The reason the model stopped generating tokens. Can be `stop`, `length`, `tool_calls`, `content_filter`, or `function_call`.
    </ResponseField>

    <ResponseField name="logprobs" type="object">
      Log probability information for the choice.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="usage" type="object">
  Usage statistics for the completion request.

  <Expandable title="Usage object">
    <ResponseField name="prompt_tokens" type="integer">
      Number of tokens in the prompt.
    </ResponseField>

    <ResponseField name="completion_tokens" type="integer">
      Number of tokens in the generated completion.
    </ResponseField>

    <ResponseField name="total_tokens" type="integer">
      Total number of tokens used in the request (prompt + completion).
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="system_fingerprint" type="string">
  This fingerprint represents the backend configuration that the model runs with. Can be used in conjunction with the `seed` request parameter to understand when backend changes have been made that might impact determinism.
</ResponseField>

## Message Format

Messages use different roles to distinguish between participants in the conversation:

### Developer Messages

High-level instructions for the model. Preferred for o1 models and newer.

```python theme={null}
{"role": "developer", "content": "You are a helpful assistant."}
```

### System Messages

Developer-provided instructions that the model should follow. With o1 models and newer, use `developer` messages instead.

```python theme={null}
{"role": "system", "content": "You are a helpful assistant."}
```

### User Messages

Messages sent by an end user, containing prompts or additional context information.

```python theme={null}
{"role": "user", "content": "What is the capital of France?"}
```

### Assistant Messages

Messages sent by the model in response to user messages.

```python theme={null}
{"role": "assistant", "content": "The capital of France is Paris."}
```

### Tool Messages

Messages containing the result of a tool call.

```python theme={null}
{
    "role": "tool",
    "content": '{"temperature": 72}',
    "tool_call_id": "call_abc123"
}
```

### Multi-modal Content

User messages can include images and other content types:

```python theme={null}
{
    "role": "user",
    "content": [
        {"type": "text", "text": "What's in this image?"},
        {
            "type": "image_url",
            "image_url": {"url": "https://example.com/image.jpg"}
        }
    ]
}
```

## Function Calling

You can provide tools for the model to call during the completion.

### Basic Example

```python theme={null}
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get the current weather in a location",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, e.g. San Francisco, CA"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"]
                    }
                },
                "required": ["location"]
            }
        }
    }
]

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "What's the weather in Boston?"}],
    tools=tools,
    tool_choice="auto"
)
```

### Handling Tool Calls

```python theme={null}
from openai import OpenAI
import json

client = OpenAI()

def get_weather(location, unit="fahrenheit"):
    # Your implementation here
    return {"temperature": 72, "unit": unit, "condition": "sunny"}

messages = [{"role": "user", "content": "What's the weather in Boston?"}]

response = client.chat.completions.create(
    model="gpt-4o",
    messages=messages,
    tools=tools
)

message = response.choices[0].message

# Check if the model wants to call a function
if message.tool_calls:
    # Extend conversation with assistant's reply
    messages.append(message)
    
    # Execute each tool call
    for tool_call in message.tool_calls:
        function_name = tool_call.function.name
        function_args = json.loads(tool_call.function.arguments)
        
        # Call the function
        if function_name == "get_weather":
            function_response = get_weather(
                location=function_args.get("location"),
                unit=function_args.get("unit", "fahrenheit")
            )
        
        # Add function response to messages
        messages.append(
            {
                "role": "tool",
                "content": json.dumps(function_response),
                "tool_call_id": tool_call.id
            }
        )
    
    # Get final response from the model
    final_response = client.chat.completions.create(
        model="gpt-4o",
        messages=messages
    )
    
    print(final_response.choices[0].message.content)
```

### Parallel Function Calling

By default, the model can call multiple functions in parallel:

```python theme={null}
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "What's the weather in Boston and New York?"}],
    tools=tools,
    parallel_tool_calls=True  # Default behavior
)

# The response may contain multiple tool_calls
for tool_call in response.choices[0].message.tool_calls:
    print(f"Calling {tool_call.function.name}")
```

### Forcing Tool Usage

```python theme={null}
# Force the model to call a specific function
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "What's the weather?"}],
    tools=tools,
    tool_choice={"type": "function", "function": {"name": "get_weather"}}
)

# Require the model to call at least one tool
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "What's the weather?"}],
    tools=tools,
    tool_choice="required"
)

# Disable tool calling
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "What's the weather?"}],
    tools=tools,
    tool_choice="none"
)
```

## Structured Outputs with Pydantic

Use the `.parse()` method to automatically parse responses into Pydantic models:

```python theme={null}
from pydantic import BaseModel
from openai import OpenAI

client = OpenAI()

class Step(BaseModel):
    explanation: str
    output: str

class MathResponse(BaseModel):
    steps: list[Step]
    final_answer: str

completion = client.chat.completions.parse(
    model="gpt-4o-2024-08-06",
    messages=[
        {"role": "system", "content": "You are a helpful math tutor."},
        {"role": "user", "content": "solve 8x + 31 = 2"},
    ],
    response_format=MathResponse,
)

message = completion.choices[0].message
if message.parsed:
    print(message.parsed.steps)
    print("answer:", message.parsed.final_answer)
```

## Examples

### Basic Chat Completion

```python theme={null}
from openai import OpenAI

client = OpenAI()

completion = client.chat.completions.create(
    model="gpt-5.2",
    messages=[
        {"role": "developer", "content": "Talk like a pirate."},
        {"role": "user", "content": "How do I check if a Python object is an instance of a class?"}
    ]
)

print(completion.choices[0].message.content)
```

### Multi-turn Conversation

```python theme={null}
messages = [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "Who won the world series in 2020?"},
]

response = client.chat.completions.create(
    model="gpt-4o",
    messages=messages
)

# Add assistant's response to conversation
messages.append(response.choices[0].message)

# Continue the conversation
messages.append({"role": "user", "content": "Where was it played?"})

response = client.chat.completions.create(
    model="gpt-4o",
    messages=messages
)

print(response.choices[0].message.content)
```

### Vision with Images

```python theme={null}
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "What's in this image?"},
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"
                    }
                }
            ]
        }
    ]
)

print(response.choices[0].message.content)
```

### JSON Mode

```python theme={null}
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "system", "content": "You are a helpful assistant designed to output JSON."},
        {"role": "user", "content": "List 3 colors in JSON format"}
    ],
    response_format={"type": "json_object"}
)

print(response.choices[0].message.content)
# Output: {"colors": ["red", "blue", "green"]}
```
