vHaaS REST API
All features available on the vHaaS website are also accessible through the REST API.
API Versions
vHaaS provides two API versions:
| Version | Base URL | Status |
|---|---|---|
| v3 | https://vhaas.vector.cloud/api/v3/ |
Current — recommended for all new integrations |
| v2.0 | https://vhaas.vector.cloud/api/v2.0/ |
Legacy — supported, but v3 is preferred |
v3 uses an organization-scoped URL structure (e.g. /api/v3/organizations/{organization_id}/assemblies), which aligns resources clearly with their tenant context. v2.0 uses a flat structure and remains fully supported for existing integrations.
Authentication
Every request must include one of the following HTTP headers:
| Header | Value | When to use |
|---|---|---|
Authorization |
Bearer <JWT Token> |
Used automatically by the Web UI with a token issued by the identity provider. |
private-token |
<Access Token> |
Use this in scripts, CI pipelines, and the CLI. Accepts personal, group, and organization tokens. |
Access tokens can be created in the vHaaS Web UI at personal, group, or organization scope.
Interactive Documentation (Swagger UI)
The full API is documented and interactable in the live Swagger UI:
| Version | Swagger UI | OpenAPI Spec |
|---|---|---|
| v3 | /api/v3/docs | /api/v3/openapi.json |
| v2.0 | /api/v2.0/docs | /api/v2.0/openapi.json |
Click Authorize at the top of the Swagger UI and enter your access token to send requests directly from the browser.
Endpoint Reference
The complete list of all v3 endpoints, grouped by resource type, is available on the following page:
Common Endpoints (Quick Reference)
The most commonly used endpoints for day-to-day automation and CI integration. Replace {org_id} with your organization's ID.
| Method | Path (v3) | Description |
|---|---|---|
GET |
/api/v3/self |
Get the profile of the currently authenticated user. |
GET |
/api/v3/organizations/{org_id}/assemblies |
List all Assemblies visible to you. |
GET |
/api/v3/organizations/{org_id}/assemblies/{assembly_ref} |
Get a single Assembly by reference. |
POST |
/api/v3/organizations/{org_id}/assembly-sessions |
Book (allocate) an Assembly session. |
GET |
/api/v3/organizations/{org_id}/assembly-sessions/{session_id} |
Get the status and details of an active session. |
PATCH |
/api/v3/organizations/{org_id}/assembly-sessions/{session_id} |
Update a session (e.g. extend end time). |
DELETE |
/api/v3/organizations/{org_id}/assembly-sessions/{session_id} |
Release a session immediately. |
GET |
/api/v3/organizations/{org_id}/virtual-machines |
List Virtual Machines accessible to you. |
GET |
/api/v3/organizations/{org_id}/jobs |
List scheduled and running jobs. |
Using the CLI instead
For most of these operations there is a dedicated CLI command. See the Command Line Tool reference for details.
Pagination
All list endpoints return paginated results via two query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
page |
integer | 1 |
Page number (1-based). |
size |
integer | 50 |
Number of items per page. |
The response envelope includes: items, total, page, size, pages.
Example:
v2.0 Pagination
The legacy v2.0 API uses skip / limit parameters instead of page / size.
API Errors
Every v3 error response is an RFC 9457 application/problem+json body. Branch on the stable code field — not the HTTP status or the human-readable title — and use the type URI to reach an error's entry below. Codes that share an HTTP status are still distinguished by code.
Opt in while this format rolls out
An error only takes the shape described here if the request asks for it:
Without it the response is still application/problem+json, but without the stable codes documented here — that older shape carries no compatibility guarantee.
Never branch on title or detail: both are human-readable text and may be reworded at any time. code is the only field to check an error against.
The header is temporary. This format becomes the default in a later release; the header then has no effect and can be dropped. Until then, sending it is safe, and anything you write against code today keeps working unchanged afterwards.
Every error response shares this RFC 9457 application/problem+json shape:
{
"type": "https://docs.vhaas.vector.cloud/reference/api/#resource-has-dependents",
"title": "Resource Has Dependents",
"status": 409,
"code": "RESOURCE_HAS_DEPENDENTS",
"detail": "The cluster cannot be deleted while assemblies are assigned to it.",
"instance": "/api/v3",
"timestamp": "2026-01-01T00:00:00.000000Z",
"resource_type": "assembly"
}
The type, title, status, code, instance and timestamp members are present on every error; detail is optional. Some codes add extra top-level members (extensions) — e.g. resource_type above — called out in the Description column below.
Domain errors
| Code | HTTP status | Description |
|---|---|---|
ASSEMBLY_IN_USE |
409 | Assembly is in use and cannot be modified/unassigned. |
REFERENCE_IMMUTABLE |
422 | A resource reference cannot be changed after creation. |
USER_HAS_OPEN_TASKS |
409 | A user cannot be removed while they own open tasks. |
JOB_NOT_DELETABLE |
409 | A job is not in a deletable state. |
TECHNICAL_USER_OPERATION |
409 | An operation is not allowed on a technical/service user. |
CROSS_ORGANIZATION_MISMATCH |
422 | Two referenced resources belong to different organizations. |
VM_LINKED_TO_ASSEMBLY |
409 | A VM operation is blocked because it is linked to an assembly. |
RESOURCE_HAS_DEPENDENTS |
409 | A resource cannot be deleted/modified while dependents exist. |
RESOURCE_LIMIT_EXCEEDED |
422 | A per-resource cap was reached. resource_type names the cap. |
SESSION_STATE_CONFLICT |
409 | A session is in a state that forbids the operation. |
ASSEMBLY_NOT_OPERATIONAL |
409 | The assembly is not in an operational state. |
DEVICE_NO_HAI |
422 | The device has no HAI available. |
ASSEMBLY_NOT_IN_CLUSTER |
409 | A VM cannot be assigned because the assembly is not in a cluster. |
DEFAULT_RUNNER_REQUIRED |
409 | A default runner is required for the operation. |
INVITATION_INVALID_OR_EXPIRED |
404 | An invitation token is unknown, not pending, or expired. |
INVITATION_EMAIL_MISMATCH |
403 | The authenticated user's email does not match the invited address. |
INVITATION_EMAIL_NOT_VERIFIED |
403 | The authenticated user's email address is not verified. |
SEATS_EXHAUSTED |
409 | An organization has no remaining seats for the request. |
ROLE_UNCHANGED |
409 | The user already has the requested role. |
BULK_BOOKING_FAILED |
409 | A bulk booking partially failed. errors carries per-item detail. |
ENDPOINT_DISABLED |
410 | A disabled v2-shape route. |
NOT_IMPLEMENTED |
501 | A stubbed endpoint that is not yet implemented. |
Generic errors
| Code | HTTP status | Description |
|---|---|---|
OBJECT_NOT_FOUND |
404 | A requested resource cannot be found. |
DUPLICATE_RESOURCE |
409 | A resource already exists. Covers "already exists" + insert conflicts. |
CONSTRAINT_VIOLATED |
409 | A domain constraint/precondition was violated. |
VALIDATION_ERROR |
422 | A business-rule validation failure raised by logic. |
PERMISSION_DENIED |
403 | The caller is authenticated but not authorized. |
UPSTREAM_SERVICE_ERROR |
502 | A downstream/upstream dependency failed. service names it. |
SERVICE_UNAVAILABLE |
503 | A dependency is temporarily unavailable. Optional retry_after. |
RATE_LIMITED |
429 | Too many requests. Dormant until the agent API (package h). |
INTERNAL_ERROR |
500 | Sanitized catch-all for an unhandled/unexpected failure. |
UNAUTHORIZED |
401 | Authentication is required or has failed. Shared cross-version auth raiser. |
BAD_REQUEST |
400 | A raw 400 with no more-specific typed error. |
METHOD_NOT_ALLOWED |
405 | Router-generated wrong-method on a v3 route. |
GENERIC |
500 | Migration-era fallback for an un-migrated raw HTTPException. |
Integration
CLI and Python library
The vHaaS CLI (pes-vhaas Python package) wraps the full API and is the recommended way to interact with vHaaS from scripts and pipelines.
Auto-generating a client
Download the OpenAPI spec and use the OpenAPI Generator to generate a typed client in any supported language: