# LetsBe Biz — API Reference **Version:** 1.0 **Date:** February 26, 2026 **Authors:** Matt (Founder), Claude (Architecture) **Status:** Engineering Spec — Ready for Implementation **Companion docs:** Technical Architecture v1.2, Repo Analysis v1.0, Infrastructure Runbook v1.0 --- ## 1. Purpose This document is the complete API reference for the LetsBe Biz platform. It covers: 1. **Hub API** — The central platform's REST endpoints (admin, customer, tenant, webhooks) 2. **Safety Wrapper API** — The on-tenant endpoints for Hub ↔ VPS communication 3. **Authentication flows** — How each actor authenticates 4. **Webhook specifications** — Inbound and outbound webhook contracts This reference is designed to serve as the implementation blueprint for Claude Code and Codex sessions. --- ## 2. API Overview ### 2.1 Base URLs | API | Base URL | Auth | |-----|----------|------| | Hub (admin) | `https://hub.letsbe.biz/api/v1/admin/` | Bearer {staffSessionToken} | | Hub (customer) | `https://hub.letsbe.biz/api/v1/customer/` | Bearer {customerSessionToken} | | Hub (tenant comms) | `https://hub.letsbe.biz/api/v1/tenant/` | Bearer {hubApiKey} | | Hub (public) | `https://hub.letsbe.biz/api/v1/public/` | None or API key | | Hub (webhooks) | `https://hub.letsbe.biz/api/v1/webhooks/` | Signature verification | | Safety Wrapper (local) | `http://127.0.0.1:8100/` | Internal only | | OpenClaw Gateway (local) | `http://127.0.0.1:18789/` | Token auth | ### 2.2 Common Patterns **Response format:** All Hub API responses follow this envelope: ```json { "success": true, "data": { ... }, "meta": { "page": 1, "pageSize": 25, "total": 142 } } ``` **Error format:** ```json { "success": false, "error": { "code": "VALIDATION_ERROR", "message": "Invalid email format", "details": [ { "field": "email", "message": "Must be a valid email address" } ] } } ``` **Pagination:** Cursor-based where possible, offset-based for admin lists. - `?page=1&pageSize=25` (offset) - `?cursor=abc123&limit=25` (cursor) **Validation:** Zod schemas on all endpoints. 400 returned with field-level errors. **Rate limiting:** 60 requests/minute per authenticated session. 429 returned with `Retry-After` header. --- ## 3. Authentication ### 3.1 Staff Authentication (Admin Panel) NextAuth.js with Credentials provider, JWT sessions. | Method | Path | Auth | Description | |--------|------|------|-------------| | GET/POST | `/api/auth/[...nextauth]` | None | NextAuth handlers (login, logout, session) | | POST | `/api/v1/setup` | None (one-time) | Initial owner account creation | **Login flow:** ``` 1. POST /api/auth/callback/credentials Body: { email, password } 2. If 2FA enabled: Response: { requires2FA: true, pendingToken: "..." } 3. POST /api/v1/auth/2fa/verify Body: { token: pendingToken, code: "123456" } Response: Sets session cookie 4. Session token in cookie → used as Bearer token for API calls ``` **2FA Management:** | Method | Path | Auth | Description | |--------|------|------|-------------| | GET | `/api/v1/auth/2fa/status` | Session | Check if 2FA is enabled | | POST | `/api/v1/auth/2fa/setup` | Session | Generate TOTP secret + QR code | | POST | `/api/v1/auth/2fa/verify` | Session/Pending | Verify TOTP code | | POST | `/api/v1/auth/2fa/disable` | Session | Disable 2FA (requires current code) | | GET | `/api/v1/auth/2fa/backup-codes` | Session | Get/regenerate backup codes | **Staff Invitations:** | Method | Path | Auth | Description | |--------|------|------|-------------| | GET | `/api/v1/auth/invite/{token}` | None | Look up invitation details | | POST | `/api/v1/auth/accept-invite` | None | Accept invitation, set password | ### 3.2 Customer Authentication (Customer Portal) Same NextAuth.js flow, separate user type. Customers log in via: - Email + password (created during Stripe checkout) - Future: SSO via Keycloak on their tenant VPS ### 3.3 Tenant Authentication (Safety Wrapper ↔ Hub) Bearer token authentication using a Hub-generated API key. **Registration flow:** ``` 1. During provisioning, the Hub generates a registration token per order 2. Safety Wrapper boots, calls: POST /api/v1/tenant/register Body: { registrationToken: "..." } 3. Hub validates token, returns: { hubApiKey: "hk_abc123..." } 4. Safety Wrapper stores hubApiKey in encrypted secrets registry 5. All subsequent requests use: Authorization: Bearer hk_abc123... ``` ### 3.4 Stripe Webhook Authentication Stripe webhook signature verification using `stripe.webhooks.constructEvent()`. --- ## 4. Hub Admin API (Staff) ### 4.1 Profile | Method | Path | Description | |--------|------|-------------| | GET | `/api/v1/profile` | Get current staff profile | | PATCH | `/api/v1/profile` | Update name, email | | POST | `/api/v1/profile/photo` | Upload profile photo (multipart/form-data → S3/MinIO) | | POST | `/api/v1/profile/password` | Change password (requires current password) | ### 4.2 Customers | Method | Path | Description | |--------|------|-------------| | GET | `/api/v1/admin/customers` | List customers. Query: `?page=1&pageSize=25&search=acme` | | POST | `/api/v1/admin/customers` | Create customer (staff-initiated) | | GET | `/api/v1/admin/customers/{id}` | Get customer detail with orders, subscription | | PATCH | `/api/v1/admin/customers/{id}` | Update customer details | **Customer object:** ```json { "id": "cust_abc123", "email": "maria@acme.com", "name": "Maria Weber", "company": "Acme Marketing GmbH", "status": "ACTIVE", "subscription": { "plan": "PRO", "tier": "Build", "tokenLimit": 15000000, "tokensUsed": 8234000, "stripeCustomerId": "cus_xxx", "status": "ACTIVE" }, "orders": [ ... ], "foundingMember": { "number": 42, "tokenMultiplier": 2, "expiresAt": "2027-03-15T00:00:00Z" }, "createdAt": "2026-03-15T10:00:00Z" } ``` ### 4.3 Orders | Method | Path | Description | |--------|------|-------------| | GET | `/api/v1/admin/orders` | List orders. Query: `?status=FULFILLED&tier=Build&search=acme` | | POST | `/api/v1/admin/orders` | Create order (staff-initiated, MANUAL mode) | | GET | `/api/v1/admin/orders/{id}` | Get order detail (full — server IP, tools, domain, status) | | PATCH | `/api/v1/admin/orders/{id}` | Update order (credentials, server details) | **Order lifecycle:** | Method | Path | Description | |--------|------|-------------| | POST | `/api/v1/admin/orders/{id}/provision` | Spawn Docker provisioner container | | GET | `/api/v1/admin/orders/{id}/logs/stream` | SSE stream of provisioning logs | | GET | `/api/v1/admin/orders/{id}/dns` | Get DNS verification status | | POST | `/api/v1/admin/orders/{id}/dns/verify` | Trigger DNS A-record verification | | POST | `/api/v1/admin/orders/{id}/dns/skip` | Manual DNS override | | POST | `/api/v1/admin/orders/{id}/dns/create` | **NEW:** Auto-create DNS A records (Cloudflare/Entri) | | GET | `/api/v1/admin/orders/{id}/automation` | Get automation mode (AUTO/MANUAL/PAUSED) | | PATCH | `/api/v1/admin/orders/{id}/automation` | Change automation mode | **Order object (key fields):** ```json { "id": "ord_abc123", "userId": "cust_abc123", "status": "FULFILLED", "tier": "Build", "domain": "acme.letsbe.biz", "tools": ["nextcloud", "chatwoot", "ghost", "calcom", "odoo", "stalwart", "listmonk", "umami"], "serverIp": "88.99.xx.xx", "sshPort": 22022, "automationMode": "AUTO", "dashboardUrl": "https://acme.letsbe.biz", "portainerUrl": "https://portainer.acme.letsbe.biz", "createdAt": "2026-03-15T10:00:00Z", "fulfilledAt": "2026-03-15T12:34:56Z" } ``` ### 4.4 Container Management (via Portainer) | Method | Path | Description | |--------|------|-------------| | GET | `/api/v1/admin/orders/{id}/containers` | List all containers on the tenant VPS | | GET | `/api/v1/admin/orders/{id}/containers/stats` | All container stats (CPU, RAM) | | GET | `/api/v1/admin/orders/{id}/containers/{cId}` | Container detail | | POST | `/api/v1/admin/orders/{id}/containers/{cId}/start` | Start container | | POST | `/api/v1/admin/orders/{id}/containers/{cId}/stop` | Stop container | | POST | `/api/v1/admin/orders/{id}/containers/{cId}/restart` | Restart container | | GET | `/api/v1/admin/orders/{id}/containers/{cId}/logs` | Container logs. Query: `?tail=100&since=1h` | | GET | `/api/v1/admin/orders/{id}/containers/{cId}/stats` | Container resource stats | | GET | `/api/v1/admin/orders/{id}/portainer` | Get Portainer credentials | | POST | `/api/v1/admin/orders/{id}/portainer/init` | Initialize Portainer endpoint | | POST | `/api/v1/admin/orders/{id}/test-ssh` | Test SSH connectivity | ### 4.5 Servers | Method | Path | Description | |--------|------|-------------| | GET | `/api/v1/admin/servers` | List active servers (from fulfilled orders) | | GET | `/api/v1/admin/servers/{id}/health` | Server health (heartbeat status, Safety Wrapper version) | | POST | `/api/v1/admin/servers/{id}/command` | Queue remote command for Safety Wrapper | | POST | `/api/v1/admin/portainer/ping` | Test Portainer connectivity | ### 4.6 Netcup Integration | Method | Path | Description | |--------|------|-------------| | GET | `/api/v1/admin/netcup/auth` | Get Netcup OAuth2 connection status | | POST | `/api/v1/admin/netcup/auth` | Initiate OAuth2 Device Flow | | DELETE | `/api/v1/admin/netcup/auth` | Disconnect Netcup | | GET | `/api/v1/admin/netcup/servers` | List Netcup servers | | GET | `/api/v1/admin/netcup/servers/{id}` | Server detail (IP, status, plan) | | PATCH | `/api/v1/admin/netcup/servers/{id}` | Power action (start/stop/restart), hostname, nickname | | GET | `/api/v1/admin/netcup/servers/{id}/metrics` | CPU, disk, network metrics | | GET | `/api/v1/admin/netcup/servers/{id}/snapshots` | List snapshots | | POST | `/api/v1/admin/netcup/servers/{id}/snapshots` | Create snapshot | | DELETE | `/api/v1/admin/netcup/servers/{id}/snapshots/{snapId}` | Delete snapshot | | POST | `/api/v1/admin/netcup/servers/{id}/snapshots/{snapId}/revert` | Revert to snapshot | ### 4.7 Staff Management | Method | Path | Description | |--------|------|-------------| | GET | `/api/v1/admin/staff` | List staff members | | POST | `/api/v1/admin/staff/invite` | Send staff invitation email | | GET | `/api/v1/admin/staff/invitations` | List pending invitations | | PATCH | `/api/v1/admin/staff/{id}` | Update staff role/status | | DELETE | `/api/v1/admin/staff/{id}` | Deactivate staff member | **Roles and permissions:** | Role | Level | Key Permissions | |------|-------|-----------------| | OWNER | Full | All permissions, manage staff, delete account | | ADMIN | High | Manage customers, orders, servers, billing | | MANAGER | Medium | View/manage customers and orders, no billing | | SUPPORT | Low | View customers, view orders, manage containers | ### 4.8 Agent Management (NEW) | Method | Path | Description | |--------|------|-------------| | GET | `/api/v1/admin/agents/templates` | List available agent role templates | | POST | `/api/v1/admin/orders/{id}/agents` | Deploy new agent to tenant server | | GET | `/api/v1/admin/orders/{id}/agents` | List agents on tenant server | | PATCH | `/api/v1/admin/orders/{id}/agents/{agentId}` | Update agent config (SOUL.md, tools, autonomy) | | DELETE | `/api/v1/admin/orders/{id}/agents/{agentId}` | Remove agent from tenant | **AgentConfig object:** ```json { "id": "agcfg_abc123", "orderId": "ord_abc123", "agentId": "it-admin", "name": "IT Admin", "role": "it-admin", "soulMd": "# IT Admin\n\n## Identity\n...", "toolsAllowed": ["shell", "docker", "file_read", "file_write", "env_read", "env_update"], "toolsDenied": [], "toolProfile": "coding", "autonomyLevel": 3, "externalCommsUnlocks": null, "isActive": true } ``` ### 4.9 Command Approval Queue (NEW) | Method | Path | Description | |--------|------|-------------| | GET | `/api/v1/admin/approvals` | List all pending approvals across tenants | | GET | `/api/v1/admin/approvals/{id}` | Approval detail with full command context | | POST | `/api/v1/admin/approvals/{id}` | Approve or deny. Body: `{ "action": "approve" \| "deny", "reason": "..." }` | **CommandApproval object:** ```json { "id": "appr_abc123", "orderId": "ord_abc123", "agentId": "it-admin", "commandClass": "red", "toolName": "file_delete", "toolArgs": { "path": "/opt/letsbe/stacks/nextcloud/data/tmp/*", "recursive": true }, "humanReadable": "IT Admin wants to delete /nextcloud/data/tmp/* (47 files, 2.3GB)", "status": "PENDING", "requestedAt": "2026-03-15T14:22:00Z", "expiresAt": "2026-03-16T14:22:00Z" } ``` ### 4.10 Billing & Token Metering (NEW) | Method | Path | Description | |--------|------|-------------| | POST | `/api/v1/admin/billing/usage` | Ingest token usage report from Safety Wrapper | | GET | `/api/v1/admin/billing/{customerId}` | Customer billing summary | | GET | `/api/v1/admin/billing/{customerId}/history` | Historical usage data | | POST | `/api/v1/admin/billing/overages` | Trigger overage billing via Stripe | **TokenUsageBucket object (reported by Safety Wrapper):** ```json { "agentId": "marketing", "model": "deepseek/deepseek-v3.2", "bucketHour": "2026-03-15T14:00:00Z", "tokensInput": 45000, "tokensOutput": 12000, "tokensCacheRead": 28000, "tokensCacheWrite": 0, "webSearchCount": 2, "webFetchCount": 1, "costCents": 3 } ``` ### 4.11 Analytics | Method | Path | Description | |--------|------|-------------| | GET | `/api/v1/admin/analytics/tokens` | Global token usage overview (all tenants) | | GET | `/api/v1/admin/analytics/tokens/{orderId}` | Per-tenant token usage | | GET | `/api/v1/admin/analytics/costs` | Cost breakdown by customer/model/agent | | GET | `/api/v1/admin/stats` | Platform statistics (total customers, orders, revenue) | | GET | `/api/v1/admin/analytics` | Dashboard analytics (growth, churn, usage trends) | ### 4.12 Settings | Method | Path | Description | |--------|------|-------------| | GET | `/api/v1/admin/settings` | Get all settings by category | | PATCH | `/api/v1/admin/settings` | Update settings (bulk). Body: `{ "category.key": "value" }` | | POST | `/api/v1/admin/settings/test-email` | Send test email | | POST | `/api/v1/admin/settings/test-storage` | Test S3/MinIO connection | **Settings categories:** docker, dockerhub, gitea, hub, provisioning, netcup, email, notifications, storage (50+ settings total). ### 4.13 Enterprise Client Management | Method | Path | Description | |--------|------|-------------| | GET | `/api/v1/admin/enterprise-clients` | List enterprise clients | | POST | `/api/v1/admin/enterprise-clients` | Create enterprise client | | GET | `/api/v1/admin/enterprise-clients/{id}` | Client detail with servers | | PATCH | `/api/v1/admin/enterprise-clients/{id}` | Update client | | DELETE | `/api/v1/admin/enterprise-clients/{id}` | Deactivate client | | GET | `/api/v1/admin/enterprise-clients/{id}/servers` | List client's servers | | POST | `/api/v1/admin/enterprise-clients/{id}/servers` | Add server to client | | GET | `/api/v1/admin/enterprise-clients/{id}/servers/{sId}/stats` | Server stats | | GET | `/api/v1/admin/enterprise-clients/{id}/servers/{sId}/events` | Container events | | GET | `/api/v1/admin/enterprise-clients/{id}/error-rules` | Error detection rules | | POST | `/api/v1/admin/enterprise-clients/{id}/error-rules` | Create error rule | | PATCH | `/api/v1/admin/enterprise-clients/{id}/error-rules/{rId}` | Update error rule | | DELETE | `/api/v1/admin/enterprise-clients/{id}/error-rules/{rId}` | Delete error rule | | GET | `/api/v1/admin/enterprise-clients/{id}/errors` | Detected errors | | POST | `/api/v1/admin/enterprise-clients/{id}/errors/{eId}/acknowledge` | Acknowledge error | | GET | `/api/v1/admin/enterprise-clients/{id}/notifications` | Notification settings | | PATCH | `/api/v1/admin/enterprise-clients/{id}/notifications` | Update notification settings | | POST | `/api/v1/admin/enterprise-clients/{id}/security/verify` | Request security verification code | | POST | `/api/v1/admin/enterprise-clients/{id}/security/confirm` | Confirm verification code | --- ## 5. Hub Customer API (NEW) Self-service portal for customers. All endpoints require customer session authentication. | Method | Path | Description | |--------|------|-------------| | GET | `/api/v1/customer/dashboard` | Customer overview (server status, agent status, recent activity) | | GET | `/api/v1/customer/agents` | List customer's agents with status | | GET | `/api/v1/customer/agents/{id}` | Get agent detail (SOUL.md, tools, autonomy) | | PATCH | `/api/v1/customer/agents/{id}` | Update agent config (personality, tools, autonomy level) | | PATCH | `/api/v1/customer/agents/{id}/external-comms` | Update external comms gate per tool | | GET | `/api/v1/customer/agents/{id}/activity` | Agent activity feed | | GET | `/api/v1/customer/agents/{id}/conversations` | Conversation history | | GET | `/api/v1/customer/usage` | Token usage summary (per agent, per model, daily/weekly/monthly) | | GET | `/api/v1/customer/usage/breakdown` | Detailed usage breakdown for billing transparency | | GET | `/api/v1/customer/approvals` | Pending command approval queue | | POST | `/api/v1/customer/approvals/{id}` | Approve or deny a pending command | | GET | `/api/v1/customer/tools` | List deployed tools with status | | GET | `/api/v1/customer/billing` | Current billing period, usage, overages | | GET | `/api/v1/customer/billing/history` | Billing history | | GET | `/api/v1/customer/backups` | Backup status and history | | PATCH | `/api/v1/customer/settings` | Update customer preferences (timezone, locale, notifications) | --- ## 6. Hub Tenant Communication API (NEW) Endpoints called by the Safety Wrapper on each tenant VPS. All require Bearer {hubApiKey} authentication. | Method | Path | Description | |--------|------|-------------| | POST | `/api/v1/tenant/register` | Safety Wrapper registers post-deploy. Body: `{ registrationToken }`. Returns: `{ hubApiKey }` | | POST | `/api/v1/tenant/heartbeat` | Status heartbeat. Sent every 5 minutes. | | GET | `/api/v1/tenant/config` | Pull full config (agent configs, autonomy levels, model routing) | | POST | `/api/v1/tenant/approval-request` | Push command approval request to Hub | | GET | `/api/v1/tenant/approval-response/{id}` | Poll for approval/denial (or via webhook) | | POST | `/api/v1/tenant/usage` | Report token usage buckets (hourly) | | POST | `/api/v1/tenant/backup-status` | Report backup execution status | **Heartbeat request body:** ```json { "status": "healthy", "openclawVersion": "v2026.2.1", "safetyWrapperVersion": "v1.0.3", "configVersion": 7, "agents": { "dispatcher": { "status": "active", "lastActiveAt": "2026-03-15T14:20:00Z" }, "it-admin": { "status": "active", "lastActiveAt": "2026-03-15T14:18:00Z" }, "marketing": { "status": "idle", "lastActiveAt": "2026-03-14T09:00:00Z" }, "secretary": { "status": "active", "lastActiveAt": "2026-03-15T14:22:00Z" }, "sales": { "status": "idle", "lastActiveAt": "2026-03-13T16:00:00Z" } }, "resources": { "cpuPercent": 23, "memoryUsedMb": 6144, "memoryTotalMb": 16384, "diskUsedGb": 45, "diskTotalGb": 320, "containersRunning": 18, "containersStopped": 2 }, "tokenUsage": { "periodStart": "2026-03-01T00:00:00Z", "tokensUsed": 8234000, "tokenAllotment": 15000000, "premiumTokensUsed": 125000, "premiumCostCents": 1250 }, "backupStatus": { "lastBackup": "2026-03-15T02:15:00Z", "status": "success", "sizeGb": 4.2 } } ``` **Heartbeat response body:** ```json { "configVersion": 8, "configChanged": true, "pendingCommands": [ { "id": "cmd_123", "type": "RESTART_SERVICE", "payload": { "service": "ghost" } } ], "pendingApprovals": [ { "id": "appr_456", "action": "approve" } ] } ``` If `configChanged: true`, the Safety Wrapper follows up with `GET /api/v1/tenant/config` to pull the updated configuration. --- ## 7. Public API | Method | Path | Auth | Description | |--------|------|------|-------------| | POST | `/api/v1/public/orders` | API key | Create order from external source (Stripe checkout redirect) | | GET | `/api/v1/public/orders/{id}` | API key | Get order status (for progress page) | | GET | `/api/v1/public/founding-members/count` | None | Get founding member spots remaining | --- ## 8. Webhooks ### 8.1 Inbound Webhooks (Hub Receives) **Stripe Checkout:** | Method | Path | Source | Description | |--------|------|--------|-------------| | POST | `/api/v1/webhooks/stripe` | Stripe | `checkout.session.completed` → Creates User + Subscription + Order | **Stripe webhook payload handling:** ``` Event: checkout.session.completed → Verify signature (stripe.webhooks.constructEvent) → Extract: customer email, plan, payment amount → Create User (status: ACTIVE) → Create Subscription (plan mapping: STARTER/PRO/ENTERPRISE) → Create Order (status: PAYMENT_CONFIRMED, mode: AUTO) → Automation worker picks up the order and begins provisioning ``` ### 8.2 Outbound Webhooks (Hub Sends) The Hub can push events to tenant VPS Safety Wrappers and to configured external endpoints. **To Safety Wrapper:** | Event | Method | Path (on tenant) | Payload | |-------|--------|-------------------|---------| | Config updated | POST | `{safetyWrapperUrl}/webhooks/config-update` | `{ configVersion, changedFields }` | | Approval response | POST | `{safetyWrapperUrl}/webhooks/approval-response` | `{ approvalId, action, respondedBy }` | | Remote command | POST | `{safetyWrapperUrl}/webhooks/command` | `{ commandId, type, payload }` | **Webhook security:** All outbound webhooks include: - `X-LetsBe-Signature`: HMAC-SHA256 of the request body using the shared Hub API key - `X-LetsBe-Timestamp`: Unix timestamp (for replay protection) - `X-LetsBe-Event`: Event type string ### 8.3 Safety Wrapper Webhook Endpoints Endpoints exposed by the Safety Wrapper for Hub communication: | Method | Path | Description | |--------|------|-------------| | POST | `/webhooks/config-update` | Hub notifies of config changes | | POST | `/webhooks/approval-response` | Hub delivers approval/denial for gated commands | | POST | `/webhooks/command` | Hub pushes remote commands | | POST | `/webhooks/diun` | Diun container update notifications | | GET | `/health` | Health check (returns Safety Wrapper + OpenClaw status) | --- ## 9. Cron Endpoints (Hub Internal) | Method | Path | Description | Schedule | |--------|------|-------------|----------| | POST | `/api/v1/cron/stats-collection` | Collect stats from all tenant Portainer instances | Every 15 min | | POST | `/api/v1/cron/stats-cleanup` | Delete stats older than 90 days | Daily at 03:00 | | POST | `/api/v1/cron/billing-cycle` | Process monthly billing cycles | Daily at 00:00 | | POST | `/api/v1/cron/pool-alerts` | Check token pools and send usage alerts | Every hour | | POST | `/api/v1/cron/approval-expiry` | Expire pending approvals older than 24h | Every hour | --- ## 10. Data Models (Prisma) ### 10.1 Existing Models | Model | Table | Primary Key | Key Relations | |-------|-------|-------------|---------------| | User | users | id (UUID) | → Subscription, Order[], FoundingMember? | | Staff | staff | id (UUID) | — | | StaffInvitation | staff_invitations | id (UUID) | — | | Subscription | subscriptions | id (UUID) | → User | | Order | orders | id (UUID) | → User, DnsVerification?, ProvisioningJob[], ServerConnection? | | DnsVerification | dns_verifications | id (UUID) | → Order, DnsRecord[] | | DnsRecord | dns_records | id (UUID) | → DnsVerification | | ProvisioningJob | provisioning_jobs | id (UUID) | → Order, JobLog[] | | JobLog | job_logs | id (UUID) | → ProvisioningJob | | ProvisioningLog | provisioning_logs | id (UUID) | → Order | | TokenUsage (legacy) | token_usage | id (UUID) | → User | | RunnerToken | runner_tokens | id (UUID) | — | | ServerConnection | server_connections | id (UUID) | → Order | | RemoteCommand | remote_commands | id (UUID) | → ServerConnection | | SystemSetting | system_settings | id (UUID) | — | ### 10.2 New Models (v1.2 Architecture) | Model | Table | Primary Key | Key Relations | |-------|-------|-------------|---------------| | TokenUsageBucket | token_usage_buckets | id (UUID) | → User, Order | | BillingPeriod | billing_periods | id (UUID) | → User, Subscription | | FoundingMember | founding_members | id (UUID) | → User | | AgentConfig | agent_configs | id (UUID) | → Order | | CommandApproval | command_approvals | id (UUID) | → Order | ### 10.3 Enterprise/Monitoring Models | Model | Table | Primary Key | Key Relations | |-------|-------|-------------|---------------| | EnterpriseClient | enterprise_clients | id (UUID) | → EnterpriseServer[] | | EnterpriseServer | enterprise_servers | id (UUID) | → EnterpriseClient | | ServerStatsSnapshot | server_stats_snapshots | id (UUID) | → EnterpriseServer, EnterpriseClient | | ErrorDetectionRule | error_detection_rules | id (UUID) | → EnterpriseClient | | DetectedError | detected_errors | id (UUID) | → EnterpriseServer, ErrorDetectionRule | | SecurityVerificationCode | security_verification_codes | id (UUID) | → EnterpriseClient | | LogScanPosition | log_scan_positions | id (UUID) | — | | ContainerStateSnapshot | container_state_snapshots | id (UUID) | — | | ContainerEvent | container_events | id (UUID) | — | | NotificationSetting | notification_settings | id (UUID) | → EnterpriseClient | | NotificationCooldown | notification_cooldowns | id (UUID) | — | | Pending2FASession | pending_2fa_sessions | id (UUID) | — | --- ## 11. Error Codes | Code | HTTP Status | Description | |------|------------|-------------| | `VALIDATION_ERROR` | 400 | Request body failed Zod validation | | `UNAUTHORIZED` | 401 | Missing or invalid authentication | | `FORBIDDEN` | 403 | Authenticated but insufficient permissions | | `NOT_FOUND` | 404 | Resource does not exist | | `CONFLICT` | 409 | Duplicate resource (e.g., duplicate email) | | `RATE_LIMITED` | 429 | Too many requests. Check `Retry-After` header | | `PROVISIONING_FAILED` | 500 | Server provisioning pipeline failed | | `PORTAINER_UNAVAILABLE` | 502 | Cannot reach tenant Portainer instance | | `NETCUP_ERROR` | 502 | Netcup API returned an error | | `STRIPE_ERROR` | 502 | Stripe API returned an error | | `TENANT_OFFLINE` | 503 | Tenant VPS Safety Wrapper is not responding | | `INTERNAL_ERROR` | 500 | Unhandled server error | --- ## 12. Implementation Priority | Phase | Endpoints | Effort | |-------|-----------|--------| | **Phase 1: Core** | Auth, Customers, Orders, Provisioning, DNS, Containers, Settings | Existing (retool) | | **Phase 2: Tenant Comms** | /tenant/register, /heartbeat, /config, /usage, /approval-request | 3 weeks | | **Phase 3: Customer Portal** | /customer/* endpoints | 3 weeks | | **Phase 4: Agent Management** | /admin/agents/*, /customer/agents/* | 2 weeks | | **Phase 5: Billing** | /admin/billing/*, cron jobs, Stripe integration | 3 weeks | | **Phase 6: Analytics** | /admin/analytics/*, customer usage dashboards | 2 weeks | --- ## 13. Changelog | Version | Date | Changes | |---------|------|---------| | 1.0 | 2026-02-26 | Initial API reference. 80+ existing endpoints documented. New endpoint groups: Tenant Communication (7), Customer Portal (16), Agent Management (5), Billing (4), Approvals (3), Analytics (3). Authentication flows. Webhook specs. Data models. Error codes. Implementation priorities. |