Endpoint reference

Every v1 REST route, grouped by resource. All paths are relative to https://www.skillzdrive.com.

Skills

Search and discover skills from the public marketplace or the caller's scoped catalog.

GET/api/v1/skillsAnonymous ✓

List or search skills. With ?q=, full-text searches name/description/slug. Without, lists everything accessible to the caller.

Query params:

  • q — search query (required for anonymous).
  • limit — max results (default 20, cap 50).
  • collection — filter to a named collection (auth-only).
bash
curl "https://www.skillzdrive.com/api/v1/skills?q=pdf&limit=5" \
     -H "X-Skillzdrive-Install-Id: $(uuidgen)"
GET/api/v1/skills/:slugAnonymous ✓

One skill by slug. Response includes download with the latest content-addressed artifact URL when the skill has one (populated after publish + backfill).

Sample response
{
  "data": {
    "skill": {
      "id": "...",
      "slug": "pdf",
      "name": "PDF tools",
      "description": "...",
      "tags": ["document", "pdf"],
      "version": 3,
      "github_url": null,
      "category": "public"
    },
    "download": {
      "content_sha": "abc123...",
      "content_size": 45213,
      "version": 3,
      "url": "/api/v1/downloads/public/pdf/abc123....zip"
    }
  }
}
GET/api/v1/skills/discoverAuth required

Broad discovery across marketplace + cached GitHub sources. Paginated (10 results per page).

  • keywords — required.
  • offset — for pagination.
GET/api/v1/skills/leaderboardAuth required

Top public skills.

  • sort_byexecutions (default), installs, or rating.

Drive

Manage the authenticated user's hosted drive — the set of skills available to their API keys.

GET/api/v1/driveAuth required

Lists all accessible skills (drive ∪ team ∪ shared, filtered by the key's allowed_skill_ids).

POST/api/v1/drive/importAuth required

Import a marketplace skill or GitHub URL into the drive.

Body
{ "skillSlug": "pdf" }

Accepts either a marketplace slug or a GitHub URL (https://github.com/owner/repo/tree/main/subpath).

DELETE/api/v1/drive/:slugAuth required

Remove a skill from the drive.

POST/api/v1/drive/:slug/toggleAuth required

Flip the enabled state without removing.

GET/api/v1/drive/updatesAuth required

List pending version updates for skills in the drive.

POST/api/v1/drive/updates/:slug/acceptAuth required

Accept an update — may charge credits per existing pricing rules.

POST/api/v1/drive/updates/:slug/dismissAuth required

Dismiss a pending update; no charge.

POST/api/v1/drive/sync/previewAuth required

Dry-run classification for a skillzdrive sync invocation. Tells the caller, per-skill, what action would happen and how much it would cost. Mutates no state.

POST/api/v1/drive/sync/executeAuth required

Server-side commit step. Re-validates classifications, executes claim_public atomically, returns deferred upload/download instructions for the CLI. Opens a row in cli_sync_runs.

Body
{
  "install_id": "uuid-from-cli",
  "kind": "first_run" | "daily" | "manual",
  "mode": "all" | "public_only" | "pulls_only" | "as_many_as_credits_allow",
  "classifications": [/* from sync/preview */]
}
Response
{
  "data": {
    "run_id": "uuid",
    "results": [
      { "slug": "...", "action": "claim_public", "status": "committed", "canonical_skill_id": "..." },
      { "slug": "...", "action": "upload_private", "status": "pending_upload", "credits_required": 5 },
      { "slug": "...", "action": "download_install", "status": "pending_download", "download_url": "...", "download_content_sha": "...", "download_version": 3 }
    ]
  }
}
POST/api/v1/drive/sync/finalizeAuth required

Closes the audit row. Sets users.drive_grandfather_high_water on first run. Returns post-sync drive count + watermark.

Body
{
  "run_id": "uuid",
  "item_results": [{ "slug": "...", "status": "committed", "credits_charged": 3 }],
  "counters": { "public_claimed": 9, "private_uploaded": 2, "credits_charged": 6 /* ... */ }
}
POST/api/v1/drive/diffAuth required

Lightweight three-way diff between local lockfile state and the hosted drive. Drives the once-daily sync-divergence prompt.

Body
{
  "local": [{ "slug": "pdf-fill", "content_sha": "abc..." }]
}
Response
{
  "data": {
    "local_only": [...],
    "drive_only": [...],
    "divergent": [{ "slug": "...", "local_content_sha": "...", "drive_content_sha": "..." }]
  }
}
Body
{
  "local": [
    { "slug": "pdf-fill", "content_sha": "abc123…", "size_bytes": 12340, "source": "skillzdrive:pdf-fill" }
  ],
  "hosted_known": [
    { "slug": "old-skill", "content_sha": "def456…" }
  ]
}
Response
{
  "data": {
    "classifications": [
      { "slug": "pdf-fill", "direction": "push", "action": "claim_public", "credits_required": 0, "canonical_skill_id": "…", "reason": "Public marketplace skill — free to claim." }
    ],
    "summary": {
      "pushes": { "free_claims": 9, "paid_uploads": 2, "total_credits": 6 },
      "pulls":  { "installs": 1, "updates": 1 },
      "balance": 25, "balance_after": 19, "balance_sufficient": true,
      "free_tier_overage": { "current_max": 10, "after_sync": 12, "would_grandfather": true }
    }
  }
}

Collections

A collection is a named API key that scopes access to a subset of the owner's drive. Partners use this pattern to give each of their users a private slice of a master account.

GET/api/v1/collectionsAuth required

List the owner's collections. Restricted: only usable with an all-skills key.

POST/api/v1/collectionsAuth required

Create a collection. Omit skillSlugs for an all-skills key. Response returns the generated sk_live_* key exactly once.

Body
{
  "name": "acme-user-42",
  "skillSlugs": ["pdf", "docx-to-pdf"],
  "includeTeamSkills": true,
  "includeSharedSkills": true
}
PATCH/api/v1/collections/:nameAuth required

Rename or reconfigure. Pass only the fields you want to change.

Body
{
  "newName": "acme-user-42-renamed",
  "skillSlugs": ["pdf"],
  "isPublicMarketplace": true
}

Tip

Setting isPublicMarketplace: true exposes the collection at /marketplace/collections/:name.json — see the Marketplace section.
POST/api/v1/collections/:name/skillsAuth required

Add a skill to the collection.

Body
{ "skillSlug": "pdf" }
DELETE/api/v1/collections/:name/skills/:slugAuth required

Remove a skill from the collection.

DELETE/api/v1/collections/:nameAuth required

Delete the collection itself and revoke its API key. Irreversible. Restricted: only usable with an all-skills key — scoped keys cannot delete collections, including their own.

Uploads

POST/api/v1/uploads/ticketAuth required

Mint a short-lived (10-minute, single-use) upload token. Response includes the token itself plus an inline bash script for local upload flows.

Body (all optional)
{
  "collectionName": "acme-user-42",
  "filename": "my-skill.zip"
}

To upload, POST multipart/form-data with file=@path/to/skill.zip and Authorization: Bearer <ticket> to /api/uploads/process-skill.

POST/api/v1/uploads/urlAuth required

Returns the canonical upload URL for browser-based flows.

Downloads

POST/api/v1/downloadsAuth required

Dynamically package skills into a zip and return a 24-hour signed URL. Use for drive-wide or collection-wide exports, or one-off bundling of a skill the caller doesn't have in their drive.

Body
{
  "scope": "drive" | "collection" | "skill",
  "collectionName": "acme-user-42",
  "skillSlug": "pdf"
}
GET/api/v1/downloads/public/:slug/:sha.zipAnonymous ✓

Content-addressed, immutable. Redirects (302) to a signed Supabase Storage URL for the exact zip bytes matching :sha. Cache forever — these URLs never change.

bash
curl -L "https://www.skillzdrive.com/api/v1/downloads/public/pdf/abc123...zip" \
     -o pdf.zip

Runs

POST/api/v1/runsAuth required

Execute a skill script in the hosted E2B sandbox. Blocking response — returns when the script finishes. Consumes credits per the skill's credit_cost_per_use.

Body
{
  "skillSlug": "pdf",
  "scriptName": "extract.sh",
  "args": ["input.pdf"],
  "stdin": "",
  "sessionId": null,
  "reuseSession": false
}
Response
{
  "data": {
    "stdout": "...",
    "stderr": "",
    "exit_code": 0,
    "sessionId": "...",
    "duration_ms": 1420
  }
}

Account

GET/api/v1/account/creditsAuth required

Current credit balance, tier, monthly skill-call usage + limit, and the 10 most recent transactions. Returns monthly_skill_call_limit: "unlimited" for admin/moderator roles.

GET/api/v1/account/webhooksAuth required

List configured webhook subscriptions — see the dedicated Webhooks page.

POST/api/v1/account/webhooksAuth required
DELETE/api/v1/account/webhooks/:idAuth required

Marketplace

Public .claude-plugin/marketplace.json-compatible manifests. Consumable by Anthropic Claude Code (/plugin marketplace add <url>) and GitHub Copilot CLI (copilot plugin marketplace add <url>).

GET/marketplace.jsonAnonymous ✓

The global public catalog. Every public+approved skill with a downloadable source (artifact or GitHub). Cached 5 minutes.

One-line Claude Code install
# Then in Claude Code:
/plugin marketplace add https://www.skillzdrive.com/marketplace.json
GET/marketplace/collections/:name.jsonAnonymous ✓

Curated per-collection manifest. Returns 404 unless the collection was published with isPublicMarketplace: true (see PATCH Collections).

Telemetry + Migration

POST/api/v1/telemetry/anonymousAnonymous ✓

Record a CLI command event. Mandatory per product terms — no opt-out — but the payload is entirely anonymized until a user logs in and claims their install_id.

Body
{
  "install_id": "uuid-v4",
  "event_type": "install" | "sync" | "update" | "audit" | "scan" | "init_defaults" | "login",
  "cli_version": "0.1.0",
  "os": "darwin/arm64",
  "skill_slugs": ["pdf", "docx"],
  "source_types": ["skillzdrive"],
  "metadata": { "installed": 2, "failed": 0 }
}
POST/api/v1/migrations/anonymous-adoptAuth required

Claim an anonymous install_id for the authenticated user on first login. Backfills any prior anonymous telemetry under that install_id to the user's account. Idempotent. Returns 409 if another account has already claimed that install_id.

Body
{ "install_id": "uuid-v4" }

Under the hood

Every endpoint except the anonymous read/download/marketplace paths forwards internally to a single MCP server. That means permission, quota, collection filtering, and usage-logging semantics are bit-identical to the MCP protocol — a REST call and an equivalent MCPtools/call do the same thing.