Rate Limiting: Auth endpoints are rate-limited to 5 requests per minute per IP to prevent brute-force attacks.
Register a new user account.
Request:
{
"email": "user@example.com",
"password": "password",
"name": "User Name"
}Response:
{
"message": "user created successfully",
"user_id": "uuid"
}Login to obtain an API Key.
Request:
{
"email": "user@example.com",
"password": "password"
}Response:
{
"user": {
"id": "uuid",
"email": "user@example.com",
"name": "User Name"
},
"api_key": "thecloud_xxxxx"
}Request a password reset token (rate limited: 5 requests/minute).
Request:
{
"email": "user@example.com"
}Response:
{
"message": "If the email exists, a reset token has been sent."
}Reset password using a valid token (rate limited: 5 requests/minute).
Request:
{
"token": "reset-token-from-email",
"new_password": "new-secure-password"
}Response:
{
"message": "password updated successfully"
}Headers Required: X-API-Key: <your-api-key>
Create a new API key.
Request:
{
"name": "Production Key"
}Response:
{
"id": "uuid",
"user_id": "user-uuid",
"name": "Production Key",
"key": "thecloud_xxxxx",
"created_at": "2026-01-05T23:00:00Z",
"last_used": "2026-01-05T23:00:00Z"
}List all API keys for the authenticated user.
Revoke an API key.
Rotate an API key (creates new key, deletes old one).
Regenerate an API key (alias for rotate).
Headers Required: X-API-Key: <your-api-key>
List all tenants (organizations) the authenticated user belongs to.
Create a new tenant. Request:
{
"name": "Acme Corp",
"slug": "acme"
}Switch the user's active/default tenant. This affects which resources are visible in subsequent requests.
Add a new member to a tenant. Request:
{
"user_id": "uuid",
"role": "member"
}Liveness probe. Returns 200 OK if the process is running.
Response: {"status": "ok"}
Readiness probe. Checks connections to Database and Docker daemon. Response (200 OK):
{
"status": "UP",
"checks": { "database": "CONNECTED", "docker": "CONNECTED" },
"time": "..."
}Response (503 Service Unavailable):
{
"status": "DEGRADED",
"checks": { "database": "DISCONNECTED", ... }
}Headers Required: X-API-Key: <your-api-key>
List all instances owned by the authenticated user.
Launch a new instance.
{
"name": "web-01",
"image": "nginx",
"instance_type": "basic-2",
"vpc_id": "vpc-uuid",
"subnet_id": "subnet-uuid",
"ports": "80:80",
"volumes": [
{ "volume_id": "vol-uuid", "mount_path": "/data" }
]
}List all available instance types. Response:
[
{
"id": "basic-2",
"name": "Basic 2",
"vcpus": 1,
"memory_mb": 1024,
"disk_gb": 10,
"network_mbps": 1000,
"price_per_hour": 0.02,
"category": "general-purpose"
}
]Get details of a specific instance.
Update instance (e.g., status).
Terminate an instance.
Resize an instance to a different instance type (CPU/memory).
Request:
{
"instance_type": "basic-4"
}Response:
{
"message": "instance resized"
}Error Responses:
400— Invalid input (bad instance ID, empty instance type, invalid type)404— Instance not found403— Insufficient quota for the requested type
Get the VNC console URL for the instance. Response:
{
"console_url": "vnc://127.0.0.1:5901"
}Pause a running instance (freezes CPU, retains memory/network).
Prerequisites: Instance must be in RUNNING state.
Response:
{
"message": "instance paused"
}Error Responses:
400— Instance not in RUNNING state (returned asCONFLICT)404— Instance not found403— Insufficient permissions
Resume a paused instance back to running state.
Prerequisites: Instance must be in PAUSED state.
Response:
{
"message": "instance resumed"
}Error Responses:
400— Instance not in PAUSED state (returned asCONFLICT)404— Instance not found403— Insufficient permissions
Headers Required: X-API-Key: <your-api-key>
List all images available to the authenticated user (own + public).
Response:
[
{
"id": "uuid",
"name": "ubuntu-22.04",
"description": "Ubuntu 22.04 LTS",
"os": "linux",
"version": "22.04",
"format": "qcow2",
"size_gb": 2,
"is_public": false,
"status": "ACTIVE",
"created_at": "2026-04-21T10:00:00Z"
}
]Register a new image (metadata only; upload the file separately via POST /images/:id/upload).
Request:
{
"name": "my-custom-image",
"description": "My custom OS image",
"os": "linux",
"version": "22.04",
"is_public": false
}Get details of a specific image.
Delete an image and its associated file from storage.
Upload the qcow2/image file for a registered image (multipart/form-data).
Form field: file — the image binary file.
Import an image from a remote URL. The file is downloaded and stored automatically.
Request:
{
"name": "ubuntu-22.04-cloud",
"url": "https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img",
"description": "Ubuntu 22.04 LTS cloud image",
"os": "linux",
"version": "22.04",
"is_public": false
}Response: 202 Accepted — image metadata is returned immediately. The image status transitions from PENDING to ACTIVE once the download completes.
Headers Required: X-API-Key: <your-api-key>
List all VPCs.
Create a new VPC.
{
"name": "prod-vpc"
}Delete a VPC.
Headers Required: X-API-Key: <your-api-key>
List all VPC peering connections for the tenant.
Initiate a new VPC peering request.
{
"requester_vpc_id": "uuid",
"accepter_vpc_id": "uuid"
}Response (201 Created):
{
"id": "uuid",
"status": "pending-acceptance",
"requester_vpc_id": "uuid",
"accepter_vpc_id": "uuid",
"arn": "arn:thecloud:vpc-peering:..."
}Get details of a specific peering connection.
Accept a pending peering request. This activates cross-bridge routing via OVS.
Reject a pending peering request.
Delete a peering connection and remove all associated network routes.
Headers Required: X-API-Key: <your-api-key>
List all route tables for a VPC.
Query params: ?vpc_id=<vpc-uuid> (required)
Create a new custom route table.
{
"vpc_id": "vpc-uuid",
"name": "custom-rt",
"is_main": false
}Get details of a specific route table including its routes.
Delete a custom route table. Cannot delete the main route table of a VPC.
Add a route to a route table.
{
"destination_cidr": "0.0.0.0/0",
"target_type": "igw",
"target_id": "igw-uuid"
}Target Types:
local- Traffic within VPC CIDRigw- Internet Gatewaynat- NAT Gatewaypeering- VPC Peering connection
Remove a route from a route table. Query param route_id is required.
Associate a subnet with a route table.
{
"subnet_id": "subnet-uuid"
}Disassociate a subnet from a route table.
{
"subnet_id": "subnet-uuid"
}Headers Required: X-API-Key: <your-api-key>
List all internet gateways for the tenant.
Create a new internet gateway. Response (201 Created):
{
"id": "uuid",
"status": "detached",
"arn": "arn:thecloud:vpc:local:tenant:igw/uuid"
}Get details of a specific internet gateway.
Attach an internet gateway to a VPC.
{
"vpc_id": "vpc-uuid"
}Detach an internet gateway from its VPC. Must remove all routes referencing this IGW first.
Delete an internet gateway. Must be detached first.
Headers Required: X-API-Key: <your-api-key>
List all NAT gateways for a VPC.
Query params: ?vpc_id=<vpc-uuid> (required)
Create a new NAT gateway in a subnet with an allocated Elastic IP.
{
"subnet_id": "subnet-uuid",
"eip_id": "eip-uuid"
}Response (201 Created):
{
"id": "uuid",
"vpc_id": "vpc-uuid",
"subnet_id": "subnet-uuid",
"elastic_ip_id": "eip-uuid",
"status": "active",
"private_ip": "10.0.1.100",
"arn": "arn:thecloud:vpc:local:tenant:nat-gateway/uuid"
}Get details of a specific NAT gateway.
Delete a NAT gateway and release the associated Elastic IP back to allocated state.
Headers Required: X-API-Key: <your-api-key>
List all security groups.
Query params: ?vpc_id=<vpc-uuid> (required)
Create a new security group.
{
"vpc_id": "vpc-uuid",
"name": "web-tier",
"description": "Port 80 and 443 allowed"
}Get details and rules for a security group.
Delete a security group.
Add a firewall rule.
{
"direction": "ingress",
"protocol": "tcp",
"port_min": 80,
"port_max": 80,
"cidr": "0.0.0.0/0",
"priority": 100
}Remove a firewall rule.
Attach a security group to an instance.
{
"instance_id": "inst-uuid",
"group_id": "sg-uuid"
}Detach a security group from an instance.
{
"instance_id": "inst-uuid",
"group_id": "sg-uuid"
}Headers Required: X-API-Key: <your-api-key>
List all subnets in a VPC.
Create a new subnet.
{
"name": "private-subnet-1",
"cidr_block": "10.0.1.0/24",
"availability_zone": "us-east-1a"
}Get details of a specific subnet.
Delete a subnet.
Headers Required: X-API-Key: <your-api-key>
List all allocated elastic IPs for the tenant.
Allocate a new elastic IP. No body required. Response:
{
"id": "uuid",
"public_ip": "100.64.x.y",
"status": "allocated",
"arn": "arn:thecloud:vpc:local:tenant:eip/uuid"
}Get details of a specific elastic IP.
Release an elastic IP back to the pool. Fails if still associated.
Associate an elastic IP with a compute instance. Request:
{
"instance_id": "inst-uuid"
}Disassociate an elastic IP from its current instance.
Headers Required: X-API-Key: <your-api-key> for protected endpoints.
List pipelines for the authenticated user.
Create a pipeline definition.
{
"name": "lint-thecloud",
"repository_url": "https://github.com/poyrazK/thecloud.git",
"branch": "main",
"webhook_secret": "your-secret",
"config": {
"stages": [
{
"name": "lint",
"steps": [
{
"name": "golangci",
"image": "golang:1.24",
"commands": [
"git clone https://github.com/poyrazK/thecloud.git /workspace/thecloud",
"cd /workspace/thecloud",
"go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.60.3",
"/go/bin/golangci-lint run ./..."
]
}
]
}
]
}
}Get a pipeline by ID.
Update mutable fields of a pipeline.
Delete a pipeline.
Trigger a manual run.
{
"commit_hash": "abc123",
"trigger_type": "MANUAL"
}List runs for a pipeline.
Get run details.
List step results for a run.
List logs for a run.
Public webhook trigger endpoint.
provider:githuborgitlab- No API key required (validated by webhook secret/signature).
X-GitHub-Event(supported:push)X-Hub-Signature-256(HMAC SHA-256)X-GitHub-Delivery(used for idempotency)
X-Gitlab-Event(supported:Push Hook)X-Gitlab-TokenX-Gitlab-Event-UUID(used for idempotency)
202 acceptedwith build payload when a run is queued.202 acceptedwith{ "status": "ignored" }for duplicate/non-matching events.
Headers Required: X-API-Key: <your-api-key>
List all buckets owned by or accessible to the tenant.
Create a new storage bucket.
{
"name": "my-assets",
"is_public": false
}Delete a bucket. Fails if the bucket is not empty unless ?force=true is provided.
Enable or disable versioning for a bucket.
{
"enabled": true
}List all objects in a bucket (latest versions only).
Upload an object. The request body is the raw file data. Response:
{
"id": "uuid",
"bucket": "my-bucket",
"key": "test.txt",
"size_bytes": 1024,
"content_type": "text/plain",
"checksum": "sha256-hex-hash",
"upload_status": "AVAILABLE",
"version_id": "null",
"created_at": "2026-03-04T17:00:00Z"
}Download an object (latest version).
Soft-delete an object (latest version).
List all versions of a specific object.
Get health and node status of the distributed storage cluster.
Initiate a multipart upload session.
Response: {"id": "upload-uuid", ...}
Upload a part for a multipart session.
Finalize a multipart upload and assemble the object.
Abort a multipart upload and clean up uploaded parts.
List lifecycle rules for a bucket.
Create a new lifecycle rule.
{
"prefix": "logs/",
"expiration_days": 30
}Delete a lifecycle rule.
Release an elastic IP back to the pool. Fails if still associated.
Associate an elastic IP with a compute instance. Request:
{
"instance_id": "inst-uuid"
}Disassociate an elastic IP from its current instance.
Headers Required: X-API-Key: <your-api-key>
List all volumes.
Create a new volume.
{
"name": "data-vol",
"size_gb": 10
}Headers Required: X-API-Key: <your-api-key>
List all managed databases.
Provision a new primary database.
{
"name": "prod-db",
"engine": "postgres",
"version": "16",
"vpc_id": "vpc-uuid",
"allocated_storage": 20,
"pooling_enabled": true,
"metrics_enabled": true,
"parameters": {
"max_connections": "100"
}
}Get details of a specific database.
Modify an existing database configuration.
{
"allocated_storage": 40,
"pooling_enabled": false,
"metrics_enabled": true,
"parameters": {
"max_connections": "200"
}
}Terminate a database instance.
Get the connection string for the database.
Create a read-replica for a primary database.
{
"name": "prod-db-replica-1"
}Promote a replica to a standalone primary database.
Regenerate the database password and update it in both the database engine and Vault.
- Security: Ensures credentials are never stored in plain text in the primary metadata store.
- Workflow: Automated update of database users and sidecar (pooler) reloads.
Response Example:
{
"message": "database credentials rotated successfully",
"data": {
"message": "database credentials rotated successfully"
}
}Stop a running database instance. The data volume is retained.
- Constraints: Cannot stop replicas (must promote first) or databases in CREATING/DELETING state.
- Response:
{
"message": "database stopped"
}Start a stopped database instance.
- Constraints: Database must be in STOPPED state.
- Workflow: Starts container, waits for readiness, starts sidecars if enabled.
- Response:
{
"message": "database started"
}Headers Required: X-API-Key: <your-api-key>
List all global load balancers owned by the authenticated user.
Create a new global load balancer.
{
"name": "api-global",
"hostname": "api.myapp.com",
"policy": "LATENCY",
"health_check": {
"protocol": "HTTP",
"port": 80,
"path": "/health"
}
}Get details of a GLB including its endpoints.
Delete a global load balancer and its DNS records. Only the owner can delete the resource.
Add a regional endpoint to the GLB.
{
"region": "us-east-1",
"target_type": "IP",
"target_ip": "1.2.3.4",
"weight": 100
}Remove an endpoint from the GLB.
Headers Required: X-API-Key: <your-api-key>
List auto-scaling groups.
Create an ASG.
Headers Required: X-API-Key: <your-api-key>
List all registered routes.
Register a new gateway route. Supports advanced pattern matching and HTTP method filtering.
Request:
{
"name": "users-api",
"path_prefix": "/users/{id}",
"target_url": "http://user-service:8080",
"methods": ["GET", "PUT"],
"strip_prefix": true,
"priority": 10
}Fields:
path_prefix: The pattern to match (e.g.,/api/*,/users/{id},/id/{id:[0-9]+}).methods: Array of allowed HTTP methods (empty/null = all).priority: Higher values take precedence when multiple patterns match.strip_prefix: If true, the matched part of the path is removed before forwarding.
Extracted Parameters:
Matched parameters like {id} are made available to downstream services as headers (in the future) and are currently injected into the gateway context.
Remove a route.
Headers Required: X-API-Key: <your-api-key>
List all deployed functions.
Create a new function.
{
"name": "hello-world",
"runtime": "nodejs20",
"code_zip": "<base64>"
}Invoke a function.
{
"payload": { "foo": "bar" },
"async": false
}Get execution logs.
Update a function's configuration (timeout, memory, handler, environment variables).
Environment variables — each entry can be either a plain-text value or a secret reference, but not both:
{
"handler": "newhandler.js",
"timeout": 300,
"memory_mb": 256,
"env_vars": [
{ "key": "FOO", "value": "bar" },
{ "key": "API_KEY", "secret_ref": "@my-api-key" }
]
}| Field | Type | Description |
|---|---|---|
key |
string | Env var name |
value |
string | Plain-text value (mutually exclusive with secret_ref) |
secret_ref |
string | Secret name reference with @ prefix (e.g. "@my-api-key") |
List all function schedules.
Create a scheduled function invocation.
{
"function_id": "uuid",
"name": "nightly-processing",
"schedule": "0 2 * * *",
"payload": {}
}Get a specific schedule.
Delete a schedule.
Pause a schedule.
Resume a paused schedule.
Get run history for a schedule.
Headers Required: X-API-Key: <your-api-key>
Search and filter historical platform logs.
Query Parameters:
resource_id: Filter by specific resource UUID.resource_type: Filter by type (instance,function).level: Filter by severity (INFO,WARN,ERROR).search: Keyword search in log messages.start_time: RFC3339 start timestamp.end_time: RFC3339 end timestamp.limit: Max results (default 100).offset: Pagination offset.
Get historical logs for a specific resource.
Parameters:
| Name | In | Type | Required | Description |
|---|---|---|---|---|
resource_id |
path | string | Yes | The UUID of the resource (instance or function) |
limit |
query | integer | No | Max logs to return |
Example:
curl -H "X-API-Key: $API_KEY" http://api.thecloud.local/logs/a1b2c3d4-5678-90ab-cdef-1234567890ab?limit=10Headers Required: X-API-Key: <your-api-key>
List all cache instances.
Provision a new Redis cache.
{
"name": "my-cache",
"memory_mb": 256
}Terminate a cache instance.
Headers Required: X-API-Key: <your-api-key>
List all queues.
Create a new message queue.
{
"name": "task-queue",
"visibility_timeout": 30
}Send a message.
{
"body": "payload-data"
}Receive messages.
Query params: ?count=1
Headers Required: X-API-Key: <your-api-key>
List topics.
Create a new topic.
Subscribe to a topic.
{
"topic_id": "uuid",
"protocol": "webhook",
"endpoint": "http://my-api/hook"
}Headers Required: X-API-Key: <your-api-key>
List scheduled jobs.
Create a scheduled job.
{
"name": "daily-cleanup",
"schedule": "0 0 * * *",
"target_url": "http://my-service/cleanup"
}Pause a job.
Resume a job.
Headers Required: X-API-Key: <your-api-key>
Constraint: These endpoints require PermissionFullAccess (Admin).
List all IAM policies.
Create a new granular IAM policy.
{
"name": "ReadOnlyS3",
"statements": [
{
"effect": "Allow",
"action": ["storage:list", "storage:get"],
"resource": ["*"]
}
]
}Get details of a specific policy.
Delete a policy.
Attach a policy to a specific user.
Detach a policy from a user.
List all policies attached to a specific user.
Headers Required: X-API-Key: <your-api-key>
Get billing summary for the current period.
Response:
{
"period_start": "2026-01-01T00:00:00Z",
"period_end": "2026-01-31T23:59:59Z",
"total_amount": 150.25,
"currency": "USD",
"usage_by_type": {
"compute": 45.50,
"storage": 12.75,
"database": 92.00
}
}List detailed usage records.
Headers Required: X-API-Key: <your-api-key>
List platform audit logs for the authenticated user/tenant.
Query Parameters:
limit: Max results (default 50).
Response:
[
{
"id": "uuid",
"timestamp": "2026-01-05T23:00:00Z",
"actor": "user@example.com",
"action": "INSTANCE_LAUNCH",
"resource": "instance/a1b2c3d4",
"status": "success",
"ip_address": "1.2.3.4"
}
]Headers Required: X-API-Key: <your-api-key>
List all Kubernetes clusters.
Create a new Kubernetes cluster (Asynchronous).
{
"name": "my-cluster",
"vpc_id": "vpc-uuid",
"version": "v1.29.0",
"workers": 3,
"ha": true
}Get detailed information and status.
Delete a cluster (Asynchronous).
Download the admin kubeconfig.
Get operational health (nodes ready, api server reachability).
Upgrade cluster version (Asynchronous).
{
"version": "v1.30.0"
}Scale worker nodes.
{
"workers": 5
}Re-run bootstrap scripts on nodes.
Trigger an etcd backup.
Restore etcd state from path.
{
"backup_path": "/backups/etcd-snapshot.db"
}| Status Code | Description |
|---|---|
| 200/201 | Success |
| 400 | Bad Request (Invalid input) |
| 401 | Unauthorized (Missing/Invalid API Key) |
| 403 | Forbidden (Access denied to resource) |
| 404 | Not Found |
| 429 | Too Many Requests (Rate limit exceeded) |
| 500 | Internal Server Error |