SparkCloud API Reference
The SparkCloud API lets you manage containers, spaces, databases, CDN files, and AI keys programmatically. All endpoints live under /api/v1/.
Authentication
Generate an API key in your Account settings under API Keys. Keys begin with sc_live_.
Pass your key on every request:
X-API-Key: sc_live_your_key_here
# — or —
Authorization: Bearer sc_live_your_key_here /admin/) require the admin role on your account.Errors
All responses are JSON. Errors return an error string. Successful mutations return a message string.
Error
{
"error": "Container not found"
}Success
{
"message": "Container stopped"
}Paginated endpoints accept ?page=1&limit=25 query parameters (max limit 100).
Account
Manage your own profile and credentials.
GET /api/v1/account
Returns your profile, credit balance, quotas, and current usage.
Response
{
"id": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
"username": "alice",
"email": "alice@example.com",
"role": "user",
"credits": 42.5,
"quotas": {
"containers": { "used": 1, "limit": 3 },
"spaces": { "used": 0, "limit": 2 },
"databases": { "used": 1, "limit": 2 }
},
"createdAt": "2025-01-15T10:00:00.000Z"
}PATCH /api/v1/account
Update your username and/or email address.
Request
{
"username": "alice2",
"email": "alice2@example.com"
}Response
{
"user": {
"id": "3f2504e0...",
"username": "alice2",
"email": "alice2@example.com",
"role": "user"
}
}POST /api/v1/account/change-password
Change your own account password.
Request
{
"currentPassword": "oldSecret123",
"newPassword": "newSecret456"
}Response
{
"message": "Password changed successfully"
}GET /api/v1/account/transactions
Paginated credit transaction history. Query: ?page=1&limit=25
Response
{
"transactions": [
{
"id": "uuid",
"amount": -0.002,
"type": "debit",
"description": "Container hourly billing",
"createdAt": "2025-03-07T12:00:00.000Z"
}
],
"page": 1,
"limit": 25,
"total": 84
}GET /api/v1/account/storage
Full storage usage breakdown for your account, including quota, allocated instances, and CDN files. Running/stopped instances report their allocated disk. Hibernated instances report their actual compressed snapshot size.
Response
{
"quota": {
"quotaGb": 0,
"allocatedGb": 15,
"cdnGb": 0.12,
"availableGb": 4.88
},
"totalBytes": 21474836480,
"totalMb": 20480,
"breakdown": {
"containers": {
"count": 2,
"allocatedBytes": 10737418240,
"snapshotBytes": 524288000,
"totalBytes": 11261706240
},
"spaces": {
"count": 1,
"allocatedBytes": 5368709120,
"snapshotBytes": 0,
"totalBytes": 5368709120
},
"databases": {
"count": 1,
"allocatedBytes": 5368709120,
"snapshotBytes": 0,
"totalBytes": 5368709120
},
"backups": {
"count": 3,
"totalBytes": 314572800
},
"cdn": {
"count": 12,
"totalBytes": 130023424
}
}
}Notifications
Platform notifications sent to your account.
GET /api/v1/notifications
List your notifications. Query: ?unread=true, ?page=1&limit=25.
Response
{
"notifications": [
{
"id": "uuid",
"title": "Container transferred",
"message": "Your container has been moved to a new node.",
"type": "info",
"read": false,
"link": "/containers/uuid",
"createdAt": "2025-03-07T12:00:00.000Z"
}
],
"page": 1,
"limit": 25,
"total": 3,
"unreadCount": 1
}Mark Notifications Read
/api/v1/notifications/:id/read/api/v1/notifications/read-allResponse
{ "message": "All notifications marked as read" }Delete Notifications
/api/v1/notifications/:idDelete one/api/v1/notificationsClear allResponse
{ "message": "All notifications cleared" }Vouchers
Redeem voucher codes to add credits to your account.
POST /api/v1/vouchers/redeem
Redeem a voucher code. Each code can only be redeemed once per user.
Request
{ "code": "ABCD-EFGH-WXYZ" }Response
{ "message": "Voucher redeemed successfully", "credits": 500 }Containers
Linux containers with full SSH access, a dedicated IP, and an optional extra port.
Compute & Images
/api/v1/containers/plansDynamic plan info & priceSparkCloud runs a single Dynamic plan: CPU and RAM fluctuate to your workload, so there is nothing to choose at create time.
Response
{
"plans": [
{ "id": "dynamic", "name": "Dynamic", "dynamic": true, "pricePerHour": 0.5,
"note": "CPU and RAM fluctuate to your workload — no plan selection needed." }
]
} /api/v1/containers/imagesList allowed imagesResponse
{ "images": [ { "value": "ubuntu:22.04", "label": "Spark Ubuntu 22.04 LTS" } ] }POST /api/v1/containers
Create a new container. The container is queued immediately and typically starts within 30–60 seconds. No plan to choose — CPU and RAM scale to the node automatically.
Request
{
"name": "my-ubuntu",
"image": "ubuntu:22.04",
"diskGb": 10
}Response
{
"container": {
"id": "uuid",
"name": "my-ubuntu",
"status": "queued",
"image": "ubuntu:22.04",
"subdomain": "myapp",
"host": "myapp.node1.yourdomain.com",
"sshPort": 32100,
"sshUser": "root",
"sshPassword": "xK9mP2qL...",
"hostname": "my-ubuntu",
"extraPort": 32101,
"ssh": {
"host": "1.2.3.4",
"port": 32100,
"user": "root",
"password": "xK9mP2qL...",
"command": "ssh root@1.2.3.4 -p 32100"
},
"createdAt": "2025-01-15T10:00:00.000Z"
},
"message": "Container queued for deployment"
}ubuntu:22.04 (Spark Ubuntu 22.04 LTS). Poll GET /containers/:id until status becomes running. Pass optional diskGb to allocate a specific amount of your storage quota to this container (default: 10GB).GET /api/v1/containers
List your containers. Query: ?status=running. Statuses: running, stopped, hibernated, creating, error.
Response
{
"containers": [
{
"id": "uuid",
"name": "my-ubuntu",
"status": "running",
"image": "ubuntu:22.04",
"subdomain": "myapp",
"host": "myapp.node1.yourdomain.com",
"sshPort": 32100,
"sshUser": "root",
"sshPassword": "xK9mP2qL...",
"hostname": "my-ubuntu",
"extraPort": 32101,
"hibernated": false,
"ssh": {
"host": "1.2.3.4",
"port": 32100,
"user": "root",
"password": "xK9mP2qL...",
"command": "ssh root@1.2.3.4 -p 32100"
},
"plan": { "name": "Nano", "cpu": 1, "memoryMb": 512, "diskGb": 10 },
"nodeRegion": "us-east-1",
"createdAt": "2025-01-15T10:00:00.000Z"
}
]
}GET /api/v1/containers/:id
Full details for a single container including SSH connection command.
Response
{
"id": "uuid",
"name": "my-ubuntu",
"status": "running",
"ssh": {
"host": "1.2.3.4",
"port": 32100,
"user": "root",
"password": "xK9mP2qL...",
"command": "ssh root@1.2.3.4 -p 32100"
},
"plan": { "id": "uuid", "name": "Nano", "cpu": 1, "memoryMb": 512, "diskGb": 10 },
"nodeRegion": "us-east-1",
"createdAt": "2025-01-15T10:00:00.000Z"
}DELETE /api/v1/containers/:id
Permanently destroy a container and all its data.
Response
{ "message": "Container destroyed" }Start / Stop / Restart
/api/v1/containers/:id/start/api/v1/containers/:id/stop/api/v1/containers/:id/restartNo request body required.
Response
{ "message": "Container started" }
{ "message": "Container stopped" }
{ "message": "Container restarted" }GET /api/v1/containers/:id/logs
Recent container logs. Query: ?tail=100 (max 500 lines).
Response
{
"logs": "Welcome to Ubuntu 22.04
...
root@my-ubuntu:~#",
"lines": 42
}POST /api/v1/containers/:id/exec
Run a shell command inside a running container.
Request
{ "command": "df -h && uptime" }Response
{
"output": "Filesystem Size Used
...",
"exitCode": 0
}POST /api/v1/containers/:id/regenerate-password
Generate a new SSH password. Applied instantly and saved to your account.
Response
{
"message": "Password regenerated",
"password": "nX7kQ2mPvRtL9s3J",
"ssh": {
"host": "1.2.3.4",
"port": 32100,
"user": "root",
"password": "nX7kQ2mPvRtL9s3J",
"command": "ssh root@1.2.3.4 -p 32100"
}
}Hibernate & Wake
Hibernation snapshots the filesystem to storage and deallocates compute. Storage charges continue; CPU/RAM charges stop.
/api/v1/containers/:id/hibernate/api/v1/containers/:id/unhibernateResponse
{ "message": "Container hibernated" }
{ "message": "Container is running" }PATCH /api/v1/containers/:id/storage
Reallocate disk storage for a container. The new allocation is saved immediately and applied to the Docker storage quota on the next restart. Must not exceed your available storage quota.
Request
{ "diskGb": 20 }Response
{
"message": "Storage updated. Restart to apply.",
"diskGb": 20
}GET /api/v1/account/storage. A restart is required for Docker to enforce the new limit.Spaces
Browser-based VS Code environments. Auto-hibernates after 30 minutes of inactivity.
GET /api/v1/spaces/plans
Spaces run on the single Dynamic plan — CPU and RAM scale to the node automatically.
Response
{
"plans": [
{ "id": "dynamic", "name": "Dynamic", "dynamic": true, "pricePerHour": 0.5 }
]
}POST /api/v1/spaces
Create a new dev space (browser VS Code). No plan to choose — CPU and RAM scale to the node automatically.
Request
{
"name": "my-workspace",
"diskGb": 10
}Response
{
"space": {
"id": "uuid",
"name": "my-workspace",
"status": "creating",
"subdomain": "myapp",
"host": "myapp.node1.yourdomain.com",
"webPort": 43210,
"createdAt": "2025-01-15T10:00:00.000Z"
},
"message": "Space is launching…"
}GET /spaces/:id until status is running, then open the space through the dashboard. Pass optional diskGb to allocate a specific amount of your storage quota (default: plan disk size).GET /api/v1/spaces
List your spaces. Query: ?status=running
Response
{
"spaces": [
{
"id": "uuid",
"name": "my-workspace",
"status": "running",
"subdomain": "myapp",
"host": "myapp.node1.yourdomain.com",
"webPort": 56100,
"hibernated": false,
"lastActiveAt": "2025-03-07T11:45:00.000Z",
"nodeRegion": "us-east-1",
"createdAt": "2025-02-01T08:00:00.000Z"
}
]
}GET /api/v1/spaces/:id
Response
{
"id": "uuid",
"name": "my-workspace",
"status": "running",
"subdomain": "myapp",
"host": "myapp.node1.yourdomain.com",
"webPort": 56100,
"hibernated": false,
"lastActiveAt": "2025-03-07T11:45:00.000Z",
"nodeRegion": "us-east-1",
"createdAt": "2025-02-01T08:00:00.000Z"
}DELETE /api/v1/spaces/:id
Response
{ "message": "Space deleted" }Start / Stop
/api/v1/spaces/:id/start/api/v1/spaces/:id/stopResponse
{ "message": "Space started" }
{ "message": "Space stopped" }Logs & Activity
/api/v1/spaces/:id/logsQuery: ?tail=100Response
{ "logs": "[16:42:05] INFO Server listening on :8080
..." } /api/v1/spaces/:id/activityResponse
{
"lastActiveAt": "2025-03-07T11:45:00.000Z",
"status": "running"
}Hibernate & Wake
/api/v1/spaces/:id/hibernate/api/v1/spaces/:id/unhibernateResponse
{ "message": "Space hibernated" }
{ "message": "Space is running" }PATCH /api/v1/spaces/:id/storage
Reallocate disk storage for a space. Saved immediately; applied to the Docker storage quota on next restart.
Request
{ "diskGb": 15 }Response
{
"message": "Storage updated. Restart to apply.",
"diskGb": 15
}Databases
Managed PostgreSQL with automated backups, SQL Studio, and table browser.
GET /api/v1/databases/pricing
Returns the current hourly credit cost and default resource specs for a new database.
Response
{
"pricePerHour": 1,
"engine": "postgresql",
"defaultDiskGb": 5,
"defaultMemoryMb": 512,
"defaultCpu": 1
}POST /api/v1/databases
Provision a new PostgreSQL database. Only a name is required — resources are fixed at the defaults shown in GET /databases/pricing. Pass optional diskGb to allocate a specific amount of your storage quota (default: 5 GB).
Request
{
"name": "my-db"
}Response
{
"database": {
"id": "uuid",
"name": "my-db",
"status": "creating",
"subdomain": "myapp",
"host": "myapp.node1.yourdomain.com",
"dbPort": 35000,
"dbName": "sparkcloud",
"dbUser": "sparkcloud",
"dbPassword": "auto-generated",
"connectionString": "postgresql://sparkcloud:pass@1.2.3.4:35000/sparkcloud",
"createdAt": "2025-01-15T10:00:00.000Z"
},
"message": "Database is provisioning…"
}GET /databases/:id until status is running. The connectionString is ready to use at that point.GET /api/v1/databases
List your databases. Query: ?status=running
Response
{
"databases": [
{
"id": "uuid",
"name": "my-postgres",
"status": "running",
"subdomain": "myapp",
"host": "myapp.node1.yourdomain.com",
"dbPort": 5432,
"dbName": "sparkcloud",
"dbUser": "sparkcloud",
"dbPassword": "secret123",
"connectionString": "postgresql://sparkcloud:secret123@1.2.3.4:5432/sparkcloud",
"hibernated": false,
"backupSchedule": "daily",
"nodeRegion": "us-east-1",
"createdAt": "2025-01-20T08:00:00.000Z"
}
]
}GET /api/v1/databases/:id
Response
{
"id": "uuid",
"name": "my-postgres",
"status": "running",
"connectionString": "postgresql://sparkcloud:secret123@1.2.3.4:5432/sparkcloud",
"backupSchedule": "daily",
"hibernated": false,
"nodeRegion": "us-east-1",
"createdAt": "2025-01-20T08:00:00.000Z"
}DELETE /api/v1/databases/:id
Response
{ "message": "Database destroyed" }Start / Stop / Restart
/api/v1/databases/:id/start/api/v1/databases/:id/stop/api/v1/databases/:id/restartResponse
{ "message": "Database started" }POST /api/v1/databases/:id/reset-password
Generate a new PostgreSQL password. Applied instantly. Returns a fresh connection string.
Response
{
"message": "Password reset",
"newPassword": "Xk9mQ2pL...",
"connectionString": "postgresql://sparkcloud:Xk9mQ2pL...@1.2.3.4:5432/sparkcloud"
}PATCH /api/v1/databases/:id/backup-schedule
Request
{ "schedule": "daily" } Values: "daily", "weekly", null
Response
{ "message": "Backup schedule set to daily" }POST /api/v1/databases/:id/query
Execute any SQL statement. Database must be running.
Request
{ "sql": "SELECT id, name FROM users LIMIT 3" }Response
{
"columns": ["id", "name"],
"rows": [["1","Alice"],["2","Bob"]],
"rowCount": 2,
"duration": 12
}GET /api/v1/databases/:id/tables
All tables in the public schema with column definitions.
Response
{
"tables": [
{
"name": "users",
"columns": [
{ "name": "id", "type": "uuid", "nullable": false },
{ "name": "email", "type": "text", "nullable": false }
]
}
]
}Backups
/api/v1/databases/:id/backupsListResponse
{
"backups": [
{
"id": "uuid",
"label": "Before migration",
"type": "manual",
"status": "ready",
"sizeBytes": 2097152,
"createdAt": "2025-03-07T10:00:00.000Z"
}
]
} /api/v1/databases/:id/backupsCreate manual backupRequest
{ "label": "Before migration" }Response
{ "message": "Backup started", "backup": { "id": "uuid" } }/api/v1/databases/:id/backups/:bid/restore{ "message": "Backup restored successfully" } /api/v1/databases/:id/backups/:bid{ "message": "Backup deleted" }Hibernate & Wake
/api/v1/databases/:id/hibernate/api/v1/databases/:id/unhibernateResponse
{ "message": "Database hibernated" }
{ "message": "Database is running" }PATCH /api/v1/databases/:id/storage
Reallocate disk storage for a database. Saved immediately; applied to the Docker storage quota on next restart.
Request
{ "diskGb": 10 }Response
{
"message": "Storage updated. Restart to apply.",
"diskGb": 10
}CDN Storage
Upload and serve files via SparkStore. Files get a permanent slug-based URL.
GET /api/v1/cdn/files
List your CDN files. Query: ?page=1&limit=25
Response
{
"files": [
{
"slug": "xK9mP2qL",
"filename": "photo.jpg",
"size": 204800,
"visibility": "private",
"url": "https://cdn.example.com/api/files/xK9mP2qL",
"createdAt": "2025-03-01T10:00:00.000Z"
}
],
"page": 1, "limit": 25, "total": 12
}POST /api/v1/cdn/upload
All uploads are private.
Option A — multipart/form-data
curl -X POST /api/v1/cdn/upload -H "X-API-Key: sc_live_..." -F "file=@photo.jpg" Option B — binary body
curl -X POST /api/v1/cdn/upload -H "X-API-Key: sc_live_..." -H "X-Filename: photo.jpg" --data-binary @photo.jpg Response
{
"slug": "xK9mP2qL",
"url": "https://cdn.example.com/api/files/xK9mP2qL",
"filename": "photo.jpg",
"size": 204800,
"visibility": "private"
}GET /api/v1/cdn/files/:slug
Response
{
"slug": "xK9mP2qL",
"filename": "photo.jpg",
"size": 204800,
"visibility": "private",
"url": "https://cdn.example.com/api/files/xK9mP2qL",
"createdAt": "2025-03-01T10:00:00.000Z"
}DELETE /api/v1/cdn/files/:slug
Response
{ "message": "File deleted" }AI Keys
Manage keys for SparkCloud's OpenAI-compatible proxy at /api/ai/v1/.
GET /api/v1/ai/keys
Response
{
"keys": [
{
"id": "uuid",
"name": "My App",
"prefix": "sc-ai-3f2504e0…",
"createdAt": "2025-02-15T10:00:00.000Z"
}
]
}POST /api/v1/ai/keys
Request
{ "name": "Production App" }Response
{
"id": "uuid",
"name": "Production App",
"key": "sc-ai-3f2504e04f89..."
}DELETE /api/v1/ai/keys/:id
Response
{ "message": "AI key deleted" }