skills-guide changedbuild-with-claude/skills-guide
Nearest release: v2.1.304, published under an hour after this site recorded the change. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Recorded here
Lines+47added
Lines−272removed
From line
316
where the diff opens
First seen
14 Aug 2026
this site's first read of the page
Recorded edits21to this page, all time
The whole hunk
from line 316, old and new numbered
/
from line 316
316316
317317**Example: creating and downloading an Excel file**
318318
319<CodeGroup>
320 ```bash cURL
321 # Step 1: Use a Skill to create a file
322 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-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 }')
319<CodeGroup exclude="shell:cURL, shell:CLI">
320 <CodeGroupItem language="cURL">
321 This workflow needs more logic than a single shell command. Use the [Claude SDK](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) to run it.
322 </CodeGroupItem>
343323
344 # 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')
324 <CodeGroupItem language="CLI">
325 This workflow needs more logic than a single shell command. Use the [Claude SDK](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) to run it.
326 </CodeGroupItem>
346327
347 # Step 3: Get filename from metadata
348 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')
351
352 # Step 4: Download the file using Files API
353 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"
357
358 echo "Downloaded: $FILENAME"
359 ```
360
361 ```bash CLI
362 # Step 1: Use the xlsx Skill to create a file
363 # 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-5-5
368 max_tokens: 4096
369 container:
370 skills:
371 - type: anthropic
372 skill_id: xlsx
373 version: latest
374 messages:
375 - role: user
376 content: Create an Excel file with a simple budget spreadsheet
377 tools:
378 - type: code_execution_20250825
379 name: code_execution
380 YAML
381 )
382
383 # Step 3: Get the filename from file metadata
384 FILENAME=$(ant files retrieve-metadata \
385 --file-id "$FILE_ID" \
386 --transform filename \
387 --raw-output)
388
389 # Step 4: Download the file using Files API
390 ant files download --file-id "$FILE_ID" --output "$FILENAME" > /dev/null
391
392 printf 'Downloaded: %s\n' "$FILENAME"
393 ```
394
395328 ```python Python
396329 client = anthropic.Anthropic()
397330
from line 713
780713 ```bash CLI
781714 # Get file metadata
782715 ant files retrieve-metadata \
783 --file-id "$FILE_ID" \
784 --transform '{filename,size_bytes}' \
785 --format yaml
716 --file-id "$FILE_ID"
786717
787718 # List all files
788 ant files list --transform '{filename,created_at}' --format yaml
719 ant files list
789720
790721 # Delete a file
791 ant files delete --file-id "$FILE_ID" >/dev/null
722 ant files delete --file-id "$FILE_ID"
792723 ```
793724
794725 ```python Python
from line 867
936867
937868The 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:
938869
939<CodeGroup exclude="shell:cURL">
870<CodeGroup exclude="shell:cURL, shell:CLI">
940871 <CodeGroupItem language="cURL">
941872 Multi-turn container reuse needs more logic than a single shell command, so use the Claude SDK for it. To build the requests yourself, capture `container.id` from the first response. Then pass it in the next request as `"container": {"id": "...", "skills": [...]}`, together with the conversation history.
942873 </CodeGroupItem>
943874
944 ```bash CLI
945 # First request creates container
946 CONTAINER_ID=$(ant messages create \
947 --transform container.id \
948 --raw-output <<'YAML'
949 model: claude-opus-5-5
950 max_tokens: 4096
951 container:
952 skills:
953 - {type: anthropic, skill_id: xlsx, version: latest}
954 messages:
955 - role: user
956 content: Create a sample sales dataset and analyze it
957 tools:
958 - {type: code_execution_20250825, name: code_execution}
959 YAML
960 )
875 <CodeGroupItem language="CLI">
876 This workflow needs more logic than a single shell command. Use the [Claude SDK](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) to run it.
877 </CodeGroupItem>
961878
962 # Continue conversation with same container
963 ant messages create <<YAML
964 model: claude-opus-5-5
965 max_tokens: 4096
966 container:
967 id: $CONTAINER_ID # Reuse container
968 skills:
969 - {type: anthropic, skill_id: xlsx, version: latest}
970 messages:
971 - role: user
972 content: Create a sample sales dataset and analyze it
973 - role: assistant
974 content: [] # the assistant's text from the first response
975 - role: user
976 content: What was the total revenue?
977 tools:
978 - {type: code_execution_20250825, name: code_execution}
979 YAML
980 ```
981
982879 ```python Python
983880 client = anthropic.Anthropic()
984881
from line 1239
13421239
13431240Skills may perform operations that require multiple turns. Handle `pause_turn` stop reasons:
13441241
1345<CodeGroup>
1346 ```bash cURL
1347 # Initial request
1348 RESPONSE=$(curl https://api.anthropic.com/v1/messages \
1349 -H "x-api-key: $ANTHROPIC_API_KEY" \
1350 -H "anthropic-version: 2023-06-01" \
1351 -H "content-type: application/json" \
1352 -d '{
1353 "model": "claude-opus-5-5",
1354 "max_tokens": 4096,
1355 "container": {
1356 "skills": [
1357 {
1358 "type": "custom",
1359 "skill_id": "skill_01AbCdEfGhIjKlMnOpQrStUv",
1360 "version": "latest"
1361 }
1362 ]
1363 },
1364 "messages": [{
1365 "role": "user",
1366 "content": "Generate and process a large sample dataset"
1367 }],
1368 "tools": [{
1369 "type": "code_execution_20250825",
1370 "name": "code_execution"
1371 }]
1372 }')
1242<CodeGroup exclude="shell:cURL, shell:CLI">
1243 <CodeGroupItem language="cURL">
1244 This workflow needs more logic than a single shell command. Use the [Claude SDK](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) to run it.
1245 </CodeGroupItem>
13731246
1374 # If stop_reason is "pause_turn", continue in the same container, appending
1375 # the prior response's content array to messages as the assistant turn.
1376 # Repeat this continuation request until stop_reason is no longer "pause_turn".
1377 STOP_REASON=$(echo "$RESPONSE" | jq -r '.stop_reason')
1378 CONTAINER_ID=$(echo "$RESPONSE" | jq -r '.container.id')
1247 <CodeGroupItem language="CLI">
1248 This workflow needs more logic than a single shell command. Use the [Claude SDK](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) to run it.
1249 </CodeGroupItem>
13791250
1380 RESPONSE=$(curl https://api.anthropic.com/v1/messages \
1381 -H "x-api-key: $ANTHROPIC_API_KEY" \
1382 -H "anthropic-version: 2023-06-01" \
1383 -H "content-type: application/json" \
1384 -d "{
1385 \"model\": \"claude-opus-5-5\",
1386 \"max_tokens\": 4096,
1387 \"container\": {
1388 \"id\": \"$CONTAINER_ID\",
1389 \"skills\": [{
1390 \"type\": \"custom\",
1391 \"skill_id\": \"skill_01AbCdEfGhIjKlMnOpQrStUv\",
1392 \"version\": \"latest\"
1393 }]
1394 },
1395 \"messages\": [],
1396 \"tools\": [{
1397 \"type\": \"code_execution_20250825\",
1398 \"name\": \"code_execution\"
1399 }]
1400 }")
1401 ```
1402
1403 ```bash CLI
1404 RESP=$(mktemp)
1405
1406 # Initial request: capture the full JSON response to a temp file
1407 ant messages create > "$RESP" <<'YAML'
1408 model: claude-opus-5-5
1409 max_tokens: 4096
1410 container:
1411 skills:
1412 - type: custom
1413 skill_id: skill_01AbCdEfGhIjKlMnOpQrStUv
1414 version: latest
1415 messages:
1416 - role: user
1417 content: Generate and process a large sample dataset
1418 tools:
1419 - type: code_execution_20250825
1420 name: code_execution
1421 YAML
1422
1423 # If stop_reason is "pause_turn", continue in the same container,
1424 # appending the prior response's content array to messages as the
1425 # assistant turn. Repeat until stop_reason is no longer "pause_turn".
1426 CONTAINER_ID=$(jq -r '.container.id' "$RESP")
1427
1428 ant messages create > "$RESP" <<YAML
1429 model: claude-opus-5-5
1430 max_tokens: 4096
1431 container:
1432 id: $CONTAINER_ID
1433 skills:
1434 - type: custom
1435 skill_id: skill_01AbCdEfGhIjKlMnOpQrStUv
1436 version: latest
1437 messages: [] # replace with conversation history + prior assistant content
1438 tools:
1439 - type: code_execution_20250825
1440 name: code_execution
1441 YAML
1442 ```
1443
14441251 ```python Python
14451252 client = anthropic.Anthropic()
14461253
from line 2525
27182525 ```
27192526
27202527 ```bash CLI
2721 ant skills delete --skill-id skill_01AbCdEfGhIjKlMnOpQrStUv >/dev/null
2528 ant skills delete --skill-id skill_01AbCdEfGhIjKlMnOpQrStUv
27222529 ```
27232530
27242531 ```python Python
from line 2601
27942601<CodeGroup>
27952602 ```bash cURL
27962603 # Create a new version
2797 NEW_VERSION=$(curl -X POST "https://api.anthropic.com/v1/skills/skill_01AbCdEfGhIjKlMnOpQrStUv/versions" \
2604 curl -X POST "https://api.anthropic.com/v1/skills/skill_01AbCdEfGhIjKlMnOpQrStUv/versions" \
27982605 -H "x-api-key: $ANTHROPIC_API_KEY" \
27992606 -H "anthropic-version: 2023-06-01" \
28002607 -F "files[]=@financial_skill/SKILL.md;filename=financial_skill/SKILL.md" \
2801 -F "files[]=@financial_skill/analyze.py;filename=financial_skill/analyze.py")
2608 -F "files[]=@financial_skill/analyze.py;filename=financial_skill/analyze.py"
28022609
2803 VERSION_ID=$(echo "$NEW_VERSION" | jq -r '.id')
2804
2805 # Use specific version
2610 # Use a specific version: the id from the create response
28062611 curl https://api.anthropic.com/v1/messages \
28072612 -H "x-api-key: $ANTHROPIC_API_KEY" \
28082613 -H "anthropic-version: 2023-06-01" \
28092614 -H "content-type: application/json" \
2810 -d "{
2811 \"model\": \"claude-opus-5-5\",
2812 \"max_tokens\": 4096,
2813 \"container\": {
2814 \"skills\": [{
2815 \"type\": \"custom\",
2816 \"skill_id\": \"skill_01AbCdEfGhIjKlMnOpQrStUv\",
2817 \"version\": \"$VERSION_ID\"
2615 -d '{
2616 "model": "claude-opus-5-5",
2617 "max_tokens": 4096,
2618 "container": {
2619 "skills": [{
2620 "type": "custom",
2621 "skill_id": "skill_01AbCdEfGhIjKlMnOpQrStUv",
2622 "version": "'"$VERSION_ID"'"
28182623 }]
28192624 },
2820 \"messages\": [{\"role\": \"user\", \"content\": \"Use updated Skill\"}],
2821 \"tools\": [{\"type\": \"code_execution_20250825\", \"name\": \"code_execution\"}]
2822 }"
2625 "messages": [{"role": "user", "content": "Use updated Skill"}],
2626 "tools": [{"type": "code_execution_20250825", "name": "code_execution"}]
2627 }'
28232628
28242629 # Use latest version
28252630 curl https://api.anthropic.com/v1/messages \
from line 2648
28432648
28442649 ```bash CLI
28452650 # Create a new version
2846 VERSION_ID=$(ant skills:versions create \
2651 ant skills:versions create \
28472652 --skill-id skill_01AbCdEfGhIjKlMnOpQrStUv \
2848 --file financial_skill.zip \
2849 --transform id \
2850 --raw-output)
2653 --file financial_skill.zip
28512654
2852 # Use specific version
2655 # Use a specific version: the id from the create response
28532656 ant messages create <<YAML
28542657 model: claude-opus-5-5
28552658 max_tokens: 4096
from line 4269
44664269
44674270Handle Skill-related errors gracefully:
44684271
4469<CodeGroup exclude="shell:cURL">
4272<CodeGroup exclude="shell:cURL, shell:CLI">
44704273 <CodeGroupItem language="cURL">
44714274 This error-handling flow needs more logic than a single shell command, so use the Claude SDK for it. A request that fails because of a Skill problem returns HTTP 400. The `error.message` field in the JSON response body describes the problem.
44724275 </CodeGroupItem>
44734276
4474 ```bash CLI
4475 if ! RESULT=$(ant messages create \
4476 --transform-error error.message \
4477 --format-error yaml 2>&1 <<'YAML'
4478 model: claude-opus-5-5
4479 max_tokens: 4096
4480 container:
4481 skills:
4482 - type: custom
4483 skill_id: skill_01AbCdEfGhIjKlMnOpQrStUv
4484 version: latest
4485 messages:
4486 - role: user
4487 content: Process data
4488 tools:
4489 - type: code_execution_20250825
4490 name: code_execution
4491 YAML
4492 ); then
4493 case "$RESULT" in
4494 *skill*)
4495 printf 'Skill error: %s\n' "$RESULT"
4496 # Handle skill-specific errors
4497 ;;
4498 *)
4499 printf '%s\n' "$RESULT" >&2
4500 exit 1
4501 ;;
4502 esac
4503 fi
4504 ```
4277 <CodeGroupItem language="CLI">
4278 This workflow needs more logic than a single shell command. Use the [Claude SDK](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) to run it.
4279 </CodeGroupItem>
45054280
45064281 ```python Python
45074282 client = anthropic.Anthropic()
No line in this hunk matches that.