Repository Public
1---2title: Using Agent Skills with the API3url: https://platform.claude.com/docs/en/build-with-claude/skills-guide4description: Learn how to use Agent Skills to extend Claude's capabilities through the API.5---67Agent Skills extend Claude's capabilities through organized folders of instructions, scripts, and resources. This guide shows you how to use both pre-built and custom Skills with the Claude API.89<Note>10 For complete API reference including request/response schemas and all parameters, see:1112 * [Skill Management API Reference](https://platform.claude.com/docs/en/api/skills/list) - CRUD operations for Skills13 * [Skill Versions API Reference](https://platform.claude.com/docs/en/api/skills/versions/list) - Version management14</Note>1516<Note>17 To learn how zero data retention (ZDR) applies to this feature, see [API and data retention](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention).18</Note>1920## Quick links2122<CardGroup cols={2}>23 <Card title="Get started with Agent Skills in the API" icon="rocket" href="https://platform.claude.com/docs/en/agents-and-tools/agent-skills/quickstart">24 Learn how to use Agent Skills to create documents with the Claude API in under 10 minutes.25 </Card>2627 <Card title="Skill authoring best practices" icon="hammer" href="https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices">28 Learn how to write effective Skills that Claude can discover and use successfully.29 </Card>30</CardGroup>3132## Overview3334<Note>35 For a detailed look at the architecture and real-world applications of Agent Skills, read the engineering blog post: [Equipping agents for the real world with Agent Skills](https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills).36</Note>3738Skills integrate with the Messages API through the [code execution tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool). Whether using pre-built Skills managed by Anthropic or custom Skills you've uploaded, the integration shape is identical: both require code execution and use the same `container` structure.3940### Using Skills4142Skills integrate identically in the Messages API regardless of source. You specify Skills in the `container` parameter with a `skill_id`, `type`, and optional `version`, and they run in the code execution environment.4344You can use Skills from two sources:4546| Aspect | Anthropic Skills | Custom Skills |47| ------------------ | ------------------------------------------ | ------------------------------------------------------------------------------------------------- |48| **Type value** | `anthropic` | `custom` |49| **Skill IDs** | Short names: `pptx`, `xlsx`, `docx`, `pdf` | Generated: `skill_01AbCdEfGhIjKlMnOpQrStUv` |50| **Version format** | Date-based: `20251013` or `latest` | Version ID: `skver_01AbCdEfGhIjKlMnOpQrStUv` or `latest` |51| **Management** | Pre-built and maintained by Anthropic | Upload and manage through the [Skills API](https://platform.claude.com/docs/en/api/skills/create) |52| **Availability** | Available to all users | Private to your workspace |5354Both skill sources are returned by the [List Skills endpoint](https://platform.claude.com/docs/en/api/skills/list) (use the `source` parameter to filter). The integration shape and execution environment are identical. The only difference is where the Skills come from and how they're managed.5556### Prerequisites5758To use Skills, you need:59601. **Claude API key** from the [Claude Console](https://platform.claude.com/settings/keys)612. **[Code execution tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool)** enabled in your requests6263Skills require the code execution tool, so use a model from its [model compatibility list](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#compatibility).6465***6667## Using Skills in Messages6869### Container parameter7071Skills are specified using the `container` parameter in the Messages API. You can include up to 20 Skills for each request.7273The structure is identical for both Anthropic and custom Skills. Specify the required `type` and `skill_id`, and optionally include `version` to pin to a specific version:7475<CodeGroup>76 ```bash cURL77 curl https://api.anthropic.com/v1/messages \78 -H "x-api-key: $ANTHROPIC_API_KEY" \79 -H "anthropic-version: 2023-06-01" \80 -H "content-type: application/json" \81 -d '{82 "model": "claude-opus-5",83 "max_tokens": 4096,84 "container": {85 "skills": [86 {87 "type": "anthropic",88 "skill_id": "pptx",89 "version": "latest"90 }91 ]92 },93 "messages": [{94 "role": "user",95 "content": "Create a presentation about renewable energy"96 }],97 "tools": [{98 "type": "code_execution_20250825",99 "name": "code_execution"100 }]101 }'102 ```103104 ```bash CLI105 ant messages create <<'YAML'106 model: claude-opus-5107 max_tokens: 4096108 container:109 skills:110 - type: anthropic111 skill_id: pptx112 version: latest113 messages:114 - role: user115 content: Create a presentation about renewable energy116 tools:117 - type: code_execution_20250825118 name: code_execution119 YAML120 ```121122 ```python Python123 client = anthropic.Anthropic()124125 response = client.messages.create(126 model="claude-opus-5",127 max_tokens=4096,128 container={129 "skills": [{"type": "anthropic", "skill_id": "pptx", "version": "latest"}]130 },131 messages=[132 {"role": "user", "content": "Create a presentation about renewable energy"}133 ],134 tools=[{"type": "code_execution_20250825", "name": "code_execution"}],135 )136 ```137138 ```typescript TypeScript139 const client = new Anthropic();140141 const response = await client.messages.create({142 model: "claude-opus-5",143 max_tokens: 4096,144 container: {145 skills: [146 {147 type: "anthropic",148 skill_id: "pptx",149 version: "latest"150 }151 ]152 },153 messages: [154 {155 role: "user",156 content: "Create a presentation about renewable energy"157 }158 ],159 tools: [160 {161 type: "code_execution_20250825",162 name: "code_execution"163 }164 ]165 });166 ```167168 ```csharp C#169 AnthropicClient client = new();170171 var parameters = new MessageCreateParams172 {173 Model = "claude-opus-5",174 MaxTokens = 4096,175 Container = new ContainerParams176 {177 Skills =178 [179 new SkillParams180 {181 Type = SkillParamsType.Anthropic,182 SkillID = "pptx",183 Version = "latest",184 },185 ],186 },187 Messages = [new() { Role = Role.User, Content = "Create a presentation about renewable energy" }],188 Tools = [new CodeExecutionTool20250825()],189 };190191 var message = await client.Messages.Create(parameters);192 Console.WriteLine(message);193 ```194195 ```go Go196 client := anthropic.NewClient()197198 response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{199 Model: "claude-opus-5",200 MaxTokens: 4096,201 Container: anthropic.MessageCreateParamsContainerUnion{202 OfContainers: &anthropic.ContainerParams{203 Skills: []anthropic.SkillParams{204 {205 Type: anthropic.SkillParamsTypeAnthropic,206 SkillID: "pptx",207 Version: anthropic.String("latest"),208 },209 },210 },211 },212 Messages: []anthropic.MessageParam{213 anthropic.NewUserMessage(anthropic.NewTextBlock("Create a presentation about renewable energy")),214 },215 Tools: []anthropic.ToolUnionParam{216 {OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}},217 },218 })219 if err != nil {220 log.Fatal(err)221 }222 fmt.Println(response)223 ```224225 ```java Java226 import com.anthropic.models.messages.ContainerParams;227 import com.anthropic.models.messages.SkillParams;228 import com.anthropic.models.messages.CodeExecutionTool20250825;229 // ...230 void main() {231 AnthropicClient client = AnthropicOkHttpClient.fromEnv();232233 MessageCreateParams params = MessageCreateParams.builder()234 .model(Model.CLAUDE_OPUS_5)235 .maxTokens(4096L)236 .container(ContainerParams.builder()237 .addSkill(SkillParams.builder()238 .type(SkillParams.Type.ANTHROPIC)239 .skillId("pptx")240 .version("latest")241 .build())242 .build())243 .addUserMessage("Create a presentation about renewable energy")244 .addTool(CodeExecutionTool20250825.builder().build())245 .build();246247 Message response = client.messages().create(params);248 System.out.println(response);249 }250 ```251252 ```php PHP253 $client = new Client();254255 $message = $client->messages->create(256 maxTokens: 4096,257 messages: [258 ['role' => 'user', 'content' => 'Create a presentation about renewable energy']259 ],260 model: 'claude-opus-5',261 container: [262 'skills' => [263 [264 'type' => 'anthropic',265 'skillID' => 'pptx',266 'version' => 'latest'267 ]268 ]269 ],270 tools: [271 ['type' => 'code_execution_20250825', 'name' => 'code_execution']272 ]273 );274275 echo $message;276 ```277278 ```ruby Ruby279 client = Anthropic::Client.new280281 message = client.messages.create(282 model: "claude-opus-5",283 max_tokens: 4096,284 container: {285 skills: [286 {287 type: "anthropic",288 skill_id: "pptx",289 version: "latest"290 }291 ]292 },293 messages: [294 { role: "user", content: "Create a presentation about renewable energy" }295 ],296 tools: [297 { type: "code_execution_20250825", name: "code_execution" }298 ]299 )300 puts message301 ```302</CodeGroup>303304### Downloading generated files305306When Skills create documents (Excel, PowerPoint, PDF, Word), they return `file_id` attributes in the response. You must use the Files API to download these files.307308**How it works:**3093101. Skills create files during code execution.3112. The response includes a `file_id` for each created file, inside code-execution tool result blocks (see [Response format](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#response-format)).3123. Use the Files API to download the actual file content.3134. Save locally or process as needed.314315To provide input files for Skills to work on, [upload them with the Files API](https://platform.claude.com/docs/en/build-with-claude/files#uploading-a-file) and reference them in your request with a [container upload block](https://platform.claude.com/docs/en/build-with-claude/files#container-upload-blocks).316317**Example: creating and downloading an Excel file**318319<CodeGroup>320 ```bash cURL321 # Step 1: Use a Skill to create a file322 RESPONSE=$(curl https://api.anthropic.com/v1/messages \323 -H "x-api-key: $ANTHROPIC_API_KEY" \324 -H "anthropic-version: 2023-06-01" \325 -H "content-type: application/json" \326 -d '{327 "model": "claude-opus-5",328 "max_tokens": 4096,329 "container": {330 "skills": [331 {"type": "anthropic", "skill_id": "xlsx", "version": "latest"}332 ]333 },334 "messages": [{335 "role": "user",336 "content": "Create an Excel file with a simple budget spreadsheet"337 }],338 "tools": [{339 "type": "code_execution_20250825",340 "name": "code_execution"341 }]342 }')343344 # Step 2: Extract file_id from response (using jq)345 FILE_ID=$(echo "$RESPONSE" | jq -r '.content[] | select(.type=="bash_code_execution_tool_result") | .content | select(.type=="bash_code_execution_result") | .content[] | select(.file_id) | .file_id')346347 # Step 3: Get filename from metadata348 FILENAME=$(curl "https://api.anthropic.com/v1/files/$FILE_ID" \349 -H "x-api-key: $ANTHROPIC_API_KEY" \350 -H "anthropic-version: 2023-06-01" | jq -r '.filename')351352 # Step 4: Download the file using Files API353 curl "https://api.anthropic.com/v1/files/$FILE_ID/content" \354 -H "x-api-key: $ANTHROPIC_API_KEY" \355 -H "anthropic-version: 2023-06-01" \356 --output "$FILENAME"357358 echo "Downloaded: $FILENAME"359 ```360361 ```bash CLI362 # Step 1: Use the xlsx Skill to create a file363 # Step 2: Extract file_id from the response with --transform (GJSON path)364 FILE_ID=$(ant messages create \365 --transform 'content.#.content.content.#.file_id|@flatten|0' \366 --raw-output <<'YAML'367 model: claude-opus-5368 max_tokens: 4096369 container:370 skills:371 - type: anthropic372 skill_id: xlsx373 version: latest374 messages:375 - role: user376 content: Create an Excel file with a simple budget spreadsheet377 tools:378 - type: code_execution_20250825379 name: code_execution380 YAML381 )382383 # Step 3: Get the filename from file metadata384 FILENAME=$(ant files retrieve-metadata \385 --file-id "$FILE_ID" \386 --transform filename \387 --raw-output)388389 # Step 4: Download the file using Files API390 ant files download --file-id "$FILE_ID" --output "$FILENAME" > /dev/null391392 printf 'Downloaded: %s\n' "$FILENAME"393 ```394395 ```python Python396 client = anthropic.Anthropic()397398 # Step 1: Use a Skill to create a file399 response = client.messages.create(400 model="claude-opus-5",401 max_tokens=4096,402 container={403 "skills": [{"type": "anthropic", "skill_id": "xlsx", "version": "latest"}]404 },405 messages=[406 {407 "role": "user",408 "content": "Create an Excel file with a simple budget spreadsheet",409 }410 ],411 tools=[{"type": "code_execution_20250825", "name": "code_execution"}],412 )413414415 # Step 2: Extract file IDs from the response416 def extract_file_ids(response):417 file_ids = []418 for item in response.content:419 if item.type == "bash_code_execution_tool_result":420 content_item = item.content421 if content_item.type == "bash_code_execution_result":422 # each content item is a bash_code_execution_output block carrying a file_id423 for file in content_item.content:424 file_ids.append(file.file_id)425 return file_ids426427428 # Step 3: Download the file using Files API429 for file_id in extract_file_ids(response):430 file_metadata = client.files.retrieve_metadata(file_id=file_id)431 file_content = client.files.download(file_id=file_id)432433 # Step 4: Save to disk434 file_content.write_to_file(file_metadata.filename)435 print(f"Downloaded: {file_metadata.filename}")436 ```437438 ```typescript TypeScript439 import { writeFile } from "node:fs/promises";440441 const client = new Anthropic();442443 // Step 1: Use a Skill to create a file444 const response = await client.messages.create({445 model: "claude-opus-5",446 max_tokens: 4096,447 container: {448 skills: [{ type: "anthropic", skill_id: "xlsx", version: "latest" }]449 },450 messages: [451 {452 role: "user",453 content: "Create an Excel file with a simple budget spreadsheet"454 }455 ],456 tools: [{ type: "code_execution_20250825", name: "code_execution" }]457 });458459 // Step 2: Extract file IDs from the response460 const fileIds: string[] = [];461 for (const block of response.content) {462 if (463 block.type === "bash_code_execution_tool_result" &&464 block.content.type === "bash_code_execution_result"465 ) {466 for (const outputBlock of block.content.content) {467 fileIds.push(outputBlock.file_id);468 }469 }470 }471472 // Step 3: Download each file and save to disk473 for (const fileId of fileIds) {474 const fileMetadata = await client.files.retrieveMetadata(fileId);475 const fileResponse = await client.files.download(fileId);476477 await writeFile(fileMetadata.filename, Buffer.from(await fileResponse.arrayBuffer()));478 console.log(`Downloaded: ${fileMetadata.filename}`);479 }480 ```481482 ```csharp C#483 AnthropicClient client = new();484485 // Step 1: Use a Skill to create a file486 var parameters = new MessageCreateParams487 {488 Model = "claude-opus-5",489 MaxTokens = 4096,490 Container = new ContainerParams491 {492 Skills =493 [494 new SkillParams495 {496 Type = SkillParamsType.Anthropic,497 SkillID = "xlsx",498 Version = "latest",499 },500 ],501 },502 Messages = [new() { Role = Role.User, Content = "Create an Excel file with a simple budget spreadsheet" }],503 Tools = [new CodeExecutionTool20250825()],504 };505506 var response = await client.Messages.Create(parameters);507508 // Step 2: Extract file IDs from the response509 List<string> fileIds = [];510 foreach (var block in response.Content)511 {512 if (block.TryPickBashCodeExecutionToolResult(out var toolResult)513 && toolResult.Content.TryPickBashCodeExecutionResultBlock(out var result))514 {515 foreach (var output in result.Content)516 {517 fileIds.Add(output.FileID);518 }519 }520 }521522 // Step 3: Download each file and save to disk523 foreach (var fileId in fileIds)524 {525 var fileMetadata = await client.Files.RetrieveMetadata(fileId);526 using var download = await client.Files.Download(fileId);527 using var downloadStream = await download.ReadAsStream();528 using var outputFile = File.Create(fileMetadata.Filename);529 await downloadStream.CopyToAsync(outputFile);530 Console.WriteLine($"Downloaded: {fileMetadata.Filename}");531 }532 ```533534 ```go Go535 func main() {536 client := anthropic.NewClient()537538 // Step 1: Use a Skill to create a file539 response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{540 Model: "claude-opus-5",541 MaxTokens: 4096,542 Container: anthropic.MessageCreateParamsContainerUnion{543 OfContainers: &anthropic.ContainerParams{544 Skills: []anthropic.SkillParams{545 {546 Type: anthropic.SkillParamsTypeAnthropic,547 SkillID: "xlsx",548 Version: anthropic.String("latest"),549 },550 },551 },552 },553 Messages: []anthropic.MessageParam{554 anthropic.NewUserMessage(anthropic.NewTextBlock("Create an Excel file with a simple budget spreadsheet")),555 },556 Tools: []anthropic.ToolUnionParam{557 {OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}},558 },559 })560 if err != nil {561 log.Fatal(err)562 }563564 // Step 2: Extract file IDs from the response565 fileIDs := extractFileIDs(response)566567 // Step 3: Download the file using Files API568 for _, fileID := range fileIDs {569 fileMetadata, err := client.Files.GetMetadata(context.TODO(), fileID, anthropic.FileGetMetadataParams{})570 if err != nil {571 log.Fatal(err)572 }573574 fileContent, err := client.Files.Download(context.TODO(), fileID, anthropic.FileDownloadParams{})575 if err != nil {576 log.Fatal(err)577 }578579 // Step 4: Save to disk580 out, err := os.Create(fileMetadata.Filename)581 if err != nil {582 log.Fatal(err)583 }584 if _, err := io.Copy(out, fileContent.Body); err != nil {585 log.Fatal(err)586 }587 out.Close()588 fileContent.Body.Close()589 fmt.Printf("Downloaded: %s\n", fileMetadata.Filename)590 }591 }592593 func extractFileIDs(response *anthropic.Message) []string {594 var fileIDs []string595 for _, item := range response.Content {596 switch v := item.AsAny().(type) {597 case anthropic.BashCodeExecutionToolResultBlock:598 if v.Content.Type == "bash_code_execution_result" {599 for _, output := range v.Content.Content {600 fileIDs = append(fileIDs, output.FileID)601 }602 }603 }604 }605 return fileIDs606 }607 ```608609 ```java Java610 import com.anthropic.models.messages.ContainerParams;611 import com.anthropic.models.messages.SkillParams;612 import com.anthropic.models.messages.CodeExecutionTool20250825;613 import com.anthropic.models.messages.ContentBlock;614 import com.anthropic.models.files.FileMetadata;615 import com.anthropic.core.http.HttpResponse;616 // ...617 void main() throws Exception {618 AnthropicClient client = AnthropicOkHttpClient.fromEnv();619620 // Step 1: Use a Skill to create a file621 MessageCreateParams params = MessageCreateParams.builder()622 .model(Model.CLAUDE_OPUS_5)623 .maxTokens(4096L)624 .container(ContainerParams.builder()625 .addSkill(SkillParams.builder()626 .type(SkillParams.Type.ANTHROPIC)627 .skillId("xlsx")628 .version("latest")629 .build())630 .build())631 .addUserMessage("Create an Excel file with a simple budget spreadsheet")632 .addTool(CodeExecutionTool20250825.builder().build())633 .build();634635 Message response = client.messages().create(params);636637 // Step 2: Extract file IDs from the response638 List<String> fileIds = new ArrayList<>();639 for (ContentBlock block : response.content()) {640 if (block.isBashCodeExecutionToolResult()) {641 var content = block.asBashCodeExecutionToolResult().content();642 if (content.isBashCodeExecutionResultBlock()) {643 for (var outputBlock : content.asBashCodeExecutionResultBlock().content()) {644 fileIds.add(outputBlock.fileId());645 }646 }647 }648 }649650 // Step 3: Download the file using Files API651 for (String fileId : fileIds) {652 FileMetadata fileMetadata = client.files().retrieveMetadata(fileId);653 HttpResponse fileContent = client.files().download(fileId);654655 // Step 4: Save to disk656 try (InputStream is = fileContent.body();657 FileOutputStream fos = new FileOutputStream(fileMetadata.filename())) {658 is.transferTo(fos);659 }660 System.out.println("Downloaded: " + fileMetadata.filename());661 }662 }663 ```664665 ```php PHP666 $client = new Client();667668 // Step 1: Use a Skill to create a file669 $response = $client->messages->create(670 maxTokens: 4096,671 messages: [672 ['role' => 'user', 'content' => 'Create an Excel file with a simple budget spreadsheet']673 ],674 model: 'claude-opus-5',675 container: [676 'skills' => [677 ['type' => 'anthropic', 'skillID' => 'xlsx', 'version' => 'latest']678 ]679 ],680 tools: [681 ['type' => 'code_execution_20250825', 'name' => 'code_execution']682 ]683 );684685 // Step 2: Extract file IDs from the response686 function extractFileIds($response) {687 $fileIds = [];688 foreach ($response->content as $item) {689 if ($item->type === 'bash_code_execution_tool_result') {690 $contentItem = $item->content;691 if ($contentItem->type === 'bash_code_execution_result') {692 foreach ($contentItem->content as $file) {693 $fileIds[] = $file->fileID;694 }695 }696 }697 }698 return $fileIds;699 }700701 // Step 3: Download the file using Files API702 foreach (extractFileIds($response) as $fileId) {703 $fileMetadata = $client->files->retrieveMetadata($fileId);704 $fileContent = $client->files->download($fileId);705706 // Step 4: Save to disk707 file_put_contents($fileMetadata->filename, $fileContent);708 echo "Downloaded: {$fileMetadata->filename}\n";709 }710 ```711712 ```ruby Ruby713 client = Anthropic::Client.new714715 # Step 1: Use a Skill to create a file716 response = client.messages.create(717 model: "claude-opus-5",718 max_tokens: 4096,719 container: {720 skills: [{ type: "anthropic", skill_id: "xlsx", version: "latest" }]721 },722 messages: [723 {724 role: "user",725 content: "Create an Excel file with a simple budget spreadsheet"726 }727 ],728 tools: [{ type: "code_execution_20250825", name: "code_execution" }]729 )730731 # Step 2: Extract file IDs from the response732 def extract_file_ids(response)733 file_ids = []734 response.content.each do |item|735 if item.type == :bash_code_execution_tool_result736 content_item = item.content737 if content_item.type == :bash_code_execution_result738 content_item.content.each do |file|739 file_ids << file.file_id740 end741 end742 end743 end744 file_ids745 end746747 # Step 3: Download the file using Files API748 extract_file_ids(response).each do |file_id|749 file_metadata = client.files.retrieve_metadata(file_id)750751 file_content = client.files.download(file_id)752753 # Step 4: Save to disk754 File.binwrite(file_metadata.filename, file_content.read)755 puts "Downloaded: #{file_metadata.filename}"756 end757 ```758</CodeGroup>759760**Additional Files API operations:**761762<CodeGroup>763 ```bash cURL764 # Get file metadata765 curl "https://api.anthropic.com/v1/files/$FILE_ID" \766 -H "x-api-key: $ANTHROPIC_API_KEY" \767 -H "anthropic-version: 2023-06-01"768769 # List all files770 curl "https://api.anthropic.com/v1/files" \771 -H "x-api-key: $ANTHROPIC_API_KEY" \772 -H "anthropic-version: 2023-06-01"773774 # Delete a file775 curl -X DELETE "https://api.anthropic.com/v1/files/$FILE_ID" \776 -H "x-api-key: $ANTHROPIC_API_KEY" \777 -H "anthropic-version: 2023-06-01"778 ```779780 ```bash CLI781 # Get file metadata782 ant files retrieve-metadata \783 --file-id "$FILE_ID" \784 --transform '{filename,size_bytes}' \785 --format yaml786787 # List all files788 ant files list --transform '{filename,created_at}' --format yaml789790 # Delete a file791 ant files delete --file-id "$FILE_ID" >/dev/null792 ```793794 ```python Python795 client = anthropic.Anthropic()796 file_id = "file_011CNha8iCJcU1wXNR6q4V8w"797 # Get file metadata798 file_info = client.files.retrieve_metadata(file_id=file_id)799 print(f"Filename: {file_info.filename}, Size: {file_info.size_bytes} bytes")800801 # List all files802 for file in client.files.list():803 print(f"{file.filename} - {file.created_at}")804805 # Delete a file806 client.files.delete(file_id=file_id)807 ```808809 ```typescript TypeScript810 const client = new Anthropic();811 const fileId = "file_011CNha8iCJcU1wXNR6q4V8w";812813 // Get file metadata814 const fileInfo = await client.files.retrieveMetadata(fileId);815 console.log(`Filename: ${fileInfo.filename}, Size: ${fileInfo.size_bytes} bytes`);816817 // List all files818 for await (const file of client.files.list()) {819 console.log(`${file.filename} - ${file.created_at}`);820 }821822 // Delete a file823 await client.files.delete(fileId);824 ```825826 ```csharp C#827 AnthropicClient client = new();828829 var fileId = "file_011CNha8iCJcU1wXNR6q4V8w";830831 // Get file metadata832 var fileInfo = await client.Files.RetrieveMetadata(fileId);833 Console.WriteLine($"Filename: {fileInfo.Filename}, Size: {fileInfo.SizeBytes} bytes");834835 // List files836 await foreach (var file in (await client.Files.List()).Paginate())837 {838 Console.WriteLine($"{file.Filename} - {file.CreatedAt}");839 }840841 // Delete the file842 await client.Files.Delete(fileId);843 ```844845 ```go Go846 client := anthropic.NewClient()847 fileID := "file_011CNha8iCJcU1wXNR6q4V8w"848849 // Get file metadata850 fileInfo, err := client.Files.GetMetadata(context.TODO(), fileID, anthropic.FileGetMetadataParams{})851 if err != nil {852 log.Fatal(err)853 }854 fmt.Printf("Filename: %s, Size: %d bytes\n", fileInfo.Filename, fileInfo.SizeBytes)855856 // List all files857 files := client.Files.ListAutoPaging(context.TODO(), anthropic.FileListParams{})858 for files.Next() {859 file := files.Current()860 fmt.Printf("%s - %s\n", file.Filename, file.CreatedAt)861 }862 if files.Err() != nil {863 log.Fatal(files.Err())864 }865866 // Delete a file867 _, err = client.Files.Delete(context.TODO(), fileID, anthropic.FileDeleteParams{})868 if err != nil {869 log.Fatal(err)870 }871 ```872873 ```java Java874 import com.anthropic.models.files.FileMetadata;875 import com.anthropic.models.files.FileListPage;876 // ...877 void main() {878 AnthropicClient client = AnthropicOkHttpClient.fromEnv();879 String fileId = "file_011CNha8iCJcU1wXNR6q4V8w";880881 // Get file metadata882 FileMetadata fileInfo = client.files().retrieveMetadata(fileId);883 System.out.println("Filename: " + fileInfo.filename() + ", Size: " + fileInfo.sizeBytes() + " bytes");884885 // List files (first page)886 FileListPage files = client.files().list();887 for (var file : files.data()) {888 System.out.println(file.filename() + " - " + file.createdAt());889 }890891 // Delete a file892 client.files().delete(fileId);893 }894 ```895896 ```php PHP897 $client = new Client();898 $fileId = 'file_011CNha8iCJcU1wXNR6q4V8w';899900 // Get file metadata901 $fileInfo = $client->files->retrieveMetadata($fileId);902 echo "Filename: {$fileInfo->filename}, Size: {$fileInfo->sizeBytes} bytes\n";903904 // List files (first page)905 foreach ($client->files->list()->getItems() as $file) {906 echo "{$file->filename} - {$file->createdAt->format(DATE_ATOM)}\n";907 }908909 // Delete a file910 $client->files->delete($fileId);911 ```912913 ```ruby Ruby914 client = Anthropic::Client.new915 file_id = "file_011CNha8iCJcU1wXNR6q4V8w"916917 # Get file metadata918 file_info = client.files.retrieve_metadata(file_id)919 puts "Filename: #{file_info.filename}, Size: #{file_info.size_bytes} bytes"920921 # List all files922 client.files.list.auto_paging_each do |file|923 puts "#{file.filename} - #{file.created_at}"924 end925926 # Delete a file927 client.files.delete(file_id)928 ```929</CodeGroup>930931<Note>932 For complete details, see [Files API](https://platform.claude.com/docs/en/build-with-claude/files).933</Note>934935### Multi-turn conversations936937The response's `container` object carries the container's `id` and `expires_at` timestamp (see [Container reuse](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool#container-reuse) for lifetime details). Reuse the same container across multiple messages by specifying the container ID:938939<CodeGroup>940 ```bash cURL941 # Multi-turn container reuse doesn't translate well to a one-off shell942 # command; one of the SDK options would be a better fit. Capture943 # container.id from the first response, then pass it in the next request as944 # "container": {"id": "...", "skills": [...]} with the conversation history.945 ```946947 ```bash CLI948 # First request creates container949 CONTAINER_ID=$(ant messages create \950 --transform container.id \951 --raw-output <<'YAML'952 model: claude-opus-5953 max_tokens: 4096954 container:955 skills:956 - {type: anthropic, skill_id: xlsx, version: latest}957 messages:958 - role: user959 content: Create a sample sales dataset and analyze it960 tools:961 - {type: code_execution_20250825, name: code_execution}962 YAML963 )964965 # Continue conversation with same container966 ant messages create <<YAML967 model: claude-opus-5968 max_tokens: 4096969 container:970 id: $CONTAINER_ID # Reuse container971 skills:972 - {type: anthropic, skill_id: xlsx, version: latest}973 messages:974 - role: user975 content: Create a sample sales dataset and analyze it976 - role: assistant977 content: [] # the assistant's text from the first response978 - role: user979 content: What was the total revenue?980 tools:981 - {type: code_execution_20250825, name: code_execution}982 YAML983 ```984985 ```python Python986 client = anthropic.Anthropic()987988 # First request creates container989 response1 = client.messages.create(990 model="claude-opus-5",991 max_tokens=4096,992 container={993 "skills": [{"type": "anthropic", "skill_id": "xlsx", "version": "latest"}]994 },995 messages=[996 {"role": "user", "content": "Create a sample sales dataset and analyze it"}997 ],998 tools=[{"type": "code_execution_20250825", "name": "code_execution"}],999 )10001001 # Continue conversation with same container1002 messages = [1003 {"role": "user", "content": "Create a sample sales dataset and analyze it"},1004 {1005 # Carry the assistant's text forward; container.id carries the execution state1006 "role": "assistant",1007 "content": "\n".join(1008 block.text for block in response1.content if block.type == "text"1009 ),1010 },1011 {"role": "user", "content": "What was the total revenue?"},1012 ]10131014 response2 = client.messages.create(1015 model="claude-opus-5",1016 max_tokens=4096,1017 container={1018 "id": response1.container.id, # Reuse container1019 "skills": [{"type": "anthropic", "skill_id": "xlsx", "version": "latest"}],1020 },1021 messages=messages,1022 tools=[{"type": "code_execution_20250825", "name": "code_execution"}],1023 )1024 ```10251026 ```typescript TypeScript1027 const client = new Anthropic();10281029 // First request creates container1030 const response1 = await client.messages.create({1031 model: "claude-opus-5",1032 max_tokens: 4096,1033 container: {1034 skills: [{ type: "anthropic", skill_id: "xlsx", version: "latest" }]1035 },1036 messages: [{ role: "user", content: "Create a sample sales dataset and analyze it" }],1037 tools: [{ type: "code_execution_20250825", name: "code_execution" }]1038 });10391040 // Continue conversation with same container1041 const messages: Anthropic.MessageParam[] = [1042 { role: "user", content: "Create a sample sales dataset and analyze it" },1043 {1044 role: "assistant",1045 // Carry the assistant's text forward; container.id carries the execution state1046 content: response1.content1047 .filter((block) => block.type === "text")1048 .map((block) => block.text)1049 .join("\n")1050 },1051 { role: "user", content: "What was the total revenue?" }1052 ];10531054 const response2 = await client.messages.create({1055 model: "claude-opus-5",1056 max_tokens: 4096,1057 container: {1058 id: response1.container!.id, // Reuse container1059 skills: [{ type: "anthropic", skill_id: "xlsx", version: "latest" }]1060 },1061 messages,1062 tools: [{ type: "code_execution_20250825", name: "code_execution" }]1063 });1064 ```10651066 ```csharp C#1067 AnthropicClient client = new();10681069 // First request with a Skill1070 var parameters1 = new MessageCreateParams1071 {1072 Model = "claude-opus-5",1073 MaxTokens = 4096,1074 Container = new ContainerParams1075 {1076 Skills =1077 [1078 new SkillParams1079 {1080 Type = SkillParamsType.Anthropic,1081 SkillID = "xlsx",1082 Version = "latest",1083 },1084 ],1085 },1086 Messages = [new() { Role = Role.User, Content = "Create a sample sales dataset and analyze it" }],1087 Tools = [new CodeExecutionTool20250825()],1088 };10891090 var response1 = await client.Messages.Create(parameters1);10911092 // Continue the conversation in the same container1093 // Carry the assistant's text forward; container.id carries the execution state1094 var assistantText = string.Join(1095 "\n",1096 response1.Content.Select(block => block.TryPickText(out var text) ? text.Text : null).Where(text => text is not null)1097 );10981099 var parameters2 = new MessageCreateParams1100 {1101 Model = "claude-opus-5",1102 MaxTokens = 4096,1103 Container = new ContainerParams1104 {1105 ID = response1.Container!.ID,1106 Skills =1107 [1108 new SkillParams1109 {1110 Type = SkillParamsType.Anthropic,1111 SkillID = "xlsx",1112 Version = "latest",1113 },1114 ],1115 },1116 Messages =1117 [1118 new() { Role = Role.User, Content = "Create a sample sales dataset and analyze it" },1119 new() { Role = Role.Assistant, Content = assistantText },1120 new() { Role = Role.User, Content = "What was the total revenue?" },1121 ],1122 Tools = [new CodeExecutionTool20250825()],1123 };11241125 var response2 = await client.Messages.Create(parameters2);1126 Console.WriteLine(response2);1127 ```11281129 ```go Go1130 client := anthropic.NewClient()11311132 response1, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{1133 Model: "claude-opus-5",1134 MaxTokens: 4096,1135 Container: anthropic.MessageCreateParamsContainerUnion{1136 OfContainers: &anthropic.ContainerParams{1137 Skills: []anthropic.SkillParams{1138 {1139 Type: anthropic.SkillParamsTypeAnthropic,1140 SkillID: "xlsx",1141 Version: anthropic.String("latest"),1142 },1143 },1144 },1145 },1146 Messages: []anthropic.MessageParam{1147 anthropic.NewUserMessage(anthropic.NewTextBlock("Create a sample sales dataset and analyze it")),1148 },1149 Tools: []anthropic.ToolUnionParam{1150 {OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}},1151 },1152 })1153 if err != nil {1154 log.Fatal(err)1155 }11561157 // Carry the assistant's text forward; container.id carries the execution state1158 var textParts []string1159 for _, block := range response1.Content {1160 if block.Type == "text" {1161 textParts = append(textParts, block.Text)1162 }1163 }1164 assistantText := strings.Join(textParts, "\n")11651166 response2, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{1167 Model: "claude-opus-5",1168 MaxTokens: 4096,1169 Container: anthropic.MessageCreateParamsContainerUnion{1170 OfContainers: &anthropic.ContainerParams{1171 ID: anthropic.String(response1.Container.ID), // Reuse container1172 Skills: []anthropic.SkillParams{1173 {1174 Type: anthropic.SkillParamsTypeAnthropic,1175 SkillID: "xlsx",1176 Version: anthropic.String("latest"),1177 },1178 },1179 },1180 },1181 Messages: []anthropic.MessageParam{1182 anthropic.NewUserMessage(anthropic.NewTextBlock("Create a sample sales dataset and analyze it")),1183 {1184 Role: anthropic.MessageParamRoleAssistant,1185 Content: []anthropic.ContentBlockParamUnion{anthropic.NewTextBlock(assistantText)},1186 },1187 anthropic.NewUserMessage(anthropic.NewTextBlock("What was the total revenue?")),1188 },1189 Tools: []anthropic.ToolUnionParam{1190 {OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}},1191 },1192 })1193 if err != nil {1194 log.Fatal(err)1195 }11961197 fmt.Println(response2)1198 ```11991200 ```java Java1201 import com.anthropic.models.messages.ContainerParams;1202 import com.anthropic.models.messages.SkillParams;1203 import com.anthropic.models.messages.CodeExecutionTool20250825;1204 import com.anthropic.models.messages.ContentBlock;1205 // ...1206 void main() {1207 AnthropicClient client = AnthropicOkHttpClient.fromEnv();12081209 MessageCreateParams params1 = MessageCreateParams.builder()1210 .model(Model.CLAUDE_OPUS_5)1211 .maxTokens(4096L)1212 .container(ContainerParams.builder()1213 .addSkill(SkillParams.builder()1214 .type(SkillParams.Type.ANTHROPIC)1215 .skillId("xlsx")1216 .version("latest")1217 .build())1218 .build())1219 .addUserMessage("Create a sample sales dataset and analyze it")1220 .addTool(CodeExecutionTool20250825.builder().build())1221 .build();12221223 Message response1 = client.messages().create(params1);12241225 MessageCreateParams params2 = MessageCreateParams.builder()1226 .model(Model.CLAUDE_OPUS_5)1227 .maxTokens(4096L)1228 .container(ContainerParams.builder()1229 .id(response1.container().get().id())1230 .addSkill(SkillParams.builder()1231 .type(SkillParams.Type.ANTHROPIC)1232 .skillId("xlsx")1233 .version("latest")1234 .build())1235 .build())1236 .addUserMessage("Create a sample sales dataset and analyze it")1237 // Carry the assistant's text forward; container.id carries the execution state1238 .addAssistantMessage(response1.content().stream()1239 .filter(ContentBlock::isText)1240 .map(block -> block.asText().text())1241 .collect(Collectors.joining("\n")))1242 .addUserMessage("What was the total revenue?")1243 .addTool(CodeExecutionTool20250825.builder().build())1244 .build();12451246 Message response2 = client.messages().create(params2);1247 System.out.println(response2);1248 }1249 ```12501251 ```php PHP1252 $client = new Client();12531254 $response1 = $client->messages->create(1255 maxTokens: 4096,1256 messages: [1257 ['role' => 'user', 'content' => 'Create a sample sales dataset and analyze it']1258 ],1259 model: 'claude-opus-5',1260 container: [1261 'skills' => [1262 ['type' => 'anthropic', 'skillID' => 'xlsx', 'version' => 'latest']1263 ]1264 ],1265 tools: [1266 ['type' => 'code_execution_20250825', 'name' => 'code_execution']1267 ]1268 );12691270 $messages = [1271 ['role' => 'user', 'content' => 'Create a sample sales dataset and analyze it'],1272 // Carry the assistant's text forward; container.id carries the execution state1273 ['role' => 'assistant', 'content' => implode("\n", array_map(1274 fn ($block) => $block->text,1275 array_filter($response1->content, fn ($block) => $block->type === 'text'),1276 ))],1277 ['role' => 'user', 'content' => 'What was the total revenue?']1278 ];12791280 $response2 = $client->messages->create(1281 maxTokens: 4096,1282 messages: $messages,1283 model: 'claude-opus-5',1284 container: [1285 'id' => $response1->container->id,1286 'skills' => [1287 ['type' => 'anthropic', 'skillID' => 'xlsx', 'version' => 'latest']1288 ]1289 ],1290 tools: [1291 ['type' => 'code_execution_20250825', 'name' => 'code_execution']1292 ]1293 );12941295 echo $response2;1296 ```12971298 ```ruby Ruby1299 client = Anthropic::Client.new13001301 response1 = client.messages.create(1302 model: "claude-opus-5",1303 max_tokens: 4096,1304 container: {1305 skills: [{ type: "anthropic", skill_id: "xlsx", version: "latest" }]1306 },1307 messages: [1308 { role: "user", content: "Create a sample sales dataset and analyze it" }1309 ],1310 tools: [1311 { type: "code_execution_20250825", name: "code_execution" }1312 ]1313 )13141315 messages = [1316 { role: "user", content: "Create a sample sales dataset and analyze it" },1317 {1318 # Carry the assistant's text forward; container.id carries the execution state1319 role: "assistant",1320 content: response1.content.filter_map { |block| block.text if block.type == :text }.join("\n")1321 },1322 { role: "user", content: "What was the total revenue?" }1323 ]13241325 response2 = client.messages.create(1326 model: "claude-opus-5",1327 max_tokens: 4096,1328 container: {1329 id: response1.container.id,1330 skills: [1331 { type: "anthropic", skill_id: "xlsx", version: "latest" }1332 ]1333 },1334 messages: messages,1335 tools: [1336 { type: "code_execution_20250825", name: "code_execution" }1337 ]1338 )13391340 puts response21341 ```1342</CodeGroup>13431344### Long-running operations13451346Skills may perform operations that require multiple turns. Handle `pause_turn` stop reasons:13471348<CodeGroup>1349 ```bash cURL1350 # Initial request1351 RESPONSE=$(curl https://api.anthropic.com/v1/messages \1352 -H "x-api-key: $ANTHROPIC_API_KEY" \1353 -H "anthropic-version: 2023-06-01" \1354 -H "content-type: application/json" \1355 -d '{1356 "model": "claude-opus-5",1357 "max_tokens": 4096,1358 "container": {1359 "skills": [1360 {1361 "type": "custom",1362 "skill_id": "skill_01AbCdEfGhIjKlMnOpQrStUv",1363 "version": "latest"1364 }1365 ]1366 },1367 "messages": [{1368 "role": "user",1369 "content": "Generate and process a large sample dataset"1370 }],1371 "tools": [{1372 "type": "code_execution_20250825",1373 "name": "code_execution"1374 }]1375 }')13761377 # If stop_reason is "pause_turn", continue in the same container, appending1378 # the prior response's content array to messages as the assistant turn.1379 # Repeat this continuation request until stop_reason is no longer "pause_turn".1380 STOP_REASON=$(echo "$RESPONSE" | jq -r '.stop_reason')1381 CONTAINER_ID=$(echo "$RESPONSE" | jq -r '.container.id')13821383 RESPONSE=$(curl https://api.anthropic.com/v1/messages \1384 -H "x-api-key: $ANTHROPIC_API_KEY" \1385 -H "anthropic-version: 2023-06-01" \1386 -H "content-type: application/json" \1387 -d "{1388 \"model\": \"claude-opus-5\",1389 \"max_tokens\": 4096,1390 \"container\": {1391 \"id\": \"$CONTAINER_ID\",1392 \"skills\": [{1393 \"type\": \"custom\",1394 \"skill_id\": \"skill_01AbCdEfGhIjKlMnOpQrStUv\",1395 \"version\": \"latest\"1396 }]1397 },1398 \"messages\": [],1399 \"tools\": [{1400 \"type\": \"code_execution_20250825\",1401 \"name\": \"code_execution\"1402 }]1403 }")1404 ```14051406 ```bash CLI1407 RESP=$(mktemp)14081409 # Initial request: capture the full JSON response to a temp file1410 ant messages create > "$RESP" <<'YAML'1411 model: claude-opus-51412 max_tokens: 40961413 container:1414 skills:1415 - type: custom1416 skill_id: skill_01AbCdEfGhIjKlMnOpQrStUv1417 version: latest1418 messages:1419 - role: user1420 content: Generate and process a large sample dataset1421 tools:1422 - type: code_execution_202508251423 name: code_execution1424 YAML14251426 # If stop_reason is "pause_turn", continue in the same container,1427 # appending the prior response's content array to messages as the1428 # assistant turn. Repeat until stop_reason is no longer "pause_turn".1429 CONTAINER_ID=$(jq -r '.container.id' "$RESP")14301431 ant messages create > "$RESP" <<YAML1432 model: claude-opus-51433 max_tokens: 40961434 container:1435 id: $CONTAINER_ID1436 skills:1437 - type: custom1438 skill_id: skill_01AbCdEfGhIjKlMnOpQrStUv1439 version: latest1440 messages: [] # replace with conversation history + prior assistant content1441 tools:1442 - type: code_execution_202508251443 name: code_execution1444 YAML1445 ```14461447 ```python Python1448 client = anthropic.Anthropic()14491450 messages = [{"role": "user", "content": "Generate and process a large sample dataset"}]1451 max_retries = 1014521453 response = client.messages.create(1454 model="claude-opus-5",1455 max_tokens=4096,1456 container={1457 "skills": [1458 {1459 "type": "custom",1460 "skill_id": "skill_01AbCdEfGhIjKlMnOpQrStUv",1461 "version": "latest",1462 }1463 ]1464 },1465 messages=messages,1466 tools=[{"type": "code_execution_20250825", "name": "code_execution"}],1467 )14681469 # Handle pause_turn for long operations1470 for _ in range(max_retries):1471 if response.stop_reason != "pause_turn":1472 break14731474 messages.append({"role": "assistant", "content": response.content})1475 response = client.messages.create(1476 model="claude-opus-5",1477 max_tokens=4096,1478 container={1479 "id": response.container.id,1480 "skills": [1481 {1482 "type": "custom",1483 "skill_id": "skill_01AbCdEfGhIjKlMnOpQrStUv",1484 "version": "latest",1485 }1486 ],1487 },1488 messages=messages,1489 tools=[{"type": "code_execution_20250825", "name": "code_execution"}],1490 )1491 ```14921493 ```typescript TypeScript1494 const client = new Anthropic();1495 const messages: Anthropic.MessageParam[] = [1496 { role: "user", content: "Generate and process a large sample dataset" }1497 ];1498 const maxRetries = 10;14991500 let response = await client.messages.create({1501 model: "claude-opus-5",1502 max_tokens: 4096,1503 container: {1504 skills: [{ type: "custom", skill_id: "skill_01AbCdEfGhIjKlMnOpQrStUv", version: "latest" }]1505 },1506 messages,1507 tools: [{ type: "code_execution_20250825", name: "code_execution" }]1508 });15091510 // Handle pause_turn for long operations1511 for (let i = 0; i < maxRetries; i++) {1512 if (response.stop_reason !== "pause_turn") {1513 break;1514 }15151516 messages.push({1517 role: "assistant",1518 content: response.content as Anthropic.ContentBlockParam[]1519 });1520 response = await client.messages.create({1521 model: "claude-opus-5",1522 max_tokens: 4096,1523 container: {1524 id: response.container!.id,1525 skills: [1526 { type: "custom", skill_id: "skill_01AbCdEfGhIjKlMnOpQrStUv", version: "latest" }1527 ]1528 },1529 messages,1530 tools: [{ type: "code_execution_20250825", name: "code_execution" }]1531 });1532 }1533 ```15341535 ```csharp C#1536 using System.Text.Json;1537 // ...1538 AnthropicClient client = new();15391540 List<MessageParam> messages =1541 [1542 new() { Role = Role.User, Content = "Generate and process a large sample dataset" },1543 ];15441545 var maxRetries = 10;1546 string? containerId = null;1547 Message? response = null;15481549 for (var i = 0; i < maxRetries; i++)1550 {1551 var parameters = new MessageCreateParams1552 {1553 Model = "claude-opus-5",1554 MaxTokens = 4096,1555 Container = containerId is null1556 ? new ContainerParams1557 {1558 Skills =1559 [1560 new SkillParams1561 {1562 Type = SkillParamsType.Custom,1563 SkillID = "skill_01AbCdEfGhIjKlMnOpQrStUv",1564 Version = "latest",1565 },1566 ],1567 }1568 : new ContainerParams1569 {1570 ID = containerId,1571 Skills =1572 [1573 new SkillParams1574 {1575 Type = SkillParamsType.Custom,1576 SkillID = "skill_01AbCdEfGhIjKlMnOpQrStUv",1577 Version = "latest",1578 },1579 ],1580 },1581 Messages = messages,1582 Tools = [new CodeExecutionTool20250825()],1583 };15841585 response = await client.Messages.Create(parameters);1586 containerId = response.Container!.ID;15871588 if (response.StopReason != StopReason.PauseTurn)1589 {1590 break;1591 }15921593 // Append the paused turn's content and continue1594 var assistantContent = JsonSerializer.SerializeToElement(1595 response.Content.Select(block => block.Json).ToArray()1596 );1597 messages.Add(new() { Role = Role.Assistant, Content = new MessageParamContent(assistantContent) });1598 }1599 ```16001601 ```go Go1602 client := anthropic.NewClient()16031604 messages := []anthropic.MessageParam{1605 anthropic.NewUserMessage(anthropic.NewTextBlock("Generate and process a large sample dataset")),1606 }1607 maxRetries := 1016081609 response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{1610 Model: "claude-opus-5",1611 MaxTokens: 4096,1612 Container: anthropic.MessageCreateParamsContainerUnion{1613 OfContainers: &anthropic.ContainerParams{1614 Skills: []anthropic.SkillParams{1615 {1616 Type: anthropic.SkillParamsTypeCustom,1617 SkillID: "skill_01AbCdEfGhIjKlMnOpQrStUv",1618 Version: anthropic.String("latest"),1619 },1620 },1621 },1622 },1623 Messages: messages,1624 Tools: []anthropic.ToolUnionParam{1625 {OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}},1626 },1627 })1628 if err != nil {1629 log.Fatal(err)1630 }16311632 for i := 0; i < maxRetries; i++ {1633 if response.StopReason != anthropic.StopReasonPauseTurn {1634 break1635 }16361637 messages = append(messages, response.ToParam())16381639 response, err = client.Messages.New(context.TODO(), anthropic.MessageNewParams{1640 Model: "claude-opus-5",1641 MaxTokens: 4096,1642 Container: anthropic.MessageCreateParamsContainerUnion{1643 OfContainers: &anthropic.ContainerParams{1644 ID: anthropic.String(response.Container.ID), // Reuse container1645 Skills: []anthropic.SkillParams{1646 {1647 Type: anthropic.SkillParamsTypeCustom,1648 SkillID: "skill_01AbCdEfGhIjKlMnOpQrStUv",1649 Version: anthropic.String("latest"),1650 },1651 },1652 },1653 },1654 Messages: messages,1655 Tools: []anthropic.ToolUnionParam{1656 {OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}},1657 },1658 })1659 if err != nil {1660 log.Fatal(err)1661 }1662 }16631664 fmt.Println(response)1665 ```16661667 ```java Java1668 import com.anthropic.models.messages.ContainerParams;1669 import com.anthropic.models.messages.SkillParams;1670 import com.anthropic.models.messages.CodeExecutionTool20250825;1671 import com.anthropic.models.messages.StopReason;1672 // ...1673 void main() {1674 AnthropicClient client = AnthropicOkHttpClient.fromEnv();16751676 List<MessageParam> messages = new ArrayList<>();1677 messages.add(1678 MessageParam.builder()1679 .role(MessageParam.Role.USER)1680 .content("Generate and process a large sample dataset")1681 .build()1682 );1683 int maxRetries = 10;16841685 Message response = client.messages().create(1686 MessageCreateParams.builder()1687 .model(Model.CLAUDE_OPUS_5)1688 .maxTokens(4096L)1689 .container(ContainerParams.builder()1690 .addSkill(SkillParams.builder()1691 .type(SkillParams.Type.CUSTOM)1692 .skillId("skill_01AbCdEfGhIjKlMnOpQrStUv")1693 .version("latest")1694 .build())1695 .build())1696 .messages(messages)1697 .addTool(CodeExecutionTool20250825.builder().build())1698 .build());16991700 for (int i = 0; i < maxRetries; i++) {1701 if (!response.stopReason().isPresent()1702 || !response.stopReason().get().equals(StopReason.PAUSE_TURN)) {1703 break;1704 }17051706 messages.add(response.toParam());17071708 response = client.messages().create(1709 MessageCreateParams.builder()1710 .model(Model.CLAUDE_OPUS_5)1711 .maxTokens(4096L)1712 .container(ContainerParams.builder()1713 .id(response.container().get().id())1714 .addSkill(SkillParams.builder()1715 .type(SkillParams.Type.CUSTOM)1716 .skillId("skill_01AbCdEfGhIjKlMnOpQrStUv")1717 .version("latest")1718 .build())1719 .build())1720 .messages(messages)1721 .addTool(CodeExecutionTool20250825.builder().build())1722 .build());1723 }1724 }1725 ```17261727 ```php PHP1728 $client = new Client();17291730 $messages = [1731 ['role' => 'user', 'content' => 'Generate and process a large sample dataset']1732 ];1733 $maxRetries = 10;17341735 $response = $client->messages->create(1736 maxTokens: 4096,1737 messages: $messages,1738 model: 'claude-opus-5',1739 container: [1740 'skills' => [1741 [1742 'type' => 'custom',1743 'skillID' => 'skill_01AbCdEfGhIjKlMnOpQrStUv',1744 'version' => 'latest'1745 ]1746 ]1747 ],1748 tools: [['type' => 'code_execution_20250825', 'name' => 'code_execution']]1749 );17501751 for ($i = 0; $i < $maxRetries; $i++) {1752 if ($response->stopReason !== 'pause_turn') {1753 break;1754 }17551756 $messages[] = ['role' => 'assistant', 'content' => $response->content];17571758 $response = $client->messages->create(1759 maxTokens: 4096,1760 messages: $messages,1761 model: 'claude-opus-5',1762 container: [1763 'id' => $response->container->id,1764 'skills' => [1765 [1766 'type' => 'custom',1767 'skillID' => 'skill_01AbCdEfGhIjKlMnOpQrStUv',1768 'version' => 'latest'1769 ]1770 ]1771 ],1772 tools: [['type' => 'code_execution_20250825', 'name' => 'code_execution']]1773 );1774 }1775 ```17761777 ```ruby Ruby1778 client = Anthropic::Client.new17791780 messages = [1781 { role: "user", content: "Generate and process a large sample dataset" }1782 ]1783 max_retries = 1017841785 response = client.messages.create(1786 model: "claude-opus-5",1787 max_tokens: 4096,1788 container: {1789 skills: [1790 {1791 type: "custom",1792 skill_id: "skill_01AbCdEfGhIjKlMnOpQrStUv",1793 version: "latest"1794 }1795 ]1796 },1797 messages: messages,1798 tools: [{ type: "code_execution_20250825", name: "code_execution" }]1799 )18001801 max_retries.times do1802 break if response.stop_reason != :pause_turn18031804 messages << { role: "assistant", content: response.content }18051806 response = client.messages.create(1807 model: "claude-opus-5",1808 max_tokens: 4096,1809 container: {1810 id: response.container.id,1811 skills: [1812 {1813 type: "custom",1814 skill_id: "skill_01AbCdEfGhIjKlMnOpQrStUv",1815 version: "latest"1816 }1817 ]1818 },1819 messages: messages,1820 tools: [{ type: "code_execution_20250825", name: "code_execution" }]1821 )1822 end1823 ```1824</CodeGroup>18251826<Note>1827 The response may include a `pause_turn` stop reason, which indicates that the API paused a long-running Skill operation. You can provide the response back as-is in a subsequent request to let Claude continue its turn, or modify the content if you want to interrupt the conversation and provide additional guidance.1828</Note>18291830### Using multiple Skills18311832Combine multiple Skills in a single request to handle complex workflows:18331834<CodeGroup>1835 ```bash cURL1836 curl https://api.anthropic.com/v1/messages \1837 -H "x-api-key: $ANTHROPIC_API_KEY" \1838 -H "anthropic-version: 2023-06-01" \1839 -H "content-type: application/json" \1840 -d '{1841 "model": "claude-opus-5",1842 "max_tokens": 4096,1843 "container": {1844 "skills": [1845 {1846 "type": "anthropic",1847 "skill_id": "xlsx",1848 "version": "latest"1849 },1850 {1851 "type": "anthropic",1852 "skill_id": "pptx",1853 "version": "latest"1854 },1855 {1856 "type": "custom",1857 "skill_id": "skill_01AbCdEfGhIjKlMnOpQrStUv",1858 "version": "latest"1859 }1860 ]1861 },1862 "messages": [{1863 "role": "user",1864 "content": "Analyze sales data and create a presentation"1865 }],1866 "tools": [{1867 "type": "code_execution_20250825",1868 "name": "code_execution"1869 }]1870 }'1871 ```18721873 ```bash CLI1874 ant messages create <<'YAML'1875 model: claude-opus-51876 max_tokens: 40961877 container:1878 skills:1879 - type: anthropic1880 skill_id: xlsx1881 version: latest1882 - type: anthropic1883 skill_id: pptx1884 version: latest1885 - type: custom1886 skill_id: skill_01AbCdEfGhIjKlMnOpQrStUv1887 version: latest1888 messages:1889 - role: user1890 content: Analyze sales data and create a presentation1891 tools:1892 - type: code_execution_202508251893 name: code_execution1894 YAML1895 ```18961897 ```python Python1898 client = anthropic.Anthropic()18991900 response = client.messages.create(1901 model="claude-opus-5",1902 max_tokens=4096,1903 container={1904 "skills": [1905 {"type": "anthropic", "skill_id": "xlsx", "version": "latest"},1906 {"type": "anthropic", "skill_id": "pptx", "version": "latest"},1907 {1908 "type": "custom",1909 "skill_id": "skill_01AbCdEfGhIjKlMnOpQrStUv",1910 "version": "latest",1911 },1912 ]1913 },1914 messages=[1915 {"role": "user", "content": "Analyze sales data and create a presentation"}1916 ],1917 tools=[{"type": "code_execution_20250825", "name": "code_execution"}],1918 )1919 ```19201921 ```typescript TypeScript1922 const client = new Anthropic();19231924 const response = await client.messages.create({1925 model: "claude-opus-5",1926 max_tokens: 4096,1927 container: {1928 skills: [1929 {1930 type: "anthropic",1931 skill_id: "xlsx",1932 version: "latest"1933 },1934 {1935 type: "anthropic",1936 skill_id: "pptx",1937 version: "latest"1938 },1939 {1940 type: "custom",1941 skill_id: "skill_01AbCdEfGhIjKlMnOpQrStUv",1942 version: "latest"1943 }1944 ]1945 },1946 messages: [1947 {1948 role: "user",1949 content: "Analyze sales data and create a presentation"1950 }1951 ],1952 tools: [1953 {1954 type: "code_execution_20250825",1955 name: "code_execution"1956 }1957 ]1958 });1959 ```19601961 ```csharp C#1962 AnthropicClient client = new();19631964 var parameters = new MessageCreateParams1965 {1966 Model = "claude-opus-5",1967 MaxTokens = 4096,1968 Container = new ContainerParams1969 {1970 Skills =1971 [1972 new SkillParams1973 {1974 Type = SkillParamsType.Anthropic,1975 SkillID = "xlsx",1976 Version = "latest",1977 },1978 new SkillParams1979 {1980 Type = SkillParamsType.Anthropic,1981 SkillID = "pptx",1982 Version = "latest",1983 },1984 new SkillParams1985 {1986 Type = SkillParamsType.Custom,1987 SkillID = "skill_01AbCdEfGhIjKlMnOpQrStUv",1988 Version = "latest",1989 },1990 ],1991 },1992 Messages = [new() { Role = Role.User, Content = "Analyze sales data and create a presentation" }],1993 Tools = [new CodeExecutionTool20250825()],1994 };19951996 var message = await client.Messages.Create(parameters);1997 Console.WriteLine(message);1998 ```19992000 ```go Go2001 client := anthropic.NewClient()20022003 response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{2004 Model: "claude-opus-5",2005 MaxTokens: 4096,2006 Container: anthropic.MessageCreateParamsContainerUnion{2007 OfContainers: &anthropic.ContainerParams{2008 Skills: []anthropic.SkillParams{2009 {2010 Type: anthropic.SkillParamsTypeAnthropic,2011 SkillID: "xlsx",2012 Version: anthropic.String("latest"),2013 },2014 {2015 Type: anthropic.SkillParamsTypeAnthropic,2016 SkillID: "pptx",2017 Version: anthropic.String("latest"),2018 },2019 {2020 Type: anthropic.SkillParamsTypeCustom,2021 SkillID: "skill_01AbCdEfGhIjKlMnOpQrStUv",2022 Version: anthropic.String("latest"),2023 },2024 },2025 },2026 },2027 Messages: []anthropic.MessageParam{2028 anthropic.NewUserMessage(anthropic.NewTextBlock("Analyze sales data and create a presentation")),2029 },2030 Tools: []anthropic.ToolUnionParam{2031 {OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}},2032 },2033 })2034 if err != nil {2035 log.Fatal(err)2036 }2037 fmt.Println(response)2038 ```20392040 ```java Java2041 import com.anthropic.models.messages.ContainerParams;2042 import com.anthropic.models.messages.SkillParams;2043 import com.anthropic.models.messages.CodeExecutionTool20250825;2044 // ...2045 void main() {2046 AnthropicClient client = AnthropicOkHttpClient.fromEnv();20472048 MessageCreateParams params = MessageCreateParams.builder()2049 .model(Model.CLAUDE_OPUS_5)2050 .maxTokens(4096L)2051 .container(ContainerParams.builder()2052 .skills(List.of(2053 SkillParams.builder()2054 .type(SkillParams.Type.ANTHROPIC)2055 .skillId("xlsx")2056 .version("latest")2057 .build(),2058 SkillParams.builder()2059 .type(SkillParams.Type.ANTHROPIC)2060 .skillId("pptx")2061 .version("latest")2062 .build(),2063 SkillParams.builder()2064 .type(SkillParams.Type.CUSTOM)2065 .skillId("skill_01AbCdEfGhIjKlMnOpQrStUv")2066 .version("latest")2067 .build()2068 ))2069 .build())2070 .addUserMessage("Analyze sales data and create a presentation")2071 .addTool(CodeExecutionTool20250825.builder().build())2072 .build();20732074 Message response = client.messages().create(params);2075 System.out.println(response);2076 }2077 ```20782079 ```php PHP2080 $client = new Client();20812082 $message = $client->messages->create(2083 maxTokens: 4096,2084 messages: [2085 ['role' => 'user', 'content' => 'Analyze sales data and create a presentation']2086 ],2087 model: 'claude-opus-5',2088 container: [2089 'skills' => [2090 [2091 'type' => 'anthropic',2092 'skillID' => 'xlsx',2093 'version' => 'latest'2094 ],2095 [2096 'type' => 'anthropic',2097 'skillID' => 'pptx',2098 'version' => 'latest'2099 ],2100 [2101 'type' => 'custom',2102 'skillID' => 'skill_01AbCdEfGhIjKlMnOpQrStUv',2103 'version' => 'latest'2104 ]2105 ]2106 ],2107 tools: [2108 ['type' => 'code_execution_20250825', 'name' => 'code_execution']2109 ]2110 );21112112 echo $message;2113 ```21142115 ```ruby Ruby2116 client = Anthropic::Client.new21172118 message = client.messages.create(2119 model: "claude-opus-5",2120 max_tokens: 4096,2121 container: {2122 skills: [2123 {2124 type: "anthropic",2125 skill_id: "xlsx",2126 version: "latest"2127 },2128 {2129 type: "anthropic",2130 skill_id: "pptx",2131 version: "latest"2132 },2133 {2134 type: "custom",2135 skill_id: "skill_01AbCdEfGhIjKlMnOpQrStUv",2136 version: "latest"2137 }2138 ]2139 },2140 messages: [2141 { role: "user", content: "Analyze sales data and create a presentation" }2142 ],2143 tools: [2144 { type: "code_execution_20250825", name: "code_execution" }2145 ]2146 )2147 puts message2148 ```2149</CodeGroup>21502151***21522153## Managing custom Skills21542155<Warning id="workspace-scoped-access">2156 **Custom Skills are accessible to your entire workspace, not scoped to an end user, conversation, or session.** Any API key with access to a workspace can read, invoke, and delete every custom Skill uploaded to that workspace. Every service account, and every user whose organization role allows API access, can use the Default Workspace in addition to any workspace you add them to, so keep Skills that must stay separate in their own [workspace](https://platform.claude.com/docs/en/manage-claude/workspaces#api-keys-and-resource-scoping) and access them only with keys scoped to that workspace.21572158 If you are building a multi-tenant platform on the Skills API, create a separate [workspace](https://platform.claude.com/docs/en/manage-claude/workspaces) for each tenant. The workspace is the isolation boundary for custom Skills, so a workspace per tenant gives each tenant's Skills hard isolation from every other tenant. Each organization can have up to 100 workspaces by default (see [How workspaces work](https://platform.claude.com/docs/en/manage-claude/workspaces#how-workspaces-work)); if you need more for tenant isolation, contact your account team.2159</Warning>21602161### Creating a Skill21622163A Skill bundle is a directory containing a `SKILL.md` file at the top level with `name` and `description` YAML frontmatter, plus any supporting scripts or resources. See [Get started with Agent Skills in the API](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/quickstart) to author one, and the **Requirements** list following the examples for the full constraints.21642165Upload your custom Skill to make it available in your workspace. You can upload a zip archive or individual file objects. The Python SDK also provides a `files_from_dir` helper that accepts a directory path.21662167Files are identified by the filename you attach (the `;filename=` suffix in the cURL example and the filename arguments in the SDK examples). For the walkthrough's skill, create a zip with `zip -r financial_skill.zip financial_skill/` and substitute it for the `example_skill.zip` placeholder in the zip-upload options.21682169<CodeGroup>2170 ```bash cURL2171 curl -X POST "https://api.anthropic.com/v1/skills" \2172 -H "x-api-key: $ANTHROPIC_API_KEY" \2173 -H "anthropic-version: 2023-06-01" \2174 -F "files[]=@financial_skill/SKILL.md;filename=financial_skill/SKILL.md" \2175 -F "files[]=@financial_skill/analyze.py;filename=financial_skill/analyze.py"2176 ```21772178 <MultiFileExample language="cli" label="CLI">2179 ```bash CLI2180 zip -r financial_skill.zip financial_skill/2181 ant skills create --file financial_skill.zip2182 ```21832184 <File filename="financial_skill/SKILL.md">2185 ```markdown2186 ---2187 name: financial-skill2188 description: Docs example skill.2189 ---2190 ```2191 </File>21922193 <File filename="financial_skill/analyze.py">2194 ```python2195 print("financial analysis helper")2196 ```2197 </File>2198 </MultiFileExample>21992200 ```python Python2201 from anthropic.lib import files_from_dir22022203 client = anthropic.Anthropic()22042205 # Option 1: Using a zip file2206 skill = client.skills.create(2207 files=[open("example_skill.zip", "rb")],2208 )22092210 # Option 2: Using file tuples (filename, file_content, mime_type)2211 skill = client.skills.create(2212 files=[2213 (2214 "financial_skill/SKILL.md",2215 open("financial_skill/SKILL.md", "rb"),2216 "text/markdown",2217 ),2218 (2219 "financial_skill/analyze.py",2220 open("financial_skill/analyze.py", "rb"),2221 "text/x-python",2222 ),2223 ],2224 )22252226 # Option 3: Using the files_from_dir helper (Python only)2227 skill = client.skills.create(2228 files=files_from_dir("financial_skill"),2229 )22302231 print(f"Created skill: {skill.id}")2232 print(f"Latest version: {skill.latest_version_id}")2233 ```22342235 ```typescript TypeScript2236 import { toFile } from "@anthropic-ai/sdk";2237 import fs from "node:fs";2238 // ...22392240 const client = new Anthropic();22412242 // Option 1: Using a zip file2243 const skillFromZip = await client.skills.create({2244 files: [await toFile(fs.createReadStream("example_skill.zip"), "example_skill.zip")]2245 });22462247 // Option 2: Using individual file objects2248 const skill = await client.skills.create({2249 files: [2250 await toFile(fs.createReadStream("financial_skill/SKILL.md"), "financial_skill/SKILL.md", {2251 type: "text/markdown"2252 }),2253 await toFile(2254 fs.createReadStream("financial_skill/analyze.py"),2255 "financial_skill/analyze.py",2256 { type: "text/x-python" }2257 )2258 ]2259 });22602261 console.log(`Created skill: ${skill.id}`);2262 console.log(`Latest version: ${skill.latest_version_id}`);2263 ```22642265 ```csharp C#2266 using Anthropic.Core;2267 // ...22682269 AnthropicClient client = new();22702271 // Option 1: Using a zip file2272 var parameters = new SkillCreateParams2273 {2274 Files = [File.OpenRead("example_skill.zip")],2275 };22762277 var skill = await client.Skills.Create(parameters);22782279 // Option 2: Using individual files (path-qualified filenames preserve the Skill's directory layout)2280 var parameters2 = new SkillCreateParams2281 {2282 Files =2283 [2284 new BinaryContent2285 {2286 Stream = File.OpenRead("financial_skill/SKILL.md"),2287 FileName = "financial_skill/SKILL.md",2288 },2289 new BinaryContent2290 {2291 Stream = File.OpenRead("financial_skill/analyze.py"),2292 FileName = "financial_skill/analyze.py",2293 },2294 ],2295 };22962297 var skill2 = await client.Skills.Create(parameters2);22982299 Console.WriteLine($"Created skill: {skill.ID}");2300 Console.WriteLine($"Latest version: {skill.LatestVersionID}");2301 Console.WriteLine($"Created skill 2: {skill2.ID}");2302 ```23032304 ```go Go2305 client := anthropic.NewClient()23062307 // Option 1: Using a zip file2308 zipFile, err := os.Open("example_skill.zip")2309 if err != nil {2310 log.Fatal(err)2311 }2312 defer zipFile.Close()23132314 skill, err := client.Skills.New(context.TODO(), anthropic.SkillNewParams{2315 Files: []io.Reader{zipFile},2316 })2317 if err != nil {2318 log.Fatal(err)2319 }23202321 // Option 2: Using individual files2322 skillMd, err := os.Open("financial_skill/SKILL.md")2323 if err != nil {2324 log.Fatal(err)2325 }2326 defer skillMd.Close()23272328 analyzePy, err := os.Open("financial_skill/analyze.py")2329 if err != nil {2330 log.Fatal(err)2331 }2332 defer analyzePy.Close()23332334 skill2, err := client.Skills.New(context.TODO(), anthropic.SkillNewParams{2335 Files: []io.Reader{2336 anthropic.File(skillMd, "financial_skill/SKILL.md", "text/markdown"),2337 anthropic.File(analyzePy, "financial_skill/analyze.py", "text/x-python"),2338 },2339 })2340 if err != nil {2341 log.Fatal(err)2342 }23432344 fmt.Printf("Created skill: %s\n", skill.ID)2345 fmt.Printf("Latest version: %s\n", skill.LatestVersionID)2346 fmt.Printf("Created skill 2: %s\n", skill2.ID)2347 ```23482349 ```java Java2350 import com.anthropic.core.MultipartField;2351 import com.anthropic.models.skills.SkillCreateParams;2352 import com.anthropic.models.skills.Skill;2353 // ...2354 void main() throws Exception {2355 // ...2356 AnthropicClient client = AnthropicOkHttpClient.fromEnv();23572358 // Option 1: Using a zip file2359 SkillCreateParams params = SkillCreateParams.builder()2360 .addFile(MultipartField.<InputStream>builder()2361 .value(Files.newInputStream(Path.of("example_skill.zip")))2362 .filename("example_skill.zip")2363 .contentType("application/zip")2364 .build())2365 .build();23662367 Skill skill = client.skills().create(params);23682369 // Option 2: Using individual files (path-qualified filenames preserve the Skill's directory layout)2370 SkillCreateParams params2 = SkillCreateParams.builder()2371 .addFile(MultipartField.<InputStream>builder()2372 .value(Files.newInputStream(Path.of("financial_skill/SKILL.md")))2373 .filename("financial_skill/SKILL.md")2374 .contentType("text/markdown")2375 .build())2376 .addFile(MultipartField.<InputStream>builder()2377 .value(Files.newInputStream(Path.of("financial_skill/analyze.py")))2378 .filename("financial_skill/analyze.py")2379 .contentType("text/x-python")2380 .build())2381 .build();23822383 Skill skill2 = client.skills().create(params2);23842385 System.out.println("Created skill: " + skill.id());2386 System.out.println("Latest version: " + skill.latestVersionId());2387 System.out.println("Created skill 2: " + skill2.id());2388 }2389 ```23902391 ```php PHP2392 use Anthropic\Core\FileParam;2393 // ...23942395 $client = new Client();23962397 // Option 1: Using a zip file2398 $skill = $client->skills->create(2399 files: [2400 FileParam::fromResource(fopen('example_skill.zip', 'r')),2401 ],2402 );24032404 // Option 2: Using individual files2405 $skill = $client->skills->create(2406 files: [2407 FileParam::fromResource(2408 fopen('financial_skill/SKILL.md', 'r'),2409 filename: 'financial_skill/SKILL.md',2410 contentType: 'text/markdown',2411 ),2412 FileParam::fromResource(2413 fopen('financial_skill/analyze.py', 'r'),2414 filename: 'financial_skill/analyze.py',2415 contentType: 'text/x-python',2416 ),2417 ],2418 );24192420 echo "Created skill: {$skill->id}\n";2421 echo "Latest version: {$skill->latestVersionID}\n";2422 ```24232424 ```ruby Ruby2425 client = Anthropic::Client.new24262427 # Option 1: Using a zip file2428 skill = client.skills.create(2429 files: [2430 File.open("example_skill.zip", "rb")2431 ]2432 )24332434 # Option 2: Using individual files2435 skill = client.skills.create(2436 files: [2437 Anthropic::FilePart.new(2438 Pathname("financial_skill/SKILL.md"),2439 filename: "financial_skill/SKILL.md",2440 content_type: "text/markdown"2441 ),2442 Anthropic::FilePart.new(2443 Pathname("financial_skill/analyze.py"),2444 filename: "financial_skill/analyze.py",2445 content_type: "text/x-python"2446 )2447 ]2448 )24492450 puts "Created skill: #{skill.id}"2451 puts "Latest version: #{skill.latest_version_id}"2452 ```2453</CodeGroup>24542455**Requirements:**24562457* Must include a `SKILL.md` file at the upload root (or at the top of a single enclosing folder)24582459* `display_name` is optional: when omitted, it derives from the `SKILL.md` `name`; an explicit value may be up to 255 characters and does not need to be unique within the workspace24602461* Total upload size must be under 30 MB (uncompressed)24622463* YAML frontmatter requirements:24642465 * `name`: Maximum 64 characters, lowercase letters/numbers/hyphens only, no XML tags, no reserved words ("anthropic", "claude")2466 * `description`: Maximum 1024 characters, non-empty, no XML tags24672468For complete request/response schemas, see the [Create Skill API reference](https://platform.claude.com/docs/en/api/skills/create).24692470### Listing Skills24712472Retrieve all Skills available to your workspace, including both Anthropic pre-built Skills and your custom Skills. Use the `source` parameter to filter by skill type:24732474<CodeGroup>2475 ```bash cURL2476 # List all Skills2477 curl "https://api.anthropic.com/v1/skills" \2478 -H "x-api-key: $ANTHROPIC_API_KEY" \2479 -H "anthropic-version: 2023-06-01"24802481 # List only custom Skills2482 curl "https://api.anthropic.com/v1/skills?source=custom" \2483 -H "x-api-key: $ANTHROPIC_API_KEY" \2484 -H "anthropic-version: 2023-06-01"2485 ```24862487 ```bash CLI2488 # List all Skills2489 ant skills list24902491 # List only custom Skills2492 ant skills list --source custom2493 ```24942495 ```python Python2496 client = anthropic.Anthropic()24972498 # List all Skills2499 for skill in client.skills.list():2500 print(f"{skill.id}: {skill.display_name} (source: {skill.source.type})")25012502 # List only custom Skills2503 custom_skills = client.skills.list(source="custom")2504 ```25052506 ```typescript TypeScript2507 const client = new Anthropic();25082509 // List all Skills2510 for await (const skill of client.skills.list()) {2511 console.log(`${skill.id}: ${skill.display_name} (source: ${skill.source.type})`);2512 }25132514 // List only custom Skills2515 const customSkills = await client.skills.list({2516 source: "custom"2517 });2518 ```25192520 ```csharp C#2521 AnthropicClient client = new();25222523 // List all Skills2524 await foreach (var skill in (await client.Skills.List()).Paginate())2525 {2526 Console.WriteLine($"{skill.ID}: {skill.DisplayName} (source: {skill.Source.Type})");2527 }25282529 // List only custom Skills2530 var customSkills = await client.Skills.List(new SkillListParams { Source = "custom" });2531 ```25322533 ```go Go2534 client := anthropic.NewClient()25352536 // List all Skills2537 skills := client.Skills.ListAutoPaging(context.TODO(), anthropic.SkillListParams{})25382539 for skills.Next() {2540 skill := skills.Current()2541 fmt.Printf("%s: %s (source: %s)\n", skill.ID, skill.DisplayName, skill.Source.Type)2542 }2543 if skills.Err() != nil {2544 log.Fatal(skills.Err())2545 }25462547 // List only custom Skills2548 customSkills := client.Skills.ListAutoPaging(context.TODO(), anthropic.SkillListParams{2549 Source: anthropic.String("custom"),2550 })25512552 for customSkills.Next() {2553 skill := customSkills.Current()2554 fmt.Printf("%s: %s (source: %s)\n", skill.ID, skill.DisplayName, skill.Source.Type)2555 }2556 if customSkills.Err() != nil {2557 log.Fatal(customSkills.Err())2558 }2559 ```25602561 ```java Java2562 import com.anthropic.models.skills.SkillListParams;2563 import com.anthropic.models.skills.SkillListPage;2564 import com.anthropic.models.skills.Skill;2565 // ...2566 void main() {2567 AnthropicClient client = AnthropicOkHttpClient.fromEnv();25682569 // List Skills (first page)2570 SkillListPage skills = client.skills().list();25712572 for (Skill skill : skills.data()) {2573 System.out.println(skill.id() + ": " + skill.displayName() + " (source: " + skill.source().type() + ")");2574 }25752576 // List only custom Skills2577 SkillListParams customParams = SkillListParams.builder()2578 .source("custom")2579 .build();25802581 SkillListPage customSkills = client.skills().list(customParams);2582 }2583 ```25842585 ```php PHP2586 $client = new Client();25872588 // List Skills (first page)2589 foreach ($client->skills->list()->getItems() as $skill) {2590 echo "{$skill->id}: {$skill->displayName} (source: {$skill->source->type})\n";2591 }25922593 // List only custom Skills2594 $customSkills = $client->skills->list(2595 source: 'custom',2596 );2597 ```25982599 ```ruby Ruby2600 client = Anthropic::Client.new26012602 # List all Skills2603 client.skills.list.auto_paging_each do |skill|2604 puts "#{skill.id}: #{skill.display_name} (source: #{skill.source.type})"2605 end26062607 # List only custom Skills2608 custom_skills = client.skills.list(2609 source: "custom"2610 )2611 ```2612</CodeGroup>26132614See the [List Skills API reference](https://platform.claude.com/docs/en/api/skills/list) for pagination and filtering options.26152616### Retrieving a Skill26172618Get details about a specific Skill:26192620<CodeGroup>2621 ```bash cURL2622 curl "https://api.anthropic.com/v1/skills/skill_01AbCdEfGhIjKlMnOpQrStUv" \2623 -H "x-api-key: $ANTHROPIC_API_KEY" \2624 -H "anthropic-version: 2023-06-01"2625 ```26262627 ```bash CLI2628 ant skills retrieve --skill-id skill_01AbCdEfGhIjKlMnOpQrStUv2629 ```26302631 ```python Python2632 client = anthropic.Anthropic()26332634 skill = client.skills.retrieve(skill_id="skill_01AbCdEfGhIjKlMnOpQrStUv")26352636 print(f"Skill: {skill.display_name}")2637 print(f"Latest version: {skill.latest_version_id}")2638 print(f"Created: {skill.created_at}")2639 ```26402641 ```typescript TypeScript2642 const client = new Anthropic();26432644 const skill = await client.skills.retrieve("skill_01AbCdEfGhIjKlMnOpQrStUv");26452646 console.log(`Skill: ${skill.display_name}`);2647 console.log(`Latest version: ${skill.latest_version_id}`);2648 console.log(`Created: ${skill.created_at}`);2649 ```26502651 ```csharp C#2652 AnthropicClient client = new();26532654 var skill = await client.Skills.Retrieve("skill_01AbCdEfGhIjKlMnOpQrStUv");26552656 Console.WriteLine($"Skill: {skill.DisplayName}");2657 Console.WriteLine($"Latest version: {skill.LatestVersionID}");2658 Console.WriteLine($"Created: {skill.CreatedAt}");2659 ```26602661 ```go Go2662 client := anthropic.NewClient()26632664 skill, err := client.Skills.Get(2665 context.TODO(),2666 "skill_01AbCdEfGhIjKlMnOpQrStUv",2667 anthropic.SkillGetParams{},2668 )2669 if err != nil {2670 log.Fatal(err)2671 }26722673 fmt.Printf("Skill: %s\n", skill.DisplayName)2674 fmt.Printf("Latest version: %s\n", skill.LatestVersionID)2675 fmt.Printf("Created: %s\n", skill.CreatedAt)2676 ```26772678 ```java Java2679 import com.anthropic.models.skills.Skill;2680 // ...2681 void main() {2682 AnthropicClient client = AnthropicOkHttpClient.fromEnv();26832684 Skill skill = client.skills().retrieve("skill_01AbCdEfGhIjKlMnOpQrStUv");26852686 System.out.println("Skill: " + skill.displayName());2687 System.out.println("Latest version: " + skill.latestVersionId());2688 System.out.println("Created: " + skill.createdAt());2689 }2690 ```26912692 ```php PHP2693 $client = new Client();26942695 $skill = $client->skills->retrieve('skill_01AbCdEfGhIjKlMnOpQrStUv');26962697 echo "Skill: {$skill->displayName}\n";2698 echo "Latest version: {$skill->latestVersionID}\n";2699 echo "Created: {$skill->createdAt->format(DATE_ATOM)}\n";2700 ```27012702 ```ruby Ruby2703 client = Anthropic::Client.new27042705 skill = client.skills.retrieve("skill_01AbCdEfGhIjKlMnOpQrStUv")27062707 puts "Skill: #{skill.display_name}"2708 puts "Latest version: #{skill.latest_version_id}"2709 puts "Created: #{skill.created_at}"2710 ```2711</CodeGroup>27122713### Deleting a Skill27142715Deleting a Skill also removes all of its versions.27162717<CodeGroup>2718 ```bash cURL2719 curl -X DELETE "https://api.anthropic.com/v1/skills/skill_01AbCdEfGhIjKlMnOpQrStUv" \2720 -H "x-api-key: $ANTHROPIC_API_KEY" \2721 -H "anthropic-version: 2023-06-01"2722 ```27232724 ```bash CLI2725 ant skills delete --skill-id skill_01AbCdEfGhIjKlMnOpQrStUv >/dev/null2726 ```27272728 ```python Python2729 client = anthropic.Anthropic()27302731 client.skills.delete(skill_id="skill_01AbCdEfGhIjKlMnOpQrStUv")2732 ```27332734 ```typescript TypeScript2735 const client = new Anthropic();27362737 await client.skills.delete("skill_01AbCdEfGhIjKlMnOpQrStUv");2738 ```27392740 ```csharp C#2741 AnthropicClient client = new();27422743 await client.Skills.Delete("skill_01AbCdEfGhIjKlMnOpQrStUv");2744 ```27452746 ```go Go2747 client := anthropic.NewClient()27482749 _, err := client.Skills.Delete(2750 context.TODO(),2751 "skill_01AbCdEfGhIjKlMnOpQrStUv",2752 anthropic.SkillDeleteParams{},2753 )2754 if err != nil {2755 log.Fatal(err)2756 }2757 ```27582759 ```java Java2760 void main() {2761 AnthropicClient client = AnthropicOkHttpClient.fromEnv();27622763 client.skills().delete("skill_01AbCdEfGhIjKlMnOpQrStUv");2764 }2765 ```27662767 ```php PHP2768 $client = new Client();27692770 $client->skills->delete('skill_01AbCdEfGhIjKlMnOpQrStUv');2771 ```27722773 ```ruby Ruby2774 client = Anthropic::Client.new27752776 client.skills.delete("skill_01AbCdEfGhIjKlMnOpQrStUv")2777 ```2778</CodeGroup>27792780### Versioning27812782Skills support versioning to manage updates safely:27832784**Anthropic Skills:**27852786* Versions use date format: `20251013`2787* New versions released as updates are made2788* Specify exact versions for stability27892790**Custom Skills:**27912792* Auto-generated version IDs: `skver_01AbCdEfGhIjKlMnOpQrStUv`2793* Use `"latest"` to always get the most recent version2794* Create new versions when updating Skill files27952796A new version is a complete snapshot, not a delta: upload the Skill's full file set each time. Files you omit are not carried over, and the `name` in the new version's `SKILL.md` must match the Skill's existing name. The following examples re-upload the complete `financial_skill/` bundle from [Creating a Skill](https://platform.claude.com/docs/en/build-with-claude/skills-guide#creating-a-skill).27972798<CodeGroup>2799 ```bash cURL2800 # Create a new version2801 NEW_VERSION=$(curl -X POST "https://api.anthropic.com/v1/skills/skill_01AbCdEfGhIjKlMnOpQrStUv/versions" \2802 -H "x-api-key: $ANTHROPIC_API_KEY" \2803 -H "anthropic-version: 2023-06-01" \2804 -F "files[]=@financial_skill/SKILL.md;filename=financial_skill/SKILL.md" \2805 -F "files[]=@financial_skill/analyze.py;filename=financial_skill/analyze.py")28062807 VERSION_ID=$(echo "$NEW_VERSION" | jq -r '.id')28082809 # Use specific version2810 curl https://api.anthropic.com/v1/messages \2811 -H "x-api-key: $ANTHROPIC_API_KEY" \2812 -H "anthropic-version: 2023-06-01" \2813 -H "content-type: application/json" \2814 -d "{2815 \"model\": \"claude-opus-5\",2816 \"max_tokens\": 4096,2817 \"container\": {2818 \"skills\": [{2819 \"type\": \"custom\",2820 \"skill_id\": \"skill_01AbCdEfGhIjKlMnOpQrStUv\",2821 \"version\": \"$VERSION_ID\"2822 }]2823 },2824 \"messages\": [{\"role\": \"user\", \"content\": \"Use updated Skill\"}],2825 \"tools\": [{\"type\": \"code_execution_20250825\", \"name\": \"code_execution\"}]2826 }"28272828 # Use latest version2829 curl https://api.anthropic.com/v1/messages \2830 -H "x-api-key: $ANTHROPIC_API_KEY" \2831 -H "anthropic-version: 2023-06-01" \2832 -H "content-type: application/json" \2833 -d '{2834 "model": "claude-opus-5",2835 "max_tokens": 4096,2836 "container": {2837 "skills": [{2838 "type": "custom",2839 "skill_id": "skill_01AbCdEfGhIjKlMnOpQrStUv",2840 "version": "latest"2841 }]2842 },2843 "messages": [{"role": "user", "content": "Use latest Skill version"}],2844 "tools": [{"type": "code_execution_20250825", "name": "code_execution"}]2845 }'2846 ```28472848 ```bash CLI2849 # Create a new version2850 VERSION_ID=$(ant skills:versions create \2851 --skill-id skill_01AbCdEfGhIjKlMnOpQrStUv \2852 --file financial_skill.zip \2853 --transform id \2854 --raw-output)28552856 # Use specific version2857 ant messages create <<YAML2858 model: claude-opus-52859 max_tokens: 40962860 container:2861 skills:2862 - type: custom2863 skill_id: skill_01AbCdEfGhIjKlMnOpQrStUv2864 version: "$VERSION_ID"2865 messages:2866 - role: user2867 content: Use updated Skill2868 tools:2869 - type: code_execution_202508252870 name: code_execution2871 YAML28722873 # Use latest version2874 ant messages create <<YAML2875 model: claude-opus-52876 max_tokens: 40962877 container:2878 skills:2879 - type: custom2880 skill_id: skill_01AbCdEfGhIjKlMnOpQrStUv2881 version: latest2882 messages:2883 - role: user2884 content: Use latest Skill version2885 tools:2886 - type: code_execution_202508252887 name: code_execution2888 YAML2889 ```28902891 ```python Python2892 from anthropic.lib import files_from_dir28932894 client = anthropic.Anthropic()28952896 # Create a new version28972898 new_version = client.skills.versions.create(2899 skill_id="skill_01AbCdEfGhIjKlMnOpQrStUv",2900 files=files_from_dir("financial_skill"),2901 )29022903 # Use specific version2904 response = client.messages.create(2905 model="claude-opus-5",2906 max_tokens=4096,2907 container={2908 "skills": [2909 {2910 "type": "custom",2911 "skill_id": "skill_01AbCdEfGhIjKlMnOpQrStUv",2912 "version": new_version.id,2913 }2914 ]2915 },2916 messages=[{"role": "user", "content": "Use updated Skill"}],2917 tools=[{"type": "code_execution_20250825", "name": "code_execution"}],2918 )29192920 # Use latest version2921 response = client.messages.create(2922 model="claude-opus-5",2923 max_tokens=4096,2924 container={2925 "skills": [2926 {2927 "type": "custom",2928 "skill_id": "skill_01AbCdEfGhIjKlMnOpQrStUv",2929 "version": "latest",2930 }2931 ]2932 },2933 messages=[{"role": "user", "content": "Use latest Skill version"}],2934 tools=[{"type": "code_execution_20250825", "name": "code_execution"}],2935 )2936 ```29372938 ```typescript TypeScript2939 import fs from "node:fs";29402941 const client = new Anthropic();29422943 // Create a new version from a zip of the complete financial_skill/ bundle2944 const newVersion = await client.skills.versions.create("skill_01AbCdEfGhIjKlMnOpQrStUv", {2945 files: [fs.createReadStream("financial_skill.zip")]2946 });29472948 // Use specific version2949 const specificVersionResponse = await client.messages.create({2950 model: "claude-opus-5",2951 max_tokens: 4096,2952 container: {2953 skills: [2954 {2955 type: "custom",2956 skill_id: "skill_01AbCdEfGhIjKlMnOpQrStUv",2957 version: newVersion.id2958 }2959 ]2960 },2961 messages: [{ role: "user", content: "Use updated Skill" }],2962 tools: [{ type: "code_execution_20250825", name: "code_execution" }]2963 });29642965 // Use latest version2966 const latestVersionResponse = await client.messages.create({2967 model: "claude-opus-5",2968 max_tokens: 4096,2969 container: {2970 skills: [2971 {2972 type: "custom",2973 skill_id: "skill_01AbCdEfGhIjKlMnOpQrStUv",2974 version: "latest"2975 }2976 ]2977 },2978 messages: [{ role: "user", content: "Use latest Skill version" }],2979 tools: [{ type: "code_execution_20250825", name: "code_execution" }]2980 });2981 ```29822983 ```csharp C#2984 using Anthropic.Core;2985 using Anthropic.Models.Skills.Versions;2986 // ...2987 AnthropicClient client = new();29882989 // Create a new version2990 var versionParams = new VersionCreateParams2991 {2992 Files =2993 [2994 new BinaryContent2995 {2996 Stream = File.OpenRead("financial_skill/SKILL.md"),2997 FileName = "financial_skill/SKILL.md",2998 },2999 new BinaryContent3000 {3001 Stream = File.OpenRead("financial_skill/analyze.py"),3002 FileName = "financial_skill/analyze.py",3003 },3004 ],3005 };30063007 var newVersion = await client.Skills.Versions.Create("skill_01AbCdEfGhIjKlMnOpQrStUv", versionParams);30083009 // Use specific version3010 var specificVersionParams = new MessageCreateParams3011 {3012 Model = "claude-opus-5",3013 MaxTokens = 4096,3014 Container = new ContainerParams3015 {3016 Skills =3017 [3018 new SkillParams3019 {3020 Type = SkillParamsType.Custom,3021 SkillID = "skill_01AbCdEfGhIjKlMnOpQrStUv",3022 Version = newVersion.ID,3023 },3024 ],3025 },3026 Messages = [new() { Role = Role.User, Content = "Use updated Skill" }],3027 Tools = [new CodeExecutionTool20250825()],3028 };30293030 var response = await client.Messages.Create(specificVersionParams);3031 Console.WriteLine(response);30323033 // Use latest version3034 var latestVersionParams = new MessageCreateParams3035 {3036 Model = "claude-opus-5",3037 MaxTokens = 4096,3038 Container = new ContainerParams3039 {3040 Skills =3041 [3042 new SkillParams3043 {3044 Type = SkillParamsType.Custom,3045 SkillID = "skill_01AbCdEfGhIjKlMnOpQrStUv",3046 Version = "latest",3047 },3048 ],3049 },3050 Messages = [new() { Role = Role.User, Content = "Use latest Skill version" }],3051 Tools = [new CodeExecutionTool20250825()],3052 };30533054 var latestResponse = await client.Messages.Create(latestVersionParams);3055 Console.WriteLine(latestResponse);3056 ```30573058 ```go Go3059 client := anthropic.NewClient()30603061 // Create a new version3062 skillMd, err := os.Open("financial_skill/SKILL.md")3063 if err != nil {3064 log.Fatal(err)3065 }3066 defer skillMd.Close()3067 analyzePy, err := os.Open("financial_skill/analyze.py")3068 if err != nil {3069 log.Fatal(err)3070 }3071 defer analyzePy.Close()30723073 newVersion, err := client.Skills.Versions.New(3074 context.TODO(),3075 "skill_01AbCdEfGhIjKlMnOpQrStUv",3076 anthropic.SkillVersionNewParams{3077 Files: []io.Reader{3078 anthropic.File(skillMd, "financial_skill/SKILL.md", "text/markdown"),3079 anthropic.File(analyzePy, "financial_skill/analyze.py", "text/x-python"),3080 },3081 },3082 )3083 if err != nil {3084 log.Fatal(err)3085 }30863087 // Use specific version3088 response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{3089 Model: "claude-opus-5",3090 MaxTokens: 4096,3091 Container: anthropic.MessageCreateParamsContainerUnion{3092 OfContainers: &anthropic.ContainerParams{3093 Skills: []anthropic.SkillParams{3094 {3095 Type: anthropic.SkillParamsTypeCustom,3096 SkillID: "skill_01AbCdEfGhIjKlMnOpQrStUv",3097 Version: anthropic.String(newVersion.ID),3098 },3099 },3100 },3101 },3102 Messages: []anthropic.MessageParam{3103 anthropic.NewUserMessage(anthropic.NewTextBlock("Use updated Skill")),3104 },3105 Tools: []anthropic.ToolUnionParam{3106 {OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}},3107 },3108 })3109 if err != nil {3110 log.Fatal(err)3111 }3112 fmt.Println(response)31133114 // Use latest version3115 latestResponse, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{3116 Model: "claude-opus-5",3117 MaxTokens: 4096,3118 Container: anthropic.MessageCreateParamsContainerUnion{3119 OfContainers: &anthropic.ContainerParams{3120 Skills: []anthropic.SkillParams{3121 {3122 Type: anthropic.SkillParamsTypeCustom,3123 SkillID: "skill_01AbCdEfGhIjKlMnOpQrStUv",3124 Version: anthropic.String("latest"),3125 },3126 },3127 },3128 },3129 Messages: []anthropic.MessageParam{3130 anthropic.NewUserMessage(anthropic.NewTextBlock("Use latest Skill version")),3131 },3132 Tools: []anthropic.ToolUnionParam{3133 {OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}},3134 },3135 })3136 if err != nil {3137 log.Fatal(err)3138 }3139 fmt.Println(latestResponse)3140 ```31413142 ```java Java3143 import com.anthropic.models.messages.MessageCreateParams;3144 import com.anthropic.models.messages.Message;3145 import com.anthropic.models.messages.Model;3146 import com.anthropic.core.MultipartField;3147 import com.anthropic.models.messages.ContainerParams;3148 import com.anthropic.models.messages.SkillParams;3149 import com.anthropic.models.messages.CodeExecutionTool20250825;3150 import com.anthropic.models.skills.versions.VersionCreateParams;3151 import com.anthropic.models.skills.versions.SkillVersion;3152 import java.io.InputStream;3153 import java.nio.file.Files;3154 import java.nio.file.Path;31553156 AnthropicClient client = AnthropicOkHttpClient.fromEnv();31573158 // Create a new version from a zip of the complete financial_skill/ bundle3159 VersionCreateParams versionParams = VersionCreateParams.builder()3160 .addFile(MultipartField.<InputStream>builder()3161 .value(Files.newInputStream(Path.of("financial_skill.zip")))3162 .filename("financial_skill.zip")3163 .contentType("application/zip")3164 .build())3165 .build();31663167 SkillVersion newVersion = client.skills().versions()3168 .create("skill_01AbCdEfGhIjKlMnOpQrStUv", versionParams);31693170 // Use specific version3171 MessageCreateParams specificVersionParams = MessageCreateParams.builder()3172 .model(Model.CLAUDE_OPUS_5)3173 .maxTokens(4096L)3174 .container(ContainerParams.builder()3175 .addSkill(SkillParams.builder()3176 .type(SkillParams.Type.CUSTOM)3177 .skillId("skill_01AbCdEfGhIjKlMnOpQrStUv")3178 .version(newVersion.id())3179 .build())3180 .build())3181 .addUserMessage("Use updated Skill")3182 .addTool(CodeExecutionTool20250825.builder().build())3183 .build();31843185 Message response = client.messages().create(specificVersionParams);3186 System.out.println(response);31873188 // Use latest version3189 MessageCreateParams latestVersionParams = MessageCreateParams.builder()3190 .model(Model.CLAUDE_OPUS_5)3191 .maxTokens(4096L)3192 .container(ContainerParams.builder()3193 .addSkill(SkillParams.builder()3194 .type(SkillParams.Type.CUSTOM)3195 .skillId("skill_01AbCdEfGhIjKlMnOpQrStUv")3196 .version("latest")3197 .build())3198 .build())3199 .addUserMessage("Use latest Skill version")3200 .addTool(CodeExecutionTool20250825.builder().build())3201 .build();32023203 Message latestResponse = client.messages().create(latestVersionParams);3204 System.out.println(latestResponse);3205 ```32063207 ```php PHP3208 use Anthropic\Core\FileParam;3209 // ...32103211 $client = new Client();32123213 // Create a new version3214 $newVersion = $client->skills->versions->create(3215 skillID: 'skill_01AbCdEfGhIjKlMnOpQrStUv',3216 files: [3217 FileParam::fromResource(3218 fopen('financial_skill/SKILL.md', 'r'),3219 filename: 'financial_skill/SKILL.md',3220 contentType: 'text/markdown',3221 ),3222 FileParam::fromResource(3223 fopen('financial_skill/analyze.py', 'r'),3224 filename: 'financial_skill/analyze.py',3225 contentType: 'text/x-python',3226 ),3227 ],3228 );32293230 // Use specific version3231 $response = $client->messages->create(3232 maxTokens: 4096,3233 messages: [['role' => 'user', 'content' => 'Use updated Skill']],3234 model: 'claude-opus-5',3235 container: [3236 'skills' => [[3237 'type' => 'custom',3238 'skillID' => 'skill_01AbCdEfGhIjKlMnOpQrStUv',3239 'version' => $newVersion->id3240 ]]3241 ],3242 tools: [['type' => 'code_execution_20250825', 'name' => 'code_execution']]3243 );3244 echo $response;32453246 // Use latest version3247 $latestResponse = $client->messages->create(3248 maxTokens: 4096,3249 messages: [['role' => 'user', 'content' => 'Use latest Skill version']],3250 model: 'claude-opus-5',3251 container: [3252 'skills' => [[3253 'type' => 'custom',3254 'skillID' => 'skill_01AbCdEfGhIjKlMnOpQrStUv',3255 'version' => 'latest'3256 ]]3257 ],3258 tools: [['type' => 'code_execution_20250825', 'name' => 'code_execution']]3259 );3260 echo $latestResponse;3261 ```32623263 ```ruby Ruby3264 client = Anthropic::Client.new32653266 # Create a new version3267 new_version = client.skills.versions.create(3268 "skill_01AbCdEfGhIjKlMnOpQrStUv",3269 files: [3270 Anthropic::FilePart.new(3271 Pathname("financial_skill/SKILL.md"),3272 filename: "financial_skill/SKILL.md",3273 content_type: "text/markdown"3274 ),3275 Anthropic::FilePart.new(3276 Pathname("financial_skill/analyze.py"),3277 filename: "financial_skill/analyze.py",3278 content_type: "text/x-python"3279 )3280 ]3281 )32823283 # Use specific version3284 response = client.messages.create(3285 model: "claude-opus-5",3286 max_tokens: 4096,3287 container: {3288 skills: [{3289 type: "custom",3290 skill_id: "skill_01AbCdEfGhIjKlMnOpQrStUv",3291 version: new_version.id3292 }]3293 },3294 messages: [{ role: "user", content: "Use updated Skill" }],3295 tools: [{ type: "code_execution_20250825", name: "code_execution" }]3296 )3297 puts response32983299 # Use latest version3300 latest_response = client.messages.create(3301 model: "claude-opus-5",3302 max_tokens: 4096,3303 container: {3304 skills: [{3305 type: "custom",3306 skill_id: "skill_01AbCdEfGhIjKlMnOpQrStUv",3307 version: "latest"3308 }]3309 },3310 messages: [{ role: "user", content: "Use latest Skill version" }],3311 tools: [{ type: "code_execution_20250825", name: "code_execution" }]3312 )3313 puts latest_response3314 ```3315</CodeGroup>33163317See the [Create Skill Version API reference](https://platform.claude.com/docs/en/api/skills/versions/create) for complete details.33183319***33203321## How Skills are loaded33223323When you specify Skills in a container:332433251. **Metadata discovery:** Claude sees metadata for each Skill (name, description) in the system prompt.33262. **File loading:** Skill files are copied into the container at `/skills/{skill-name}/`. The directory is the Skill's name (`pptx` for an Anthropic Skill, the `SKILL.md` `name` for a custom Skill), not its `skill_01...` ID.33273. **Automatic use:** Claude automatically loads and uses Skills when relevant to your request.33284. **Composition:** Multiple Skills compose together for complex workflows.33293330Claude loads full Skill instructions only when needed.33313332***33333334## Use cases33353336Skills fit both organizational and personal work. Organizations use them to apply brand formatting to documents, structure notes and reports around company templates, and run company-specific analytical procedures. Individuals use them for custom document templates, specialized data pipelines, and code generation or deployment conventions.33373338### Example: financial modeling33393340Combine Excel and custom DCF analysis Skills:33413342<CodeGroup>3343 ```bash cURL3344 # Create custom DCF analysis Skill3345 DCF_SKILL=$(curl -X POST "https://api.anthropic.com/v1/skills" \3346 -H "x-api-key: $ANTHROPIC_API_KEY" \3347 -H "anthropic-version: 2023-06-01" \3348 -F "files[]=@dcf_skill/SKILL.md;filename=dcf_skill/SKILL.md")33493350 DCF_SKILL_ID=$(echo "$DCF_SKILL" | jq -r '.id')33513352 # Use with Excel to create financial model3353 curl https://api.anthropic.com/v1/messages \3354 -H "x-api-key: $ANTHROPIC_API_KEY" \3355 -H "anthropic-version: 2023-06-01" \3356 -H "content-type: application/json" \3357 -d "{3358 \"model\": \"claude-opus-5\",3359 \"max_tokens\": 4096,3360 \"container\": {3361 \"skills\": [3362 {3363 \"type\": \"anthropic\",3364 \"skill_id\": \"xlsx\",3365 \"version\": \"latest\"3366 },3367 {3368 \"type\": \"custom\",3369 \"skill_id\": \"$DCF_SKILL_ID\",3370 \"version\": \"latest\"3371 }3372 ]3373 },3374 \"messages\": [{3375 \"role\": \"user\",3376 \"content\": \"Build a DCF valuation model for a SaaS company\"3377 }],3378 \"tools\": [{3379 \"type\": \"code_execution_20250825\",3380 \"name\": \"code_execution\"3381 }]3382 }"3383 ```33843385 ```bash CLI3386 # Create custom DCF analysis Skill3387 DCF_SKILL_ID=$(ant skills create \3388 --file dcf_skill.zip \3389 --transform id \3390 --raw-output)33913392 # Use with Excel to create financial model3393 ant messages create <<YAML3394 model: claude-opus-53395 max_tokens: 40963396 container:3397 skills:3398 - type: anthropic3399 skill_id: xlsx3400 version: latest3401 - type: custom3402 skill_id: $DCF_SKILL_ID3403 version: latest3404 messages:3405 - role: user3406 content: Build a DCF valuation model for a SaaS company3407 tools:3408 - type: code_execution_202508253409 name: code_execution3410 YAML3411 ```34123413 ```python Python3414 from anthropic.lib import files_from_dir34153416 client = anthropic.Anthropic()34173418 # Create custom DCF analysis Skill34193420 dcf_skill = client.skills.create(3421 files=files_from_dir("/path/to/dcf_skill"),3422 )34233424 # Use with Excel to create financial model3425 response = client.messages.create(3426 model="claude-opus-5",3427 max_tokens=4096,3428 container={3429 "skills": [3430 {"type": "anthropic", "skill_id": "xlsx", "version": "latest"},3431 {"type": "custom", "skill_id": dcf_skill.id, "version": "latest"},3432 ]3433 },3434 messages=[3435 {3436 "role": "user",3437 "content": "Build a DCF valuation model for a SaaS company",3438 }3439 ],3440 tools=[{"type": "code_execution_20250825", "name": "code_execution"}],3441 )3442 print(response)3443 ```34443445 ```typescript TypeScript3446 import Anthropic, { toFile } from "@anthropic-ai/sdk";3447 import fs from "node:fs";34483449 const client = new Anthropic();34503451 // Create custom DCF analysis Skill3452 const dcfSkill = await client.skills.create({3453 files: [await toFile(fs.createReadStream("dcf_skill.zip"), "dcf_skill.zip")]3454 });34553456 // Use with Excel to create financial model3457 const response = await client.messages.create({3458 model: "claude-opus-5",3459 max_tokens: 4096,3460 container: {3461 skills: [3462 { type: "anthropic", skill_id: "xlsx", version: "latest" },3463 { type: "custom", skill_id: dcfSkill.id, version: "latest" }3464 ]3465 },3466 messages: [3467 {3468 role: "user",3469 content: "Build a DCF valuation model for a SaaS company"3470 }3471 ],3472 tools: [{ type: "code_execution_20250825", name: "code_execution" }]3473 });3474 console.log(response);3475 ```34763477 ```csharp C#3478 using Anthropic.Core;3479 // ...3480 AnthropicClient client = new();34813482 // Create custom DCF analysis Skill3483 var dcfSkill = await client.Skills.Create(new SkillCreateParams3484 {3485 Files =3486 [3487 new BinaryContent3488 {3489 Stream = File.OpenRead("dcf_skill/SKILL.md"),3490 FileName = "dcf_skill/SKILL.md",3491 },3492 ],3493 });34943495 // Use with Excel to create financial model3496 var parameters = new MessageCreateParams3497 {3498 Model = "claude-opus-5",3499 MaxTokens = 4096,3500 Container = new ContainerParams3501 {3502 Skills =3503 [3504 new SkillParams3505 {3506 Type = SkillParamsType.Anthropic,3507 SkillID = "xlsx",3508 Version = "latest",3509 },3510 new SkillParams3511 {3512 Type = SkillParamsType.Custom,3513 SkillID = dcfSkill.ID,3514 Version = "latest",3515 },3516 ],3517 },3518 Messages = [new() { Role = Role.User, Content = "Build a DCF valuation model for a SaaS company" }],3519 Tools = [new CodeExecutionTool20250825()],3520 };35213522 var message = await client.Messages.Create(parameters);3523 Console.WriteLine(message);3524 ```35253526 ```go Go3527 client := anthropic.NewClient()35283529 // Custom DCF analysis Skill (ID obtained from Skills API create response)3530 dcfSkillID := "skill_01AbCdEfGhIjKlMnOpQrStUv"35313532 // Use with Excel to create financial model3533 response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{3534 Model: "claude-opus-5",3535 MaxTokens: 4096,3536 Container: anthropic.MessageCreateParamsContainerUnion{3537 OfContainers: &anthropic.ContainerParams{3538 Skills: []anthropic.SkillParams{3539 {3540 Type: anthropic.SkillParamsTypeAnthropic,3541 SkillID: "xlsx",3542 Version: anthropic.String("latest"),3543 },3544 {3545 Type: anthropic.SkillParamsTypeCustom,3546 SkillID: dcfSkillID,3547 Version: anthropic.String("latest"),3548 },3549 },3550 },3551 },3552 Messages: []anthropic.MessageParam{3553 anthropic.NewUserMessage(anthropic.NewTextBlock("Build a DCF valuation model for a SaaS company")),3554 },3555 Tools: []anthropic.ToolUnionParam{3556 {OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}},3557 },3558 })3559 if err != nil {3560 log.Fatal(err)3561 }3562 fmt.Println(response)3563 ```35643565 ```java Java3566 import com.anthropic.models.messages.ContainerParams;3567 import com.anthropic.models.messages.SkillParams;3568 import com.anthropic.models.messages.CodeExecutionTool20250825;3569 // ...3570 void main() {3571 AnthropicClient client = AnthropicOkHttpClient.fromEnv();35723573 // Custom DCF analysis Skill (ID obtained from Skills API create response)3574 String dcfSkillId = "skill_01AbCdEfGhIjKlMnOpQrStUv";35753576 // Use with Excel Skill to create financial model3577 MessageCreateParams params = MessageCreateParams.builder()3578 .model(Model.CLAUDE_OPUS_5)3579 .maxTokens(4096L)3580 .container(ContainerParams.builder()3581 .skills(List.of(3582 SkillParams.builder()3583 .type(SkillParams.Type.ANTHROPIC)3584 .skillId("xlsx")3585 .version("latest")3586 .build(),3587 SkillParams.builder()3588 .type(SkillParams.Type.CUSTOM)3589 .skillId(dcfSkillId)3590 .version("latest")3591 .build()3592 ))3593 .build())3594 .addUserMessage("Build a DCF valuation model for a SaaS company")3595 .addTool(CodeExecutionTool20250825.builder().build())3596 .build();35973598 Message response = client.messages().create(params);3599 System.out.println(response);3600 }3601 ```36023603 ```php PHP3604 $client = new Client();36053606 // Custom DCF analysis Skill (ID obtained from Skills API create response)3607 $dcfSkillId = 'skill_01AbCdEfGhIjKlMnOpQrStUv';36083609 // Use with Excel to create financial model3610 $message = $client->messages->create(3611 maxTokens: 4096,3612 messages: [3613 ['role' => 'user', 'content' => 'Build a DCF valuation model for a SaaS company']3614 ],3615 model: 'claude-opus-5',3616 container: [3617 'skills' => [3618 ['type' => 'anthropic', 'skillID' => 'xlsx', 'version' => 'latest'],3619 ['type' => 'custom', 'skillID' => $dcfSkillId, 'version' => 'latest']3620 ]3621 ],3622 tools: [3623 ['type' => 'code_execution_20250825', 'name' => 'code_execution']3624 ]3625 );3626 echo $message;3627 ```36283629 ```ruby Ruby3630 client = Anthropic::Client.new36313632 # Create custom DCF analysis Skill3633 dcf_skill = client.skills.create(3634 files: [3635 Anthropic::FilePart.new(3636 Pathname("dcf_skill/SKILL.md"),3637 filename: "dcf_skill/SKILL.md",3638 content_type: "text/markdown"3639 )3640 ]3641 )36423643 # Use with Excel to create financial model3644 response = client.messages.create(3645 model: "claude-opus-5",3646 max_tokens: 4096,3647 container: {3648 skills: [3649 { type: "anthropic", skill_id: "xlsx", version: "latest" },3650 { type: "custom", skill_id: dcf_skill.id, version: "latest" }3651 ]3652 },3653 messages: [3654 { role: "user", content: "Build a DCF valuation model for a SaaS company" }3655 ],3656 tools: [{ type: "code_execution_20250825", name: "code_execution" }]3657 )3658 puts response3659 ```3660</CodeGroup>36613662***36633664## Limits and constraints36653666### Request limits36673668* **Maximum Skills per request:** 2036693670* **Maximum Skill upload size:** 30 MB (all files combined, uncompressed)36713672* **YAML frontmatter requirements:**36733674 * `name`: Maximum 64 characters, lowercase letters/numbers/hyphens only, no XML tags, no reserved words ("anthropic", "claude")3675 * `description`: Maximum 1024 characters, non-empty, no XML tags36763677### Environment constraints36783679Skills run in the code execution container with these limitations:36803681* **No network access:** Cannot make external API calls3682* **No runtime package installation:** Only pre-installed packages available3683* **Isolated environment:** A fresh container is created unless you specify an existing container ID36843685See [Code execution tool](https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool) for available packages.36863687***36883689## Best practices36903691### When to use multiple Skills36923693Combine Skills when tasks involve multiple document types or domains:36943695**Good use cases:**36963697* Data analysis (Excel) + presentation creation (PowerPoint)3698* Report generation (Word) + export to PDF3699* Custom domain logic + document generation37003701**Avoid:**37023703* Including unused Skills (impacts performance)37043705### Version management strategy37063707The SDK tabs in this section show the `container` value to include in a Messages request. The cURL and CLI tabs show the full request.37083709**For production:** pin a specific version, so Skill updates never change your deployed behavior. If you omit `version` or set it to `"latest"`, requests use the newest version of the Skill, so a version uploaded by anyone in the [workspace](https://platform.claude.com/docs/en/build-with-claude/skills-guide#workspace-scoped-access) immediately changes what your production agents run. The version ID comes from the create-version response in [Versioning](https://platform.claude.com/docs/en/build-with-claude/skills-guide#versioning) or from the [List Skill Versions API](https://platform.claude.com/docs/en/api/skills/versions/list). The ID is always a string, so quote it in JSON or YAML even when it looks numeric.37103711<CodeGroup>3712 ```bash cURL3713 # Pin to specific versions for stability3714 curl https://api.anthropic.com/v1/messages \3715 -H "x-api-key: $ANTHROPIC_API_KEY" \3716 -H "anthropic-version: 2023-06-01" \3717 -H "content-type: application/json" \3718 -d '{3719 "model": "claude-opus-5",3720 "max_tokens": 4096,3721 "container": {3722 "skills": [{3723 "type": "custom",3724 "skill_id": "skill_01AbCdEfGhIjKlMnOpQrStUv",3725 "version": "skver_01AbCdEfGhIjKlMnOpQrStUv"3726 }]3727 },3728 "messages": [{"role": "user", "content": "Analyze the sales data"}],3729 "tools": [{"type": "code_execution_20250825", "name": "code_execution"}]3730 }'3731 ```37323733 ```bash CLI3734 # Pin to specific versions for stability3735 ant messages create <<YAML3736 model: claude-opus-53737 max_tokens: 40963738 container:3739 skills:3740 - type: custom3741 skill_id: skill_01AbCdEfGhIjKlMnOpQrStUv3742 version: "skver_01AbCdEfGhIjKlMnOpQrStUv"3743 messages:3744 - role: user3745 content: Analyze the sales data3746 tools:3747 - type: code_execution_202508253748 name: code_execution3749 YAML3750 ```37513752 ```python Python3753 # Pin to specific versions for stability3754 container = {3755 "skills": [3756 {3757 "type": "custom",3758 "skill_id": "skill_01AbCdEfGhIjKlMnOpQrStUv",3759 "version": "skver_01AbCdEfGhIjKlMnOpQrStUv",3760 }3761 ]3762 }3763 ```37643765 ```typescript TypeScript3766 // Pin to specific versions for stability3767 const container: Anthropic.ContainerParams = {3768 skills: [3769 {3770 type: "custom",3771 skill_id: "skill_01AbCdEfGhIjKlMnOpQrStUv",3772 version: "skver_01AbCdEfGhIjKlMnOpQrStUv"3773 }3774 ]3775 };3776 ```37773778 ```csharp C#3779 using Anthropic.Models.Messages;37803781 // Pin to specific versions for stability3782 var container = new ContainerParams3783 {3784 Skills =3785 [3786 new SkillParams3787 {3788 Type = SkillParamsType.Custom,3789 SkillID = "skill_01AbCdEfGhIjKlMnOpQrStUv",3790 Version = "skver_01AbCdEfGhIjKlMnOpQrStUv",3791 },3792 ],3793 };3794 ```37953796 ```go Go3797 // Pin to specific versions for stability3798 container := anthropic.MessageCreateParamsContainerUnion{3799 OfContainers: &anthropic.ContainerParams{3800 Skills: []anthropic.SkillParams{3801 {3802 Type: anthropic.SkillParamsTypeCustom,3803 SkillID: "skill_01AbCdEfGhIjKlMnOpQrStUv",3804 Version: anthropic.String("skver_01AbCdEfGhIjKlMnOpQrStUv"),3805 },3806 },3807 },3808 }3809 ```38103811 ```java Java3812 import com.anthropic.models.messages.ContainerParams;3813 import com.anthropic.models.messages.SkillParams;38143815 void main() {3816 // Pin to specific versions for stability3817 ContainerParams container = ContainerParams.builder()3818 .addSkill(SkillParams.builder()3819 .type(SkillParams.Type.CUSTOM)3820 .skillId("skill_01AbCdEfGhIjKlMnOpQrStUv")3821 .version("skver_01AbCdEfGhIjKlMnOpQrStUv")3822 .build())3823 .build();3824 }3825 ```38263827 ```php PHP3828 // Pin to specific versions for stability3829 $container = [3830 'skills' => [[3831 'type' => 'custom',3832 'skillID' => 'skill_01AbCdEfGhIjKlMnOpQrStUv',3833 'version' => 'skver_01AbCdEfGhIjKlMnOpQrStUv'3834 ]]3835 ];3836 ```38373838 ```ruby Ruby3839 # Pin to specific versions for stability3840 container = {3841 skills: [{3842 type: "custom",3843 skill_id: "skill_01AbCdEfGhIjKlMnOpQrStUv",3844 version: "skver_01AbCdEfGhIjKlMnOpQrStUv"3845 }]3846 }3847 ```3848</CodeGroup>38493850**For development:** use `latest` to pick up the newest version automatically as you iterate.38513852<CodeGroup>3853 ```bash cURL3854 # Use latest for active development3855 curl https://api.anthropic.com/v1/messages \3856 -H "x-api-key: $ANTHROPIC_API_KEY" \3857 -H "anthropic-version: 2023-06-01" \3858 -H "content-type: application/json" \3859 -d '{3860 "model": "claude-opus-5",3861 "max_tokens": 4096,3862 "container": {3863 "skills": [{3864 "type": "custom",3865 "skill_id": "skill_01AbCdEfGhIjKlMnOpQrStUv",3866 "version": "latest"3867 }]3868 },3869 "messages": [{"role": "user", "content": "Analyze the sales data"}],3870 "tools": [{"type": "code_execution_20250825", "name": "code_execution"}]3871 }'3872 ```38733874 ```bash CLI3875 # Use latest for active development3876 ant messages create <<YAML3877 model: claude-opus-53878 max_tokens: 40963879 container:3880 skills:3881 - type: custom3882 skill_id: skill_01AbCdEfGhIjKlMnOpQrStUv3883 version: latest3884 messages:3885 - role: user3886 content: Analyze the sales data3887 tools:3888 - type: code_execution_202508253889 name: code_execution3890 YAML3891 ```38923893 ```python Python3894 # Use latest for active development3895 container = {3896 "skills": [3897 {3898 "type": "custom",3899 "skill_id": "skill_01AbCdEfGhIjKlMnOpQrStUv",3900 "version": "latest",3901 }3902 ]3903 }3904 ```39053906 ```typescript TypeScript3907 // Use latest for active development3908 const container: Anthropic.ContainerParams = {3909 skills: [3910 {3911 type: "custom",3912 skill_id: "skill_01AbCdEfGhIjKlMnOpQrStUv",3913 version: "latest"3914 }3915 ]3916 };3917 ```39183919 ```csharp C#3920 using Anthropic.Models.Messages;39213922 // Use latest for active development3923 var container = new ContainerParams3924 {3925 Skills =3926 [3927 new SkillParams3928 {3929 Type = SkillParamsType.Custom,3930 SkillID = "skill_01AbCdEfGhIjKlMnOpQrStUv",3931 Version = "latest",3932 },3933 ],3934 };3935 ```39363937 ```go Go3938 // Use latest for active development3939 container := anthropic.MessageCreateParamsContainerUnion{3940 OfContainers: &anthropic.ContainerParams{3941 Skills: []anthropic.SkillParams{3942 {3943 Type: anthropic.SkillParamsTypeCustom,3944 SkillID: "skill_01AbCdEfGhIjKlMnOpQrStUv",3945 Version: anthropic.String("latest"),3946 },3947 },3948 },3949 }3950 ```39513952 ```java Java3953 import com.anthropic.models.messages.ContainerParams;3954 import com.anthropic.models.messages.SkillParams;39553956 void main() {3957 // Use latest for active development3958 ContainerParams container = ContainerParams.builder()3959 .addSkill(SkillParams.builder()3960 .type(SkillParams.Type.CUSTOM)3961 .skillId("skill_01AbCdEfGhIjKlMnOpQrStUv")3962 .version("latest")3963 .build())3964 .build();3965 }3966 ```39673968 ```php PHP3969 // Use latest for active development3970 $container = [3971 'skills' => [[3972 'type' => 'custom',3973 'skillID' => 'skill_01AbCdEfGhIjKlMnOpQrStUv',3974 'version' => 'latest'3975 ]]3976 ];3977 ```39783979 ```ruby Ruby3980 # Use latest for active development3981 container = {3982 skills: [{3983 type: "custom",3984 skill_id: "skill_01AbCdEfGhIjKlMnOpQrStUv",3985 version: "latest"3986 }]3987 }3988 ```3989</CodeGroup>39903991### Prompt caching considerations39923993If you use [Prompt caching](https://platform.claude.com/docs/en/build-with-claude/prompt-caching), changing the Skills list in your container breaks the cache. Skills render into the system prompt in a fixed order, so the same list produces the same cacheable prefix:39943995<CodeGroup>3996 ```bash cURL3997 # Skills render into the system prompt in a fixed, cache-friendly order3998 curl https://api.anthropic.com/v1/messages \3999 -H "x-api-key: $ANTHROPIC_API_KEY" \4000 -H "anthropic-version: 2023-06-01" \4001 -H "content-type: application/json" \4002 -d '{4003 "model": "claude-opus-5",4004 "max_tokens": 4096,4005 "container": {4006 "skills": [4007 {"type": "anthropic", "skill_id": "xlsx", "version": "latest"}4008 ]4009 },4010 "messages": [{"role": "user", "content": "Analyze sales data"}],4011 "tools": [{"type": "code_execution_20250825", "name": "code_execution"}]4012 }'40134014 # Changing the Skills list ([xlsx] vs [xlsx, pptx]) changes the prefix: a cache miss, while an identical list is a cache hit4015 curl https://api.anthropic.com/v1/messages \4016 -H "x-api-key: $ANTHROPIC_API_KEY" \4017 -H "anthropic-version: 2023-06-01" \4018 -H "content-type: application/json" \4019 -d '{4020 "model": "claude-opus-5",4021 "max_tokens": 4096,4022 "container": {4023 "skills": [4024 {"type": "anthropic", "skill_id": "xlsx", "version": "latest"},4025 {"type": "anthropic", "skill_id": "pptx", "version": "latest"}4026 ]4027 },4028 "messages": [{"role": "user", "content": "Create a presentation"}],4029 "tools": [{"type": "code_execution_20250825", "name": "code_execution"}]4030 }'4031 ```40324033 ```bash CLI4034 # Skills render into the system prompt in a fixed, cache-friendly order4035 ant messages create <<'YAML'4036 model: claude-opus-54037 max_tokens: 40964038 container:4039 skills:4040 - type: anthropic4041 skill_id: xlsx4042 version: latest4043 messages:4044 - role: user4045 content: Analyze sales data4046 tools:4047 - type: code_execution_202508254048 name: code_execution4049 YAML40504051 # Changing the Skills list ([xlsx] vs [xlsx, pptx]) changes the prefix: a cache miss, while an identical list is a cache hit4052 ant messages create <<'YAML'4053 model: claude-opus-54054 max_tokens: 40964055 container:4056 skills:4057 - type: anthropic4058 skill_id: xlsx4059 version: latest4060 - type: anthropic4061 skill_id: pptx4062 version: latest4063 messages:4064 - role: user4065 content: Create a presentation4066 tools:4067 - type: code_execution_202508254068 name: code_execution4069 YAML4070 ```40714072 ```python Python4073 client = anthropic.Anthropic()40744075 # Skills render into the system prompt in a fixed, cache-friendly order4076 response1 = client.messages.create(4077 model="claude-opus-5",4078 max_tokens=4096,4079 container={4080 "skills": [{"type": "anthropic", "skill_id": "xlsx", "version": "latest"}]4081 },4082 messages=[{"role": "user", "content": "Analyze sales data"}],4083 tools=[{"type": "code_execution_20250825", "name": "code_execution"}],4084 )40854086 # Changing the Skills list ([xlsx] vs [xlsx, pptx]) changes the prefix: a cache miss, while an identical list is a cache hit4087 response2 = client.messages.create(4088 model="claude-opus-5",4089 max_tokens=4096,4090 container={4091 "skills": [4092 {"type": "anthropic", "skill_id": "xlsx", "version": "latest"},4093 {4094 "type": "anthropic",4095 "skill_id": "pptx",4096 "version": "latest",4097 }, # prefix change: cache miss4098 ]4099 },4100 messages=[{"role": "user", "content": "Create a presentation"}],4101 tools=[{"type": "code_execution_20250825", "name": "code_execution"}],4102 )4103 ```41044105 ```typescript TypeScript4106 const client = new Anthropic();41074108 // Skills render into the system prompt in a fixed, cache-friendly order4109 const response1 = await client.messages.create({4110 model: "claude-opus-5",4111 max_tokens: 4096,4112 container: {4113 skills: [{ type: "anthropic", skill_id: "xlsx", version: "latest" }]4114 },4115 messages: [{ role: "user", content: "Analyze sales data" }],4116 tools: [{ type: "code_execution_20250825", name: "code_execution" }]4117 });41184119 // Changing the Skills list ([xlsx] vs [xlsx, pptx]) changes the prefix: a cache miss, while an identical list is a cache hit4120 const response2 = await client.messages.create({4121 model: "claude-opus-5",4122 max_tokens: 4096,4123 container: {4124 skills: [4125 { type: "anthropic", skill_id: "xlsx", version: "latest" },4126 { type: "anthropic", skill_id: "pptx", version: "latest" } // prefix change: cache miss4127 ]4128 },4129 messages: [{ role: "user", content: "Create a presentation" }],4130 tools: [{ type: "code_execution_20250825", name: "code_execution" }]4131 });4132 ```41334134 ```csharp C#4135 AnthropicClient client = new();41364137 // Skills render into the system prompt in a fixed, cache-friendly order4138 var parameters1 = new MessageCreateParams4139 {4140 Model = "claude-opus-5",4141 MaxTokens = 4096,4142 Container = new ContainerParams4143 {4144 Skills =4145 [4146 new SkillParams4147 {4148 Type = SkillParamsType.Anthropic,4149 SkillID = "xlsx",4150 Version = "latest",4151 },4152 ],4153 },4154 Messages = [new() { Role = Role.User, Content = "Analyze sales data" }],4155 Tools = [new CodeExecutionTool20250825()],4156 };41574158 var response1 = await client.Messages.Create(parameters1);4159 Console.WriteLine(response1);41604161 // Different Skill set ([xlsx] vs [xlsx, pptx]) = a different prefix: a cache miss (an identical set is a cache hit)4162 var parameters2 = new MessageCreateParams4163 {4164 Model = "claude-opus-5",4165 MaxTokens = 4096,4166 Container = new ContainerParams4167 {4168 Skills =4169 [4170 new SkillParams4171 {4172 Type = SkillParamsType.Anthropic,4173 SkillID = "xlsx",4174 Version = "latest",4175 },4176 new SkillParams4177 {4178 Type = SkillParamsType.Anthropic,4179 SkillID = "pptx",4180 Version = "latest",4181 },4182 ],4183 },4184 Messages = [new() { Role = Role.User, Content = "Create a presentation" }],4185 Tools = [new CodeExecutionTool20250825()],4186 };41874188 var response2 = await client.Messages.Create(parameters2);4189 Console.WriteLine(response2);4190 ```41914192 ```go Go4193 client := anthropic.NewClient()41944195 // Skills render into the system prompt in a fixed, cache-friendly order4196 response1, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{4197 Model: "claude-opus-5",4198 MaxTokens: 4096,4199 Container: anthropic.MessageCreateParamsContainerUnion{4200 OfContainers: &anthropic.ContainerParams{4201 Skills: []anthropic.SkillParams{4202 {4203 Type: anthropic.SkillParamsTypeAnthropic,4204 SkillID: "xlsx",4205 Version: anthropic.String("latest"),4206 },4207 },4208 },4209 },4210 Messages: []anthropic.MessageParam{4211 anthropic.NewUserMessage(anthropic.NewTextBlock("Analyze sales data")),4212 },4213 Tools: []anthropic.ToolUnionParam{4214 {OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}},4215 },4216 })4217 if err != nil {4218 log.Fatal(err)4219 }4220 fmt.Println(response1)42214222 // Changing the Skills list ([xlsx] vs [xlsx, pptx]) changes the prefix: a cache miss, while an identical list is a cache hit4223 response2, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{4224 Model: "claude-opus-5",4225 MaxTokens: 4096,4226 Container: anthropic.MessageCreateParamsContainerUnion{4227 OfContainers: &anthropic.ContainerParams{4228 Skills: []anthropic.SkillParams{4229 {4230 Type: anthropic.SkillParamsTypeAnthropic,4231 SkillID: "xlsx",4232 Version: anthropic.String("latest"),4233 },4234 {4235 Type: anthropic.SkillParamsTypeAnthropic,4236 SkillID: "pptx",4237 Version: anthropic.String("latest"),4238 },4239 },4240 },4241 },4242 Messages: []anthropic.MessageParam{4243 anthropic.NewUserMessage(anthropic.NewTextBlock("Create a presentation")),4244 },4245 Tools: []anthropic.ToolUnionParam{4246 {OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}},4247 },4248 })4249 if err != nil {4250 log.Fatal(err)4251 }4252 fmt.Println(response2)4253 ```42544255 ```java Java4256 import com.anthropic.models.messages.ContainerParams;4257 import com.anthropic.models.messages.SkillParams;4258 import com.anthropic.models.messages.CodeExecutionTool20250825;4259 // ...4260 void main() {4261 AnthropicClient client = AnthropicOkHttpClient.fromEnv();42624263 // Skills render into the system prompt in a fixed, cache-friendly order4264 MessageCreateParams params1 = MessageCreateParams.builder()4265 .model(Model.CLAUDE_OPUS_5)4266 .maxTokens(4096L)4267 .container(ContainerParams.builder()4268 .skills(List.of(4269 SkillParams.builder()4270 .type(SkillParams.Type.ANTHROPIC)4271 .skillId("xlsx")4272 .version("latest")4273 .build()4274 ))4275 .build())4276 .addUserMessage("Analyze sales data")4277 .addTool(CodeExecutionTool20250825.builder().build())4278 .build();42794280 Message response1 = client.messages().create(params1);4281 System.out.println(response1);42824283 // Changing the Skills list ([xlsx] vs [xlsx, pptx]) changes the prefix: a cache miss, while an identical list is a cache hit4284 MessageCreateParams params2 = MessageCreateParams.builder()4285 .model(Model.CLAUDE_OPUS_5)4286 .maxTokens(4096L)4287 .container(ContainerParams.builder()4288 .skills(List.of(4289 SkillParams.builder()4290 .type(SkillParams.Type.ANTHROPIC)4291 .skillId("xlsx")4292 .version("latest")4293 .build(),4294 SkillParams.builder()4295 .type(SkillParams.Type.ANTHROPIC)4296 .skillId("pptx")4297 .version("latest")4298 .build()4299 ))4300 .build())4301 .addUserMessage("Create a presentation")4302 .addTool(CodeExecutionTool20250825.builder().build())4303 .build();43044305 Message response2 = client.messages().create(params2);4306 System.out.println(response2);4307 }4308 ```43094310 ```php PHP4311 $client = new Client();43124313 // Skills render into the system prompt in a fixed, cache-friendly order4314 $response1 = $client->messages->create(4315 maxTokens: 4096,4316 messages: [4317 ['role' => 'user', 'content' => 'Analyze sales data']4318 ],4319 model: 'claude-opus-5',4320 container: [4321 'skills' => [4322 ['type' => 'anthropic', 'skillID' => 'xlsx', 'version' => 'latest']4323 ]4324 ],4325 tools: [4326 ['type' => 'code_execution_20250825', 'name' => 'code_execution']4327 ]4328 );4329 echo $response1;43304331 // Changing the Skills list ([xlsx] vs [xlsx, pptx]) changes the prefix: a cache miss, while an identical list is a cache hit4332 $response2 = $client->messages->create(4333 maxTokens: 4096,4334 messages: [4335 ['role' => 'user', 'content' => 'Create a presentation']4336 ],4337 model: 'claude-opus-5',4338 container: [4339 'skills' => [4340 ['type' => 'anthropic', 'skillID' => 'xlsx', 'version' => 'latest'],4341 ['type' => 'anthropic', 'skillID' => 'pptx', 'version' => 'latest']4342 ]4343 ],4344 tools: [4345 ['type' => 'code_execution_20250825', 'name' => 'code_execution']4346 ]4347 );4348 echo $response2;4349 ```43504351 ```ruby Ruby4352 client = Anthropic::Client.new43534354 # Skills render into the system prompt in a fixed, cache-friendly order4355 response1 = client.messages.create(4356 model: "claude-opus-5",4357 max_tokens: 4096,4358 container: {4359 skills: [{ type: "anthropic", skill_id: "xlsx", version: "latest" }]4360 },4361 messages: [{ role: "user", content: "Analyze sales data" }],4362 tools: [{ type: "code_execution_20250825", name: "code_execution" }]4363 )4364 puts response143654366 # Changing the Skills list ([xlsx] vs [xlsx, pptx]) changes the prefix: a cache miss, while an identical list is a cache hit4367 response2 = client.messages.create(4368 model: "claude-opus-5",4369 max_tokens: 4096,4370 container: {4371 skills: [4372 { type: "anthropic", skill_id: "xlsx", version: "latest" },4373 { type: "anthropic", skill_id: "pptx", version: "latest" } # prefix change: cache miss4374 ]4375 },4376 messages: [{ role: "user", content: "Create a presentation" }],4377 tools: [{ type: "code_execution_20250825", name: "code_execution" }]4378 )4379 puts response24380 ```4381</CodeGroup>43824383For best caching performance, keep your Skills list, including its order, consistent across requests. Pinning custom Skill versions also helps: with `"latest"`, publishing a new version can invalidate the cached prefix if it changes the Skill's description.43844385### Error handling43864387Handle Skill-related errors gracefully:43884389<CodeGroup>4390 ```bash cURL4391 # This error-handling flow doesn't translate well to a one-off shell4392 # command; one of the SDK options would be a better fit. A failing request4393 # returns HTTP 400 with an error JSON whose .error.message names the4394 # Skill problem.4395 ```43964397 ```bash CLI4398 if ! RESULT=$(ant messages create \4399 --transform-error error.message \4400 --format-error yaml 2>&1 <<'YAML'4401 model: claude-opus-54402 max_tokens: 40964403 container:4404 skills:4405 - type: custom4406 skill_id: skill_01AbCdEfGhIjKlMnOpQrStUv4407 version: latest4408 messages:4409 - role: user4410 content: Process data4411 tools:4412 - type: code_execution_202508254413 name: code_execution4414 YAML4415 ); then4416 case "$RESULT" in4417 *skill*)4418 printf 'Skill error: %s\n' "$RESULT"4419 # Handle skill-specific errors4420 ;;4421 *)4422 printf '%s\n' "$RESULT" >&24423 exit 14424 ;;4425 esac4426 fi4427 ```44284429 ```python Python4430 client = anthropic.Anthropic()44314432 try:4433 response = client.messages.create(4434 model="claude-opus-5",4435 max_tokens=4096,4436 container={4437 "skills": [4438 {4439 "type": "custom",4440 "skill_id": "skill_01AbCdEfGhIjKlMnOpQrStUv",4441 "version": "latest",4442 }4443 ]4444 },4445 messages=[{"role": "user", "content": "Process data"}],4446 tools=[{"type": "code_execution_20250825", "name": "code_execution"}],4447 )4448 except anthropic.BadRequestError as e:4449 if "skill" in str(e):4450 print(f"Skill error: {e}")4451 # Handle skill-specific errors4452 else:4453 raise4454 ```44554456 ```typescript TypeScript4457 const client = new Anthropic();44584459 try {4460 const response = await client.messages.create({4461 model: "claude-opus-5",4462 max_tokens: 4096,4463 container: {4464 skills: [4465 { type: "custom", skill_id: "skill_01AbCdEfGhIjKlMnOpQrStUv", version: "latest" }4466 ]4467 },4468 messages: [{ role: "user", content: "Process data" }],4469 tools: [{ type: "code_execution_20250825", name: "code_execution" }]4470 });4471 console.log(response);4472 } catch (error) {4473 if (error instanceof Anthropic.BadRequestError && error.message.includes("skill")) {4474 console.error(`Skill error: ${error.message}`);4475 // Handle skill-specific errors4476 } else {4477 throw error;4478 }4479 }4480 ```44814482 ```csharp C#4483 using Anthropic.Exceptions;4484 // ...4485 AnthropicClient client = new();44864487 try4488 {4489 var parameters = new MessageCreateParams4490 {4491 Model = "claude-opus-5",4492 MaxTokens = 4096,4493 Container = new ContainerParams4494 {4495 Skills =4496 [4497 new SkillParams4498 {4499 Type = SkillParamsType.Custom,4500 SkillID = "skill_01AbCdEfGhIjKlMnOpQrStUv",4501 Version = "latest",4502 },4503 ],4504 },4505 Messages = [new() { Role = Role.User, Content = "Process data" }],4506 Tools = [new CodeExecutionTool20250825()],4507 };45084509 var response = await client.Messages.Create(parameters);4510 Console.WriteLine(response);4511 }4512 catch (AnthropicBadRequestException e) when (e.Message.Contains("skill"))4513 {4514 Console.WriteLine($"Skill error: {e.Message}");4515 }4516 ```45174518 ```go Go4519 client := anthropic.NewClient()45204521 response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{4522 Model: "claude-opus-5",4523 MaxTokens: 4096,4524 Container: anthropic.MessageCreateParamsContainerUnion{4525 OfContainers: &anthropic.ContainerParams{4526 Skills: []anthropic.SkillParams{4527 {4528 Type: anthropic.SkillParamsTypeCustom,4529 SkillID: "skill_01AbCdEfGhIjKlMnOpQrStUv",4530 Version: anthropic.String("latest"),4531 },4532 },4533 },4534 },4535 Messages: []anthropic.MessageParam{4536 anthropic.NewUserMessage(anthropic.NewTextBlock("Process data")),4537 },4538 Tools: []anthropic.ToolUnionParam{4539 {OfCodeExecutionTool20250825: &anthropic.CodeExecutionTool20250825Param{}},4540 },4541 })45424543 if err != nil {4544 var apierr *anthropic.Error4545 if errors.As(err, &apierr) && apierr.Type() == anthropic.ErrorTypeInvalidRequestError &&4546 strings.Contains(apierr.Error(), "skill") {4547 fmt.Printf("Skill error: %v\n", apierr)4548 } else {4549 log.Fatal(err)4550 }4551 return4552 }4553 fmt.Println(response)4554 ```45554556 ```java Java4557 import com.anthropic.errors.BadRequestException;4558 import com.anthropic.models.messages.ContainerParams;4559 import com.anthropic.models.messages.SkillParams;4560 import com.anthropic.models.messages.CodeExecutionTool20250825;4561 // ...4562 void main() {4563 AnthropicClient client = AnthropicOkHttpClient.fromEnv();45644565 try {4566 MessageCreateParams params = MessageCreateParams.builder()4567 .model(Model.CLAUDE_OPUS_5)4568 .maxTokens(4096L)4569 .container(ContainerParams.builder()4570 .addSkill(SkillParams.builder()4571 .type(SkillParams.Type.CUSTOM)4572 .skillId("skill_01AbCdEfGhIjKlMnOpQrStUv")4573 .version("latest")4574 .build())4575 .build())4576 .addUserMessage("Process data")4577 .addTool(CodeExecutionTool20250825.builder().build())4578 .build();45794580 Message response = client.messages().create(params);4581 System.out.println(response);4582 } catch (BadRequestException e) {4583 if (e.getMessage().contains("skill")) {4584 System.err.println("Skill error: " + e.getMessage());4585 } else {4586 throw e;4587 }4588 }4589 }4590 ```45914592 ```php PHP4593 use Anthropic\Core\Exceptions\BadRequestException;45944595 $client = new Client();45964597 try {4598 $message = $client->messages->create(4599 maxTokens: 4096,4600 messages: [4601 ['role' => 'user', 'content' => 'Process data']4602 ],4603 model: 'claude-opus-5',4604 container: [4605 'skills' => [4606 [4607 'type' => 'custom',4608 'skillID' => 'skill_01AbCdEfGhIjKlMnOpQrStUv',4609 'version' => 'latest'4610 ]4611 ]4612 ],4613 tools: [4614 ['type' => 'code_execution_20250825', 'name' => 'code_execution']4615 ]4616 );4617 echo $message;4618 } catch (BadRequestException $e) {4619 if (str_contains($e->getMessage(), 'skill')) {4620 echo "Skill error: " . $e->getMessage();4621 } else {4622 throw $e;4623 }4624 }4625 ```46264627 ```ruby Ruby4628 client = Anthropic::Client.new46294630 begin4631 response = client.messages.create(4632 model: "claude-opus-5",4633 max_tokens: 4096,4634 container: {4635 skills: [4636 {4637 type: "custom",4638 skill_id: "skill_01AbCdEfGhIjKlMnOpQrStUv",4639 version: "latest"4640 }4641 ]4642 },4643 messages: [{ role: "user", content: "Process data" }],4644 tools: [{ type: "code_execution_20250825", name: "code_execution" }]4645 )4646 rescue Anthropic::Errors::BadRequestError => e4647 if e.message.include?("skill")4648 puts "Skill error: #{e.message}"4649 else4650 raise4651 end4652 end4653 ```4654</CodeGroup>46554656***46574658## Migrate from `skills-2025-10-02`46594660The Skills API is out of beta and needs no beta header. Migrating off `skills-2025-10-02` is optional: requests that still send it keep working and keep returning the beta response shapes, so an existing integration keeps working until you change it. Removing the header switches those requests to the shapes documented on this page:46614662| | With `skills-2025-10-02` | Without the header |4663| ------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |4664| Skill label | `display_title` (up to 64 characters, unique per workspace) | `display_name` (up to 255 characters, not unique); derived from the `SKILL.md` `name` when omitted |4665| Newest version pointer | `latest_version`, an epoch-microsecond string such as `"1759178010641129"` | `latest_version_id`, a version ID such as `"skver_01AbCdEfGhIjKlMnOpQrStUv"`; `GET /v1/skills/{skill_id}/versions/latest` resolves it in one call |4666| Version identifier in URLs | Epoch-microsecond string | Version ID (`skver_...`). IDs captured under the beta with the `skill_version_` prefix are accepted as input. |4667| Version object | Includes `directory` (always equal to the Skill `name`) | No `directory` field |4668| `source` | A string, `"custom"` or `"anthropic"` | An object, for example `{"type": "custom"}`; the example catalog value is `"anthropic_example"` |4669| List responses | `{ data, has_more, next_page }` | `{ data, next_page }`; `limit` from 1 to 1,000 (default 20) |4670| Versions list order | Oldest first | Newest first, default `limit` 20. Page cursors from one shape are not valid on the other. |4671| Deleting a Skill | Returns a 400 error while any version exists | Deletes the Skill and all of its versions |4672| Deleting a Skill's only version | Allowed, leaving a Skill with no versions | Returns a 400 error; upload a replacement version first, or delete the Skill |4673| Upload layout | Files must sit inside a top-level directory whose name matches the Skill `name` | `SKILL.md` may sit at the root of the upload; stored paths are the same either way |4674| Response types | `CreateSkillResponse`, `GetSkillResponse`, and one type per operation | `Skill`, `SkillVersion`, `DeletedSkill`, `DeletedSkillVersion` |46754676To migrate:467746781. **Remove the beta header.** Drop `anthropic-beta: skills-2025-10-02` from your requests. In the SDKs, call `client.skills` instead of `client.beta.skills`; keeping `client.beta.skills` works only on the [SDK releases that no longer send the header](https://platform.claude.com/docs/en/build-with-claude/skills-guide#sdk-beta-namespace). Earlier releases send it from `client.beta.skills` even with no `betas` argument.46792. **Rename fields** in your code: `display_title` to `display_name`, `latest_version` to `latest_version_id`, and read `source.type` instead of comparing `source` to a string.46803. **Use version IDs.** Wherever you stored an epoch-microsecond version, store the version's `id` instead, or use `latest`. Skill references in Messages requests accept a version ID, `latest`, or (for Anthropic Skills) the catalog version.46814. **Review delete calls.** `DELETE /v1/skills/{skill_id}` now removes every version with the Skill. If you relied on the beta's refusal as a safeguard, add your own check.46824683<Warning>4684 After migrating, `client.skills.delete(skill_id)` and `client.beta.skills.delete(skill_id)` delete the Skill together with all of its versions in one call.4685</Warning>46864687A Skill whose versions were all deleted under the beta has no current version to return: `GET /v1/skills/{skill_id}` returns a 400 error and the Skill is omitted from list responses until you upload a version to it. You can still delete it.46884689### SDK beta namespace46904691Starting with Python SDK 1.2.0, TypeScript SDK 0.122.0, Go SDK 1.68.0, Java SDK 2.59.0, Ruby SDK 1.67.0, and C# SDK 12.44.0, `client.beta.skills` no longer sends `skills-2025-10-02` and returns the same shapes as `client.skills`, with `Beta`-prefixed type names (`BetaSkill`, `BetaSkillVersion`, `BetaDeletedSkill`, `BetaDeletedSkillVersion`). It accepts a `betas` argument for Skills features that are still in beta. In the beta Messages types, the container Skill reference type is renamed from `BetaSkill` to `BetaContainerSkill` (same fields: `type`, `skill_id`, `version`); `BetaSkill` now names the Skill resource, matching `Skill` and `ContainerSkill` in the non-beta types. Earlier SDK releases are typed to the beta shapes; if you depend on those types, stay on an earlier release until you migrate.46924693## Data retention46944695Agent Skills are not covered by ZDR arrangements. Skill definitions and execution data are retained according to Anthropic's standard data retention policy.46964697For ZDR eligibility across all features, see [API and data retention](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention).46984699## Audit logging47004701If your organization has the [Compliance API](https://platform.claude.com/docs/en/manage-claude/compliance-api) enabled, its [Activity Feed](https://platform.claude.com/docs/en/manage-claude/compliance-activity-feed) records the creation and deletion of Skills and Skill versions made with a Claude API key or from the Claude Console. Operations that occur while the Compliance API is off are not recorded and cannot be recovered later, so [set up the Compliance API](https://platform.claude.com/docs/en/manage-claude/compliance-api-access) before you rely on this audit trail.47024703## Next steps47044705<CardGroup cols={3}>4706 <Card title="API reference" icon="book" href="https://platform.claude.com/docs/en/api/skills/create">4707 Complete API reference with all endpoints4708 </Card>47094710 <Card title="Skill authoring best practices" icon="edit" href="https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices">4711 Learn how to write effective Skills that Claude can discover and use successfully.4712 </Card>47134714 <Card title="Code execution tool" icon="terminal" href="https://platform.claude.com/docs/en/agents-and-tools/tool-use/code-execution-tool">4715 Run Python and bash code in a sandboxed container to analyze data, generate files, and iterate on solutions.4716 </Card>4717</CardGroup>4718