Home › Agent Skills › Messages API — skills ride the code-execution container
Agent Skills · Build

Messages API — skills ride the code-execution container

A skill runs inside a single Messages API request by riding along on the code-execution container, with no beta header required.

In one line

Skills on the Messages API ride the code-execution container, so container.skills and the code_execution tool must both be present in the same request or it fails; no beta header is required.

Why you'd careThe problem it solves

You want a .pptx out of one stateless API call. No agent runtime, no session to drive, no event stream to consume — one request, one response, a file at the end. So you add container={"skills": [...]} to your existing messages.create call and get a 400. It takes another round trip to discover that this is not a parameter you bolt onto a normal request. It is a composition of two features that only works assembled: the skill list, and the execution tool that gives the skill somewhere to run. Either one missing and the request is invalid.

ConceptWhat it is

On the Messages API a skill is not a runtime of its own. It is a set of files staged into the code-execution container — the sandboxed environment Anthropic provisions when you declare the code-execution tool. The skill's instructions enter the model's context; the skill's scripts and assets land on a filesystem the model can reach because that filesystem exists for the execution tool. Take the tool away and there is nowhere to stage anything, which is why the two are inseparable here.

That explains the shape of the request. container is where you say which skills; tools is where you say that there is a container at all. No beta header gates the pair. Anthropic's pre-built document skills — pptx, xlsx, docx, pdf — are referenced by name with type of anthropic; skills you registered yourself are referenced by their skill_id with type of custom.

The boundary against Managed Agents is worth stating precisely, because a correction was needed here. This surface is stateless: one request, one container, no persisted configuration. Managed Agents is stateful and persists the skill set on a versioned Agent object. Both fully support skills. Choosing the Messages API is a choice about statefulness and about who runs the loop — it is not the only path to a generated document, and reaching for an Agent to build a deck is not a wrong turn.

How it worksThe mechanics

The two required pieces, together, on the standard messages endpoint:

code
response = client.messages.create(
    model="claude-opus-5",
    max_tokens=16000,
    container={"skills": [
        {"type": "anthropic", "skill_id": "pptx", "version": "latest"}
    ]},
    tools=[{"type": "code_execution_20260521", "name": "code_execution"}],
    messages=[{"role": "user", "content": "Build a 3-slide deck on Q3 churn."}],
)

Four details that trip people up:

  • It is plain client.messages.create, with no betas argument.The Skills API is out of beta and all three code execution tool versions are generally available, so the composed request needs no beta header. skills-2025-10-02 still works as an opt-in, but a request that keeps sending it keeps getting the beta response shapes; the legacy code-execution headers remain valid opt-ins too.
  • Both pieces, not one.container.skills and the code_execution tool do different halves of the job. Sending the skills without the tool is the most common first 400.
  • Generated files come back as IDs, not bytes.The skill writes into the container; the response carries a file ID per output. Download it through the Files API, which is also out of beta and needs no header.
  • Listing available skills is a separate call.GET /v1/skills needs no beta header either; send skills-2025-10-02 there and you get the beta response shapes back.

One thing that used to be open is now documented. The container parameter is overloaded: documented examples pass a bare container ID string to reuse a previous container, and pass an object carrying skills to enable skills. The skills guide now shows the two together — skills plus a warm container in one request — by passing the previous response's container.id inside the object, container={"id": ..., "skills": [...]}, along with the conversation history.

At a glanceSee it

Messages API — skills ride the code-execution container diagram

The three-part request that enables a skill on the Messages API, and how the output file gets back to you.

Where it runsSurfaces and availability

SurfaceStatusNotes
Claude API / Messages APIYesGenerally available. This is the surface the entry describes: container.skills plus the code-execution tool, with no beta header — not even for the Files API when you upload inputs or download what a Skill produces. Maximum 20 Skills per request. Confirmed on Using Agent Skills with the API (platform.claude.com/docs/en/build-with-claude/skills-guide).
Claude Platform on AWSYesBeta. Anthropic-operated with same-day parity: the docs state you use pre-built and custom Agent Skills “with the same container.skills parameter as the Claude API”, and that all four pre-built Skills work out of the box (platform.claude.com/docs/en/build-with-claude/claude-platform-on-aws).
Managed AgentsYesSkills work here too, but through a different field — skills on the Agent object, not container.skills. Do not port the request shape across, and note the limits differ by more than an order of magnitude: 20 skills per Messages API request versus up to 500 per Managed Agents session.
Claude CodeNoNot applicable rather than unsupported: Claude Code resolves skills from local directories and never sends container.skills.
Claude Desktop or claude.aiUnverifiedclaude.ai does have Skills — pre-built ones active for document creation, custom ones uploaded as zips under Settings > Features, and they require code execution enabled on a Pro, Max, Team or Enterprise plan. But whether the underlying request uses this same container.skills mechanism is not documented, and cannot be settled from outside.
Agent SDKNoNow confirmable. The Agent SDK's skills are filesystem artefacts discovered through settingSources/setting_sources, and the docs state directly that “you create skills as files on disk. The SDK doesn't provide a programmatic API for registering them” (code.claude.com/docs/en/agent-sdk/skills). Nothing stops SDK-hosted code from hand-rolling a container.skills request against the API, but there is no first-class option for it.
Amazon BedrockNoNeither Agent Skills nor code execution is available; Anthropic's comparison table records Agent Skills as “Not available (requires code execution)” and notes the anthropic-beta header is not supported on Bedrock at all. The entire path is absent, not gated.
Google Vertex AINoSame. The Claude on Google Cloud page lists Agent Skills, code execution, web fetch and the Files API together under “Features not supported” (platform.claude.com/docs/en/build-with-claude/claude-on-vertex-ai).
Microsoft FoundryYes — on a Hosted on Anthropic deployment onlyBeta, with a hosting gate the availability table shows only as a footnote. Foundry offers two hosting options, and Agent Skills, code execution, the Files API and programmatic tool calling are all listed under “Additional features not supported when hosted on Azure”; requests using them against a Hosted on Azure deployment “return a 400 Bad Request error by design”. Choosing Default settings in the Foundry portal provisions Hosted on Azure for any model offering both, so the deployment that works here is the one you have to opt into. Source: platform.claude.com/docs/en/build-with-claude/claude-in-microsoft-foundry.
OpenAI, Google Gemini APIsNoThese are Anthropic parameters on Anthropic's endpoint. Other vendors' skill features are separate mechanisms with separate request shapes.

The pattern is that skills follow code execution. Every surface where code execution exists carries skills; every surface where it does not, does not — and the vendor docs bear this out row by row, with Vertex listing Agent Skills and code execution in the same “not supported” block and Bedrock refusing beta headers outright. That makes availability easy to predict, and it makes Foundry the interesting case twice over. It supports this stateless path but not Managed Agents — so a document pipeline built on the Messages API ports there and one built on Agents does not — and even the stateless path is conditional on picking the Hosted on Anthropic deployment. Verify the hosting option before you promise a Foundry customer a delivery date: the failure mode is not a missing feature flag but a hard 400, and the portal's default settings land on the wrong side of it.

ExampleIn the real world

A finance tool needs to hand users a formatted .xlsx of their monthly reconciliation. There is no chat interface, no long-running task, just a nightly job that produces a file.

The service sends one request: model, max_tokens, container={"skills": [{"type": "anthropic", "skill_id": "xlsx"}]}, the code_execution_20260521 tool, and a user message containing the reconciliation rows plus the required column layout.

Server-side, a container comes up, the Excel skill's instructions and helper files are staged into it, and the model's context gains the skill's guidance on how to build a spreadsheet properly — sheet structure, formula construction, number formatting. The model then writes and runs Python in that container using those conventions rather than inventing its own.

The response comes back as an interleaved stream of text and tool-result blocks, with a file ID for the workbook the container wrote. The service takes that ID, calls the Files API — no beta header needed — and writes the bytes to object storage.

Total server-side state held by the caller: none. That is the reason to pick this surface over an Agent. If the next month's run needs different behaviour, it is a different request, not a new agent version.

Not thisWhat it is often confused with

  • Not Managed Agentsdifferent namespace, different field, different lifecycle. Managed Agents puts skills on a persisted Agent object and runs the loop for you. This surface is one stateless request where you own the loop. A prior version of this catalogue implied Agents were the wrong path for document generation; that was wrong, and they support skills fully.
  • Not a toolskills are declared in container, not in tools. The only thing in tools here is code_execution. The model never emits a tool_use block naming a skill.
  • Not the Skills API/v1/skills is the registry where custom skill objects are created and versioned. container.skills only references what already exists. Anthropic's pre-built skills need no registration; yours do.
  • Not code execution on its owndeclaring the execution tool without container.skills gives the model a sandbox and no expertise. Declaring skills without the tool gives it expertise and nowhere to apply it. The pairing is the feature.
  • Not a local SKILL.md folderthe API cannot read your filesystem. A folder must be registered through the Skills API before container.skills can name it.

LimitsWhen not to reach for it

  • The work is genuinely long-running or multi-turn.If the task needs a persistent workspace, mounted repos, or many turns of tool use, use Managed Agents — skills are supported there and you stop hand-rolling a loop.
  • You need the same skill set enforced across many callers.Repeating the container block in every call site means it drifts. Put the skills on a versioned Agent object instead and let sessions point at it.
  • You are targeting Bedrock or Vertex.There is no request shape that makes this work there. Move the deployment to Claude Platform on AWS, or generate the document with your own library and use the model only for content.
  • What you want is a callable function.If the requirement is a deterministic action with validated arguments, define a tool with a schema. A skill will not give you a typed contract.
  • The user needs to see progress.A single stateless request has no event stream. If you need per-step visibility, that is a reason to move to a session-based surface.
Checked

Verified 2026-09-12. Moves on a scale of months. Re-check before you depend on it. Provider: Anthropic.

A living map of modern AI — kept current every morning