Strict tool use
On this page
Setting strict: true on a tool definition guarantees Claude's tool inputs match your JSON Schema by constraining the model's token sampling to schema-valid outputs (a technique called grammar-constrained sampling). This page covers why strict mode matters for agents, how to enable it, and common use cases. For the supported JSON Schema subset, see JSON Schema limitations. For non-strict schema guidance, see Define tools.
Strict tool use validates tool parameters, ensuring Claude calls your functions with correctly-typed arguments. Use strict tool use when you need to:
- Validate tool parameters
- Build agentic workflows
- Ensure type-safe function calls
- Handle complex tools with nested properties
Why strict tool use matters for agents
Building reliable agentic systems requires guaranteed schema conformance. Without strict mode, Claude might return incompatible types ("2" instead of 2) or omit required fields, breaking your functions and causing runtime errors.
Strict tool use guarantees type-safe parameters:
- Functions receive correctly-typed arguments every time
- No need to validate and retry tool calls
- Production-ready agents that work consistently at scale
For example, suppose a booking system needs passengers: int. Without strict mode, Claude might provide passengers: "two" or passengers: "2". With strict: true, the response always contains passengers: 2.
Quick start
ant messages create --transform content <<'YAML'
model: claude-opus-5
max_tokens: 1024
messages:
- role: user
content: What is the weather in San Francisco?
tools:
- name: get_weather
description: Get the current weather in a given location
strict: true
input_schema:
type: object
properties:
location:
type: string
description: The city and state, e.g. San Francisco, CA
unit:
type: string
enum: [celsius, fahrenheit]
required: [location]
additionalProperties: false
YAML
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[{"role": "user", "content": "What's the weather like in San Francisco?"}],
tools=[
{
"name": "get_weather",
"description": "Get the current weather in a given location",
"strict": True, # Enable strict mode
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA",
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "The unit of temperature, either 'celsius' or 'fahrenheit'",
},
},
"required": ["location"],
"additionalProperties": False,
},
}
],
)
print(response.content)
const client = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY
});
const response = await client.messages.create({
model: "claude-opus-5",
max_tokens: 1024,
messages: [
{
role: "user",
content: "What's the weather like in San Francisco?"
}
],
tools: [
{
name: "get_weather",
description: "Get the current weather in a given location",
strict: true, // Enable strict mode
input_schema: {
type: "object",
properties: {
location: {
type: "string",
description: "The city and state, e.g. San Francisco, CA"
},
unit: {
type: "string",
enum: ["celsius", "fahrenheit"]
}
},
required: ["location"],
additionalProperties: false
}
}
]
});
console.log(response.content);
using System.Text.Json;
using Anthropic;
using Anthropic.Models.Messages;
AnthropicClient client = new();
var parameters = new MessageCreateParams
{
Model = Model.ClaudeOpus5,
MaxTokens = 1024,
Messages = [new() { Role = Role.User, Content = "What's the weather like in San Francisco?" }],
Tools = [
new ToolUnion(new Tool()
{
Name = "get_weather",
Description = "Get the current weather in a given location",
Strict = true,
InputSchema = new InputSchema(new Dictionary<string, JsonElement>
{
["properties"] = JsonSerializer.SerializeToElement(new Dictionary<string, object>
{
["location"] = new { type = "string", description = "The city and state, e.g. San Francisco, CA" },
["unit"] = new { type = "string", @enum = new[] { "celsius", "fahrenheit" } },
}),
["required"] = JsonSerializer.SerializeToElement(new[] { "location" }),
["additionalProperties"] = JsonSerializer.SerializeToElement(false),
}),
}),
]
};
var message = await client.Messages.Create(parameters);
Console.WriteLine(message);
client := anthropic.NewClient()
response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
Model: anthropic.ModelClaudeOpus5,
MaxTokens: 1024,
Messages: []anthropic.MessageParam{
anthropic.NewUserMessage(anthropic.NewTextBlock("What's the weather like in San Francisco?")),
},
Tools: []anthropic.ToolUnionParam{
{OfTool: &anthropic.ToolParam{
Name: "get_weather",
Description: anthropic.String("Get the current weather in a given location"),
Strict: anthropic.Bool(true),
InputSchema: anthropic.ToolInputSchemaParam{
Properties: map[string]any{
"location": map[string]any{
"type": "string",
"description": "The city and state, e.g. San Francisco, CA",
},
"unit": map[string]any{
"type": "string",
"enum": []string{"celsius", "fahrenheit"},
},
},
Required: []string{"location"},
ExtraFields: map[string]any{
"additionalProperties": false,
},
}}},
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response.Content)
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
InputSchema schema = InputSchema.builder()
.properties(
JsonValue.from(
Map.of(
"location", Map.of(
"type", "string",
"description", "The city and state, e.g. San Francisco, CA"
),
"unit", Map.of(
"type", "string",
"enum", List.of("celsius", "fahrenheit")
)
)
)
)
.putAdditionalProperty("required", JsonValue.from(List.of("location")))
.putAdditionalProperty("additionalProperties", JsonValue.from(false))
.build();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_5)
.maxTokens(1024L)
.addUserMessage("What's the weather like in San Francisco?")
.addTool(
Tool.builder()
.name("get_weather")
.description("Get the current weather in a given location")
.strict(true)
.inputSchema(schema)
.build()
)
.build();
Message response = client.messages().create(params);
IO.println(response.content());
$client = new Client();
$message = $client->messages->create(
maxTokens: 1024,
messages: [
['role' => 'user', 'content' => "What's the weather like in San Francisco?"]
],
model: 'claude-opus-5',
tools: [
[
'name' => 'get_weather',
'description' => 'Get the current weather in a given location',
'strict' => true,
'input_schema' => [
'type' => 'object',
'properties' => [
'location' => [
'type' => 'string',
'description' => 'The city and state, e.g. San Francisco, CA'
],
'unit' => [
'type' => 'string',
'enum' => ['celsius', 'fahrenheit']
]
],
'required' => ['location'],
'additionalProperties' => false
]
]
],
);
echo $message;
client = Anthropic::Client.new
message = client.messages.create(
model: "claude-opus-5",
max_tokens: 1024,
messages: [
{ role: "user", content: "What's the weather like in San Francisco?" }
],
tools: [
{
name: "get_weather",
description: "Get the current weather in a given location",
strict: true,
input_schema: {
type: "object",
properties: {
location: {
type: "string",
description: "The city and state, e.g. San Francisco, CA"
},
unit: {
type: "string",
enum: ["celsius", "fahrenheit"]
}
},
required: ["location"],
additionalProperties: false
}
}
]
)
puts message.content
Response format: Tool use blocks with validated inputs in response.content[x].input
{
"type": "tool_use",
"name": "get_weather",
"input": {
"location": "San Francisco, CA"
}
}
Guarantees:
- Tool
inputstrictly follows theinput_schema - Tool
nameis always valid (from provided tools or server tools)
How it works
The computer use and browser use toolset entries (computer_toolset_20260801 and browser_toolset_20260801) don't accept strict: true; a request that sets it on either entry is rejected.
Common use cases
<CodeGroup>
```bash cURL
curl https://api.anthropic.com/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-opus-5",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Search for flights to Tokyo departing June 1, 2026"}
],
"tools": [{
"name": "search_flights",
"strict": true,
"input_schema": {
"type": "object",
"properties": {
"destination": {"type": "string"},
"departure_date": {"type": "string", "format": "date"},
"passengers": {"type": "integer", "enum": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}
},
"required": ["destination", "departure_date"],
"additionalProperties": false
}
}]
}'
```
```bash CLI
ant messages create <<'YAML'
model: claude-opus-5
max_tokens: 1024
messages:
- role: user
content: Search for flights to Tokyo departing June 1, 2026
tools:
- name: search_flights
strict: true
input_schema:
type: object
properties:
destination:
type: string
departure_date:
type: string
format: date
passengers:
type: integer
enum: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
required: [destination, departure_date]
additionalProperties: false
YAML
```
```python Python
client = Anthropic()
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[
{
"role": "user",
"content": "Search for flights to Tokyo departing June 1, 2026",
}
],
tools=[
{
"name": "search_flights",
"strict": True,
"input_schema": {
"type": "object",
"properties": {
"destination": {"type": "string"},
"departure_date": {"type": "string", "format": "date"},
"passengers": {
"type": "integer",
"enum": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
},
},
"required": ["destination", "departure_date"],
"additionalProperties": False,
},
}
],
)
print(response)
```
```typescript TypeScript
const client = new Anthropic();
const searchFlightsTool: Anthropic.Tool = {
name: "search_flights",
strict: true,
input_schema: {
type: "object",
properties: {
destination: { type: "string" },
departure_date: { type: "string", format: "date" },
passengers: { type: "integer", enum: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }
},
required: ["destination", "departure_date"],
additionalProperties: false
}
};
const response = await client.messages.create({
model: "claude-opus-5",
max_tokens: 1024,
messages: [{ role: "user", content: "Search for flights to Tokyo departing June 1, 2026" }],
tools: [searchFlightsTool]
});
console.log(response);
```
```csharp C#
using System.Text.Json;
using Anthropic;
using Anthropic.Models.Messages;
AnthropicClient client = new();
var parameters = new MessageCreateParams
{
Model = Model.ClaudeOpus5,
MaxTokens = 1024,
Messages = [new() { Role = Role.User, Content = "Search for flights to Tokyo departing June 1, 2026" }],
Tools = [
new ToolUnion(new Tool()
{
Name = "search_flights",
Strict = true,
InputSchema = new InputSchema(new Dictionary<string, JsonElement>
{
["properties"] = JsonSerializer.SerializeToElement(new Dictionary<string, object>
{
["destination"] = new { type = "string" },
["departure_date"] = new { type = "string", format = "date" },
["passengers"] = new { type = "integer", @enum = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } },
}),
["required"] = JsonSerializer.SerializeToElement(new[] { "destination", "departure_date" }),
["additionalProperties"] = JsonSerializer.SerializeToElement(false),
}),
}),
]
};
var message = await client.Messages.Create(parameters);
Console.WriteLine(message);
```
```go Go
client := anthropic.NewClient()
response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
Model: anthropic.ModelClaudeOpus5,
MaxTokens: 1024,
Messages: []anthropic.MessageParam{
anthropic.NewUserMessage(anthropic.NewTextBlock("Search for flights to Tokyo departing June 1, 2026")),
},
Tools: []anthropic.ToolUnionParam{
{OfTool: &anthropic.ToolParam{
Name: "search_flights",
Strict: anthropic.Bool(true),
InputSchema: anthropic.ToolInputSchemaParam{
Properties: map[string]any{
"destination": map[string]any{
"type": "string",
},
"departure_date": map[string]any{
"type": "string",
"format": "date",
},
"passengers": map[string]any{
"type": "integer",
"enum": []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
},
},
Required: []string{"destination", "departure_date"},
ExtraFields: map[string]any{
"additionalProperties": false,
},
}}},
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response.RawJSON())
```
```java Java
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
InputSchema schema = InputSchema.builder()
.properties(
JsonValue.from(
Map.of(
"destination", Map.of("type", "string"),
"departure_date", Map.of("type", "string", "format", "date"),
"passengers", Map.of(
"type", "integer",
"enum", List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
)
)
)
)
.putAdditionalProperty("required", JsonValue.from(List.of("destination", "departure_date")))
.putAdditionalProperty("additionalProperties", JsonValue.from(false))
.build();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_5)
.maxTokens(1024L)
.addUserMessage("Search for flights to Tokyo departing June 1, 2026")
.addTool(
Tool.builder()
.name("search_flights")
.strict(true)
.inputSchema(schema)
.build()
)
.build();
Message response = client.messages().create(params);
IO.println(response);
```
```php PHP
$client = new Client();
$message = $client->messages->create(
maxTokens: 1024,
messages: [
['role' => 'user', 'content' => 'Search for flights to Tokyo departing June 1, 2026']
],
model: 'claude-opus-5',
tools: [
[
'name' => 'search_flights',
'strict' => true,
'input_schema' => [
'type' => 'object',
'properties' => [
'destination' => ['type' => 'string'],
'departure_date' => ['type' => 'string', 'format' => 'date'],
'passengers' => [
'type' => 'integer',
'enum' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
]
],
'required' => ['destination', 'departure_date'],
'additionalProperties' => false
]
]
],
);
echo $message;
```
```ruby Ruby
client = Anthropic::Client.new
message = client.messages.create(
model: "claude-opus-5",
max_tokens: 1024,
messages: [
{ role: "user", content: "Search for flights to Tokyo departing June 1, 2026" }
],
tools: [
{
name: "search_flights",
strict: true,
input_schema: {
type: "object",
properties: {
destination: { type: "string" },
departure_date: { type: "string", format: "date" },
passengers: {
type: "integer",
enum: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
}
},
required: ["destination", "departure_date"],
additionalProperties: false
}
}
]
)
puts message
```
</CodeGroup>
<CodeGroup>
```bash cURL
curl https://api.anthropic.com/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-opus-5",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Help me plan a trip from New York to Paris for 2 people, departing June 1, 2026"}
],
"tools": [
{
"name": "search_flights",
"strict": true,
"input_schema": {
"type": "object",
"properties": {
"origin": {"type": "string"},
"destination": {"type": "string"},
"departure_date": {"type": "string", "format": "date"},
"travelers": {"type": "integer", "enum": [1, 2, 3, 4, 5, 6]}
},
"required": ["origin", "destination", "departure_date"],
"additionalProperties": false
}
},
{
"name": "search_hotels",
"strict": true,
"input_schema": {
"type": "object",
"properties": {
"city": {"type": "string"},
"check_in": {"type": "string", "format": "date"},
"guests": {"type": "integer", "enum": [1, 2, 3, 4]}
},
"required": ["city", "check_in"],
"additionalProperties": false
}
}
]
}'
```
```bash CLI
ant messages create <<'YAML'
model: claude-opus-5
max_tokens: 1024
messages:
- role: user
content: >-
Help me plan a trip from New York to Paris for 2 people,
departing June 1, 2026
tools:
- name: search_flights
strict: true
input_schema:
type: object
properties:
origin: {type: string}
destination: {type: string}
departure_date: {type: string, format: date}
travelers: {type: integer, enum: [1, 2, 3, 4, 5, 6]}
required: [origin, destination, departure_date]
additionalProperties: false
- name: search_hotels
strict: true
input_schema:
type: object
properties:
city: {type: string}
check_in: {type: string, format: date}
guests: {type: integer, enum: [1, 2, 3, 4]}
required: [city, check_in]
additionalProperties: false
YAML
```
```python Python
client = Anthropic()
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[
{
"role": "user",
"content": "Help me plan a trip from New York to Paris for 2 people, departing June 1, 2026",
}
],
tools=[
{
"name": "search_flights",
"strict": True,
"input_schema": {
"type": "object",
"properties": {
"origin": {"type": "string"},
"destination": {"type": "string"},
"departure_date": {"type": "string", "format": "date"},
"travelers": {"type": "integer", "enum": [1, 2, 3, 4, 5, 6]},
},
"required": ["origin", "destination", "departure_date"],
"additionalProperties": False,
},
},
{
"name": "search_hotels",
"strict": True,
"input_schema": {
"type": "object",
"properties": {
"city": {"type": "string"},
"check_in": {"type": "string", "format": "date"},
"guests": {"type": "integer", "enum": [1, 2, 3, 4]},
},
"required": ["city", "check_in"],
"additionalProperties": False,
},
},
],
)
print(response)
```
```typescript TypeScript
const client = new Anthropic();
const tools: Anthropic.Tool[] = [
{
name: "search_flights",
strict: true,
input_schema: {
type: "object",
properties: {
origin: { type: "string" },
destination: { type: "string" },
departure_date: { type: "string", format: "date" },
travelers: { type: "integer", enum: [1, 2, 3, 4, 5, 6] }
},
required: ["origin", "destination", "departure_date"],
additionalProperties: false
}
},
{
name: "search_hotels",
strict: true,
input_schema: {
type: "object",
properties: {
city: { type: "string" },
check_in: { type: "string", format: "date" },
guests: { type: "integer", enum: [1, 2, 3, 4] }
},
required: ["city", "check_in"],
additionalProperties: false
}
}
];
const response = await client.messages.create({
model: "claude-opus-5",
max_tokens: 1024,
messages: [
{
role: "user",
content:
"Help me plan a trip from New York to Paris for 2 people, departing June 1, 2026"
}
],
tools: tools
});
console.log(response);
```
```csharp C#
using System.Text.Json;
using Anthropic;
using Anthropic.Models.Messages;
AnthropicClient client = new();
var parameters = new MessageCreateParams
{
Model = Model.ClaudeOpus5,
MaxTokens = 1024,
Messages = [new() { Role = Role.User, Content = "Help me plan a trip from New York to Paris for 2 people, departing June 1, 2026" }],
Tools = [
new ToolUnion(new Tool()
{
Name = "search_flights",
Strict = true,
InputSchema = new InputSchema(new Dictionary<string, JsonElement>
{
["properties"] = JsonSerializer.SerializeToElement(new Dictionary<string, object>
{
["origin"] = new { type = "string" },
["destination"] = new { type = "string" },
["departure_date"] = new { type = "string", format = "date" },
["travelers"] = new { type = "integer", @enum = new[] { 1, 2, 3, 4, 5, 6 } },
}),
["required"] = JsonSerializer.SerializeToElement(new[] { "origin", "destination", "departure_date" }),
["additionalProperties"] = JsonSerializer.SerializeToElement(false),
}),
}),
new ToolUnion(new Tool()
{
Name = "search_hotels",
Strict = true,
InputSchema = new InputSchema(new Dictionary<string, JsonElement>
{
["properties"] = JsonSerializer.SerializeToElement(new Dictionary<string, object>
{
["city"] = new { type = "string" },
["check_in"] = new { type = "string", format = "date" },
["guests"] = new { type = "integer", @enum = new[] { 1, 2, 3, 4 } },
}),
["required"] = JsonSerializer.SerializeToElement(new[] { "city", "check_in" }),
["additionalProperties"] = JsonSerializer.SerializeToElement(false),
}),
}),
]
};
var message = await client.Messages.Create(parameters);
Console.WriteLine(message);
```
```go Go
client := anthropic.NewClient()
response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
Model: anthropic.ModelClaudeOpus5,
MaxTokens: 1024,
Messages: []anthropic.MessageParam{
anthropic.NewUserMessage(anthropic.NewTextBlock("Help me plan a trip from New York to Paris for 2 people, departing June 1, 2026")),
},
Tools: []anthropic.ToolUnionParam{
{OfTool: &anthropic.ToolParam{
Name: "search_flights",
Strict: anthropic.Bool(true),
InputSchema: anthropic.ToolInputSchemaParam{
Properties: map[string]any{
"origin": map[string]any{"type": "string"},
"destination": map[string]any{"type": "string"},
"departure_date": map[string]any{"type": "string", "format": "date"},
"travelers": map[string]any{"type": "integer", "enum": []int{1, 2, 3, 4, 5, 6}},
},
Required: []string{"origin", "destination", "departure_date"},
ExtraFields: map[string]any{
"additionalProperties": false,
},
}}},
{OfTool: &anthropic.ToolParam{
Name: "search_hotels",
Strict: anthropic.Bool(true),
InputSchema: anthropic.ToolInputSchemaParam{
Properties: map[string]any{
"city": map[string]any{"type": "string"},
"check_in": map[string]any{"type": "string", "format": "date"},
"guests": map[string]any{"type": "integer", "enum": []int{1, 2, 3, 4}},
},
Required: []string{"city", "check_in"},
ExtraFields: map[string]any{
"additionalProperties": false,
},
}}},
},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(response.RawJSON())
```
```java Java
AnthropicClient client = AnthropicOkHttpClient.fromEnv();
InputSchema flightsSchema = InputSchema.builder()
.properties(
JsonValue.from(
Map.of(
"origin", Map.of("type", "string"),
"destination", Map.of("type", "string"),
"departure_date", Map.of("type", "string", "format", "date"),
"travelers", Map.of("type", "integer", "enum", List.of(1, 2, 3, 4, 5, 6))
)
)
)
.putAdditionalProperty("required", JsonValue.from(List.of("origin", "destination", "departure_date")))
.putAdditionalProperty("additionalProperties", JsonValue.from(false))
.build();
InputSchema hotelsSchema = InputSchema.builder()
.properties(
JsonValue.from(
Map.of(
"city", Map.of("type", "string"),
"check_in", Map.of("type", "string", "format", "date"),
"guests", Map.of("type", "integer", "enum", List.of(1, 2, 3, 4))
)
)
)
.putAdditionalProperty("required", JsonValue.from(List.of("city", "check_in")))
.putAdditionalProperty("additionalProperties", JsonValue.from(false))
.build();
MessageCreateParams params = MessageCreateParams.builder()
.model(Model.CLAUDE_OPUS_5)
.maxTokens(1024L)
.addUserMessage("Help me plan a trip from New York to Paris for 2 people, departing June 1, 2026")
.addTool(
Tool.builder()
.name("search_flights")
.strict(true)
.inputSchema(flightsSchema)
.build()
)
.addTool(
Tool.builder()
.name("search_hotels")
.strict(true)
.inputSchema(hotelsSchema)
.build()
)
.build();
Message response = client.messages().create(params);
IO.println(response);
```
```php PHP
$client = new Client();
$message = $client->messages->create(
maxTokens: 1024,
messages: [
['role' => 'user', 'content' => 'Help me plan a trip from New York to Paris for 2 people, departing June 1, 2026']
],
model: 'claude-opus-5',
tools: [
[
'name' => 'search_flights',
'strict' => true,
'input_schema' => [
'type' => 'object',
'properties' => [
'origin' => ['type' => 'string'],
'destination' => ['type' => 'string'],
'departure_date' => ['type' => 'string', 'format' => 'date'],
'travelers' => ['type' => 'integer', 'enum' => [1, 2, 3, 4, 5, 6]]
],
'required' => ['origin', 'destination', 'departure_date'],
'additionalProperties' => false
]
],
[
'name' => 'search_hotels',
'strict' => true,
'input_schema' => [
'type' => 'object',
'properties' => [
'city' => ['type' => 'string'],
'check_in' => ['type' => 'string', 'format' => 'date'],
'guests' => ['type' => 'integer', 'enum' => [1, 2, 3, 4]]
],
'required' => ['city', 'check_in'],
'additionalProperties' => false
]
]
],
);
echo $message;
```
```ruby Ruby
client = Anthropic::Client.new
message = client.messages.create(
model: "claude-opus-5",
max_tokens: 1024,
messages: [
{ role: "user", content: "Help me plan a trip from New York to Paris for 2 people, departing June 1, 2026" }
],
tools: [
{
name: "search_flights",
strict: true,
input_schema: {
type: "object",
properties: {
origin: { type: "string" },
destination: { type: "string" },
departure_date: { type: "string", format: "date" },
travelers: { type: "integer", enum: [1, 2, 3, 4, 5, 6] }
},
required: ["origin", "destination", "departure_date"],
additionalProperties: false
}
},
{
name: "search_hotels",
strict: true,
input_schema: {
type: "object",
properties: {
city: { type: "string" },
check_in: { type: "string", format: "date" },
guests: { type: "integer", enum: [1, 2, 3, 4] }
},
required: ["city", "check_in"],
additionalProperties: false
}
}
]
)
puts message
```
</CodeGroup>
Data retention
Strict tool use compiles tool input_schema definitions into grammars using the same pipeline as structured outputs. Tool schemas are temporarily cached for up to 24 hours since last use. Prompts and responses are not retained beyond the API response.
Strict tool use is HIPAA eligible, but protected health information (PHI) must not be included in tool schema definitions. The API caches compiled schemas separately from message content, and these cached schemas do not receive the same PHI protections as prompts and responses. Do not include PHI in input_schema property names, enum values, const values, or pattern regular expressions. PHI should only appear in message content (prompts and responses), where it is protected under HIPAA safeguards.
For ZDR and HIPAA eligibility across all features, see API and data retention.