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.