An Agent Skill is refreshingly portable: one folder holding a SKILL.md and some optional scripts, and it works across Claude Code, the Claude API, and claude.ai. The trap is assuming runs the same way follows from runs everywhere. It doesn't. The file is identical on every surface; the environment it executes in is not — and that gap is what turns a Skill that sailed through your terminal into one that fails silently in production.

The short answer, up front: the SKILL.md contract is fixed everywhere, but three things change per surface — network and package access at runtime, whether the Skill is even present (they don't sync), and who can share it. Get those three right before you ship.

Gotcha 1 — Runtime: the API has no network and no package install#

This is the one that bites hardest. On the Claude API, Skills run in a sandboxed container with no network access and no runtime package installation — only pre-installed packages are available, and you cannot pip install or npm install anything during execution. In Claude Code, a Skill has "the same network access as any other program on the user's computer" and can install packages locally (global installs are discouraged, not blocked). On claude.ai, network access is full, partial, or none depending on user and admin settings.

So a Skill whose helper script fetches an external URL or installs a dependency behaves like this:

If you plan to serve a Skill through the API, write it to use only bundled packages and zero external calls. Push anything that needs the network into your own application code around the API, not into the Skill.

Gotcha 2 — Skills don't sync across surfaces#

There is no single place your Skill "lives." Custom Skills do not sync across surfaces: a Skill uploaded to claude.ai is not available on the API, an API Skill is not on claude.ai, and Claude Code Skills are filesystem-based and separate from both. You upload and manage it separately everywhere you want it.

That means the delivery mechanism differs too:

Treat "publish this Skill" as N deploys, not one. If you're versioning a Skill for a team, that's N places to bump.

Gotcha 3 — Sharing scope is different in each place#

Who else can use your Skill is not a global answer:

The practical read: for a team that should all get the same Skill automatically, the API workspace model and Claude Code's project folder (committed to your repo) are the low-friction paths. claude.ai's per-user model means you're asking each person to install it themselves.

What stays the same everywhere#

The authoring contract doesn't move. A Skill is always a SKILL.md with YAML frontmatter, and the fields have hard limits: name is at most 64 characters, lowercase letters, numbers and hyphens only, and cannot contain the reserved words anthropic or claude; description is non-empty and at most 1024 characters, and it must state both what the Skill does and when Claude should use it — that description is what Claude matches your request against to decide whether to trigger the Skill. Progressive disclosure is also universal: metadata is always loaded (~100 tokens per Skill), the SKILL.md body loads only when the Skill triggers, and bundled files cost nothing until read. If you're writing your first one, start with our SKILL.md walkthrough and the publish-and-install guide.

The one API-specific step people miss#

Using Skills through the API needs plumbing the other surfaces hide from you: the code execution tool (the container Skills run in) plus the skills-2025-10-02 beta header. Add files-api-2025-04-14 when you upload input files or download files a Skill produces. Pre-built document Skills are referenced by skill_idpptx, xlsx, docx, pdf — and custom ones come from your /v1/skills uploads. Forget the header and the Skill simply isn't there; the model won't tell you why.

Ship-check#

Before you call a Skill "done," answer three questions for the surface you're deploying to:

  1. Does it need the network or a package install? If yes, it can't be an API Skill — refactor the network parts out.
  2. **Have you actually deployed it there?** Filesystem, /v1/skills, or zip upload — Skills don't travel between surfaces on their own.
  3. Will the right people have it? Per-user (claude.ai), workspace (API), or repo/Plugins (Claude Code).

The Skill format earned its portability. The runtime didn't — and that's the part that pages you at 2 a.m. Decide the surface first, then write the Skill to its constraints, and the same folder will behave the way you expect wherever it runs. And if your Skill never even fires in the first place, that's a different failure with a different fix — see Why Your Agent Skill Never Fires. Still choosing between a Skill and an MCP server for the job? We broke that down in Agent Skills vs MCP.