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
-
POST
Auth.Login
/api/login.php
Craft
-
POST
Craft.UploadCraft
/api/craft_upload.php -
GET
Craft.DownloadCraftFile
/api/craft_file.php?id={id} -
POST
Craft.UploadCraftImage
/api/craft_image_upload.php -
GET
Craft.GetCraftImage
/api/craft_image.php?id={id} -
GET
Craft.GetImageFile
/api/image_file.php?file={filename}
TaggedCraft
-
GET
TaggedCraft.GetTaggedCrafts
/api/tagged_crafts.php -
POST
TaggedCraft.UntagCraft
/api/untag_craft.php
Search
-
POST
Search.CreateSearch
/api/search.php -
GET
Search.GetSearchBatch
/api/search_batch.php
Tags
-
GET
Tags.GetAvailableTags
/api/tags.php
PartMapper
-
POST
PartMapper.Upload
/api/partmapper_upload.php
Downloads
-
GET
Downloads.GetMyDownloads
/api/downloads.php
Modpacks
-
GET
Modpacks.List
/api/modpacks.php -
POST
Modpacks.Upload
/api/modpack_upload.php -
GET
Modpacks.Download
/api/modpack_download.php?id={id} -
POST
Modpacks.Delete
/api/modpack_delete.php
KoS Scripts
-
GET
KosScripts.List
/api/kos_scripts.php -
POST
KosScripts.Upload
/api/kos_upload.php -
GET
KosScripts.Download
/api/kos_download.php?id={id} -
POST
KosScripts.Delete
/api/kos_delete.php
Hangars
-
GET
Hangars.List
/api/hangars.php -
GET
Hangars.GetCrafts
/api/hangar_crafts.php?id={id}
Interactions
-
POST
Content.Vote
/api/vote.php -
GET
Content.Comments
/api/comments.php?type={type}&id={id} -
POST
Content.AddComment
/api/comments.php
Utility
-
GET
Utility.GetErrors
/api/errors.php
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.