REST API reference
Base URL: https://skilldrunk.com/api/v1
Authentication
Send your API key in the Authorization header:
Authorization: Bearer sd_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxCreate a key at /settings/api-keys. Read endpoints work without a key but at a lower rate limit. Write endpoints (vote, comment) require a key with the write scope.
Response envelope
Success responses:
{ "data": <payload>, "meta": { ... } }Errors:
{ "error": { "code": "not_found", "message": "The requested skill was not found." } }Error codes you'll see in the wild:
unauthorized— missing or invalid API key (401)forbidden— key lacks the required scope (403)not_found— 404bad_request— validation failed (400)rate_limited— 429; checkRetry-Afterinternal_error— 500
Endpoints
GET /skills
List / search skills.
Query parameters:
q— full-text search querytype— one ofclaude_skill,gpt,mcp_server,cursor_rule,prompt,agenttag— filter by tag (repeatable; AND semantics)sort—trending(default) |new|toplimit— 1–100 (default 20)cursor— opaque cursor from a previous response'smeta.next_cursor
curl "https://skilldrunk.com/api/v1/skills?q=pdf&type=claude_skill&limit=5"GET /skills/:slug
Fetch a single skill with its full markdown body.
curl "https://skilldrunk.com/api/v1/skills/pdf-skill"GET /skills/:slug/comments
List the discussion thread (up to 200 comments).
POST /skills/:slug/vote
Cast or clear a vote. Requires write scope.
curl -X POST "https://skilldrunk.com/api/v1/skills/pdf-skill/vote" \
-H "Authorization: Bearer $SKILLDRUNK_KEY" \
-H "Content-Type: application/json" \
-d '{"value": 1}'Body: { "value": 1 | -1 | 0 } — 0 clears any existing vote.
POST /skills/:slug/comments
Post a comment (or a threaded reply). Requires write scope.
curl -X POST "https://skilldrunk.com/api/v1/skills/pdf-skill/comments" \
-H "Authorization: Bearer $SKILLDRUNK_KEY" \
-H "Content-Type: application/json" \
-d '{"body_md": "This saved me 3 hours. Thanks!"}'Include parent_id (UUID of another comment) to reply in a thread.
GET /me
Return the profile + scopes for the authenticated API key. Handy for verifying a key is valid.
Language examples
JavaScript / TypeScript
const res = await fetch("https://skilldrunk.com/api/v1/skills?q=pdf", {
headers: { Authorization: `Bearer ${process.env.SKILLDRUNK_KEY}` },
});
const { data } = await res.json();
console.log(data.length, "skills matched");Python
import os, requests
r = requests.get(
"https://skilldrunk.com/api/v1/skills",
params={"q": "pdf", "type": "claude_skill"},
headers={"Authorization": f"Bearer {os.environ['SKILLDRUNK_KEY']}"}
)
r.raise_for_status()
print(r.json()["data"])Versioning
We're on v1. Breaking changes will ship as v2, and v1 will be supported for at least 12 months after v2 stabilises. Additive changes (new fields, new endpoints) can land in v1 at any time.