API Reference
Caster provides a REST API for programmatic access to all platform features. The base URL is https://console.caster.zip/api/v1.
Authentication
All endpoints (except register and login) require an Authorization header:
Authorization: Bearer YOUR_API_KEY
API keys are created from the Account page or via POST /api/v1/api-keys. You also receive an API key when you register. Keys are shown only once at creation time and cannot be retrieved later.
Error Responses
All errors return JSON with an error field:
{"error": "description of what went wrong"}
Common status codes: 400 (bad request), 401 (not authenticated), 404 (not found), 409 (conflict), 500 (internal error).
Auth
Register
POST /api/v1/auth/register
Create a new account. No authentication required.
Request body:
{
"email": "alice@example.com",
"password": "secret123"
}
Response (201 Created):
{
"user": {
"id": 1,
"email": "alice@example.com",
"created_at": "2025-01-15T10:30:00Z"
},
"api_key": "a1b2c3..."
}
Login
POST /api/v1/auth/login
Request body:
{
"email": "alice@example.com",
"password": "secret123"
}
Response (200 OK):
{
"user": {
"id": 1,
"email": "alice@example.com",
"created_at": "2025-01-15T10:30:00Z"
}
}
Note: Login does not return an API key. If you need a new key, create one from the Account page or via the API Keys endpoints.
Get Current User
GET /api/v1/me
Response (200 OK):
{
"user": {
"id": 1,
"email": "alice@example.com",
"created_at": "2025-01-15T10:30:00Z"
}
}
API Keys
API keys are hashed on the server. The plaintext key is returned only once at creation time.
Create API Key
POST /api/v1/api-keys
Request body:
{
"name": "CI/CD pipeline"
}
Response (201 Created):
{
"id": 1,
"name": "CI/CD pipeline",
"key_prefix": "a1b2c3d4",
"created_at": "2025-01-15T10:30:00Z",
"key": "a1b2c3d4e5f6..."
}
The key field is the full plaintext key, shown only in this response.
List API Keys
GET /api/v1/api-keys
Response (200 OK): Array of API key objects (prefix only, never the full key).
Delete API Key
DELETE /api/v1/api-keys/{id}
Response: 204 No Content
SSH Keys
Add SSH Key
POST /api/v1/ssh-keys
Request body:
{
"name": "laptop",
"public_key": "ssh-ed25519 AAAA... alice@laptop"
}
Response (201 Created):
{
"id": 1,
"user_id": 1,
"name": "laptop",
"public_key": "ssh-ed25519 AAAA... alice@laptop",
"fingerprint": "SHA256:...",
"created_at": "2025-01-15T10:30:00Z"
}
List SSH Keys
GET /api/v1/ssh-keys
Response (200 OK): Array of SSH key objects.
Delete SSH Key
DELETE /api/v1/ssh-keys/{id}
Response: 204 No Content
Sites
Sites are identified by their short ID (first 8 chars of the site ID, e.g., a3f9c2e8) or by a custom name if one has been set.
Create Site
POST /api/v1/sites
No request body required. A site is created instantly with an auto-generated ID.
Response (201 Created):
{
"site": {
"id": 1,
"site_id": "a3f9c2e8b4d6f1e0c7a9b2d4e6f8a0c2",
"user_id": 1,
"name": null,
"created_at": "2025-01-15T10:30:00Z"
},
"environment": {
"id": 1,
"site_id": 1,
"name": "prod",
"container_state": "stopped",
"created_at": "2025-01-15T10:30:00Z"
},
"git_url": "git@git.caster.zip:a3f9c2e8.git"
}
Rename Site
PATCH /api/v1/sites/{identifier}
Set or change the custom subdomain name. The identifier can be a short ID or existing name.
Request body:
{
"name": "my-project"
}
Names must be 8+ characters, lowercase alphanumeric and hyphens, starting and ending with an alphanumeric character. Reserved names (api, app, git, www, mail, admin, console) cannot be used.
Response (200 OK): The updated site object.
List Sites
GET /api/v1/sites
Response (200 OK): Array of site objects.
Get Site
GET /api/v1/sites/{identifier}
Response (200 OK): Site object with environment details.
Delete Site
DELETE /api/v1/sites/{identifier}
Removes DNS records, deletes the git repository, and deletes all site data.
Response: 204 No Content
Deployments
Paste Deploy
POST /api/v1/sites/{identifier}/paste
Deploy files directly via JSON. No Dockerfile needed — static files are served with nginx automatically.
Request body:
{
"files": [
{"name": "index.html", "content": "<h1>Hello World</h1>"},
{"name": "style.css", "content": "body { color: #333; }"}
]
}
Response (202 Accepted):
{
"deployment_id": 7,
"content_hash": "a1b2c3d4...",
"status": "accepted"
}
Upload and Deploy
POST /api/v1/sites/{identifier}/deploy
Upload an archive file (zip, tar, tar.gz, or tgz) to trigger a deployment. If no Dockerfile is present, nginx is used automatically.
Request: multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
file |
file | Yes | Archive file (zip, tar, tar.gz, tgz) |
Response (202 Accepted):
{
"deployment_id": 7,
"environment": "prod",
"content_hash": "a1b2c3d4...",
"status": "accepted"
}
List Deployments
GET /api/v1/sites/{identifier}/deployments
Response (200 OK): Array of deployment objects.
Get Deployment
GET /api/v1/sites/{identifier}/deployments/{id}
Response (200 OK):
{
"id": 5,
"environment_id": 1,
"commit_sha": "abc123def456...",
"image_tag": "a3f9c2e8-abc123de",
"container_port": 80,
"status": "live",
"build_log": "Step 1/3 : FROM nginx:alpine\n...",
"created_at": "2025-01-15T11:00:00Z",
"finished_at": "2025-01-15T11:01:00Z"
}
Deployment status values: pending, building, built, deploying, live, failed, superseded.
One-Shot Deploy
Deploy (One Step)
POST /api/v1/deploy
Create a site and deploy files in a single call. Authentication is optional — anonymous deploys are supported (rate limited to 3 per hour per IP).
Request body:
{
"files": [
{"name": "index.html", "content": "<h1>Hello</h1>"},
{"name": "style.css", "content": "body { color: #333; }"}
],
"site": "a3f9c2e8"
}
| Field | Type | Required | Description |
|---|---|---|---|
files |
array | Yes | Array of {name, content} file objects |
site |
string | No | Existing site identifier (short ID or custom name). If omitted, a new site is created. |
Authenticated response (202 Accepted):
{
"site": {"id": 1, "site_id": "a3f9c2e8...", ...},
"deployment_id": 1,
"url": "https://a3f9c2e8.caster.zip",
"status": "accepted"
}
Anonymous response (202 Accepted):
{
"site": {"id": 1, "site_id": "a3f9c2e8...", ...},
"deployment_id": 1,
"url": "https://a3f9c2e8.caster.zip",
"status": "accepted",
"claim_token": "abc123..."
}
Anonymous sites expire after 24 hours unless claimed. Use the claim token to transfer ownership to your account.
Claim Anonymous Site
POST /api/v1/claim
Transfer ownership of an anonymous site to your account. Requires authentication.
Request body:
{
"claim_token": "abc123..."
}
Response (200 OK): The site object with updated ownership.
| Status | Meaning |
|---|---|
200 |
Site claimed successfully |
404 |
Invalid claim token |
409 |
Site already claimed |
410 |
Claim token expired |
MCP Server
Caster provides an MCP (Model Context Protocol) server for AI tool integration.
Session Init
GET /api/v1/mcp
Returns a session ID for the MCP connection.
JSON-RPC Endpoint
POST /api/v1/mcp
Accepts JSON-RPC 2.0 requests. Requires authentication.
Available tools:
| Tool | Description |
|---|---|
deploy_site |
Deploy files (creates site if needed). Blocks until live or timeout. |
list_sites |
List all sites owned by the user. |
get_site |
Get site details and recent deployments. |
get_deployment_logs |
Get build logs for a deployment. |
Example request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "deploy_site",
"arguments": {
"files": [{"name": "index.html", "content": "<h1>Hello</h1>"}]
}
}
}