# REST API

> Markdown variant of <https://www.skillzdrive.com/docs/rest-api>.

HTTP + JSON access to the SkillzDrive catalog, drives, collections,
uploads, and executions. Use from any language that can speak HTTP —
no MCP client required.

If you're building an *agent* that calls skills, use
[the MCP interface](https://www.skillzdrive.com/docs/agent-integration.md)
instead — it's purpose-built for that. The REST API is for web apps,
mobile backends, CI pipelines, internal tools, and any 3rd-party
product that wants to manage SkillzDrive accounts programmatically.

## Base URL

```
https://www.skillzdrive.com/api/v1
```

Every endpoint is prefixed by this base URL. Responses are JSON.
Errors follow a consistent envelope (see below).

## Authentication

Most endpoints require a SkillzDrive API key. Pass it as a Bearer
token:

```
Authorization: Bearer sk_live_<your-key>
```

Create keys at <https://www.skillzdrive.com/dashboard/get-setup>.
Keys come in two flavors:

| Key type | Scope | Use when |
|----------|-------|----------|
| All-skills | Full drive + team + shared | Account owner; admin tools |
| Scoped collection | Subset named by `allowed_skill_ids` | Per-end-user keys; sub-account-style partner integrations |

### Anonymous access

A few public read endpoints work without any key — handy for
discovery-only clients. Anonymous requests are rate-limited to **1
request per minute per IP** and should include an install-id header
for soft identity:

```
X-Skillzdrive-Install-Id: <a-uuid-you-generate-once>
```

Anonymous-capable endpoints are marked `Anonymous: ✓` in the
[endpoint reference](https://www.skillzdrive.com/docs/rest-api/endpoints.md).

## Response shape

Successful responses carry a `data` key. Errors carry an `error`
object with a stable machine code and a human-readable message.

### Success

```json
{
  "data": {
    "collections": [
      { "name": "default", "scope": "all_skills", "skillCount": "all" },
      { "name": "acme-team", "scope": "scoped", "skillCount": 12 }
    ],
    "count": 2
  }
}
```

### Error

```json
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Anonymous rate limit hit (1/min). Sign up free for unlimited access.",
    "retry_after_seconds": 53,
    "upgrade_url": "https://www.skillzdrive.com/signup?ref=cli-rate-limit"
  }
}
```

## HTTP status codes

| Status | Meaning | Typical error codes |
|--------|---------|---------------------|
| 200/201 | Success | — |
| 302 | Redirect to signed download URL | — |
| 400 | Bad request body | `invalid_json` |
| 401 | Auth required or invalid key | `auth_required`, `invalid_api_key`, `api_key_expired` |
| 403 | Forbidden (scope / quota / account) | `forbidden`, `scope_forbidden`, `account_inactive` |
| 404 | Not found | `not_found`, `method_not_found` |
| 409 | Conflict | `conflict`, `install_id_conflict` |
| 422 | Validation failed | `missing_required`, `invalid_params`, `invalid_sort_by` |
| 429 | Rate limit or quota hit | `rate_limit_exceeded`, `quota_exceeded`, `call_limit_reached` |
| 500 | Server error | `internal_error`, `render_failed` |
| 502 | MCP backend unreachable | `mcp_unreachable` |

## Your first call

Search the public catalog anonymously — zero signup required:

```bash
curl -H "X-Skillzdrive-Install-Id: $(uuidgen)" \
     "https://www.skillzdrive.com/api/v1/skills?q=weather"
```

```js
const res = await fetch(
  "https://www.skillzdrive.com/api/v1/skills?q=weather",
  { headers: { "X-Skillzdrive-Install-Id": crypto.randomUUID() } },
);
const { data } = await res.json();
console.log(data.skills);
```

```python
import requests, uuid
res = requests.get(
    "https://www.skillzdrive.com/api/v1/skills",
    params={"q": "weather"},
    headers={"X-Skillzdrive-Install-Id": str(uuid.uuid4())},
)
print(res.json()["data"]["skills"])
```

List the collections on your account (authenticated):

```bash
curl -H "Authorization: Bearer sk_live_..." \
     "https://www.skillzdrive.com/api/v1/collections"
```

## Architectural note

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
MCP `tools/call` do the same thing.

## Keep reading

- [Endpoint reference](https://www.skillzdrive.com/docs/rest-api/endpoints.md): every route, grouped by resource.
- [Webhooks](https://www.skillzdrive.com/docs/rest-api/webhooks.md): credit-alert webhook subscriptions, HMAC verification.
- [CLI](https://www.skillzdrive.com/docs/cli.md): thin client over this API.
