From api-explorer
Discover, fetch, cache, and normalize third-party API documentation — use before implementing against any external API
How this skill is triggered — by the user, by Claude, or both
Slash command
/api-explorer:api-explorerThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Discovers, fetches, caches, and normalizes third-party API documentation so you can implement against it with full context. This skill is research only — it does not generate implementation code.
Discovers, fetches, caches, and normalizes third-party API documentation so you can implement against it with full context. This skill is research only — it does not generate implementation code.
Invoke this skill when the task involves implementing against, integrating with, or building a client for an external API. Trigger phrases include: "build out X API", "implement X client", "integrate with X", "call the X API", or any task that requires understanding a third-party API's endpoints, types, and auth.
This skill runs first, before any implementation skill (emmaly:go, emmaly:svelte, etc.). Its output — a cached, normalized manifest — is what those skills consume.
All cached API documentation lives centrally at ~/.cache/api-explorer/, shared across projects. Never copy into a project directory unless the user explicitly requests it.
~/.cache/api-explorer/
index.json # Global index of all cached APIs
apis/{slug}/ # One directory per API (e.g., "stripe", "acme-fishing")
meta.json # API metadata, source URLs, fetch history
raw/{timestamp}/ # Raw fetched artifacts, one snapshot per fetch
README.md # What was fetched, from where, when
... # Spec files, HTML pages, proto files, etc.
manifest.json # Latest normalized manifest
manifest.{timestamp}.json # Archived previous manifests
scopes/{scope-slug}.json # Filtered manifests for specific use cases
Create the directory structure with Bash (mkdir -p) on first use. Initialize index.json as {"version": 1, "apis": {}} if it does not exist.
{
"version": 1,
"apis": {
"acme-fishing": {
"name": "Acme Fishing Shop API",
"path": "apis/acme-fishing",
"lastFetched": "2026-03-26T14:15:00Z",
"lastManifest": "2026-03-26T14:16:00Z",
"sourceUrl": "https://api.acmefishing.com/docs/openapi.json",
"formats": ["openapi3"]
}
}
}
{
"name": "Acme Fishing Shop API",
"slug": "acme-fishing",
"sources": [
{
"url": "https://api.acmefishing.com/docs/openapi.json",
"format": "openapi3",
"etag": "\"abc123\"",
"lastModified": "2026-03-20T00:00:00Z"
}
],
"fetchHistory": [
{ "timestamp": "20260326T1415Z", "result": "success", "sources": 1 }
]
}
Follow these seven phases in order.
Parse the user's request into three components:
Formulate a scope statement: what will be fetched and what will be excluded. Example:
Scope: order endpoints, fulfillment endpoints, authentication, and all shared types these reference. Excluding: catalog, inventory, reporting, analytics.
If the scope is obvious from the user's request, proceed without asking. If ambiguous, confirm with the user. For very large APIs (AWS, GCP, Azure), always require an explicit scope qualifier — never attempt to fetch the entire API.
~/.cache/api-explorer/index.json (create the directory structure if it does not exist)meta.json and check lastFetchedFind API documentation sources. Try these in order, stopping when you have a usable spec:
User-provided URL. If the user gave a doc URL or spec file path, start there.
Well-known spec paths. If you know the base URL, try fetching (use WebFetch):
/openapi.json, /openapi.yaml, /openapi/v3/swagger.json, /swagger.yaml, /v2/swagger.json/api-docs, /docs/api, /.well-known/openapi/graphql (with introspection query)/api/graphql (with introspection query)Web search. Use WebSearch for:
"{api name}" openapi OR swagger OR "api reference" OR "api documentation""{api name}" API site:github.com openapi filetype:json OR filetype:yaml"{api name}" developer docs OR "api docs"GitHub/repo search. Many APIs publish specs in public repos. Search for official SDK repos or API spec repos.
HTML doc sites. If no machine-readable spec is found, fall back to the HTML documentation site. This is the least reliable path — flag it.
Postman collections. Many APIs publish official Postman collections. Search for "{api name}" postman collection or check www.postman.com/explore. If found, curl the collection JSON directly to disk (~/.cache/api-explorer/apis/{slug}/raw/{timestamp}/postman-collection.json) then parse it locally. Postman collections contain endpoints, auth config, example requests/responses, and environment variables — rich source material.
Community-maintained spec registries. Check APIs.guru and their GitHub repo which aggregates thousands of OpenAPI specs. Also check SwaggerHub.
SDK source code. Official SDKs (Go, Python, JS/TS) are often the most accurate documentation. Clone or browse the SDK repo — type definitions, method signatures, and inline comments reveal endpoints, params, and auth requirements. Look for generated clients (openapi-generator output) which may contain the original spec.
Package registry metadata. npm info, pip show, or go doc on official SDK packages often link to API docs or source repos.
README and changelog files. Official API repos frequently document endpoints, auth, and usage examples in their README. Don't overlook these.
Wayback Machine. If a doc URL is dead or returning errors, try web.archive.org/web/{url} for archived versions.
Record all discovered sources and their format type.
Resourcefulness principle: Do everything you can to get the documentation, even if it means unconventional approaches. If a Postman collection exists, curl it directly to disk and parse the file locally. If the only spec lives inside an SDK's generated client, read those source files. If the HTML docs are behind a SPA that WebFetch can't render, check if there's a static build or an API powering the docs page. If a spec URL returns a massive file, download it to the raw cache first rather than trying to hold it in context. The goal is a complete, accurate manifest — be creative about how you get there.
YYYYMMDDTHHMMZ (UTC)apis/{slug}/raw/{timestamp}/| Format | Action |
|---|---|
| OpenAPI/Swagger (JSON/YAML) | Download the spec file directly |
| AsyncAPI | Download the spec file directly |
| GraphQL | Run introspection query, save result as schema.graphql or introspection.json |
| gRPC/protobuf | Download .proto files if available; note if only runtime reflection is possible |
| RAML / API Blueprint | Download the spec file directly |
| HTML doc site | Fetch relevant pages (scoped to user's requested area), save as HTML files |
| Postman Collection | Download JSON, convert to OpenAPI-compatible structures during normalization |
| SDK source code | Clone/download relevant type definition files and client methods |
| APIs.guru / community spec | Download the spec file — treat as OpenAPI but verify version and accuracy |
Large files: When a spec or collection is large (>1MB), always download it to disk first (
WebFetch→Writetoraw/{timestamp}/), then read and parse from disk. Never try to hold a massive spec entirely in context — read it in sections during normalization.
README.md in the snapshot directory documenting what was fetched and from whereIf-None-Match with ETag, If-Modified-Since) when previous values are available in meta.jsonmeta.json with the new fetch entry and source ETags/Last-Modified valuesindex.json with the new lastFetched timestampTransform raw documentation into a structured manifest. Extract these sections:
API metadata:
Authentication: Capture every auth mechanism the API supports. For each:
Note which mechanism applies to which endpoints (or if one applies globally). Record any notes about auth (e.g., "OAuth2 for user-context, API key for server-to-server").
Conventions (cross-cutting patterns — examine multiple endpoints to identify these):
Types: Build a flat dictionary of named types. For each type:
"type": "OrderStatus")Endpoints: For each operation:
dependsOn: list of endpoint IDs that are operational prerequisites (e.g., "createFulfillment depends on getOrder because it needs an order_id")Dependency graph:
A map of endpoint ID to its prerequisite endpoint IDs. Built from dependsOn fields but also from type analysis (if an endpoint's path parameter references an ID that only another endpoint can produce).
Save the manifest as apis/{slug}/manifest.json. If a previous manifest exists, archive it as manifest.{previous-timestamp}.json.
If the user requested a subset of the API (which is the common case):
dependsOn chainapis/{slug}/scopes/{scope-slug}.jsonBefore handing off to implementation, present a summary:
API: {name} v{version}
Base URL: {url}
Auth: {auth methods summary}
Scope: {scope name}
Endpoints: {N in scope} of {total} total
- {Group 1}: {endpoint list with methods}
- {Group 2}: {endpoint list with methods}
Key types: {list of main types that will become structs/interfaces}
Conventions: {pagination style}, {error format}, {id format}
Confidence: {high if from machine-readable spec, medium/low if from HTML}
If there are gaps or concerns, list them:
unknown in manifest"Wait for user confirmation before proceeding. Once confirmed, the scoped manifest is ready for consumption by implementation skills.
The manifest is a single JSON file. Top-level structure:
{
"manifestVersion": 2,
"generatedAt": "ISO 8601 timestamp",
"sourceSnapshot": "timestamp of raw snapshot used",
"api": {
"name": "string",
"slug": "string",
"version": "string",
"description": "string",
"baseUrls": [{"url": "string", "environment": "string"}],
"specFormat": "openapi3 | openapi2 | asyncapi | graphql | grpc | raml | blueprint | html",
"specUrl": "string"
},
"auth": {
"mechanisms": [
{
"type": "oauth2 | apiKey | bearer | mutualTls | custom",
"...": "mechanism-specific fields"
}
],
"requiredForAllEndpoints": "boolean",
"notes": "string"
},
"conventions": {
"pagination": {"style": "string", "params": {}, "responseFields": {}, "maxLimit": 0, "defaultLimit": 0},
"rateLimits": {"global": "string", "headers": {}},
"errors": {"format": "string", "structure": {}, "commonCodes": {}},
"idFormat": "string",
"timestamps": "string"
},
"types": {
"TypeName": {
"description": "string",
"fields": {"fieldName": {"type": "string", "description": "string", "required": "boolean", "example": "any"}},
"type": "enum (only if enum)",
"values": ["only if enum"]
}
},
"endpoints": [
{
"id": "string",
"method": "GET | POST | PUT | PATCH | DELETE",
"path": "string",
"summary": "string",
"tags": ["string"],
"auth": {"required": "boolean", "scopes": ["string"]},
"params": {
"path": [{"name": "string", "type": "string", "required": "boolean"}],
"query": [{"name": "string", "type": "string", "required": "boolean", "default": "any"}],
"header": [{"name": "string", "type": "string", "required": "boolean"}]
},
"requestBody": {"type": "string", "required": "boolean", "contentType": "string"},
"response": {
"success": {"status": 0, "type": "string"},
"errors": [0]
},
"dependsOn": ["endpoint IDs"]
}
],
"dependencyGraph": {
"endpointId": ["prerequisite endpoint IDs"]
}
}
Always include:
Include by dependency walk:
dependsOn chains (transitive)Exclude:
If-None-Match (ETag) and If-Modified-Since headers when refreshing, if previous values are stored in meta.json.raw/{timestamp}/ directory. Each fetch creates a new snapshot.| Format | Discovery Method | Confidence |
|---|---|---|
| OpenAPI 3.x | Well-known paths, web search, GitHub | High |
| Swagger / OpenAPI 2.0 | Well-known paths, web search, GitHub | High |
| AsyncAPI | Well-known paths, web search, GitHub | High |
| GraphQL | Introspection query at /graphql | High |
| gRPC / Protobuf | .proto file download, buf registry | High |
| RAML | Web search, GitHub | High |
| API Blueprint | Web search, GitHub | Medium |
| HTML documentation | Web scraping of doc pages | Low — flag in summary |
| Postman Collection v2.x | Postman search, web search, {api}.postman.co | Medium — covers endpoints and examples but may lack full type schemas |
When multiple formats are available, prefer machine-readable specs over HTML. Prefer OpenAPI 3.x over Swagger 2.0.
| Phase | Tools |
|---|---|
| Cache check | Read (for index.json, meta.json), Bash (mkdir -p for first-time setup) |
| Discovery | WebSearch, WebFetch (for well-known paths) |
| Fetch | WebFetch (download specs/pages), Write (save to cache) |
| Normalize | Read (raw files), Write (manifest.json) |
| Scope filter | Read (manifest.json), Write (scopes/{slug}.json) |
| Present | Direct text output to user |
Private/authenticated doc sites: If fetching returns 401 or 403, ask the user to either provide credentials, a pre-authenticated URL, or a locally downloaded copy of the spec file.
Very large APIs (AWS, GCP, Azure, etc.): These are mega-APIs with hundreds of services. Never attempt to fetch the whole thing. Always require a specific service name as part of the scope (e.g., "AWS S3" not "AWS").
HTML-only APIs: When no machine-readable spec exists, normalize from HTML. Flag the manifest with "confidence": "low" in the api section and include a note in the Phase 7 summary. Expect inaccuracies — recommend the user verify critical types and auth details.
Context window pressure: Only load the scoped manifest into context, not the full manifest. If even the scoped manifest is very large, summarize the types section and keep the full endpoints list.
Spec validation failures: If a fetched spec is malformed (invalid JSON, broken YAML, non-conformant OpenAPI), note the specific issue, try alternate sources, and if no valid source exists, fall back to HTML doc scraping.
These operations can be requested in natural language:
index.json and display all cached APIs with name, age, and scope countapis/{slug}/ directory and its entry from index.jsonscopes/*.json files for a given APInpx claudepluginhub emmaly/emmaly --plugin api-explorerGenerates API documentation from code, covering endpoints, parameters, request/response examples, authentication, error handling, and usage guidelines. Supports REST, GraphQL, and WebSocket APIs.
Generates API docs from code or OpenAPI specs with examples, schemas, interactive Swagger UI/Redoc, and exports to Markdown, PDF, Postman, SDKs.
Generates interactive API docs from OpenAPI specs with runnable examples in curl/JS/Python/Go, auth guides, error references, versioning, and deployment-ready sites.