HostBay Developer Portal

Complete API for domain registration, DNS management, and web hosting automation

Get Started API Reference

Platform Features

🌐

Domain Management

Register, transfer, and manage 200+ TLDs with HostBay

🔧

DNS Automation

Full Cloudflare DNS control with A, AAAA, CNAME, MX, TXT records

đŸ–Ĩī¸

cPanel Hosting

Provision and manage hosting with email, databases, and SSL

🔐

Secure Auth

API keys with granular permissions and rate limiting

📊

Real-time Monitoring

Track domain status, DNS propagation, and SSL certificates

đŸ’ŗ

Wallet Management

Easy balance management with flexible payment options

Quick Start

Get started with HostBay API in minutes with code examples in multiple languages

Step 1: Get Your API Key

Create an API key through the HostBay Telegram bot

Step 2: Make Your First Request

# List your domains
curl -X GET "https://api.hostbay.io/api/v1/domains" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Register a new domain (using HostBay contacts - easiest method)
curl -X POST "https://api.hostbay.io/api/v1/domains/register" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain_name": "example.com",
    "period": 1,
    "use_hostbay_contacts": true
  }'

Install SDK

pip install requests

Example Code

import requests

# Configuration
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.hostbay.io/api/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}

# List domains
response = requests.get(f"{BASE_URL}/domains", headers=headers)
domains = response.json()
print(f"Your domains: {domains}")

# Register a domain (using HostBay contacts - easiest method)
domain_data = {
    "domain_name": "example.com",
    "period": 1,
    "use_hostbay_contacts": True
}

response = requests.post(
    f"{BASE_URL}/domains/register",
    headers=headers,
    json=domain_data
)
result = response.json()
print(f"Registration result: {result}")

Install SDK

npm install axios

Example Code

const axios = require('axios');

// Configuration
const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.hostbay.io/api/v1';
const headers = { Authorization: `Bearer ${API_KEY}` };

// List domains
async function listDomains() {
    const response = await axios.get(`${BASE_URL}/domains`, { headers });
    console.log('Your domains:', response.data);
}

// Register a domain (using HostBay contacts - easiest method)
async function registerDomain() {
    const domainData = {
        domain_name: 'example.com',
        period: 1,
        use_hostbay_contacts: true
    };
    
    const response = await axios.post(
        `${BASE_URL}/domains/register`,
        domainData,
        { headers }
    );
    console.log('Registration result:', response.data);
}

// Run examples
listDomains();
registerDomain();

Example Code

 'example.com',
    'period' => 1,
    'use_hostbay_contacts' => true
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $BASE_URL . '/domains/register');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($domainData));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$result = json_decode($response, true);
curl_close($ch);

echo "Registration result: ";
print_r($result);
?>

Comprehensive Guides & Tutorials

🔐 Authentication Guide

Step 1: Create an API Key

You can create API keys through the HostBay Telegram bot:

  1. Open the HostBay bot on Telegram
  2. Navigate to Main Menu → API Management
  3. Click "Create New API Key"
  4. Set permissions (Domains, DNS, Hosting, Wallet)
  5. Copy your API key (shown only once!)

Step 2: Authenticate Your Requests

Include your API key in the Authorization header:

Authorization: Bearer YOUR_API_KEY

Security Best Practices

  • ✅ Never commit API keys to version control
  • ✅ Use environment variables for storing keys
  • ✅ Create separate keys for different applications
  • ✅ Rotate keys regularly (every 90 days recommended)
  • ✅ Use minimal permissions (principle of least privilege)
  • ✅ Monitor API usage in the Telegram bot dashboard

Permissions Explained

Domains: Register, transfer, renew, and manage domain names

DNS: Create, update, delete DNS records (A, AAAA, CNAME, MX, TXT)

Hosting: Provision hosting, manage cPanel accounts, SSL certificates

Wallet: View balance, make payments, transaction history

API Keys: Manage other API keys (admin permission)

Rate Limiting

⚡ Default Limits

  • Hourly Limit: 1,000 requests per hour
  • Daily Limit: 10,000 requests per day
  • Burst Protection: Max 100 requests in 60 seconds

Rate Limit Headers:

  • X-RateLimit-Limit - Maximum requests allowed
  • X-RateLimit-Remaining - Requests remaining in current window
  • X-RateLimit-Reset - Unix timestamp when limit resets

💡 If you exceed rate limits, you'll receive HTTP 429 (Too Many Requests). Custom limits available for enterprise customers.

💰 Wallet Balance & Financial Safety

âš ī¸ Insufficient Balance Protection

All financial operations (domain registration, hosting, renewals) check wallet balance before processing. You'll receive a clear error if balance is insufficient:

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Insufficient wallet balance. Required: $35.58, Available: $15.00",
    "details": {
      "required": 35.58,
      "available": 15.0,
      "shortage": 20.58
    }
  },
  "timestamp": 1761937123
}

Best Practices:

  • Always check wallet balance before initiating purchases
  • Use GET /api/v1/wallet/balance to verify available funds
  • Monitor balance via webhook notifications for low balance alerts
  • Implement retry logic for 400 errors with balance checks

🌐 Domain Management Tutorial

Two Registration Modes

HostBay API offers flexible domain registration with two approaches:

🚀 Option 1: HostBay-Managed Contacts (Simplest)

Best for: Quick integrations, resellers, and automated systems

How it works: Set use_hostbay_contacts: true - HostBay handles all contact information automatically, just like our Telegram bot does.

Advantage: Minimal API payload, fastest integration, no contact data management needed

🔧 Option 2: User-Provided Contacts (Full Control)

Best for: Enterprise, end-user portals, custom WHOIS data

How it works: Provide complete contacts object with registrant details

Advantage: Full WHOIS control, custom contact information visible in domain registration

Registering with HostBay Contacts (Simple Mode)

The easiest way to register - no contact information required:

curl -X POST "https://api.hostbay.io/api/v1/domains/register" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain_name": "example.com",
    "period": 1,
    "use_hostbay_contacts": true,
    "auto_renew": true
  }'
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.hostbay.io/api/v1"

# Simple registration with HostBay contacts
domain_data = {
    "domain_name": "example.com",
    "period": 1,
    "use_hostbay_contacts": True,
    "auto_renew": True
}

headers = {"Authorization": f"Bearer {API_KEY}"}
response = requests.post(
    f"{BASE_URL}/domains/register",
    headers=headers,
    json=domain_data
)

result = response.json()
print(f"Domain registered: {result['data']['domain_name']}")
print(f"Final price (with 10% API discount): ${result['data']['pricing']['final_price']}")
const axios = require('axios');

const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.hostbay.io/api/v1';

async function registerDomain() {
    const domainData = {
        domain_name: 'example.com',
        period: 1,
        use_hostbay_contacts: true,
        auto_renew: true
    };
    
    const response = await axios.post(
        `${BASE_URL}/domains/register`,
        domainData,
        { headers: { Authorization: `Bearer ${API_KEY}` } }
    );
    
    console.log(`Domain registered: ${response.data.data.domain_name}`);
    console.log(`Price (10% API discount): $${response.data.data.pricing.final_price}`);
}

registerDomain();

Registering with Custom Contacts (Full Control)

Provide your own contact information for WHOIS registration:

curl -X POST "https://api.hostbay.io/api/v1/domains/register" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain_name": "example.com",
    "period": 1,
    "contacts": {
      "registrant": {
        "first_name": "John",
        "last_name": "Doe",
        "email": "john@example.com",
        "phone": "+1.2025551234",
        "address": "123 Main St",
        "city": "New York",
        "state": "NY",
        "postal_code": "10001",
        "country": "US",
        "company": "Example Inc"
      }
    },
    "auto_renew": true,
    "privacy_protection": true
  }'
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.hostbay.io/api/v1"

# Domain registration data
domain_data = {
    "domain_name": "example.com",
    "period": 1,
    "contacts": {
        "registrant": {
            "first_name": "John",
            "last_name": "Doe",
            "email": "john@example.com",
            "phone": "+1.2025551234",
            "address": "123 Main St",
            "city": "New York",
            "state": "NY",
            "postal_code": "10001",
            "country": "US",
            "company": "Example Inc"
        }
    },
    "auto_renew": True,
    "privacy_protection": True
}

headers = {"Authorization": f"Bearer {API_KEY}"}
response = requests.post(
    f"{BASE_URL}/domains/register",
    headers=headers,
    json=domain_data
)

result = response.json()
print(f"Domain registered: {result['data']['domain_name']}")
print(f"Privacy enabled: {result['data']['privacy_enabled']}")
const axios = require('axios');

const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.hostbay.io/api/v1';

async function registerDomain() {
    const domainData = {
        domain_name: 'example.com',
        period: 1,
        contacts: {
            registrant: {
                first_name: 'John',
                last_name: 'Doe',
                email: 'john@example.com',
                phone: '+1.2025551234',
                address: '123 Main St',
                city: 'New York',
                state: 'NY',
                postal_code: '10001',
                country: 'US',
                company: 'Example Inc'
            }
        },
        auto_renew: true,
        privacy_protection: true
    };
    
    const response = await axios.post(
        `${BASE_URL}/domains/register`,
        domainData,
        { headers: { Authorization: `Bearer ${API_KEY}` } }
    );
    
    console.log(`Domain registered: ${response.data.data.domain_name}`);
    console.log(`Privacy enabled: ${response.data.data.privacy_enabled}`);
}

registerDomain();

Transferring a Domain

Transfer an existing domain to HostBay:

POST /api/v1/domains/transfer

{
  "domain_name": "existing-domain.com",
  "auth_code": "EPP-AUTH-CODE-HERE",
  "period": 1
}

Renewing a Domain

Renew before expiration to maintain ownership:

POST /api/v1/domains/{domain_name}/renew

{
  "period": 1
}

Managing Auto-Renewal

Enable or disable automatic renewal:

PATCH /api/v1/domains/{domain_name}

{
  "auto_renew": true
}

WHOIS Privacy Protection

HostBay offers comprehensive WHOIS privacy protection to shield your personal information from public WHOIS lookups. Privacy protection works differently based on how your domain is registered:

🔒 How Privacy Protection Works

HostBay-Managed Contacts:

  • Domains registered with use_hostbay_contacts: true use our shared privacy contact by default
  • Privacy toggle simply updates the database flag - no WHOIS changes needed
  • Your real contact is never exposed in WHOIS

User-Provided Contacts:

  • When privacy is enabled: Your real contact is stored securely in our database, and Privacy Guard contact (Iceland-based) is used in WHOIS
  • When privacy is disabled: Your original contact information is restored to WHOIS

Privacy Guard Contact Details (WHOIS Replacement):

Name: Domain Privacy Guard

Company: Whois Privacy Service

Email: cloakhost@tutamail.com

Phone: +354.4212434

Address: P.O. Box 123, Privacy Dept.

City: Reykjavik, Capital Region

Postal Code: 101

Country: Iceland (IS)

Enable Privacy During Registration

Set privacy_protection: true when registering a domain:

POST /api/v1/domains/register

{
  "domain_name": "example.com",
  "period": 1,
  "use_hostbay_contacts": false,
  "privacy_protection": true,
  "contacts": {
    "registrant": {
      "first_name": "John",
      "last_name": "Doe",
      "email": "john@example.com",
      "phone": "+1.2025551234",
      "address": "123 Main St",
      "city": "New York",
      "state": "NY",
      "postal_code": "10001",
      "country": "US"
    }
  }
}

# Result: Domain registered with Privacy Guard contact in WHOIS
# John Doe's real contact stored securely for later restoration

Toggle Privacy on Existing Domains

Enable or disable privacy protection anytime:

# Enable privacy protection
curl -X POST "https://api.hostbay.io/api/v1/domains/example.com/privacy/enable" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Disable privacy protection (restore original contact)
curl -X POST "https://api.hostbay.io/api/v1/domains/example.com/privacy/disable" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Check privacy status
curl -X GET "https://api.hostbay.io/api/v1/domains/example.com" \
  -H "Authorization: Bearer YOUR_API_KEY"
# Returns: privacy_enabled: true/false, contact_type: "hostbay_managed" or "user_provided"
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.hostbay.io/api/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}

# Enable privacy
response = requests.post(
    f"{BASE_URL}/domains/example.com/privacy/enable",
    headers=headers
)
print(response.json())
# {"success": true, "message": "Privacy protection enabled"}

# Disable privacy
response = requests.post(
    f"{BASE_URL}/domains/example.com/privacy/disable",
    headers=headers
)
print(response.json())
# {"success": true, "message": "Privacy protection disabled"}

# Check status
response = requests.get(
    f"{BASE_URL}/domains/example.com",
    headers=headers
)
domain = response.json()["data"]
print(f"Privacy enabled: {domain['privacy_enabled']}")
print(f"Contact type: {domain['contact_type']}")
const axios = require('axios');

const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.hostbay.io/api/v1';
const headers = { Authorization: `Bearer ${API_KEY}` };

// Enable privacy
const enableResponse = await axios.post(
    `${BASE_URL}/domains/example.com/privacy/enable`,
    {},
    { headers }
);
console.log(enableResponse.data);
// {"success": true, "message": "Privacy protection enabled"}

// Disable privacy
const disableResponse = await axios.post(
    `${BASE_URL}/domains/example.com/privacy/disable`,
    {},
    { headers }
);
console.log(disableResponse.data);
// {"success": true, "message": "Privacy protection disabled"}

// Check status
const domain = await axios.get(
    `${BASE_URL}/domains/example.com`,
    { headers }
);
console.log(`Privacy: ${domain.data.data.privacy_enabled}`);
console.log(`Contact type: ${domain.data.data.contact_type}`);
✅ Privacy Protection Best Practices:
  • Always enable privacy for personal/individual domains
  • Privacy is idempotent - safe to call enable/disable multiple times
  • For HostBay-managed contacts, privacy toggle is instant (no WHOIS update needed)
  • For user contacts, privacy changes are applied to WHOIS within minutes
  • Original contact data is stored securely and can be restored anytime
💡 Pro Tips:
  • Always enable auto-renew to avoid losing domains
  • Enable privacy protection for personal domains during registration
  • Check domain availability before registration
  • Keep contact information up to date
  • Transfer domains at least 60 days before expiration
  • Use HostBay-managed contacts for fastest integration

🔄 Auto-Renewal Management: Best Practices

Auto-renewal prevents service interruptions by automatically renewing hosting before expiration using your wallet balance.

📚 Quick Navigation:

When to Enable Auto-Renewal

  • Production websites: Always enable to prevent downtime
  • Critical services: Business-critical hosting should have auto-renewal enabled
  • Long-term projects: Set-and-forget solution for ongoing projects
  • Default recommendation: Enable auto-renewal for all hosting unless you plan to discontinue the service

When to Disable Auto-Renewal

  • Temporary projects: Short-term testing environments or demos
  • Migration planned: When planning to move hosting to another provider
  • Cost control: When you want manual approval for each renewal
  • Service discontinuation: When planning to shut down the website

Notification System

  • 3 days before expiration: Warning notification if auto-renewal is enabled
  • Insufficient funds warning: Notified if wallet balance is too low for renewal
  • Renewal success: Confirmation message when auto-renewal completes
  • Renewal failure: Alert if auto-renewal fails (e.g., insufficient balance)

Grace Period & Recovery

  • 7-day plans: 1-day grace period after expiration
  • 30-day plans: 2-day grace period after expiration
  • During grace period: Service continues running, manual renewal available
  • After grace period: Service suspended, requires manual intervention
  • Recovery option: Manual renewal endpoint available at any time

Wallet Balance Management

  • Maintain buffer: Keep at least 2-3 renewal periods worth of funds
  • Monitor balance: Use wallet endpoints to check balance programmatically
  • Top-up alerts: Set up monitoring for low wallet balance
  • Automatic top-up: Consider automated wallet funding for critical services

Control Endpoints & Examples

1. Enable auto-renewal during order creation:

POST /api/v1/hosting/order
{
  "domain_name": "example.com",
  "domain_type": "new",  // "new", "existing", or "external"
  "plan": "pro_30day",
  "period": 1,
  "auto_renew": true
}

2. Check auto-renewal status:

GET /api/v1/hosting/{subscription_id}/auto-renewal

Response:
{
  "success": true,
  "data": {
    "subscription_id": 123,
    "auto_renew": true
  }
}

3. Toggle auto-renewal on/off:

PUT /api/v1/hosting/{subscription_id}/auto-renewal
{
  "auto_renew": true
}

Response:
{
  "success": true,
  "data": {
    "subscription_id": 123,
    "auto_renew": true,
    "updated_at": "2025-11-01T09:00:00Z"
  },
  "message": "Auto-renewal enabled successfully"
}

4. Update auto-renewal during manual renewal:

POST /api/v1/hosting/{subscription_id}/renew
{
  "period": 3,
  "auto_renew": true
}

Response:
{
  "success": true,
  "data": {
    "subscription_id": 123,
    "renewed": true,
    "period": 3,
    "amount_charged": 13.50,
    "auto_renew_updated": true
  }
}

For detailed code examples in Python, JavaScript, and cURL, see the Hosting Management Tutorial section below.

Common Error Responses

Insufficient Wallet Balance (400 Bad Request)

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Insufficient wallet balance. Required: $35.58, Available: $15.00",
    "details": {
      "required": 35.58,
      "available": 15.0
    }
  },
  "timestamp": 1761937123
}

Domain Not Available (400 Bad Request)

{
  "error": {
    "code": "BAD_REQUEST",
    "message": "Domain example.com is not available for registration"
  },
  "timestamp": 1761937124
}

Rate Limit Exceeded (429 Too Many Requests)

{
  "error": "Rate limit exceeded",
  "retry_after": 3600,
  "timestamp": 1761937125
}

# Response Headers:
# X-RateLimit-Limit: 1000
# X-RateLimit-Remaining: 0
# X-RateLimit-Reset: 1761940725

Unauthorized (401)

{
  "error": "Invalid or expired API key",
  "timestamp": 1761937126
}

🔒 Domain Security & Transfer Management

Complete guide to securing your domains and managing transfers between registrars. Learn how to lock/unlock domains, manage authorization codes, and handle incoming/outgoing transfers.

Understanding Domain Security

Transfer Lock: Prevents unauthorized transfers by blocking EPP/auth code generation and transfer requests

EPP/Auth Code: Secret authorization code required to transfer domain to another registrar

Transfer Process: Typically takes 5-7 days; previous registrar has time to approve/reject

ICANN 60-Day Lock: Domains cannot be transferred within 60 days of registration or contact changes

Step 1: Lock/Unlock Domain

Control whether your domain can be transferred:

# Lock domain (prevent transfers)
curl -X POST "https://api.hostbay.io/api/v1/domains/example.com/lock" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Response:
# {
#   "success": true,
#   "data": {
#     "domain": "example.com",
#     "locked": true
#   },
#   "message": "Domain locked successfully"
# }

# Unlock domain (allow transfers)
curl -X POST "https://api.hostbay.io/api/v1/domains/example.com/unlock" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Response:
# {
#   "success": true,
#   "data": {
#     "domain": "example.com",
#     "locked": false
#   },
#   "message": "Domain unlocked successfully"
# }
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.hostbay.io/api/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}

# Lock domain
response = requests.post(
    f"{BASE_URL}/domains/example.com/lock",
    headers=headers
)
print(f"Domain locked: {response.json()}")

# Unlock domain
response = requests.post(
    f"{BASE_URL}/domains/example.com/unlock",
    headers=headers
)
print(f"Domain unlocked: {response.json()}")
const axios = require('axios');

const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.hostbay.io/api/v1';
const headers = { Authorization: `Bearer ${API_KEY}` };

// Lock domain
const lockResponse = await axios.post(
    `${BASE_URL}/domains/example.com/lock`,
    {},
    { headers }
);
console.log('Domain locked:', lockResponse.data);

// Unlock domain
const unlockResponse = await axios.post(
    `${BASE_URL}/domains/example.com/unlock`,
    {},
    { headers }
);
console.log('Domain unlocked:', unlockResponse.data);

Step 2: Get Authorization Code (EPP Code)

Retrieve the secret code needed to transfer your domain away from HostBay:

# Get auth code
curl -X GET "https://api.hostbay.io/api/v1/domains/example.com/auth-code" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Response:
# {
#   "success": true,
#   "data": {
#     "domain": "example.com",
#     "auth_code": "Ab7mN9pQr2tXvYz4"
#   },
#   "message": "Auth code retrieved successfully"
# }

# âš ī¸ Important: Domain must be UNLOCKED to get auth code
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.hostbay.io/api/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}

# Get auth code
response = requests.get(
    f"{BASE_URL}/domains/example.com/auth-code",
    headers=headers
)
data = response.json()
auth_code = data["data"]["auth_code"]
print(f"Auth code: {auth_code}")

# Use this code at the new registrar to initiate transfer
const axios = require('axios');

const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.hostbay.io/api/v1';
const headers = { Authorization: `Bearer ${API_KEY}` };

// Get auth code
const response = await axios.get(
    `${BASE_URL}/domains/example.com/auth-code`,
    { headers }
);

const authCode = response.data.data.auth_code;
console.log(`Auth code: ${authCode}`);

// Use this code at the new registrar to initiate transfer

Step 3: Reset Authorization Code

Generate a new auth code if the previous one was compromised or lost:

# Reset auth code
curl -X POST "https://api.hostbay.io/api/v1/domains/example.com/auth-code/reset" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Response:
# {
#   "success": true,
#   "data": {
#     "domain": "example.com",
#     "auth_code": "Zk3pL8qTw5yXrUv2",
#     "type": "internal"
#   },
#   "message": "Auth code reset successfully"
# }
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.hostbay.io/api/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}

# Reset auth code
response = requests.post(
    f"{BASE_URL}/domains/example.com/auth-code/reset",
    headers=headers
)
data = response.json()
new_auth_code = data["data"]["auth_code"]
print(f"New auth code: {new_auth_code}")
const axios = require('axios');

const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.hostbay.io/api/v1';
const headers = { Authorization: `Bearer ${API_KEY}` };

// Reset auth code
const response = await axios.post(
    `${BASE_URL}/domains/example.com/auth-code/reset`,
    {},
    { headers }
);

const newAuthCode = response.data.data.auth_code;
console.log(`New auth code: ${newAuthCode}`);

Incoming Transfer (Transfer TO HostBay)

Transfer a domain from another registrar to HostBay:

📋 Prerequisites:
  • Domain must be unlocked at current registrar
  • Valid EPP/auth code from current registrar
  • Domain must be at least 60 days old
  • Domain not transferred in last 60 days
  • Valid WHOIS contact email addresses
# Initiate transfer to HostBay
curl -X POST "https://api.hostbay.io/api/v1/domains/transfer" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain_name": "example.com",
    "auth_code": "Ab7mN9pQr2tXvYz4",
    "period": 1
  }'

# Response:
# {
#   "success": true,
#   "data": {
#     "domain": "example.com",
#     "status": "transfer_pending",
#     "openprovider_id": 12345678,
#     "period": 1,
#     "message": "Transfer initiated - typically completes in 5-7 days"
#   },
#   "message": "Domain transfer initiated successfully"
# }
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.hostbay.io/api/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}

# Initiate transfer
transfer_data = {
    "domain_name": "example.com",
    "auth_code": "Ab7mN9pQr2tXvYz4",
    "period": 1
}

response = requests.post(
    f"{BASE_URL}/domains/transfer",
    headers=headers,
    json=transfer_data
)
result = response.json()
print(f"Transfer status: {result['data']['status']}")
print(f"Expected completion: 5-7 days")
const axios = require('axios');

const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.hostbay.io/api/v1';
const headers = { Authorization: `Bearer ${API_KEY}` };

// Initiate transfer
const transferData = {
    domain_name: 'example.com',
    auth_code: 'Ab7mN9pQr2tXvYz4',
    period: 1
};

const response = await axios.post(
    `${BASE_URL}/domains/transfer`,
    transferData,
    { headers }
);

console.log(`Transfer status: ${response.data.data.status}`);
console.log('Expected completion: 5-7 days');

Outgoing Transfer Management

Approve or reject transfer requests when someone initiates a transfer of your domain to another registrar:

Approve Outgoing Transfer

Speed up transfer instead of waiting 5 days for auto-approval:

# Approve outgoing transfer
curl -X POST "https://api.hostbay.io/api/v1/domains/example.com/transfer/approve" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Response:
# {
#   "success": true,
#   "data": {
#     "domain": "example.com",
#     "approved": true,
#     "message": "Transfer approved successfully"
#   },
#   "message": "Outgoing transfer approved"
# }
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.hostbay.io/api/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}

# Approve transfer
response = requests.post(
    f"{BASE_URL}/domains/example.com/transfer/approve",
    headers=headers
)
print(f"Transfer approved: {response.json()}")
const axios = require('axios');

const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.hostbay.io/api/v1';
const headers = { Authorization: `Bearer ${API_KEY}` };

// Approve transfer
const response = await axios.post(
    `${BASE_URL}/domains/example.com/transfer/approve`,
    {},
    { headers }
);
console.log('Transfer approved:', response.data);

Reject Unauthorized Transfer

Block unauthorized transfer attempts:

# Reject outgoing transfer
curl -X POST "https://api.hostbay.io/api/v1/domains/example.com/transfer/reject" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Response:
# {
#   "success": true,
#   "data": {
#     "domain": "example.com",
#     "rejected": true,
#     "message": "Transfer rejected successfully"
#   },
#   "message": "Outgoing transfer rejected"
# }
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.hostbay.io/api/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}

# Reject transfer
response = requests.post(
    f"{BASE_URL}/domains/example.com/transfer/reject",
    headers=headers
)
print(f"Transfer rejected: {response.json()}")
const axios = require('axios');

const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.hostbay.io/api/v1';
const headers = { Authorization: `Bearer ${API_KEY}` };

// Reject transfer
const response = await axios.post(
    `${BASE_URL}/domains/example.com/transfer/reject`,
    {},
    { headers }
);
console.log('Transfer rejected:', response.data);

Restart Failed Transfer

Retry a stuck or failed transfer operation:

# Restart failed transfer
curl -X POST "https://api.hostbay.io/api/v1/domains/example.com/transfer/restart" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Response:
# {
#   "success": true,
#   "data": {
#     "domain": "example.com",
#     "restarted": true,
#     "message": "Transfer restarted successfully"
#   },
#   "message": "Transfer operation restarted"
# }
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.hostbay.io/api/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}

# Restart transfer
response = requests.post(
    f"{BASE_URL}/domains/example.com/transfer/restart",
    headers=headers
)
print(f"Transfer restarted: {response.json()}")
const axios = require('axios');

const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://api.hostbay.io/api/v1';
const headers = { Authorization: `Bearer ${API_KEY}` };

// Restart transfer
const response = await axios.post(
    `${BASE_URL}/domains/example.com/transfer/restart`,
    {},
    { headers }
);
console.log('Transfer restarted:', response.data);
✅ Domain Security Best Practices:
  • Always lock domains when not transferring to prevent unauthorized transfers
  • Store auth codes securely - treat them like passwords
  • Reset auth codes if compromised or shared accidentally
  • Monitor transfer notifications - approve/reject promptly
  • Wait 60+ days after registration before transferring
  • Verify contact email before initiating transfers
âąī¸ Transfer Timeline:
  • Day 0: Transfer initiated at new registrar with auth code
  • Day 0-1: Previous registrar receives transfer request
  • Day 1-5: Approval window (you can approve early or reject)
  • Day 5-7: Auto-approval if not manually approved/rejected
  • Day 7+: Transfer complete, domain active at new registrar
âš ī¸ Common Transfer Issues:
  • Domain locked: Unlock domain before getting auth code
  • 60-day lock: Cannot transfer within 60 days of registration or contact change
  • Invalid auth code: Reset auth code if expired or incorrect
  • Email confirmation: Check spam folder for transfer approval emails
  • Expired domain: Renew before transferring to avoid issues
â„šī¸ Transfer Endpoint Testing Requirements:
  • Approve/Reject Transfer: These endpoints require an active outgoing transfer in progress. To test, initiate a transfer from HostBay to another registrar first.
  • Restart Transfer: This endpoint requires a failed transfer operation. It cannot be tested without a previous failed transfer attempt.
  • Lock/Unlock & Auth Codes: These endpoints work immediately and can be tested on any registered domain.
  • All endpoints have been verified against official OpenProvider API v1beta documentation and include proper error handling.

🔧 DNS Management Tutorial

Understanding DNS Record Types

A Record: Points domain to IPv4 address (e.g., 192.0.2.1). Supports custom subdomains.

AAAA Record: Points domain to IPv6 address

CNAME Record: Alias one domain to another (e.g., www → example.com). Supports custom subdomains.

MX Record: Mail server for email delivery

TXT Record: Text data for verification, SPF, DKIM, DMARC. Supports custom subdomains including underscores for RFC-compliant records (e.g., _dmarc, _domainkey).

Creating DNS Records

Add an A record to point your domain to a server:

POST /api/v1/dns/{domain_name}/records

{
  "type": "A",
  "name": "@",
  "content": "192.0.2.1",
  "ttl": 3600,
  "proxied": false
}

Common DNS Configurations

1. Point Domain to Web Server

# Root domain
{
  "type": "A",
  "name": "@",
  "content": "192.0.2.1"
}

# www subdomain
{
  "type": "CNAME",
  "name": "www",
  "content": "example.com"
}

2. Configure Email Server

# MX records for email
{
  "type": "MX",
  "name": "@",
  "content": "mail.example.com",
  "priority": 10
}

# SPF record for email authentication
{
  "type": "TXT",
  "name": "@",
  "content": "v=spf1 include:_spf.example.com ~all"
}

3. Setup Subdomain

{
  "type": "A",
  "name": "blog",
  "content": "192.0.2.2"
}

4. Email Authentication (DKIM & DMARC)

TXT records support underscores for RFC-compliant email authentication:

# DMARC policy record
{
  "type": "TXT",
  "name": "_dmarc",
  "content": "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com"
}

# DKIM selector record
{
  "type": "TXT",
  "name": "default._domainkey",
  "content": "v=DKIM1; k=rsa; p=MIGfMA0GCSq..."
}

# Domain verification for services
{
  "type": "TXT",
  "name": "mail",
  "content": "google-site-verification=abc123..."
}

5. Custom Subdomains for Services

# API subdomain
{
  "type": "A",
  "name": "api",
  "content": "192.0.2.3"
}

# CDN subdomain
{
  "type": "CNAME",
  "name": "cdn",
  "content": "cdn.example.cloudfront.net"
}

# Service verification TXT record
{
  "type": "TXT",
  "name": "api",
  "content": "service-token=xyz789"
}

Cloudflare Integration

HostBay integrates with Cloudflare for advanced DNS management:

  • ✅ Automatic SSL/TLS certificates
  • ✅ DDoS protection and firewall
  • ✅ CDN acceleration for faster loading
  • ✅ Analytics and traffic insights
  • ✅ Page Rules for redirects and caching

DNS Propagation

DNS changes can take time to propagate globally:

  • Local cache: 5-15 minutes
  • ISP cache: 1-4 hours
  • Global propagation: 24-48 hours (worst case)
  • Use lower TTL (300-600) for faster updates

Bulk DNS Operations

Update multiple records at once (supports custom subdomains including underscores for TXT records):

POST /api/v1/dns/{domain_name}/records/bulk

{
  "records": [
    {"type": "A", "name": "@", "content": "192.0.2.1"},
    {"type": "A", "name": "www", "content": "192.0.2.1"},
    {"type": "A", "name": "api", "content": "192.0.2.3"},
    {"type": "CNAME", "name": "mail", "content": "example.com"},
    {"type": "MX", "name": "@", "content": "mail.example.com", "priority": 10},
    {"type": "TXT", "name": "@", "content": "v=spf1 include:_spf.example.com ~all"},
    {"type": "TXT", "name": "_dmarc", "content": "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com"}
  ]
}
💡 Custom Subdomain Support:
  • Name Field: The name field represents the subdomain portion only (e.g., "api" for api.example.com)
  • A Records: Use any subdomain (e.g., api, blog, cdn) or @ for root domain
  • CNAME Records: Point subdomains to other domains (e.g., www → example.com)
  • TXT Records: Support underscores for email authentication (_dmarc, _domainkey) and custom subdomains
  • Root Domain: Use @ to create records for the base domain
âš ī¸ DNS Best Practices:
  • Underscores: Underscores (_) in subdomains are only valid for TXT records per DNS standards (RFC 1123). Use them exclusively for email authentication (DKIM, DMARC, SPF) and service verification.
  • Subdomain Format: For A and CNAME records, use lowercase alphanumeric characters and hyphens only (e.g., api-v2, not api_v2).
  • TTL Values: Use lower TTL (300-600s) when testing, higher TTL (3600s+) for stable records to improve DNS caching.

đŸ–Ĩī¸ Hosting Management Tutorial

Provisioning Web Hosting

Create a new hosting account with cPanel:

POST /api/v1/hosting/provision

{
  "domain_name": "example.com",
  "plan": "starter",
  "username": "exampleuser",
  "password": "SecurePassword123!",
  "email": "admin@example.com",
  "package_name": "Basic Hosting"
}

Available Hosting Plans

Starter Plan

  • ✓ 10 GB Storage
  • ✓ 100 GB Bandwidth
  • ✓ 5 Email Accounts
  • ✓ 1 Database
  • ✓ Free SSL

Professional Plan

  • ✓ 50 GB Storage
  • ✓ 500 GB Bandwidth
  • ✓ 25 Email Accounts
  • ✓ 10 Databases
  • ✓ Free SSL

Business Plan

  • ✓ 100 GB Storage
  • ✓ Unlimited Bandwidth
  • ✓ Unlimited Email
  • ✓ Unlimited Databases
  • ✓ Free SSL

Subscription Details (Unified Endpoint)

Get hosting subscription details with optional credentials and usage data in a single request:

GET /api/v1/hosting/{subscription_id}
GET /api/v1/hosting/{subscription_id}?include=credentials
GET /api/v1/hosting/{subscription_id}?include=usage
GET /api/v1/hosting/{subscription_id}?include=credentials,usage

Response (with include=credentials,usage):
{
  "id": 123,
  "domain_name": "example.com",
  "plan": "Pro 30 Days",
  "status": "active",
  "cpanel_username": "exampleuser",
  "server_ip": "185.xxx.xxx.xxx",
  "auto_renew": true,
  "created_at": "2025-01-15T10:30:00Z",
  "expires_at": "2025-02-14T10:30:00Z",
  "is_active": true,
  "credentials": {
    "cpanel_url": "https://185.xxx.xxx.xxx:2083",
    "cpanel_username": "exampleuser",
    "ftp_host": "185.xxx.xxx.xxx",
    "ftp_port": 21
  },
  "usage": {
    "disk_used_mb": 256,
    "disk_limit_mb": 10240,
    "bandwidth_used_mb": 1024,
    "bandwidth_limit_mb": 102400,
    "fetched_at": "2025-01-15T12:00:00Z"
  }
}
💡 Include Flags:
  • credentials - cPanel/FTP login details (static data)
  • usage - Disk and bandwidth statistics (fetched live from cPanel)
  • Combine multiple: ?include=credentials,usage
âš ī¸ Deprecated Endpoints:
  • GET /hosting/{id}/credentials → Use ?include=credentials
  • GET /hosting/{id}/usage → Use ?include=usage

Email Account Management

Create email accounts for your domain:

POST /api/v1/hosting/{domain_name}/email

{
  "email": "info@example.com",
  "password": "SecureEmailPass123!",
  "quota": 1024
}

SSL Certificate Setup

Install free Let's Encrypt SSL certificate:

POST /api/v1/hosting/{domain_name}/ssl

{
  "type": "letsencrypt",
  "auto_renew": true
}

Database Management

Create MySQL database:

POST /api/v1/hosting/{domain_name}/databases

{
  "database_name": "my_database",
  "database_user": "db_user",
  "database_password": "SecureDBPass123!"
}

Auto-Renewal Management

Control automatic renewal for hosting subscriptions to prevent service interruptions:

How It Works: When auto-renewal is enabled, your hosting subscription automatically renews before expiration using your wallet balance.

Benefits: No service interruptions, automatic payment processing, peace of mind

Control: You can enable/disable auto-renewal at any time - during order creation, during renewal, or with dedicated endpoints

Enable Auto-Renewal During Order

Set auto-renewal when ordering hosting:

POST /api/v1/hosting/order

{
  "domain_name": "example.com",
  "domain_type": "new",  // "new", "existing", or "external"
  "plan": "pro_30day",
  "period": 1,
  "auto_renew": true
}

Check Auto-Renewal Status

Check if auto-renewal is enabled for a subscription:

GET /api/v1/hosting/{subscription_id}/auto-renewal

Response:
{
  "success": true,
  "data": {
    "subscription_id": 123,
    "auto_renew": true
  }
}

Toggle Auto-Renewal

Enable or disable auto-renewal anytime:

# Enable auto-renewal
PUT /api/v1/hosting/{subscription_id}/auto-renewal
{
  "auto_renew": true
}

# Disable auto-renewal
PUT /api/v1/hosting/{subscription_id}/auto-renewal
{
  "auto_renew": false
}

Response:
{
  "success": true,
  "data": {
    "subscription_id": 123,
    "auto_renew": true,
    "updated_at": "2025-11-01T09:00:00Z"
  },
  "message": "Auto-renewal enabled successfully"
}

Manual Renewal with Auto-Renewal Update

Renew hosting and update auto-renewal setting in one request:

POST /api/v1/hosting/{subscription_id}/renew

{
  "period": 3,
  "auto_renew": true
}

Response:
{
  "success": true,
  "data": {
    "subscription_id": 123,
    "renewed": true,
    "period": 3,
    "pricing": {
      "base_price_per_period": 5.00,
      "periods": 3,
      "price_before_discount": 15.00,
      "api_discount": 1.50,
      "final_price": 13.50
    },
    "amount_charged": 13.50,
    "auto_renew_updated": true
  },
  "message": "Hosting renewed successfully with 10% API discount"
}
âš ī¸ Important Notes:
  • Auto-renewal requires sufficient wallet balance before expiration
  • You'll receive warnings 3 days before auto-renewal attempts
  • If renewal fails due to insufficient funds, hosting enters grace period
  • Grace period: 1 day for 7-day plans, 2 days for 30-day plans
  • Auto-renewal defaults to enabled for new hosting orders

File Management

Upload files via FTP or use cPanel File Manager:

GET /api/v1/hosting/{domain_name}/ftp

Response:
{
  "ftp_server": "ftp.example.com",
  "ftp_username": "exampleuser",
  "ftp_port": 21
}

Backup and Restore

Create full account backup:

POST /api/v1/hosting/{domain_name}/backup

{
  "backup_type": "full",
  "email_notification": true
}

Addon Domain Management

Host multiple websites on a single hosting subscription using addon domains. Each addon domain gets its own document root directory.

List Addon Domains

GET /api/v1/hosting/{subscription_id}/addon-domains

Response:
{
  "success": true,
  "data": {
    "subscription_id": 123,
    "primary_domain": "mysite.com",
    "addon_domains": [
      {
        "domain": "example.com",
        "subdomain": "example",
        "document_root": "/home/user/example_com",
        "status": "active"
      }
    ],
    "total_addon": 1,
    "total_all": 2
  }
}

Add Addon Domain

Add an existing domain or register a new one as an addon:

POST /api/v1/hosting/{subscription_id}/addon-domains

// Add existing/external domain
{
  "domain": "example.com",
  "document_root": "/public_html/myfolder",  // Optional custom path
  "subdomain": "example"  // Optional, defaults to domain name
}

// Register NEW domain as addon (charges wallet)
{
  "domain": "newsite.com",
  "register_new": true,
  "period": 1,
  "auto_renew_domain": true,
  "document_root": "/public_html/newsite"
}

Response:
{
  "success": true,
  "data": {
    "subscription_id": 123,
    "primary_domain": "mysite.com",
    "addon_domain": "example.com",
    "subdomain": "example",
    "document_root": "/public_html/myfolder",
    "nameserver_status": "updated" | "manual_update_required",
    "dns_nameservers": ["ns1.cloudflare.com", "ns2.cloudflare.com"]
  }
}

Delete Addon Domain

DELETE /api/v1/hosting/{subscription_id}/addon-domains/{addon_domain}

Response:
{
  "success": true,
  "data": {
    "subscription_id": 123,
    "deleted_domain": "example.com",
    "deleted": true
  }
}
✅ Addon Domain Features:
  • Custom Document Root: Specify any path like /public_html/myfolder
  • New Domain Registration: Register and add in one API call with register_new: true
  • External Domains: Add domains from other registrars with DNS instructions
  • Automatic DNS: Cloudflare zone and A records configured automatically
📘 RDP Server Best Practices:
  • Monitor power_status field to track server state changes
  • Servers auto-start after creation and OS reinstalls - no manual intervention needed
  • Enable auto-renewal to prevent service interruptions (72-hour grace period)
  • Maintain sufficient wallet balance for automatic renewals
  • Change default Administrator password immediately after deployment
  • Use Windows Firewall to restrict RDP access to specific IP addresses
  • Enable Windows Update for security patches
  • Create regular snapshots/backups of critical data
  • Choose datacenter regions closest to your users for best performance
  • Use quarterly or yearly billing for cost savings (6-11% discount)

đŸ’ģ Windows RDP Server Management

Deploy and manage Windows Server instances with Remote Desktop Protocol (RDP) access. Perfect for development, testing, or production workloads requiring Windows environments.

Available RDP Plans

Get all available RDP plans with pricing information:

GET /api/v1/rdp/plans

Response:
{
  "success": true,
  "data": {
    "plans": [
      {
        "id": 1,
        "name": "Basic RDP",
        "vcpu": 1,
        "ram_mb": 2048,
        "ram_gb": 2,
        "storage_gb": 55,
        "bandwidth_tb": 2,
        "monthly_price": 44.00,
        "quarterly_price": 124.08,
        "yearly_price": 470.88,
        "is_active": true
      },
      {
        "id": 2,
        "name": "Standard RDP",
        "vcpu": 1,
        "ram_mb": 4096,
        "ram_gb": 4,
        "storage_gb": 80,
        "bandwidth_tb": 3,
        "monthly_price": 72.00,
        "quarterly_price": 203.04,
        "yearly_price": 770.88,
        "is_active": true
      }
    ]
  }
}

Available Windows Templates

List all available Windows Server versions:

GET /api/v1/rdp/templates

Response:
{
  "success": true,
  "data": {
    "templates": [
      {
        "id": 1,
        "windows_version": "2025",
        "edition": "Standard",
        "display_name": "Windows Server 2025 Standard",
        "is_active": true
      },
      {
        "id": 2,
        "windows_version": "2022",
        "edition": "Standard",
        "display_name": "Windows Server 2022 Standard",
        "is_active": true
      },
      {
        "id": 3,
        "windows_version": "2019",
        "edition": "Standard",
        "display_name": "Windows Server 2019 Standard",
        "is_active": true
      },
      {
        "id": 4,
        "windows_version": "2016",
        "edition": "Standard",
        "display_name": "Windows Server 2016 Standard",
        "is_active": true
      }
    ]
  }
}

Available Datacenter Regions

Get all 32 global datacenter regions:

GET /api/v1/rdp/regions

Response:
{
  "success": true,
  "data": {
    "regions": [
      {
        "id": "ewr",
        "city": "New Jersey",
        "country": "US",
        "continent": "North America"
      },
      {
        "id": "lhr",
        "city": "London",
        "country": "GB",
        "continent": "Europe"
      },
      {
        "id": "sgp",
        "city": "Singapore",
        "country": "SG",
        "continent": "Asia"
      }
    ]
  }
}

Create New RDP Server

Deploy a new Windows Server with RDP access:

POST /api/v1/rdp/servers
Authorization: Bearer YOUR_API_KEY

{
  "template_id": 1,
  "plan_id": 2,
  "region": "ewr",
  "billing_cycle": "monthly",
  "hostname": "my-windows-server"
}

Billing Cycle Options:
  "monthly"    - Full monthly price
  "quarterly"  - 6% discount (3 months prepaid)
  "yearly"     - 11% discount (12 months prepaid)

Response:
{
  "success": true,
  "data": {
    "message": "RDP server provisioning started",
    "server_id": 123,
    "hostname": "my-windows-server",
    "status": "provisioning",
    "power_status": "starting",
    "estimated_ready_time": "2-3 minutes"
  }
}
🚀 Auto-Start Behavior:
  • All new servers automatically start after provisioning completes
  • Servers automatically start after OS reinstall (1-2 minutes)
  • Smart retry logic handles temporary infrastructure delays
  • Check power_status field for current power state
💰 Billing Cycles & Discounts:
  • Monthly: Full monthly price
  • Quarterly: 6% discount (3 months prepaid)
  • Yearly: 11% discount (12 months prepaid)
  • Maximum 10 RDP servers per user
  • Auto-renewal enabled by default

Power Status Values

The power_status field indicates the current power state of your server:

  • starting - Server is powering on (auto-start in progress)
  • running - Server is powered on and accessible via RDP
  • stopped - Server is powered off (not billed for compute time)
  • stopping - Server is shutting down
  • restarting - Server is rebooting
  • reinstalling - OS reinstall in progress (1-2 minutes)

Note: Servers in starting or reinstalling states will automatically transition to running when ready. Smart retry logic ensures reliable auto-start even during temporary infrastructure delays.

List Your RDP Servers

Get all your RDP servers:

GET /api/v1/rdp/servers
Authorization: Bearer YOUR_API_KEY

Response:
{
  "success": true,
  "data": {
    "servers": [
      {
        "id": 123,
        "hostname": "my-windows-server",
        "public_ip": "192.0.2.10",
        "status": "active",
        "power_status": "running",
        "os": "Windows Server 2022 Standard",
        "plan": {
          "name": "Standard RDP",
          "vcpu": 1,
          "ram_mb": 4096,
          "storage_gb": 80
        },
        "region": "ewr",
        "billing": {
          "cycle": "monthly",
          "monthly_price": 72.00,
          "next_renewal": "2025-12-03T00:00:00Z",
          "auto_renew": true
        },
        "created_at": "2025-11-03T10:00:00Z",
        "activated_at": "2025-11-03T10:08:00Z"
      }
    ],
    "total": 1
  }
}

Get Server Details & Credentials

Retrieve full server details including RDP credentials:

GET /api/v1/rdp/servers/123
Authorization: Bearer YOUR_API_KEY

Response:
{
  "success": true,
  "data": {
    "id": 123,
    "hostname": "my-windows-server",
    "public_ip": "192.0.2.10",
    "status": "active",
    "power_status": "running",
    "os": "Windows Server 2022 Standard",
    "credentials": {
      "username": "Administrator",
      "password": "SecureP@ssw0rd123"
    },
    "plan": {
      "name": "Standard RDP",
      "vcpu": 1,
      "ram_mb": 4096,
      "storage_gb": 80
    },
    "region": "ewr",
    "billing": {
      "cycle": "monthly",
      "monthly_price": 72.00,
      "next_renewal": "2025-12-03T00:00:00Z",
      "auto_renew": true
    },
    "created_at": "2025-11-03T10:00:00Z",
    "activated_at": "2025-11-03T10:08:00Z"
  }
}

Server Control Actions

Start Server

Power on a stopped server:

POST /api/v1/rdp/servers/123/start
Authorization: Bearer YOUR_API_KEY

Response:
{
  "success": true,
  "data": {
    "message": "Server is starting",
    "server_id": 123
  }
}

Stop Server

Power off a running server:

POST /api/v1/rdp/servers/123/stop
Authorization: Bearer YOUR_API_KEY

Response:
{
  "success": true,
  "data": {
    "message": "Server is stopping",
    "server_id": 123
  }
}

Restart Server

Reboot a running server:

POST /api/v1/rdp/servers/123/restart
Authorization: Bearer YOUR_API_KEY

Response:
{
  "success": true,
  "data": {
    "message": "Server is restarting",
    "server_id": 123
  }
}

Reinstall OS

Completely wipe and reinstall Windows (generates new password):

POST /api/v1/rdp/servers/123/reinstall
Authorization: Bearer YOUR_API_KEY

Response:
{
  "success": true,
  "data": {
    "message": "OS reinstall started. Server will auto-start when ready.",
    "server_id": 123,
    "power_status": "reinstalling",
    "estimated_time": "1-2 minutes"
  }
}
âš ī¸ Warning - Reinstall OS:
  • All data on the server will be permanently deleted
  • A fresh Windows installation will be deployed
  • New Administrator password will be generated
  • Server automatically starts after reinstall completes (1-2 minutes)
  • This action cannot be undone

Delete Server

Permanently delete a server and stop billing:

DELETE /api/v1/rdp/servers/123
Authorization: Bearer YOUR_API_KEY

Response:
{
  "success": true,
  "data": {
    "message": "Server my-windows-server deleted successfully",
    "server_id": 123
  }
}

Auto-Renewal System

RDP servers have automatic renewal with a 72-hour grace period:

How It Works: When auto-renewal is enabled, your RDP server automatically renews before expiration using your wallet balance.

Grace Period: 72 hours after renewal due date before server is suspended

Warnings: You'll receive notifications 3 days before renewal

Suspension: If payment fails after grace period, server is stopped to prevent further charges

Complete Workflow Example (Python)

End-to-end example of deploying and managing a Windows RDP server:

import requests
import time

# Your API key
API_KEY = "YOUR_API_KEY_HERE"
BASE_URL = "https://api.hostbay.io/api/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}

# Step 1: Get available plans
response = requests.get(f"{BASE_URL}/rdp/plans", headers=headers)
plans = response.json()["data"]["plans"]
print(f"Available plans: {len(plans)}")

# Step 2: Get available templates
response = requests.get(f"{BASE_URL}/rdp/templates", headers=headers)
templates = response.json()["data"]["templates"]
print(f"Available Windows versions: {len(templates)}")

# Step 3: Get regions
response = requests.get(f"{BASE_URL}/rdp/regions", headers=headers)
regions = response.json()["data"]["regions"]
print(f"Available regions: {len(regions)}")

# Step 4: Create RDP server
create_data = {
    "template_id": 1,  # Windows Server 2025
    "plan_id": 2,      # Standard RDP
    "region": "ewr",   # New Jersey
    "billing_cycle": "monthly",
    "hostname": "my-dev-server"
}
response = requests.post(f"{BASE_URL}/rdp/servers", json=create_data, headers=headers)
result = response.json()["data"]
server_id = result["server_id"]
print(f"Server provisioning started: {server_id}")

# Step 5: Wait for provisioning (check every 30 seconds)
while True:
    response = requests.get(f"{BASE_URL}/rdp/servers/{server_id}", headers=headers)
    server = response.json()["data"]
    
    if server["status"] == "active":
        print(f"Server ready!")
        print(f"IP: {server['public_ip']}")
        print(f"Username: {server['credentials']['username']}")
        print(f"Password: {server['credentials']['password']}")
        break
    elif server["status"] == "failed":
        print("Provisioning failed")
        break
    
    print(f"Status: {server['status']} - waiting...")
    time.sleep(30)

# Step 6: Connect via RDP
print(f"Connect with: mstsc /v:{server['public_ip']}")

# Step 7: Manage server
# Restart server
requests.post(f"{BASE_URL}/rdp/servers/{server_id}/restart", headers=headers)
print("Server restarted")

# Step 8: Get all your servers
response = requests.get(f"{BASE_URL}/rdp/servers", headers=headers)
all_servers = response.json()["data"]["servers"]
print(f"You have {len(all_servers)} RDP server(s)")

Complete Workflow Example (JavaScript/Node.js)

const axios = require('axios');

const API_KEY = 'YOUR_API_KEY_HERE';
const BASE_URL = 'https://api.hostbay.io/api/v1';
const headers = { 'Authorization': `Bearer ${API_KEY}` };

async function deployRDPServer() {
    try {
        // Get available plans
        const plansResponse = await axios.get(`${BASE_URL}/rdp/plans`, { headers });
        console.log(`Available plans: ${plansResponse.data.data.plans.length}`);
        
        // Create RDP server
        const createData = {
            template_id: 1,
            plan_id: 2,
            region: 'ewr',
            billing_cycle: 'monthly',
            hostname: 'my-dev-server'
        };
        
        const createResponse = await axios.post(
            `${BASE_URL}/rdp/servers`,
            createData,
            { headers }
        );
        
        const serverId = createResponse.data.data.server_id;
        console.log(`Server provisioning started: ${serverId}`);
        
        // Wait for server to be ready
        while (true) {
            const serverResponse = await axios.get(
                `${BASE_URL}/rdp/servers/${serverId}`,
                { headers }
            );
            
            const server = serverResponse.data.data;
            
            if (server.status === 'active') {
                console.log('Server ready!');
                console.log(`IP: ${server.public_ip}`);
                console.log(`Username: ${server.credentials.username}`);
                console.log(`Password: ${server.credentials.password}`);
                break;
            } else if (server.status === 'failed') {
                console.log('Provisioning failed');
                break;
            }
            
            console.log(`Status: ${server.status} - waiting...`);
            await new Promise(resolve => setTimeout(resolve, 30000));
        }
    } catch (error) {
        console.error('Error:', error.response?.data || error.message);
    }
}

deployRDPServer();

Complete Workflow Example (cURL)

# Set your API key
API_KEY="YOUR_API_KEY_HERE"

# Get available plans
curl -X GET "https://api.hostbay.io/api/v1/rdp/plans" \
  -H "Authorization: Bearer $API_KEY"

# Get available Windows templates
curl -X GET "https://api.hostbay.io/api/v1/rdp/templates" \
  -H "Authorization: Bearer $API_KEY"

# Create RDP server
curl -X POST "https://api.hostbay.io/api/v1/rdp/servers" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": 1,
    "plan_id": 2,
    "region": "ewr",
    "billing_cycle": "yearly",
    "hostname": "my-dev-server"
  }'

# Billing options: "monthly", "quarterly" (6% off), "yearly" (11% off)

# Get server details (replace 123 with your server_id)
curl -X GET "https://api.hostbay.io/api/v1/rdp/servers/123" \
  -H "Authorization: Bearer $API_KEY"

# Restart server
curl -X POST "https://api.hostbay.io/api/v1/rdp/servers/123/restart" \
  -H "Authorization: Bearer $API_KEY"

# Delete server
curl -X DELETE "https://api.hostbay.io/api/v1/rdp/servers/123" \
  -H "Authorization: Bearer $API_KEY"
📘 Best Practices:
  • Enable auto-renewal to prevent service interruptions
  • Maintain sufficient wallet balance for automatic renewals
  • Change the Administrator password immediately after deployment
  • Enable Windows Firewall and configure security rules
  • Keep Windows Update enabled for security patches
  • Use strong RDP passwords (12+ characters, mixed case, numbers, symbols)
  • Consider using VPN or IP whitelist for RDP access
  • Take regular backups before major changes
  • Monitor CPU and RAM usage to ensure plan is adequate
  • Use quarterly or yearly billing for cost savings (6-11% discount)

Connecting to Your RDP Server

Windows

  1. Press Win + R
  2. Type: mstsc
  3. Enter server IP
  4. Login with credentials

macOS

  1. Install Microsoft Remote Desktop
  2. Click "Add PC"
  3. Enter server IP
  4. Login with credentials

Linux

  1. Install Remmina or FreeRDP
  2. Create new RDP connection
  3. Enter server IP
  4. Login with credentials

Quick Reference Guides

Complete API Reference

Explore all 88 endpoints with interactive testing

Interactive API Docs ReDoc View OpenAPI Schema