Instances

Endpoints for provisioning and managing ERP instances. Backed by instance.py (the largest controller in the module, ~3,100 lines) against the saas.instance model. All routes require auth and are tenant-scoped — an authenticated user only ever sees instances belonging to their own saas.tenant.

GET /api/instances

Lists every instance owned by the caller’s tenant.

{
  "success": true,
  "instances": [
    {
      "id": 12,
      "name": "Acme Corp",
      "url": "https://acme.dishonkadoh.com",
      "subdomain": "acme",
      "version": "18.0",
      "odoo_version": "18.0",
      "state": "running",
      "status": "running",
      "database_size": 512.4,
      "memory": 2048,
      "storage": 20,
      "cpu": 1.0,
      "database_name": "acme_prod",
      "postgres_db": "acme_prod",
      "last_backup": "2026-09-01 03:00",
      "last_sync": "2026-09-08 14:22"
    }
  ]
}

POST /api/instances/create

Body:

{
  "name": "Acme Corp",
  "subdomain": "acme",
  "odoo_version": "18.0",
  "backend": "kubernetes"
}

backend selects which provisioning path runs — "kubernetes" (per-tenant namespace, Deployment/Service/Ingress via the AWS EKS ALB ingress class) or "docker" (Traefik-routed container against the shared odoo18-db). See Architecture for how the dual-backend dispatch works.

GET /api/instances/<id>

Full detail for a single instance (superset of the list fields above).

GET /api/instances/<id>/status

Lightweight status-only poll — used for short-interval UI refreshes without pulling the full detail payload.

POST /api/instances/<id>/start · /stop · /restart

Lifecycle actions against the instance’s container/pod. No request body.

GET /api/instances/<id>/metrics and /metrics/history

Current resource usage (CPU/memory/storage) and a historical series, respectively, sourced from saas.instance.metric records.

POST /api/instances/<id>/backup

Triggers an on-demand backup (creates a saas.backup record and kicks off the backend backup job). See Backups for downloading/restoring the result.

GET /api/instances/<id>/users and POST /api/instances/<id>/users/invite

List the Odoo users provisioned on that specific instance, or invite a new one:

{ "email": "new.user@acme.com", "name": "New User", "role": "user" }

Modules on an instance

See Modules for GET/POST /api/instances/<id>/modules.

Logs

GET /api/instances/<id>/logs and GET /api/instances/<id>/logs/stream-token (in instance_logs.py) — the stream-token route issues a short-lived token used to authorize a separate real-time log-streaming connection, kept out of the main bearer flow so the log stream doesn’t need the full token in a URL/query string.