Authentication
All API requests require authentication via a Bearer token in the header:
Authorization: Bearer YOUR_API_KEYGenerating API Keys
- Go to Dashboard → Settings → API Keys
- Click Create New Key
- Give it a descriptive name
- Copy the key immediately (it won't be shown again)
Important: API keys have the same permissions as your account. Keep them secret and rotate regularly.
Base URL
https://hostwares.com/apiAll endpoints are relative to this base URL. Responses are JSON.
Sites API
| Method | Endpoint | Description |
|---|---|---|
GET | /sites | List all your sites |
POST | /sites | Create a new site |
GET | /sites/:id | Get site details |
PATCH | /sites/:id | Update site or trigger action |
DELETE | /sites/:id | Delete a site |
Create a site
POST /api/sites
{
"name": "my-nextjs-app",
"type": "github",
"repository": "github.com/user/my-app",
"branch": "main",
"port": 3000,
"buildCommand": "npm run build",
"startCommand": "npm start"
}Response
{
"id": "cm1234abcd",
"name": "my-nextjs-app",
"status": "DEPLOYING",
"domain": null,
"createdAt": "2026-05-20T10:30:00Z",
"url": "https://hostwares.com/api/sites/cm1234abcd"
}Databases API
| Method | Endpoint | Description |
|---|---|---|
GET | /databases | List all databases |
POST | /databases | Create a database |
GET | /databases/:id | Get database details |
PATCH | /databases/:id | Update or trigger action |
DELETE | /databases/:id | Delete a database |
Create a database
POST /api/databases
{
"name": "production-db",
"type": "postgresql"
}Credits API
| Method | Endpoint | Description |
|---|---|---|
GET | /credits | Get current balance |
GET | /credits/transactions | Transaction history |
GET | /credits/packages | Available packages |
POST | /credits/purchase | Purchase credits |
Check balance
GET /api/credits
Response:
{
"balance": 450,
"lastPurchase": "2026-05-15T08:00:00Z"
}Site Actions
Use PATCH with an action field to control site state:
PATCH /api/sites/:id
{ "action": "restart" }Available actions
| Action | Description | Requires Confirmation |
|---|---|---|
start | Start a stopped container | No |
stop | Stop a running container | No |
restart | Restart the container | No |
deploy | Trigger a new deployment | No |
delete | Delete site permanently | Yes |
Error Handling
All errors return consistent JSON with an error code and message:
{
"error": "NOT_FOUND",
"message": "Site not found or you don't have access",
"statusCode": 404
}Common error codes
| Status | Code | Meaning |
|---|---|---|
| 400 | BAD_REQUEST | Invalid request body or parameters |
| 401 | UNAUTHORIZED | Missing or invalid API key |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | NOT_FOUND | Resource not found |
| 429 | RATE_LIMITED | Too many requests |
| 500 | INTERNAL_ERROR | Server error (retry later) |
Rate Limits
- 60 requests per minute per API key
- Rate limit headers included in every response:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1716210000When rate limited, wait until the reset timestamp before retrying.
Code Examples
Node.js (fetch)
const response = await fetch('https://hostwares.com/api/sites', {
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
}
});
const sites = await response.json();Python (requests)
import requests
headers = {"Authorization": "Bearer YOUR_API_KEY"}
response = requests.get("https://hostwares.com/api/sites", headers=headers)
sites = response.json()cURL
curl -X GET https://hostwares.com/api/sites \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"Deploy a site via API
curl -X POST https://hostwares.com/api/sites \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "my-app",
"type": "github",
"repository": "github.com/user/my-app",
"branch": "main"
}'