API
The API returns JSON. Reading is open to everyone. Changing content needs an API key.
A machine-readable description is available at /openapi/v1.json.
Reading
Only items that are active, published and public are returned.
| Method | Address | Returns |
|---|---|---|
| GET | /api/projects |
All projects |
| GET | /api/projects/{slug} |
One project |
| GET | /api/projects/{slug}/releases |
Every uploaded file, newest first |
| GET | /api/projects/{slug}/releases/latest |
The newest uploaded file |
| GET | /api/products |
All products |
| GET | /api/products/{slug} |
One product |
| GET | /api/posts |
All posts, newest first |
| GET | /api/posts/{slug} |
One post |
The slug is the short name in the address, for example my-app.
curl https://example.com/api/projects/my-app/releases/latest
{
"releaseID": 3,
"version": "1.2.0",
"fileName": "MyApp-1.2.0.exe",
"fileSize": 7829504,
"sha256": "9f2c...",
"platform": "WINDOWS",
"architecture": "amd64",
"notes": "",
"downloadCount": 12,
"uploadedOn": "2026-10-25T17:40:00Z",
"downloadUrl": "/files/3/MyApp-1.2.0.exe"
}
Downloading
| Address | What happens |
|---|---|
/download/{slug}/latest |
Redirects to the newest file |
/download/{slug}/{version} |
Redirects to that version |
/download/{slug}/latest?platform=WINDOWS |
Newest file for one platform |
/files/{id}/{fileName} |
The file itself. Resumable downloads are supported |
Use the /download/... links on web pages and in scripts. They keep working when a new version is uploaded.
Changing content
Send your key in the X-Api-Key header. The key is the Api:Key setting. If it is not set, or shorter than 16 characters, every change is refused.
| Method | Address | Does |
|---|---|---|
| POST | /api/projects |
Add a project (JSON body) |
| PUT | /api/projects/{slug} |
Replace a project's fields (JSON body) |
| DELETE | /api/projects/{slug} |
Delete a project and its files |
| POST | /api/projects/{slug}/releases |
Upload a file (form data, see below) |
| DELETE | /api/releases/{id} |
Delete one uploaded file |
| POST | /api/products |
Add a product (JSON body) |
| PUT | /api/products/{slug} |
Replace a product's fields |
| DELETE | /api/products/{slug} |
Delete a product |
| POST | /api/posts |
Add a post (JSON body) |
| PUT | /api/posts/{slug} |
Replace a post's fields |
| DELETE | /api/posts/{slug} |
Delete a post |
The JSON body uses the same field names as the data classes (name, summary, description, ...). Leave slug empty and it is made from the name or title. description and content are Markdown.
curl -X POST https://example.com/api/posts \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"title": "Hello", "content": "My **first** post."}'
Uploading a release
Send a form with the file in a field called file:
| Field | Required | Example |
|---|---|---|
file |
yes | the .exe, .zip or installer |
version |
yes | 1.2.0 (letters, numbers and . _ + - only) |
platform |
no | WINDOWS, LINUX, MAC |
architecture |
no | amd64, arm64 |
notes |
no | short release notes |
curl -X POST https://example.com/api/projects/my-app/releases \
-H "X-Api-Key: YOUR_API_KEY" \
-F file=@MyApp-1.2.0.exe -F version=1.2.0 -F platform=WINDOWS -F architecture=amd64
The checksum is calculated by the server. Uploading also sets the project's version.
Status codes
| Code | Meaning |
|---|---|
| 200 / 201 / 204 | Done |
| 400 | Something in the request is wrong, such as a bad version |
| 401 | Missing or wrong API key |
| 404 | No such project, product, post or file |