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>"}]
    }
  }
}