REST API reference

Base URL: https://skilldrunk.com/api/v1

Authentication

Send your API key in the Authorization header:

Authorization: Bearer sd_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Create 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 — 404
  • bad_request — validation failed (400)
  • rate_limited — 429; check Retry-After
  • internal_error — 500

Endpoints

GET /skills

List / search skills.

Query parameters:

  • q — full-text search query
  • type — one of claude_skill, gpt, mcp_server, cursor_rule, prompt, agent
  • tag — filter by tag (repeatable; AND semantics)
  • sorttrending (default) | new | top
  • limit — 1–100 (default 20)
  • cursor — opaque cursor from a previous response's meta.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.