Agent 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.
Learn how to use Agent Skills to create documents with the Claude API in under 10 minutes.
Learn how to write effective Skills that Claude can discover and use successfully.
Skills integrate with the Messages API through the 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.
Skills 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.
You can use Skills from two sources:
| Aspect | Anthropic Skills | Custom Skills |
|---|---|---|
| Type value | anthropic | custom |
| Skill IDs | Short names: pptx, xlsx, docx, pdf | Generated: skill_01AbCdEfGhIjKlMnOpQrStUv |
| Version format | Date-based: 20251013 or latest | Epoch timestamp: 1759178010641129 or latest |
| Management | Pre-built and maintained by Anthropic | Upload and manage through the Skills API |
| Availability | Available to all users | Private to your workspace |
Both skill sources are returned by the List Skills endpoint (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.
To use Skills, you need:
code-execution-2025-08-25 - Enables code execution (required for Skills)skills-2025-10-02 - Enables Skills APIfiles-api-2025-04-14 - Required only when you use the Files API to upload input files or download files a Skill producesSkills require the code execution tool, so use a model from its model compatibility list.
Skills are specified using the container parameter in the Messages API. You can include up to 8 Skills for each request.
The 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:
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-opus-5",
max_tokens=4096,
betas=["code-execution-2025-08-25", "skills-2025-10-02"],
container={
"skills": [{"type": "anthropic", "skill_id": "pptx", "version": "latest"}]
},
messages=[
{"role": "user", "content": "Create a presentation about renewable energy"}
],
tools=[{"type": "code_execution_20250825", "name": "code_execution"}],
)When 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.
How it works:
file_id for each created file, inside code-execution tool result blocks (see Response format).To provide input files for Skills to work on, upload them with the Files API and reference them in your request with a container upload block.
Example: creating and downloading an Excel file
client = anthropic.Anthropic()
# Step 1: Use a Skill to create a file
response = client.beta.messages.create(
model="claude-opus-5",
max_tokens=4096,
betas=["code-execution-2025-08-25", "skills-2025-10-02"],
container={
"skills": [{"type": "anthropic", "skill_id": "xlsx", "version": "latest"}]
},
messages=[
{
"role": "user",
"content": "Create an Excel file with a simple budget spreadsheet",
}
],
tools=[{"type": "code_execution_20250825", "name": "code_execution"}],
)
# Step 2: Extract file IDs from the response
def extract_file_ids(response):
file_ids = []
for item in response.content:
if item.type == "bash_code_execution_tool_result":
content_item = item.content
if content_item.type == "bash_code_execution_result":
# each content item is a bash_code_execution_output block carrying a file_id
for file in content_item.content:
file_ids.append(file.file_id)
return file_ids
# Step 3: Download the file using Files API
for file_id in extract_file_ids(response):
file_metadata = client.beta.files.retrieve_metadata(file_id=file_id)
file_content = client.beta.files.download(file_id=file_id)
# Step 4: Save to disk
file_content.write_to_file(file_metadata.filename)
print(f"Downloaded: {file_metadata.filename}")Additional Files API operations:
client = anthropic.Anthropic()
file_id = "file_011CNha8iCJcU1wXNR6q4V8w"
# Get file metadata
file_info = client.beta.files.retrieve_metadata(file_id=file_id)
print(f"Filename: {file_info.filename}, Size: {file_info.size_bytes} bytes")
# List all files
for file in client.beta.files.list():
print(f"{file.filename} - {file.created_at}")
# Delete a file
client.beta.files.delete(file_id=file_id)The response's container object carries the container's id and expires_at timestamp (see Container reuse for lifetime details). Reuse the same container across multiple messages by specifying the container ID:
client = anthropic.Anthropic()
# First request creates container
response1 = client.beta.messages.create(
model="claude-opus-5",
max_tokens=4096,
betas=["code-execution-2025-08-25", "skills-2025-10-02"],
container={
"skills": [{"type": "anthropic", "skill_id": "xlsx", "version": "latest"}]
},
messages=[
{"role": "user", "content": "Create a sample sales dataset and analyze it"}
],
tools=[{"type": "code_execution_20250825", "name": "code_execution"}],
)
# Continue conversation with same container
messages = [
{"role": "user", "content": "Create a sample sales dataset and analyze it"},
{
# Carry the assistant's text forward; container.id carries the execution state
"role": "assistant",
"content": "\n".join(
block.text for block in response1.content if block.type == "text"
),
},
{"role": "user", "content": "What was the total revenue?"},
]
response2 = client.beta.messages.create(
model="claude-opus-5",
max_tokens=4096,
betas=["code-execution-2025-08-25", "skills-2025-10-02"],
container={
"id": response1.container.id, # Reuse container
"skills": [{"type": "anthropic", "skill_id": "xlsx", "version": "latest"}],