Kerbal Depot API

Reference documentation for the KCE JSON API.

Connecting to the API

https://www.kerbaldepot.com
Authorization: Bearer YOUR_API_KEY

Contents - Endpoints Grouped by Tag

Auth

Craft

TaggedCraft

Search

Tags

PartMapper

Downloads

Modpacks

KoS Scripts

Hangars

Interactions

Utility

Contents - Entities

  • ApiSuccess
  • ApiError
  • CraftSummary
  • CraftUploadResponse
  • CraftImageUploadResponse
  • TaggedCraft
  • SavedSearch
  • DownloadRecord
  • PartMapperUpload
  • ErrorCodes

Full Markdown Reference

Source file: docs/API.md

# Kerbal Depot API

## About the API

The Kerbal Depot API is a stateless HTTP JSON API for the KCE website and KSP plugin.

It supports craft upload, image upload, PartMapper upload, tagged craft download, saved searches with 25-result batches, and download history tracking.

## Connecting to the API

### Server Endpoint

```text
https://www.kerbaldepot.com
```

All API paths are under `/api/`.

### Common Headers

```http
Accept: application/json
Authorization: Bearer YOUR_API_KEY
```

JSON requests use:

```http
Content-Type: application/json
```

File uploads use:

```http
Content-Type: multipart/form-data
```

### Security and Authentication

Most endpoints require an API key. Use `POST /api/login.php` to obtain a key.

The `Authorization: Bearer` header is preferred. `?api_key=...` is also accepted for KSP plugin clients.

### Response Envelope

Success:

```json
{ "ok": true }
```

Error:

```json
{
  "ok": false,
  "error_code": "STRING_CODE",
  "error": "Human readable message",
  "request_id": "correlation id"
}
```

## Contents - Endpoints Grouped by Tag

### Auth

* POST: [Auth.Login](#authlogin)

### Craft

* POST: [Craft.UploadCraft](#craftuploadcraft)
* GET: [Craft.DownloadCraftFile](#craftdownloadcraftfile)
* POST: [Craft.UploadCraftImage](#craftuploadcraftimage)
* GET: [Craft.GetCraftImage](#craftgetcraftimage)
* GET: [Craft.GetImageFile](#craftgetimagefile)

### TaggedCraft

* GET: [TaggedCraft.GetTaggedCrafts](#taggedcraftgettaggedcrafts)
* POST: [TaggedCraft.UntagCraft](#taggedcraftuntagcraft)

### Search

* POST: [Search.CreateSearch](#searchcreatesearch)
* GET: [Search.GetSearchBatch](#searchgetsearchbatch)

### Tags

* GET: [Tags.GetAvailableTags](#tagsgetavailabletags)

### PartMapper

* POST: [PartMapper.Upload](#partmapperupload)

### Downloads

* GET: [Downloads.GetMyDownloads](#downloadsgetmydownloads)

### Utility

* GET: [Utility.GetErrors](#utilitygeterrors)

## Contents - Entities

* [ApiSuccess](#apisuccess)
* [ApiError](#apierror)
* [CraftSummary](#craftsummary)
* [CraftUploadResponse](#craftuploadresponse)
* [CraftImageUploadResponse](#craftimageuploadresponse)
* [TaggedCraft](#taggedcraft)
* [SavedSearch](#savedsearch)
* [DownloadRecord](#downloadrecord)
* [PartMapperUpload](#partmapperupload-entity)
* [ErrorCodes](#errorcodes)

# Endpoints

## Auth.Login

```http
POST /api/login.php
```

Authenticates a user and returns an API key.

Request:

```json
{
  "username": "user@example.com",
  "password": "secret"
}
```

Response:

```json
{
  "ok": true,
  "api_key": "kce_xxxxxxxxx",
  "user": {
    "id": 1,
    "username": "linuxgurugamer"
  }
}
```

## Craft.UploadCraft

```http
POST /api/craft_upload.php
Authorization: Bearer API_KEY
Content-Type: multipart/form-data
```

Form data:

| Field | Required | Description |
|---|---:|---|
| `craft_file` | yes | KSP `.craft` file |
| `image_file` | no | Optional image |
| `image_files[]` | no | Optional multiple images |
| `title` | no | Title override |
| `description` | no | Description |
| `building` | no | `VAB`, `SPH`, or `UNKNOWN` |
| `license` | no | License |
| `tags` | no | Comma-separated tags |
| `override` | no | `1` to replace existing craft with same filename |
| `overwrite` | no | Alias for `override` |

Response:

```json
{
  "ok": true,
  "message": "Craft uploaded.",
  "overwritten": false,
  "uploaded_images": 1,
  "craft": {
    "id": 15,
    "title": "Kerbal X+",
    "slug": "kerbal-x"
  }
}
```

Duplicate response:

```json
{
  "ok": false,
  "error_code": "CRAFT_ALREADY_EXISTS",
  "error": "A craft with this filename already exists. Retry with override=1 to replace it.",
  "override_field": "override"
}
```

## Craft.DownloadCraftFile

```http
GET /api/craft_file.php?id=CRAFT_ID
Authorization: Bearer API_KEY
```

Downloads a `.craft` file and records the download in `craft_downloads`.

## Craft.UploadCraftImage

```http
POST /api/craft_image_upload.php
Authorization: Bearer API_KEY
Content-Type: multipart/form-data
```

Form data:

| Field | Required | Description |
|---|---:|---|
| `craft_id` or `id` | yes | Existing craft ID |
| `image_file` | yes* | Single image |
| `image` | yes* | Alias for `image_file` |
| `image_files[]` | yes* | Multiple images |
| `replace` | no | `1` deletes existing images first |
| `replace_existing` | no | Alias for `replace` |
| `primary` | no | `1` makes first uploaded image primary |

At least one image field is required. Supported image types are PNG, JPG, JPEG, and WEBP.

## Craft.GetCraftImage

```http
GET /api/craft_image.php?id=CRAFT_ID
```

Returns the primary image for a craft.

## Craft.GetImageFile

```http
GET /api/image_file.php?file=FILENAME
```

Returns a stored image file.

## TaggedCraft.GetTaggedCrafts

```http
GET /api/tagged_crafts.php
Authorization: Bearer API_KEY
```

Response:

```json
{
  "ok": true,
  "count": 2,
  "crafts": [
    {
      "id": 15,
      "title": "Kerbal X+",
      "slug": "kerbal-x",
      "building": "VAB",
      "original_filename": "Kerbal X+.craft",
      "part_count": 60,
      "ksp_version": "1.12.5",
      "has_image": true,
      "download_url": "https://www.kerbaldepot.com/api/craft_file.php?id=15",
      "image_url": "https://www.kerbaldepot.com/api/craft_image.php?id=15",
      "thumbnail_url": "https://www.kerbaldepot.com/api/craft_image.php?id=15&thumb=1"
    }
  ]
}
```

## TaggedCraft.UntagCraft

```http
POST /api/untag_craft.php
Authorization: Bearer API_KEY
```

Also accepts:

```http
GET /api/untag_craft.php?id=CRAFT_ID
```

## Search.CreateSearch

```http
POST /api/search.php
Authorization: Bearer API_KEY
Content-Type: application/json
```

Also accepts `GET /api/search.php`.

Request:

```json
{
  "q": "lander",
  "building": "VAB",
  "tags": ["lander", "stock"],
  "has_image": true,
  "sort": "downloads",
  "sort_dir": "desc"
}
```

Searches are saved for 6 hours. Results return in batches of 25.

Response:

```json
{
  "ok": true,
  "message": "Search created.",
  "search_token": "64-char-token",
  "offset": 0,
  "batch_size": 25,
  "count": 25,
  "total": 73,
  "has_more": true,
  "next_offset": 25,
  "next_url": "https://www.kerbaldepot.com/api/search_batch.php?search_token=TOKEN&offset=25",
  "expires_at": "2026-06-13 18:00:00",
  "crafts": []
}
```

Sort values:

Optional `sort_dir` values: `asc` or `desc`. Clicking the same sort field in the CraftOrganizer search window reverses this value.


* `date_uploaded`
* `updated`
* `downloads`
* `views`
* `popularity`
* `mod_count`
* `part_count`
* `mass`
* `cost`
* `crew_capacity`
* `name`

## Search.GetSearchBatch

```http
GET /api/search_batch.php?search_token=TOKEN&offset=25
Authorization: Bearer API_KEY
```

Returns the next saved-search batch.

## Tags.GetAvailableTags

```http
GET /api/tags.php
Authorization: Bearer API_KEY
```

Returns the available search/upload tags.

Response:

```json
{
  "ok": true,
  "tags": [
    {
      "id": 1,
      "slug": "lander",
      "label": "Lander",
      "tag_group": "role",
      "sort_order": 10
    }
  ]
}
```

## PartMapper.Upload

```http
POST /api/partmapper_upload.php
Authorization: Bearer API_KEY
Content-Type: application/json
```

Request:

```json
{
  "game_directory": "D:/Games/KSP",
  "ksp_version": "1.12.5",
  "platform": "Windows",
  "mapper_version": "1.0.0",
  "mods": [],
  "parts": [],
  "modules": [],
  "localization": []
}
```

Do not send the old `"KSP Runtime"` source string.

## Downloads.GetMyDownloads

```http
GET /api/downloads.php
Authorization: Bearer API_KEY
```

Returns craft downloaded by the authenticated user.

## Utility.GetErrors

```http
GET /api/errors.php
```

Returns API schema and common error codes.

# Entities

## ApiSuccess

```json
{ "ok": true }
```

## ApiError

```json
{
  "ok": false,
  "error_code": "STRING_CODE",
  "error": "Human readable message",
  "request_id": "correlation id"
}
```

## CraftSummary

```json
{
  "id": 15,
  "title": "Kerbal X+",
  "slug": "kerbal-x",
  "building": "VAB",
  "original_filename": "Kerbal X+.craft",
  "ksp_version": "1.12.5",
  "part_count": 60,
  "downloads": 20,
  "views": 100,
  "has_image": true,
  "detail_url": "https://www.kerbaldepot.com/craft.php?slug=kerbal-x",
  "download_url": "https://www.kerbaldepot.com/api/craft_file.php?id=15",
  "image_url": "https://www.kerbaldepot.com/api/craft_image.php?id=15",
  "thumbnail_url": "https://www.kerbaldepot.com/api/craft_image.php?id=15&thumb=1"
}
```

## CraftUploadResponse

```json
{
  "ok": true,
  "message": "Craft uploaded.",
  "overwritten": false,
  "uploaded_images": 1,
  "craft": {}
}
```

## CraftImageUploadResponse

```json
{
  "ok": true,
  "message": "Image uploaded.",
  "craft_id": 15,
  "uploaded_images": 1,
  "replace": false,
  "primary": true,
  "images": []
}
```

## TaggedCraft

See `TaggedCraft.GetTaggedCrafts`.

## SavedSearch

See `Search.CreateSearch`.

## DownloadRecord

```json
{
  "id": 1,
  "craft_id": 15,
  "title": "Kerbal X+",
  "slug": "kerbal-x",
  "building": "VAB",
  "original_filename": "Kerbal X+.craft",
  "source": "api",
  "downloaded_at": "2026-06-13 12:00:00",
  "detail_url": "https://www.kerbaldepot.com/craft.php?slug=kerbal-x"
}
```

## PartMapperUpload Entity

See `PartMapper.Upload`.

## ErrorCodes

Authentication:

* `INVALID_CREDENTIALS`
* `ACCOUNT_DISABLED`
* `EMAIL_NOT_VERIFIED`
* `API_KEY_MISSING`
* `API_KEY_INVALID`
* `ACCESS_DENIED`

Craft:

* `CRAFT_NOT_FOUND`
* `CRAFT_FILE_NOT_FOUND`
* `CRAFT_ALREADY_EXISTS`
* `CRAFT_UPLOAD_FAILED`

Image:

* `IMAGE_MISSING`
* `IMAGE_UPLOAD_ERROR`
* `IMAGE_TYPE_INVALID`
* `IMAGE_SAVE_FAILED`

Search:

* `SEARCH_FAILED`
* `SEARCH_NOT_FOUND`
* `SEARCH_EXPIRED`
* `SEARCH_TOKEN_MISSING`
* `SEARCH_BATCH_FAILED`

# cURL Examples

## Login

```bash
curl -s https://www.kerbaldepot.com/api/login.php \
  -H 'Content-Type: application/json' \
  -d '{"username":"user@example.com","password":"secret"}'
```

## Upload Craft

```bash
curl -s https://www.kerbaldepot.com/api/craft_upload.php \
  -H "Authorization: Bearer $KCE_API_KEY" \
  -F "craft_file=@Mun Lander.craft" \
  -F "image_file=@screenshot.png" \
  -F "building=VAB"
```

## Start Search

```bash
curl -s https://www.kerbaldepot.com/api/search.php \
  -H "Authorization: Bearer $KCE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"q":"lander","building":"VAB","sort":"downloads"}'
```


## Modpacks.List

```http
GET /api/modpacks.php?user=USERNAME&mod=CKAN_IDENTIFIER&q=TEXT
Authorization: Bearer API_KEY
```

Returns CKAN modpacks. Search filters include uploading user, contained mod identifier, and text.

## Modpacks.Upload

```http
POST /api/modpack_upload.php
Authorization: Bearer API_KEY
Content-Type: multipart/form-data
```

Form fields: `name`, `description`, `modpack_file`.

## Modpacks.Download

```http
GET /api/modpack_download.php?id=ID
Authorization: Bearer API_KEY
```

Downloads the CKAN modpack file.

## Modpacks.Delete

```http
POST /api/modpack_delete.php
Authorization: Bearer API_KEY
```

Form fields: `id`. Deletes a modpack owned by the API user, or any modpack if the API user is an admin.

## KosScripts.List

```http
GET /api/kos_scripts.php?q=TEXT&mod=MOD_IDENTIFIER
Authorization: Bearer API_KEY
```

Lists uploaded KoS scripts. Search filters include text and required mod identifier.

## KosScripts.Upload

```http
POST /api/kos_upload.php
Authorization: Bearer API_KEY
Content-Type: multipart/form-data
```

Form fields: `name`, `description`, `source_location` (`archive` or `save`), `mods`/`required_mods` (comma-separated or repeated mod identifiers), and `kos_file`.

## KosScripts.Download

```http
GET /api/kos_download.php?id=ID
Authorization: Bearer API_KEY
```

Downloads the KoS script file.

## KosScripts.Delete

```http
POST /api/kos_delete.php
Authorization: Bearer API_KEY
```

Form fields: `id`. Deletes a KoS script owned by the API user, or any KoS script if the API user is an admin.

## Hangars.List

```http
GET /api/hangars.php?title=TITLE&description=TEXT&owner=USERNAME
Authorization: Bearer API_KEY
```

Lists public hangars and private hangars owned by the API user.

## Hangars.GetCrafts

```http
GET /api/hangar_crafts.php?id=ID
Authorization: Bearer API_KEY
```

Returns the selected hangar and all craft in it. Each craft includes `download_url` for `/api/craft_file.php`.

## Content.Vote

```http
POST /api/vote.php
Authorization: Bearer API_KEY
```

Form or JSON fields: `type` (`craft`, `modpack`, `kos_script`), `id`, and `vote` (`1`, `-1`, or `0` to clear).

## Content.Comments

```http
GET /api/comments.php?type=craft&id=ID
POST /api/comments.php
Authorization: Bearer API_KEY
```

POST fields: `type`, `id`, `body`, and optional `parent_id` to reply to a comment.