Skip to content

API Documentation

A REST API to drive your account. 37 endpoints across 3 categories.

Manage API keys

Public beta

The API is open in beta. Build, experiment and have fun with it, but use it with care: endpoints and responses may still change, and every call acts on your real deployments.

Authentication

Every request needs an API key. Pass it as a Bearer token. Create and manage keys from your developer settings.

curl -H "Authorization: Bearer bhk_your_key" \
  https://bot-hosting.net/api/v1/deployments

Scopes

A key is limited to the scopes you grant it. A request is allowed only if the key holds the endpoint's scope and you have permission on the target resource.

Deployments

deployments:read List and inspect deployments
deployments:power Start, stop, restart, console
deployments:write Create, edit, delete, resize, move
projects:read List your projects
files:read Browse and download files
files:write Upload, edit, rename, delete files
env:read Read env vars (secrets stay masked)
env:write Set env vars
backups:read List backups
backups:write Create and delete backups
packages:read View installed packages
packages:write Add and remove packages

Account

account:read Read profile and quota
billing:read Read invoices and plan
credits:spend Spend credits to create resources

Templates

templates:read Browse anyone's public templates

Rate limits

Requests are capped at 120 per minute per key (a sliding 60s window). Every response carries the remaining budget; going over returns 429 with a Retry-After header.

HTTP/1.1 200 OK
X-RateLimit-Remaining: 118

# once exceeded:
HTTP/1.1 429 Too Many Requests
Retry-After: 42

Deployments

GET /deployments deployments:read

List every deployment the caller can access.

curl "https://bot-hosting.net/api/v1/deployments" \
  -H "Authorization: Bearer bhk_your_key"
Response 200
{
  "deployments": [
    {
      "id": "dep_a1b2c3d4",
      "name": "my-bot",
      "description": "A cool Discord bot",
      "state": "running",
      "status": "active",
      "createdAt": "2026-01-01T00:00:00.000Z",
      "resources": {
        "ramMB": 512,
        "cpuPercent": 50,
        "storageMB": 1024
      },
      "domains": {
        "subdomain": "my-bot.apps",
        "slug": "my-template",
        "custom": "bot.example.com"
      }
    }
  ]
}
GET /deployments/:id deployments:read

Fetch a single deployment.

id:path
curl "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4" \
  -H "Authorization: Bearer bhk_your_key"
Response 200
{
  "id": "dep_a1b2c3d4",
  "name": "my-bot",
  "description": "A cool Discord bot",
  "state": "running",
  "status": "active",
  "createdAt": "2026-01-01T00:00:00.000Z",
  "resources": {
    "ramMB": 512,
    "cpuPercent": 50,
    "storageMB": 1024
  },
  "domains": {
    "subdomain": "my-bot.apps",
    "slug": "my-template",
    "custom": "bot.example.com"
  }
}
PATCH /deployments/:id deployments:write

Rename a deployment or change its description.

id:pathname:body?description:body?
curl -X PATCH "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4" \
  -H "Authorization: Bearer bhk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"name":"my-bot","description":"A cool Discord bot"}'
Response 200
{
  "id": "dep_a1b2c3d4",
  "name": "my-bot",
  "description": "A cool Discord bot",
  "state": "running",
  "status": "active",
  "createdAt": "2026-01-01T00:00:00.000Z",
  "resources": {
    "ramMB": 512,
    "cpuPercent": 50,
    "storageMB": 1024
  },
  "domains": {
    "subdomain": "my-bot.apps",
    "slug": "my-template",
    "custom": "bot.example.com"
  }
}
POST /deployments/:id/move deployments:write

Move a deployment to another of your projects.

id:pathtoProjectId:body
curl -X POST "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/move" \
  -H "Authorization: Bearer bhk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"toProjectId":"dep_a1b2c3d4"}'
Response 200
{
  "id": "dep_a1b2c3d4",
  "name": "my-bot",
  "description": "A cool Discord bot",
  "state": "running",
  "status": "active",
  "createdAt": "2026-01-01T00:00:00.000Z",
  "resources": {
    "ramMB": 512,
    "cpuPercent": 50,
    "storageMB": 1024
  },
  "domains": {
    "subdomain": "my-bot.apps",
    "slug": "my-template",
    "custom": "bot.example.com"
  }
}
DELETE /deployments/:id deployments:write destructive

Delete a deployment (instant; teardown runs in the background).

id:path
curl -X DELETE "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4" \
  -H "Authorization: Bearer bhk_your_key"
Response 200
{
  "ok": true
}
POST /deployments deployments:write

Create a deployment (blank, from a public GitHub repo, or a template).

name:bodydescription:body?projectId:body?source:bodygithubRepo:body?branch:body?templateId:body?env:body?runtime:body?runtimeVersion:body?
curl -X POST "https://bot-hosting.net/api/v1/deployments" \
  -H "Authorization: Bearer bhk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"name":"my-bot","description":"A cool Discord bot","projectId":"dep_a1b2c3d4","source":"blank","githubRepo":"string","branch":"string","templateId":"dep_a1b2c3d4","env":"string","runtime":"python","runtimeVersion":"string"}'
Response 200
{
  "deployment": {
    "id": "dep_a1b2c3d4",
    "name": "my-bot",
    "description": "A cool Discord bot",
    "state": "running",
    "status": "active",
    "createdAt": "2026-01-01T00:00:00.000Z",
    "resources": {
      "ramMB": 512,
      "cpuPercent": 50,
      "storageMB": 1024
    },
    "domains": {
      "subdomain": "my-bot.apps",
      "slug": "my-template",
      "custom": "bot.example.com"
    }
  }
}
POST /deployments/:id/power deployments:power

Send a power signal (start / stop / restart / kill).

id:pathaction:body
curl -X POST "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/power" \
  -H "Authorization: Bearer bhk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"action":"start"}'
Response 200
{
  "ok": true,
  "action": "restart"
}
GET /deployments/:id/logs deployments:read

Read the last N lines of the console log.

id:pathsize:query?
curl "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/logs?size=1048576" \
  -H "Authorization: Bearer bhk_your_key"
Response 200
{
  "lines": [
    "Bot is online!"
  ]
}
GET /deployments/:id/resources deployments:read

Live resource usage: CPU, memory, disk, network and uptime.

id:path
curl "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/resources" \
  -H "Authorization: Bearer bhk_your_key"
Response 200
{
  "state": "running",
  "cpu": {
    "usedPercent": 50,
    "limitPercent": 50
  },
  "memory": {
    "usedBytes": 1048576,
    "limitBytes": 1048576
  },
  "disk": {
    "usedBytes": 1048576,
    "limitBytes": 1048576
  },
  "network": {
    "rxBytes": 1048576,
    "txBytes": 1048576
  },
  "uptimeMs": 3600000
}
POST /deployments/:id/command deployments:power

Send a single command to the server console.

id:pathcommand:body
curl -X POST "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/command" \
  -H "Authorization: Bearer bhk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"command":"say hello"}'
Response 200
{
  "ok": true
}
PATCH /deployments/:id/resize deployments:write

Change RAM / CPU / storage allocation (drawn from your plan pool).

id:pathramMB:bodycpuPct:bodystorageMB:body
curl -X PATCH "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/resize" \
  -H "Authorization: Bearer bhk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"ramMB":512,"cpuPct":50,"storageMB":1024}'
Response 200
{
  "id": "dep_a1b2c3d4",
  "name": "my-bot",
  "description": "A cool Discord bot",
  "state": "running",
  "status": "active",
  "createdAt": "2026-01-01T00:00:00.000Z",
  "resources": {
    "ramMB": 512,
    "cpuPercent": 50,
    "storageMB": 1024
  },
  "domains": {
    "subdomain": "my-bot.apps",
    "slug": "my-template",
    "custom": "bot.example.com"
  }
}
GET /deployments/:id/files files:read

List a directory inside the deployment volume.

id:pathpath:query?
curl "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/files?path=%2Fmain.py" \
  -H "Authorization: Bearer bhk_your_key"
Response 200
{
  "path": "/main.py",
  "entries": [
    {
      "name": "my-bot",
      "type": "file",
      "sizeBytes": 1048576,
      "modifiedAt": "2026-01-01T00:00:00.000Z",
      "mode": "0755"
    }
  ]
}
GET /deployments/:id/files/content files:read

Read the text content of a single file.

id:pathpath:query
curl "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/files/content?path=%2Fmain.py" \
  -H "Authorization: Bearer bhk_your_key"
Response 200
{
  "path": "/main.py",
  "content": "print(\"hello world\")"
}
POST /deployments/:id/files/content files:write

Create or overwrite a text file.

id:pathpath:bodycontent:body
curl -X POST "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/files/content" \
  -H "Authorization: Bearer bhk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"path":"/main.py","content":"print(\"hello world\")"}'
Response 200
{
  "ok": true,
  "path": "/main.py"
}
POST /deployments/:id/files/rename files:write

Rename or move a file within a directory.

id:pathroot:body?from:bodyto:body
curl -X POST "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/files/rename" \
  -H "Authorization: Bearer bhk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"root":"/","from":"old.py","to":"new.py"}'
Response 200
{
  "ok": true
}
POST /deployments/:id/files/delete files:write destructive

Delete one or more files or folders.

id:pathroot:body?files:body
curl -X POST "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/files/delete" \
  -H "Authorization: Bearer bhk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"root":"/","files":["string"]}'
Response 200
{
  "ok": true,
  "deleted": 1
}
POST /deployments/:id/files/folder files:write

Create a folder.

id:pathroot:body?name:body
curl -X POST "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/files/folder" \
  -H "Authorization: Bearer bhk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"root":"/","name":"my-bot"}'
Response 200
{
  "ok": true
}
POST /deployments/:id/files/decompress files:write

Decompress an archive in place.

id:pathroot:body?file:body
curl -X POST "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/files/decompress" \
  -H "Authorization: Bearer bhk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"root":"/","file":"archive.zip"}'
Response 200
{
  "ok": true
}
POST /deployments/:id/files/compress files:write

Compress files into a new archive.

id:pathroot:body?files:body
curl -X POST "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/files/compress" \
  -H "Authorization: Bearer bhk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"root":"/","files":["string"]}'
Response 200
{
  "ok": true,
  "archive": "string"
}
POST /deployments/:id/files/copy files:write

Duplicate a file (Wings appends a "copy" suffix).

id:pathlocation:body
curl -X POST "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/files/copy" \
  -H "Authorization: Bearer bhk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"location":"string"}'
Response 200
{
  "ok": true
}
POST /deployments/:id/files/chmod files:write

Change a file mode (e.g. "0755").

id:pathroot:body?file:bodymode:body
curl -X POST "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/files/chmod" \
  -H "Authorization: Bearer bhk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"root":"/","file":"archive.zip","mode":"0755"}'
Response 200
{
  "ok": true
}
GET /deployments/:id/files/download-url files:read

Get a one-time signed URL to download a file.

id:pathpath:query
curl "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/files/download-url?path=%2Fmain.py" \
  -H "Authorization: Bearer bhk_your_key"
Response 200
{
  "url": "https://.../files/download?path=%2Fmain.py"
}
GET /deployments/:id/env env:read

List environment variables. Secret values are masked.

id:path
curl "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/env" \
  -H "Authorization: Bearer bhk_your_key"
Response 200
{
  "variables": [
    {
      "key": "MY_VAR",
      "value": "some-value",
      "secret": true,
      "system": true
    }
  ]
}
POST /deployments/:id/env env:write

Create or update a user environment variable (applies on next restart).

id:pathkey:bodyvalue:bodysecret:body?
curl -X POST "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/env" \
  -H "Authorization: Bearer bhk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"key":"MY_VAR","value":"some-value","secret":true}'
Response 200
{
  "ok": true,
  "key": "MY_VAR"
}
DELETE /deployments/:id/env/:key env:write destructive

Delete a user environment variable (applies on next restart).

id:pathkey:path
curl -X DELETE "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/env/MY_VAR" \
  -H "Authorization: Bearer bhk_your_key"
Response 200
{
  "ok": true
}
GET /deployments/:id/backups backups:read

List the backups of a deployment.

id:path
curl "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/backups" \
  -H "Authorization: Bearer bhk_your_key"
Response 200
{
  "backups": [
    {
      "id": "dep_a1b2c3d4",
      "deploymentId": "dep_a1b2c3d4",
      "label": "Manual",
      "sizeBytes": 1048576,
      "status": "active",
      "backupType": "manual",
      "fileCount": 2,
      "isOrphaned": true,
      "createdAt": "2026-01-01T00:00:00.000Z",
      "completedAt": "2026-01-01T00:00:00.000Z"
    }
  ]
}
POST /deployments/:id/backups backups:write

Start a manual backup of a deployment.

id:path
curl -X POST "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/backups" \
  -H "Authorization: Bearer bhk_your_key"
Response 200
{
  "ok": true,
  "backupId": "bak_a1b2c3d4"
}
GET /backups/:backupId backups:read

Fetch a single backup by id.

backupId:path
curl "https://bot-hosting.net/api/v1/backups/bak_a1b2c3d4" \
  -H "Authorization: Bearer bhk_your_key"
Response 200
{
  "id": "dep_a1b2c3d4",
  "deploymentId": "dep_a1b2c3d4",
  "label": "Manual",
  "sizeBytes": 1048576,
  "status": "active",
  "backupType": "manual",
  "fileCount": 2,
  "isOrphaned": true,
  "createdAt": "2026-01-01T00:00:00.000Z",
  "completedAt": "2026-01-01T00:00:00.000Z"
}
DELETE /backups/:backupId backups:write destructive

Delete a backup.

backupId:path
curl -X DELETE "https://bot-hosting.net/api/v1/backups/bak_a1b2c3d4" \
  -H "Authorization: Bearer bhk_your_key"
Response 200
{
  "ok": true
}
POST /backups/:backupId/restore backups:write destructive

Restore a backup onto a deployment (overwrites its files).

backupId:pathdeploymentId:bodystartAfter:body?
curl -X POST "https://bot-hosting.net/api/v1/backups/bak_a1b2c3d4/restore" \
  -H "Authorization: Bearer bhk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"deploymentId":"dep_a1b2c3d4","startAfter":true}'
Response 200
{
  "ok": true,
  "warning": "string"
}
GET /deployments/:id/packages packages:read

List packages in the manifest (npm or pip).

id:pathmanager:query
curl "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/packages?manager=npm" \
  -H "Authorization: Bearer bhk_your_key"
Response 200
{
  "manager": "pip",
  "file": "archive.zip",
  "exists": true,
  "packages": [
    {
      "name": "my-bot",
      "spec": "==1.0.0",
      "dev": true
    }
  ]
}
POST /deployments/:id/packages packages:write

Add or update a package in the manifest.

id:pathmanager:bodyname:bodyspec:body?dev:body?
curl -X POST "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/packages" \
  -H "Authorization: Bearer bhk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"manager":"npm","name":"my-bot","spec":"==1.0.0","dev":true}'
Response 200
{
  "manager": "pip",
  "file": "archive.zip",
  "exists": true,
  "packages": [
    {
      "name": "my-bot",
      "spec": "==1.0.0",
      "dev": true
    }
  ]
}
POST /deployments/:id/packages/remove packages:write

Remove a package from the manifest.

id:pathmanager:bodyname:body
curl -X POST "https://bot-hosting.net/api/v1/deployments/dep_a1b2c3d4/packages/remove" \
  -H "Authorization: Bearer bhk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"manager":"npm","name":"my-bot"}'
Response 200
{
  "manager": "pip",
  "file": "archive.zip",
  "exists": true,
  "packages": [
    {
      "name": "my-bot",
      "spec": "==1.0.0",
      "dev": true
    }
  ]
}
GET /projects projects:read

List the projects you own or collaborate on.

curl "https://bot-hosting.net/api/v1/projects" \
  -H "Authorization: Bearer bhk_your_key"
Response 200
{
  "projects": [
    {
      "id": "dep_a1b2c3d4",
      "name": "my-bot",
      "description": "A cool Discord bot",
      "isOwner": true,
      "createdAt": "2026-01-01T00:00:00.000Z"
    }
  ]
}

Account

GET /account account:read

Your profile, credit balance and quota (pool vs used).

curl "https://bot-hosting.net/api/v1/account" \
  -H "Authorization: Bearer bhk_your_key"
Response 200
{
  "id": "dep_a1b2c3d4",
  "username": "grality",
  "email": "[email protected]",
  "createdAt": "2026-01-01T00:00:00.000Z",
  "creditsCents": 5000,
  "quota": {
    "pool": {
      "ramMB": 512,
      "cpuPct": 50,
      "storageMB": 1024,
      "slots": 2
    },
    "used": {
      "ramMB": 512,
      "cpuPct": 50,
      "storageMB": 1024,
      "slots": 2
    }
  }
}

Templates

GET /templates templates:read

Browse the public template catalogue (any author).

sort:query?category:query?q:query?page:query?perPage:query?
curl "https://bot-hosting.net/api/v1/templates?sort=trending&category=utility&q=search&page=2&perPage=2" \
  -H "Authorization: Bearer bhk_your_key"
Response 200
{
  "total": 12,
  "page": 2,
  "perPage": 2,
  "items": [
    {
      "id": "dep_a1b2c3d4",
      "slug": "my-template",
      "name": "my-bot",
      "tagline": "A cool Discord bot",
      "category": "utility",
      "runtime": "python",
      "githubRepo": "string",
      "githubStars": 3,
      "deployCount": 3,
      "imageId": "dep_a1b2c3d4",
      "owner": {
        "username": "grality",
        "avatar": "string"
      },
      "createdAt": "2026-01-01T00:00:00.000Z"
    }
  ]
}
GET /templates/:slug templates:read

Full details + public stats of a single template by slug.

slug:path
curl "https://bot-hosting.net/api/v1/templates/my-template" \
  -H "Authorization: Bearer bhk_your_key"
Response 200
{
  "id": "dep_a1b2c3d4",
  "slug": "my-template",
  "name": "my-bot",
  "tagline": "A cool Discord bot",
  "category": "utility",
  "runtime": "python",
  "githubRepo": "string",
  "githubStars": 3,
  "deployCount": 3,
  "imageId": "dep_a1b2c3d4",
  "owner": {
    "username": "grality",
    "avatar": "string"
  },
  "createdAt": "2026-01-01T00:00:00.000Z",
  "branch": "string",
  "runtimeVersion": "string",
  "readme": "# My template",
  "stats": {
    "views": 3,
    "deploys": 3,
    "likes": 3,
    "dislikes": 3,
    "githubStars": 3,
    "trendingScore": 1.5
  },
  "envSchema": [
    {
      "key": "MY_VAR",
      "label": "Manual",
      "description": "A cool Discord bot",
      "required": true,
      "secret": true,
      "defaultValue": "string"
    }
  ],
  "updatedAt": "2026-01-01T00:00:00.000Z"
}