Skip to content

Endpoint Configuration API

These three models define the connection targets for the systems Proxbox integrates: a Proxmox VE API server, a remote NetBox instance, and the Proxbox FastAPI backend. All three share a common base structure (name, IP address or domain, port, SSL verification) and inherit from EndpointBase.

For common API conventions (authentication, pagination, nested serializers), see API Overview.


Proxmox Endpoint

Stores connection credentials for a Proxmox VE API server.

GET    /api/plugins/proxbox/endpoints/proxmox/
GET    /api/plugins/proxbox/endpoints/proxmox/{id}/
POST   /api/plugins/proxbox/endpoints/proxmox/
PUT    /api/plugins/proxbox/endpoints/proxmox/{id}/
PATCH  /api/plugins/proxbox/endpoints/proxmox/{id}/
DELETE /api/plugins/proxbox/endpoints/proxmox/{id}/

Example — list all Proxmox endpoints:

curl -H "Authorization: Token <token>" \
     http://netbox.example.com/api/plugins/proxbox/endpoints/proxmox/

Example — create a Proxmox endpoint using token auth:

curl -X POST \
     -H "Authorization: Token <token>" \
     -H "Content-Type: application/json" \
     -d '{
       "name": "prod-proxmox",
       "domain": "proxmox.example.com",
       "port": 8006,
       "username": "root@pam",
       "token_name": "proxbox",
       "token_value": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
       "verify_ssl": false
     }' \
     http://netbox.example.com/api/plugins/proxbox/endpoints/proxmox/

Example — filter by mode:

curl -H "Authorization: Token <token>" \
     "http://netbox.example.com/api/plugins/proxbox/endpoints/proxmox/?mode=cluster"

Filterable fields: id, name, domain, ip_address, mode, allowed_tenants, allowed_tenants_id, allowed_tenants__id__in, allowed_tenants__isnull

Searchable fields (?q=): name, domain

Sample response:

{
  "id": 1,
  "url": "/api/plugins/proxbox/endpoints/proxmox/1/",
  "display": "prod-proxmox (proxmox.example.com)",
  "name": "prod-proxmox",
  "ip_address": null,
  "domain": "proxmox.example.com",
  "port": 8006,
  "mode": {"value": "cluster", "label": "Cluster"},
  "version": "8.1.4",
  "repoid": "",
  "username": "root@pam",
  "token_name": "proxbox",
  "verify_ssl": false,
  "enabled": true,
  "allowed_tenants": [],
  "tags": [],
  "custom_fields": {},
  "created": "2026-01-01T00:00:00Z",
  "last_updated": "2026-04-01T00:00:00Z"
}

Write-only credentials

password and token_value are write-only. They are accepted on POST/PUT/PATCH but never returned in GET responses.

Bulk enablement

The Proxmox Endpoints UI at /plugins/proxbox/endpoints/proxmox/ shows the Enabled column by default. Select one or more rows and use Enable Selected or Disable Selected to toggle the local endpoint inventory state in one action. These buttons only update the NetBox enabled flag; they do not register endpoints with proxbox-api, start a sync, or contact Proxmox.

Disabled status

Disabled Proxmox endpoints are shown as a gray Disabled badge on the list, detail page, and dashboard card. The disabled UI state does not emit live status polling metadata, and direct keepalive calls return status="disabled" defensively instead of probing proxbox-api or Proxmox.

Data Model

Field Type Description
name string Display name for this Proxmox server
ip_address nested IPAddress (nullable) NetBox IPAddress object linked to this endpoint
domain string (nullable) FQDN, hostname, or localhost
port integer API port (default 8006)
mode choice Deployment mode. Choices: undefined, standalone, cluster
version string Proxmox VE version string (set on sync)
repoid string Proxmox repository/release ID
username string Proxmox API username (default root@pam)
password string (write-only) Proxmox user password for auth
token_name string Proxmox API token name
token_value string (write-only) Proxmox API token secret
verify_ssl boolean Whether to verify the Proxmox TLS certificate (default true for new endpoints; existing rows keep their stored value)
enabled boolean Local inventory toggle. Disabled endpoints remain visible but are excluded from operational reads, registration, keepalive, status, and sync paths.
node_device_name_template string Optional per-endpoint NetBox Device naming template. Blank inherits the global setting. Supported placeholders: {node}, {cluster}, {cluster_slug}, and {endpoint}.
allowed_tenants nested Tenant list Tenant allow-list for endpoint visibility. Empty means default/global visibility.
allow_writes boolean Gate for the operational verb routes on the paired proxbox-api (start/stop/snapshot/migrate). Defaults to false. When false, proxbox-api returns 403 {"reason": "writes_disabled_for_endpoint"} for verb POSTs against this endpoint even with a valid API key and X-Proxbox-Actor header. Flip to true per-endpoint to opt that Proxmox cluster into write access.
allow_packer_template_builds boolean Separate, default-off capability for netbox-packer Cloud-Init template-image creation. It is effective only when the endpoint is enabled and allow_writes is also true, authorizes no other Proxmox mutation, and is propagated to proxbox-api so the backend can recheck it at the final write boundary.

Node Device names

The global ProxboxPluginSettings.node_device_name_template defaults to {node}. A non-empty endpoint value overrides it; blank means inherit. The template must include {node} and may use {cluster}, {cluster_slug}, and {endpoint}. Format specs, conversions, attribute access, and index access are rejected. A representative render must be DNS-safe, with labels no longer than 63 characters and a complete name no longer than the NetBox Device limit of 64.

For example, {node}.{cluster}.example.com lets two clusters both expose a short node named prox01 without colliding in NetBox. Sync state and Proxmox API paths retain prox01; only the NetBox Device name is rendered. Template changes rename a legacy short name or a name previously managed by Proxbox, including a switch back to {node}. Operator-assigned names are preserved. | packer_template_builds_backend_authorized | boolean (read-only) | Last effective Packer template-build grant successfully confirmed on proxbox-api. Endpoint deletion remains blocked while this is true, including after a local revocation whose backend update failed. | | ssh_credential_source | choice | Browser terminal endpoint SSH source. dedicated (model/API default) uses the encrypted endpoint ssh_* fields, reuse_endpoint uses the realm-stripped endpoint username and password, and service resolves a ServiceSSHCredential through ssh_service. The UI defaults new SSH configuration to service. | | ssh_service | nested application service (nullable) | Writable by ID. The service must belong to this endpoint, include its IP address, use TCP, and expose ssh_port. | | ssh_username / ssh_port / ssh_auth_method / ssh_known_host_fingerprint | mixed | Dedicated endpoint SSH credential metadata for browser terminal sessions. The pinned host-key fingerprint is also required when ssh_credential_source=reuse_endpoint. | | has_ssh_password / has_ssh_private_key / has_ssh_terminal_credentials | boolean | Read-only browser terminal credential readiness flags. In reuse mode, readiness depends on endpoint host, pinned fingerprint, realm-stripped username, and endpoint password. OpenBao references must identify an expected credential type visible through the authenticated caller's reveal scope and policy groups; serialization does not read material. | | service_monitoring_enabled | boolean | Opt-in flag for async systemd service monitoring via the optional netbox-rpc plugin. Eligibility also requires netbox-rpc installed and enabled. | | service_monitoring_interval_minutes | integer | Scheduled collection interval, 1 through 1440 minutes. | | service_monitoring_units | JSON list | Systemd units passed to os.linux.proxmox.show_systemctl_services; an empty list lets the RPC procedure use its default Proxmox unit set. | | service_monitoring_last_success_at / service_monitoring_last_status / service_monitoring_last_error | mixed | Read-only heartbeat fields updated by completed service-monitoring projections. | | service_monitoring_eligible | boolean | Read-only gate result. True only when allow_writes=True, access_methods="api_ssh", endpoint SSH credentials are complete, and netbox-rpc is installed and effectively enabled for the endpoint. |

Validation

At least one of domain or ip_address must be provided. Omitting both returns a 400 error on both fields.

Operational verbs

allow_writes does not gate any of the read-side sync paths. It only controls the POST verb routes (/proxmox/qemu/{vmid}/{start,stop,snapshot,migrate} and the LXC equivalents) on the paired proxbox-api. See Operational verbs design and the Endpoint Operations API. All operational dispatches first require an enabled endpoint, bind the caller's exact ObjectPermission-scoped NetBox endpoint, and translate its primary key to proxbox-api's independent endpoint ID. Missing translations fail locally; the plugin never sends the NetBox primary key as a fallback. Firewall previews additionally send a one-endpoint proxmox_endpoint_ids scope and reject returned state carrying another endpoint identity.

Packer template builds need both gates

Enabling allow_writes alone does not authorize a template bake. The same endpoint must also have allow_packer_template_builds=true. The Templates tab keeps its netbox-packer action disabled with an explanatory tooltip until both flags are enabled; proxbox-api independently returns packer_template_builds_disabled_for_endpoint if the narrow capability is absent or revoked. POST .../build-pve-template/ and POST .../cloud-image-build-pipeline/ additionally require the run_proxmox_action ObjectPermission action on the URL's exact Proxmox endpoint and a write-enabled API token when token authentication is used. These custom POST actions also retain NetBox's existing endpoint add object scope, so template-build API operators need both add and run_proxmox_action on the selected endpoint. Both check the three endpoint gates before any backend call and translate the URL's NetBox endpoint ID to proxbox-api's separate endpoint ID. Grant the action on the Proxbox > Proxmox endpoint object type, optionally with an endpoint constraint such as {"pk": 17}. A failed backend revocation leaves the read-only confirmed flag true and causes single or bulk REST deletion to return 409. The literal core.run_proxmox_action remains a deprecated compatibility path and should not be used for new grants.

Connection target authority

The Proxmox and NetBox detail APIs expose a connection-authority/ action. GET returns secret-free target metadata, its fingerprint, and approval state. For remote NetBox endpoints, the metadata and fingerprint include token_identity: the selected v1 token record ID or effective v2 token key, chosen by the effective token_version. The v2 identity is the explicit token_key, or the linked v2 token's key when the explicit field is blank, matching the payload selector. They never include token_secret. PUT accepts only the reviewed target_fingerprint and requires sensitive-data access plus independent object view/change permission and a write-enabled API token. Missing or stale approval blocks backend credential payloads before resolution. Migration 0106 clears existing remote NetBox endpoint approvals so operators explicitly reapprove the newly token-bound fingerprint; Proxmox endpoint fingerprints and approvals remain unchanged. See Connection target approval.

Endpoint SSH terminal credentials

SSH secret reads also require the sensitive-data grant, API-token authentication, HTTPS outside development, object visibility, and provider reveal rights. The endpoint SSH secrets endpoint keeps the same response shape for all credential sources. Service mode resolves metadata and material through ssh_service → ServiceSSHCredential; dedicated mode decrypts stored ssh_*_enc fields and requires the plugin encryption key. Reuse mode returns auth_method=password, the realm-stripped endpoint username, the endpoint password, and an empty private_key; token-only endpoints return a 4xx error instead of an empty password.

Endpoint application services

Endpoint-owned services have full CRUD at:

GET,POST       /api/plugins/proxbox/endpoint-services/
GET,PUT,PATCH,DELETE /api/plugins/proxbox/endpoint-services/{id}/

Fields are endpoint, name, protocol, ports, ipaddresses, description, comments, tags, and custom fields. Names are unique per endpoint, protocol is tcp, udp, or sctp, and ports must contain at least one integer from 1 through 65535. Filter by endpoint_id when populating an endpoint form.

Secret-free SSH credential metadata is read-only at /api/plugins/proxbox/service-ssh-credentials/. It exposes the service, username, authentication method, selected storage backend, description, and the has_password/has_private_key readiness flags. It never serializes ciphertext, provider UUIDs, passwords, or private keys.

Endpoint service monitoring

The API route POST /api/plugins/proxbox/endpoints/proxmox/{id}/services/refresh/ queues an on-demand netbox-rpc execution for service monitoring. It requires change_proxmoxendpoint and the same eligibility gate as the UI. Read-only projections are exposed at /service-collections/, /service-samples/, and /service-statuses/.

Tenant allow-list semantics

  • allowed_tenants=[] means the endpoint remains in the default/global pool.
  • Supplying one or more tenants makes the endpoint visible only to those tenants in tenant-scoped API flows.
  • PATCH {"allowed_tenants": []} clears explicit grants and returns the endpoint to default/global visibility.
  • When an API consumer resolves X-Cloud-Tenant, it keeps global/default endpoints visible only if the tenant has no explicit endpoint grants. As soon as one explicit match exists, the backend hides the global pool and returns only explicit matches.

NetBox Endpoint

Stores connection details for a remote NetBox API instance that Proxbox synchronizes data into.

GET    /api/plugins/proxbox/endpoints/netbox/
GET    /api/plugins/proxbox/endpoints/netbox/{id}/
POST   /api/plugins/proxbox/endpoints/netbox/
PUT    /api/plugins/proxbox/endpoints/netbox/{id}/
PATCH  /api/plugins/proxbox/endpoints/netbox/{id}/
DELETE /api/plugins/proxbox/endpoints/netbox/{id}/

Example — create a NetBox endpoint with v2 token:

curl -X POST \
     -H "Authorization: Token <token>" \
     -H "Content-Type: application/json" \
     -d '{
       "name": "remote-netbox",
       "domain": "netbox.example.com",
       "port": 443,
       "verify_ssl": true,
       "token_version": "v2",
       "token_key": "my-key-id",
       "token_secret": "my-secret-value"
     }' \
     http://netbox.example.com/api/plugins/proxbox/endpoints/netbox/

Example — filter by name:

curl -H "Authorization: Token <token>" \
     "http://netbox.example.com/api/plugins/proxbox/endpoints/netbox/?name=remote-netbox"

Filterable fields: id, name, domain, ip_address

Searchable fields (?q=): name, domain

Sample response:

{
  "id": 1,
  "url": "/api/plugins/proxbox/endpoints/netbox/1/",
  "display": "remote-netbox (netbox.example.com)",
  "name": "remote-netbox",
  "ip_address": null,
  "domain": "netbox.example.com",
  "port": 443,
  "token_version": {"value": "v2", "label": "v2 Token"},
  "token": null,
  "token_key": "my-key-id",
  "verify_ssl": true,
  "tags": [],
  "custom_fields": {},
  "created": "2026-01-01T00:00:00Z",
  "last_updated": "2026-04-01T00:00:00Z"
}

Write-only credentials

token_secret is write-only and never returned in GET responses.

Data Model

Field Type Description
name string Display name for this remote NetBox instance
ip_address nested IPAddress (nullable) NetBox IPAddress object linked to this endpoint
domain string (nullable) FQDN, hostname, or localhost
port integer API port (default 443)
token_version choice Authentication style. Choices: v1, v2
token nested Token (nullable) NetBox v1 Token FK — use for v1 plaintext tokens only
token_key string v2 token key (ID)
token_secret string (write-only) v2 token secret
verify_ssl boolean Whether to verify the remote NetBox TLS certificate (default true)

Token version rules

  • v1: Provide the token FK pointing to a NetBox users.Token with a readable plaintext value. Clear token_key and token_secret.
  • v2: Provide token_key and token_secret directly. Setting token_version=v2 without both fields returns a 400 error. Do not use the token FK for v2 tokens — their secret is not retrievable from the DB.
  • At least one of domain or ip_address is required.

FastAPI Endpoint

Stores the HTTP and WebSocket connection details for the Proxbox FastAPI backend service.

GET    /api/plugins/proxbox/endpoints/fastapi/
GET    /api/plugins/proxbox/endpoints/fastapi/{id}/
POST   /api/plugins/proxbox/endpoints/fastapi/
PUT    /api/plugins/proxbox/endpoints/fastapi/{id}/
PATCH  /api/plugins/proxbox/endpoints/fastapi/{id}/
DELETE /api/plugins/proxbox/endpoints/fastapi/{id}/

Example — create a FastAPI endpoint:

curl -X POST \
     -H "Authorization: Token <token>" \
     -H "Content-Type: application/json" \
     -d '{
       "name": "proxbox-backend",
       "domain": "proxbox-api.example.com",
       "port": 8800,
       "use_https": true,
       "verify_ssl": false,
       "enabled": true,
       "use_websocket": true,
       "websocket_port": 8800
     }' \
     http://netbox.example.com/api/plugins/proxbox/endpoints/fastapi/

token is optional. When omitted, the saved URL/IP, port, and TLS policy become the exact automatic-discovery allowlist. NetBox reuses an encrypted local key after authentication or generates one only for a confirmed empty backend. An unlisted discovery target is rejected before credentials are sent. Supply token explicitly only for manual rotation or recovery.

Example — list all FastAPI endpoints:

curl -H "Authorization: Token <token>" \
     http://netbox.example.com/api/plugins/proxbox/endpoints/fastapi/

Filterable fields: id, name, domain, ip_address

Searchable fields (?q=): name, domain

Sample response:

{
  "id": 1,
  "url": "/api/plugins/proxbox/endpoints/fastapi/1/",
  "display": "proxbox-backend (proxbox-api.example.com)",
  "name": "proxbox-backend",
  "ip_address": null,
  "domain": "proxbox-api.example.com",
  "port": 8800,
  "use_https": true,
  "verify_ssl": false,
  "enabled": true,
  "use_websocket": true,
  "websocket_domain": "",
  "websocket_port": 8800,
  "server_side_websocket": false,
  "tags": [],
  "custom_fields": {},
  "created": "2026-01-01T00:00:00Z",
  "last_updated": "2026-04-01T00:00:00Z"
}

Write-only key and controlled auto-configuration

token is write-only and is never returned by list or detail responses. An operator may submit an explicit candidate, or leave it blank and let the plugin generate, encrypt, and authenticate a candidate after the database commit. Existing ciphertext is reused when an endpoint is enabled or its target changes. Until proxbox-api proves the candidate or completes its one-time empty-key bootstrap, the endpoint remains runtime-blocked.

A saved FastAPI endpoint is the complete auto-discovery allowlist: only its exact scheme, domain or IP, port, and TLS-verification policy may be contacted. Same-site or PLUGINS_CONFIG candidates are considered only when no row exists. Discovery never scans the network and never follows redirects.

The target authority is validated before the first request. Embedded credentials, paths, queries, fragments, malformed hosts, and authority injection are rejected; valid IPv6 literals use bracketed URL syntax. Disabled rows are also excluded from the legacy WebSocket and storage-detail consumers before URL or authentication-header construction.

See Endpoint Auto-Configuration for the full state machine and requirements-to-tests matrix.

Data Model

Field Type Description
name string Display name for this backend endpoint
ip_address nested IPAddress (nullable) NetBox IPAddress object linked to this endpoint
domain string (nullable) FQDN, hostname, or localhost
port integer HTTP API port (default 8800)
use_https boolean URL scheme selector (default true for new endpoints). true → https://, false → http://. Independent of verify_ssl since v0.0.15 (migration 0038, #352). See Backend Setup → TLS combinations and v0.0.15 release notes.
verify_ssl boolean Whether to verify the backend TLS certificate. Only meaningful when use_https=true.
enabled boolean Operational gate. Disabled rows perform no backend connection and cannot stage or rotate a key.
token string (write-only) Explicit backend API-key candidate. Blank preserves an existing key only when no activation or target change requires resubmission.
use_websocket boolean Whether to use a WebSocket connection for streaming
websocket_domain string Override domain for WebSocket connections (defaults to domain)
websocket_port integer WebSocket port (default 8800)
server_side_websocket boolean Whether the backend initiates the WebSocket connection