Introduction
The SparrowHost API is a REST API that gives you full programmatic control over your cloud infrastructure. Every action available in the dashboard â deploying servers, starting and stopping instances, viewing invoices â is available through the API.
All requests are made over HTTPS to https://api.sparrowhost.net. Requests and responses use JSON. All monetary values are in Indian Rupees (âš / INR).
Authentication
The API uses Bearer token authentication. Pass your API key in the Authorization header with every request.
Authorization: Bearer sph_your_api_key_hereGetting an API key
API keys are generated from the SparrowHost dashboard:
- Log in to your SparrowHost dashboard.
- Navigate to Account â API Keys.
- Click + Create API Key.
- Give your key a name, select the required scopes, and optionally set an IP allowlist or expiry date.
- Copy the key â it is shown only once. Store it securely (e.g., an environment variable).
Key format
API keys always start with the prefix sph_ followed by 48 hex characters (192 bits of entropy). Example:
sph_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6IP allowlisting
When creating a key you can restrict it to specific IPv4 or IPv6 addresses. Requests arriving from unlisted IPs will be rejected with a 403 Forbidden response.
Key expiry
Keys can have an optional expiry date. Expired keys return 401 Unauthorized. You can also revoke a key at any time from the dashboard.
Scopes
Every API key has one or more scopes that determine what actions it can perform. Select only the scopes your use-case needs (principle of least privilege).
| Scope | Description | Endpoints |
|---|---|---|
vps:read | List and view servers | GET /servers, GET /servers/:id |
vps:write | Start, stop, reboot, shutdown, rename servers | POST /servers/:id/actions, PATCH /servers/:id |
vps:deploy | Create new servers (requires âš1,000 balance) | POST /servers |
vps:delete | Permanently delete servers | DELETE /servers/:id |
billing:read | View account balance and invoices (returned in /account) | GET /account |
GET /api/v1/account does not require a scope â any valid key can call it.Rate Limits
The API enforces rate limits per API key to ensure fair usage.
| Limit | Value |
|---|---|
| Requests per minute (per key) | 120 |
| Concurrent deploys | 5 |
| Max API keys per account | 10 |
When you exceed the rate limit, the API returns 429 Too Many Requests. Back off exponentially and retry.
Responses & Errors
Success envelope
All successful responses are wrapped in a standard envelope:
{
"success": true,
"data": { ... }
}Error envelope
{
"success": false,
"message": "Human-readable error description"
}HTTP status codes
| Code | Meaning |
|---|---|
| 200 OK | Request succeeded. |
| 201 Created | Resource was created (e.g., server deployed). |
| 400 Bad Request | Missing or invalid request parameters. |
| 401 Unauthorized | API key is missing, invalid, expired, or revoked. |
| 402 Payment Required | Account balance too low (minimum âš1,000 required). |
| 403 Forbidden | Key lacks the required scope, or request IP not in allowlist. |
| 404 Not Found | The requested resource does not exist. |
| 409 Conflict | Operation conflicts with the current resource state. |
| 429 Too Many Requests | Rate limit exceeded. Retry after backing off. |
| 500 Internal Server Error | Something went wrong on our side. Contact support. |
Account
Returns the authenticated account's profile and current balance. No scope required.
Response
{
"success": true,
"data": {
"id": "clxyz123",
"name": "Anant Pandey",
"email": "anant@sparrowhost.in",
"balance": "2500.00",
"currency": "INR",
"kycVerified": true
}
}List Servers
Returns all VPS servers belonging to the authenticated account. Requires the vps:read scope.
Response
{
"success": true,
"data": [
{
"id": "clserver123",
"name": "test.com",
"status": "running",
"ipv4": "192.0.2.10",
"ipv6": null,
"region": "in-noida-1",
"plan": "vps-amd-2vcpu-4gb",
"os": "Ubuntu 24.04 LTS",
"cpuCores": 2,
"ramMb": 4096,
"diskGb": 80,
"bandwidthGb": 2000,
"monthlyPrice": "850.00",
"createdAt": "2026-01-15T10:00:00.000Z"
}
]
}Get Server
Returns details for a single server. Requires vps:read.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The server ID (CUID). |
Response
Same shape as a single item from the list endpoint above.
Deploy Server
Provisions a new VPS server. Requires the vps:deploy scope. Your account balance must be at least âš1,000 before this call will succeed.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Hostname / label for the server (e.g. web-01). |
productId | string | Yes | The plan ID to deploy (from the pricing page). |
regionId | string | Yes | Region identifier (e.g. in-noida-1). |
osId | string | Yes | OS template ID (e.g. ubuntu-24-04). |
sshKeyId | string | No | SSH key ID to inject at deploy time. |
{
"name": "web-01",
"productId": "vps-amd-2vcpu-4gb",
"regionId": "in-noida-1",
"osId": "ubuntu-24-04"
}Response
{
"success": true,
"data": {
"id": "clserver456",
"name": "web-01",
"status": "provisioning",
"ipv4": null,
"region": "in-noida-1",
"plan": "vps-amd-2vcpu-4gb",
"createdAt": "2026-05-08T12:00:00.000Z"
}
}status will be provisioning immediately after creation. Poll GET /api/v1/servers/:id every 5 seconds until it transitions to running.Server Actions
Perform a power or lifecycle action on a server. Requires vps:write.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The server ID. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
action | string | Yes | One of: start, stop, reboot, shutdown, poweron, poweroff |
{ "action": "reboot" }Actions reference
| Action | Description |
|---|---|
start | Power on a stopped server. |
stop | Force power off (equivalent to pulling the plug). |
reboot | Graceful OS reboot. |
shutdown | Graceful OS shutdown (ACPI power off). |
poweron | Alias for start. |
poweroff | Alias for stop. |
Response
{
"success": true,
"data": { "message": "reboot initiated" }
}Rename Server
Update the display name / hostname label of a server. Requires vps:write.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | The new hostname / label (3â63 chars). |
{ "name": "api-server-prod" }Response
{
"success": true,
"data": { "id": "clserver123", "name": "api-server-prod" }
}Delete Server
Permanently terminates and deletes a server and all its data. This action is irreversible. Requires vps:delete.
Response
{
"success": true,
"data": { "message": "Server deleted successfully" }
}Examples
Check your balance (curl)
curl -s \
-H "Authorization: Bearer sph_your_key_here" \
https://api.sparrowhost.net/api/v1/account | jq .data.balanceList all servers
curl -s \
-H "Authorization: Bearer sph_your_key_here" \
https://api.sparrowhost.net/api/v1/servers | jq .Reboot a server
curl -s -X POST \
-H "Authorization: Bearer sph_your_key_here" \
-H "Content-Type: application/json" \
-d '{"action":"reboot"}' \
https://api.sparrowhost.net/api/v1/servers/clserver123/actionsDeploy a new server
curl -s -X POST \
-H "Authorization: Bearer sph_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "web-01",
"productId": "vps-amd-2vcpu-4gb",
"regionId": "in-noida-1",
"osId": "ubuntu-24-04"
}' \
https://api.sparrowhost.net/api/v1/serversNode.js example
const API_KEY = process.env.SPARROWHOST_API_KEY;
const BASE = "https://api.sparrowhost.net";
async function listServers() {
const res = await fetch(`${BASE}/api/v1/servers`, {
headers: { Authorization: `Bearer ${API_KEY}` },
});
const { data } = await res.json();
return data; // array of servers
}
async function rebootServer(id) {
const res = await fetch(`${BASE}/api/v1/servers/${id}/actions`, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ action: "reboot" }),
});
return res.json();
}
listServers().then(console.log);Python example
import os, requests
API_KEY = os.environ["SPARROWHOST_API_KEY"]
BASE = "https://api.sparrowhost.net"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
# List servers
servers = requests.get(f"{BASE}/api/v1/servers", headers=HEADERS).json()["data"]
# Reboot first server
server_id = servers[0]["id"]
requests.post(
f"{BASE}/api/v1/servers/{server_id}/actions",
headers=HEADERS,
json={"action": "reboot"},
)Introduction
NestDeploy is SparrowHost's platform-as-a-service layer for deploying frontends and full-stack apps â Next.js, Vite, Astro, SvelteKit, Nuxt, Docker images, and more. The NestDeploy API is available under the same base URL and uses the same API key as the VPS API.
Every app lives inside a project automatically created for your account when you first call POST /api/v1/nestdeploy/apps. Deployments are handled by a Dokploy/Traefik stack on SparrowHost infrastructure â SSL is automatic via Let's Encrypt.
https://api.sparrowhost.net/api/v1/nestdeployAuthentication
NestDeploy uses the same Bearer token as the VPS API. Use a key with the nestdeploy:manage scope.
Authorization: Bearer sph_your_api_key_here| Scope | Description |
|---|---|
nestdeploy:manage | Full access â create, deploy, configure, and delete apps. |
nestdeploy:read | Read-only â list apps and fetch deployment logs. |
List Apps
Returns all NestDeploy apps for the authenticated account. Requires nestdeploy:read.
Response
{
"success": true,
"data": [
{
"id": "ndapp_abc123",
"name": "my-frontend",
"status": "running",
"framework": "nextjs",
"branch": "main",
"primaryDomain": "my-frontend.nestdeploy.app",
"lastDeployedAt": "2026-05-20T08:30:00.000Z",
"createdAt": "2026-05-01T10:00:00.000Z"
}
]
}Create App
Creates a new NestDeploy app and links it to a Git repository. Requires nestdeploy:manage.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | App name (used in the auto-generated subdomain). |
repoUrl | string | Yes | Full HTTPS or SSH URL of the Git repository. |
branch | string | Yes | Git branch to deploy (e.g. main). |
buildType | string | No | One of: nixpacks (default), dockerfile, static, railpack. |
publishDir | string | No | Output directory for static builds (e.g. dist, out). |
env | object | No | Key-value map of environment variables. |
{
"name": "my-frontend",
"repoUrl": "https://github.com/you/my-frontend",
"branch": "main",
"buildType": "nixpacks",
"env": {
"NEXT_PUBLIC_API_URL": "https://api.example.com"
}
}Response
{
"success": true,
"data": {
"id": "ndapp_abc123",
"name": "my-frontend",
"status": "idle",
"primaryDomain": "my-frontend.nestdeploy.app",
"createdAt": "2026-05-20T08:00:00.000Z"
}
}Get App
Returns full details for a single app. Requires nestdeploy:read.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The app ID returned by Create App. |
Response
{
"success": true,
"data": {
"id": "ndapp_abc123",
"name": "my-frontend",
"status": "running",
"framework": "nextjs",
"repoUrl": "https://github.com/you/my-frontend",
"branch": "main",
"buildType": "nixpacks",
"primaryDomain": "my-frontend.nestdeploy.app",
"customDomains": ["app.mycustomersite.com"],
"lastDeployedAt": "2026-05-20T08:30:00.000Z",
"createdAt": "2026-05-01T10:00:00.000Z"
}
}Deploy App
Triggers a fresh build and deployment from the configured Git branch. Requires nestdeploy:manage.
GET /api/v1/nestdeploy/apps/:id/logs SSE endpoint.Response
{
"success": true,
"data": {
"deploymentId": "dep_xyz789",
"status": "building"
}
}Set Environment Variables
Replaces the app's environment variables with the supplied key-value map. Changes take effect on the next deployment. Requires nestdeploy:manage.
Request body
{
"env": {
"NEXT_PUBLIC_API_URL": "https://api.example.com",
"DATABASE_URL": "postgresql://user:pass@host/db",
"NODE_ENV": "production"
}
}Response
{
"success": true,
"data": { "message": "Environment variables updated. Redeploy to apply." }
}Add Custom Domain
Attaches a custom domain to an app and provisions a Let's Encrypt TLS certificate automatically. Requires nestdeploy:manage.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
host | string | Yes | The domain to attach (e.g. app.mycustomersite.com). |
ssl | boolean | No | Enable HTTPS via Let's Encrypt (default: true). |
{ "host": "app.mycustomersite.com", "ssl": true }DNS setup
Before adding a custom domain, create a CNAME record pointing your domain to the auto-generated NestDeploy hostname shown on your app detail page (e.g. my-frontend.nestdeploy.app).
| Type | Name | Value |
|---|---|---|
| CNAME | app | my-frontend.nestdeploy.app |
Response
{
"success": true,
"data": {
"host": "app.mycustomersite.com",
"ssl": true,
"certStatus": "provisioning"
}
}certStatus will transition from provisioning to active once Let's Encrypt issues the certificate (typically under 60 seconds after DNS propagates).Stream Build Logs
Opens a Server-Sent Events (SSE) stream that emits live build and runtime log lines. The connection stays open until the deployment finishes or the client disconnects. Requires nestdeploy:read.
Query parameters
| Parameter | Type | Description |
|---|---|---|
deploymentId | string | Optional. Stream logs for a specific deployment. Omit to stream the latest. |
Event stream format
curl -N \
-H "Authorization: Bearer sph_your_key_here" \
"https://api.sparrowhost.net/api/v1/nestdeploy/apps/ndapp_abc123/logs"
# Example output:
data: {"line":"[nixpacks] Detected Next.js","ts":"2026-05-20T08:30:01Z"}
data: {"line":"[build] npm run build...","ts":"2026-05-20T08:30:04Z"}
data: {"line":"[deploy] Container started","ts":"2026-05-20T08:31:22Z"}
data: {"type":"done","status":"running"}App Actions
Perform lifecycle actions on a deployed app. Requires nestdeploy:manage.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
action | string | Yes | One of: start, stop, redeploy, rollback. |
deploymentId | string | No | Required only for rollback â the deployment ID to roll back to. |
Actions reference
| Action | Description |
|---|---|
start | Start a stopped app container without rebuilding. |
stop | Stop the running container (app goes offline). |
redeploy | Pull latest code from Git and rebuild from scratch. |
rollback | Restore a previous deployment snapshot (requires deploymentId). |
{ "action": "rollback", "deploymentId": "dep_prev456" }Response
{
"success": true,
"data": { "message": "rollback initiated", "deploymentId": "dep_prev456" }
}Delete App
Permanently removes the app, all its deployments, domains, and associated containers. This action is irreversible. Requires nestdeploy:manage.
Response
{
"success": true,
"data": { "message": "App deleted successfully" }
}Changelog
| Date | Version | Changes |
|---|---|---|
| 4 Jun 2026 | v1.1 | Added NestDeploy API: apps CRUD, deploy, env vars, custom domains, SSE logs, actions, rollback. |
| 8 May 2026 | v1.0 | Initial release. Endpoints: account, servers (CRUD), server actions. |