SDK Quick Start
SDK Quick Start
Section titled “SDK Quick Start”Get up and running with the UnboundBytes API in under 5 minutes. This guide covers authentication, making your first request, and common operations.
Prerequisites
Section titled “Prerequisites”- An UnboundBytes account with at least one device paired
- An API key or JWT token (see Authentication)
Install the SDK
Section titled “Install the SDK”No installation needed. Use any HTTP client.
No SDK needed — use the built-in fetch API or any HTTP library.
pip install requestsInitialize the Client
Section titled “Initialize the Client”export API_KEY="key_your_api_key_here"export TENANT_ID="ten_your_tenant_id"export BASE_URL="https://api.unboundbytes.com/v1"const BASE_URL = 'https://api.unboundbytes.com/v1';const HEADERS = { 'x-api-key': 'key_your_api_key_here', 'x-ub-tenant-id': 'ten_your_tenant_id', 'Content-Type': 'application/json',};import requests
BASE_URL = "https://api.unboundbytes.com/v1"HEADERS = { "x-api-key": "key_your_api_key_here", "x-ub-tenant-id": "ten_your_tenant_id", "Content-Type": "application/json",}Your First Request: List Devices
Section titled “Your First Request: List Devices”curl -s "$BASE_URL/hosts" \ -H "x-api-key: $API_KEY" \ -H "x-ub-tenant-id: $TENANT_ID" | jq '.data[] | "\(.hostname) - \(.status)"'const response = await fetch(`${BASE_URL}/hosts`, { headers: HEADERS });const { data: devices } = await response.json();
for (const device of devices) { console.log(`${device.hostname} - ${device.status}`);}response = requests.get(f"{BASE_URL}/hosts", headers=HEADERS)devices = response.json()
for device in devices["data"]: print(f"{device['hostname']} - {device['status']}")Common Operations
Section titled “Common Operations”Deploy an Application
Section titled “Deploy an Application”- Choose an app from the catalog
- Select a target device
- Create the deployment
# List app templatescurl -s "$BASE_URL/app-templates" \ -H "x-api-key: $API_KEY" \ -H "x-ub-tenant-id: $TENANT_ID" | jq '.data'
# Create a deploymentcurl -s -X POST "$BASE_URL/deployments" \ -H "x-api-key: $API_KEY" \ -H "x-ub-tenant-id: $TENANT_ID" \ -H "Content-Type: application/json" \ -d '{ "name": "my-vaultwarden", "appId": "app_vaultwarden", "deviceId": "dev_abc123" }' | jq// List available app templatesconst templatesRes = await fetch(`${BASE_URL}/app-templates`, { headers: HEADERS });const { data: templates } = await templatesRes.json();
// Create a deploymentconst deployRes = await fetch(`${BASE_URL}/deployments`, { method: 'POST', headers: HEADERS, body: JSON.stringify({ name: 'my-vaultwarden', appId: 'app_vaultwarden', deviceId: 'dev_abc123', }),});const deployment = await deployRes.json();console.log(`Deployment ${deployment.id} created: ${deployment.status}`);Create a Backup
Section titled “Create a Backup”# Create a backupcurl -s -X POST "$BASE_URL/hosts/dev_abc123/backups" \ -H "x-api-key: $API_KEY" \ -H "x-ub-tenant-id: $TENANT_ID" \ -H "Content-Type: application/json" | jq
# List backupscurl -s "$BASE_URL/hosts/dev_abc123/backups" \ -H "x-api-key: $API_KEY" \ -H "x-ub-tenant-id: $TENANT_ID" | jq '.data'// Create a backup for a deviceconst backupRes = await fetch(`${BASE_URL}/hosts/dev_abc123/backups`, { method: 'POST', headers: HEADERS,});const backup = await backupRes.json();console.log(`Backup ${backup.id} started`);
// Check backup statusconst statusRes = await fetch(`${BASE_URL}/hosts/dev_abc123/backups`, { headers: HEADERS });const { data: backups } = await statusRes.json();console.log(`Latest: ${backups[0]?.status}`);Manage Tunnels
Section titled “Manage Tunnels”# Create a tunnelcurl -s -X POST "$BASE_URL/hosts/dev_abc123/tunnels" \ -H "x-api-key: $API_KEY" \ -H "x-ub-tenant-id: $TENANT_ID" \ -H "Content-Type: application/json" \ -d '{"targetPort": 8080, "protocol": "http"}' | jq
# Check tunnel healthcurl -s "$BASE_URL/tunnels/tun_xyz789/health" \ -H "x-api-key: $API_KEY" \ -H "x-ub-tenant-id: $TENANT_ID" | jq// Create a tunnel to access a device serviceconst tunnelRes = await fetch(`${BASE_URL}/hosts/dev_abc123/tunnels`, { method: 'POST', headers: HEADERS, body: JSON.stringify({ targetPort: 8080, protocol: 'http' }),});const tunnel = await tunnelRes.json();console.log(`Tunnel URL: ${tunnel.url}`);
// Check tunnel healthconst healthRes = await fetch(`${BASE_URL}/tunnels/${tunnel.id}/health`, { headers: HEADERS });const health = await healthRes.json();console.log(`Tunnel healthy: ${health.healthy}`);Error Handling
Section titled “Error Handling”# Check HTTP status codeHTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \ "$BASE_URL/hosts/dev_nonexistent" \ -H "x-api-key: $API_KEY" \ -H "x-ub-tenant-id: $TENANT_ID")
if [ "$HTTP_STATUS" = "429" ]; then echo "Rate limited. Check Retry-After header."elif [ "$HTTP_STATUS" = "404" ]; then echo "Device not found."ficonst response = await fetch(`${BASE_URL}/hosts/dev_nonexistent`, { headers: HEADERS });
if (!response.ok) { const error = await response.json().catch(() => ({})); console.error(`API Error: ${response.status} - ${error.message ?? 'Unknown error'}`);
if (response.status === 429) { const retryAfter = response.headers.get('Retry-After') ?? '60'; console.log(`Rate limited. Retry after ${retryAfter}s`); }}Pagination
Section titled “Pagination”List endpoints return paginated results. Use limit and offset query parameters:
// Fetch all devices with paginationlet offset = 0;const limit = 50;const allDevices: unknown[] = [];
while (true) { const res = await fetch(`${BASE_URL}/hosts?limit=${limit}&offset=${offset}`, { headers: HEADERS }); const page = await res.json(); allDevices.push(...page.data);
if (!page.meta?.pagination?.hasMore) break; offset += limit;}
console.log(`Total devices: ${allDevices.length}`);Webhooks
Section titled “Webhooks”Subscribe to events for real-time notifications:
curl -s -X POST "$BASE_URL/webhooks" \ -H "x-api-key: $API_KEY" \ -H "x-ub-tenant-id: $TENANT_ID" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-app.example.com/webhooks/unboundbytes", "events": ["device.offline", "deployment.failed", "backup.completed"], "secret": "whsec_your_signing_secret" }' | jqSee the Webhooks API for the full list of available events.
Next Steps
Section titled “Next Steps” API Explorer Browse all endpoints interactively
Authentication Configure API keys, JWT, and HMAC
API Reference Full endpoint reference documentation
OpenAPI Spec Download the spec for code generation