Code & Snippets

Claude Skill — Custom API Call Template.

Copy-paste SKILL.md template for a Claude skill that calls your own custom HTTP API — covers domain whitelisting, .env-based API keys, and the single-call bash pattern.

Pure Operations
Markdown · 116 lines
C.1

Download

Grab the source file. Drop it into your service, set the required environment variables, and deploy.

Download SKILL.mdMarkdown · 116 lines
C.2

How it works

The gist

A copy-paste SKILL.md template for building a Claude skill that calls your own custom HTTP API — anything you've stood up internally (an internal search service, a CRM proxy, a private LLM endpoint, a Railway worker, etc.). Drop it into /mnt/skills/{org}/{your-skill-name}/, fill in the placeholders, ship.

The two things that trip people up

  1. You MUST whitelist the API's domain in Claude. Claude blocks network calls to any host not on its allowlist. Before the skill can make a single successful call, the user has to add the API domain (e.g. api.yourservice.com) to Claude's allowed-domains list in settings. Skip this step and every curl returns a network / permission error that looks like the skill is broken — it isn't, Claude is just refusing the egress.
  2. API keys live in a sibling .env file, never in the markdown. The template loads the key from /mnt/skills/{org}/{your-skill-name}/.env at the top of every bash block. The markdown ships clean; the secret never enters a git history or a shared skill export.

What the template covers

  • The frontmatter description: field — the single most important line, because it's what Claude reads to decide whether to activate the skill at all. The template flags it explicitly.
  • The "Hard Rules" pattern: response is plain text, one tool call per request, optimize the query before sending, never echo the key.
  • A canonical single-call bash pattern that loads the key from .env, curls the endpoint, and pipes the response to /tmp/result.txt for inspection with view / grep.
  • A "When to use / when NOT to use" section, because the negative cases ("there's a separate skill for X") are what stop the skill firing on the wrong question.

How to use it

  1. mkdir /mnt/skills/{org}/{your-skill-name}
  2. Save the template as SKILL.md in that folder.
  3. Create a sibling .env with your API key.
  4. Whitelist the API domain in Claude's settings.
  5. Replace every {placeholder}: skill name, description, endpoint, header scheme, body shape, trigger phrases, counter-examples.
  6. Test with one obvious trigger phrase and one negative case to confirm it activates (or doesn't) when you expect.

Why this exists

Most custom Claude skills people try to build fail for the same two reasons — they forgot to whitelist the domain, or they pasted the API key into the markdown. This snippet is the template that makes both of those impossible to skip by accident.

C.3

Source

Full source, exactly as shipped. The download above is byte-identical.

SKILL.mdMarkdown
---
name: your-skill-name
description: One sentence describing what this skill does and when it should
  trigger. List the phrases / question shapes that should activate it ("ask
  the X", "look up Y", "check our Z") plus the negative cases ("do NOT use
  for ..."). This description is the ONLY thing Claude reads to decide
  whether to load the skill — be specific.
---

# {Your Skill Name} — Calling a Custom API from a Claude Skill

You are the interface to {your internal system / API}. Your role is to turn
the user's question into a single optimized API call, read the plain-text
response, and answer the user's question from it.

## CRITICAL SETUP — read this first

1. **Whitelist the API domain in Claude.**
   Claude will refuse `curl` / `fetch` to any host that isn't on its
   allowlist. Before this skill can run a single call, the user must add
   the API's domain (e.g. `api.yourservice.com`) to the allowed-domains
   list in Claude's settings. Without this step every call fails with a
   network / permission error — the skill itself is fine, Claude is just
   blocking the egress.

2. **Create a `.env` file alongside this `SKILL.md`.**
   Never paste API keys into the markdown. Never hardcode them in the
   bash snippets. Put them in a sibling `.env`:

   ```
   # /mnt/skills/{org}/{your-skill-name}/.env
   YOUR_API_KEY=sk-...
   ```

   Load it at the top of every bash invocation:

   ```bash
   YOUR_API_KEY=$(grep '^YOUR_API_KEY=' \
     /mnt/skills/{org}/{your-skill-name}/.env | cut -d'=' -f2-)
   ```

3. **One tool call per request.** Don't chain multiple API calls in a
   single bash block unless the API explicitly supports it. Sequential,
   inspectable calls are easier to debug.

## The Hard Rules

- **The response is text. Read it.** Treat the response body as plain
  text. Even if chunks inside look like JSON, HTML, code, tables, or
  fragmented OCR, that's source material — not a contract. Never
  JSON-parse it unless the API guarantees JSON. Never assume a weird
  chunk means the API changed.
- **Optimize the query before sending.** Strip conversational filler
  from the user's question. Never add words the user didn't write.
- **Never log or echo the API key.** Read it from `.env`, pass it in the
  header, move on.

## How to Call the API

**Endpoint:** `POST https://api.yourservice.com/{path}`

**Headers:**

- `Content-Type: application/json`
- `X-API-Key: $YOUR_API_KEY` (or `Authorization: Bearer $YOUR_API_KEY` —
  match whatever your API expects)

**Body:**

```json
{
  "query": "optimized natural language query",
  "options": ["..."]
}
```

**Single call pattern:**

```bash
YOUR_API_KEY=$(grep '^YOUR_API_KEY=' \
  /mnt/skills/{org}/{your-skill-name}/.env | cut -d'=' -f2-)

curl -s -X POST https://api.yourservice.com/{path} \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $YOUR_API_KEY" \
  -d '{"query": "your optimized query", "options": ["..."]}' \
  > /tmp/result.txt
```

Always pipe the response to a named temp file in `/tmp/` so you can read
or grep it without re-running the call.

## How to Read the Response

The response is plain text. After the curl call:

- **Full read:** `view /tmp/result.txt`
- **Targeted grep:** `grep -in -C2 -E "term1|term2" /tmp/result.txt`
- **Sources / citations block** (if your API returns one): preserve it
  verbatim in your final answer to the user.

If a chunk inside the response looks malformed, keep reading. It's
almost always an embedded source document, not a broken API.

## When to use this skill

List 4–8 trigger phrases the user is likely to say, plus 1–2 explicit
negative cases ("do NOT use this skill for X — there's a separate
{other-skill} for that"). The trigger list is what makes the skill
actually activate at the right moment.

## When NOT to use this skill

- {Counter-example 1 — point at the sibling skill that owns it}
- {Counter-example 2 — public web questions, etc.}