Skip to main content

Vertex API

Everything Entrosity Vertex does is available through a REST API under /api/v1; the Vertex web interface, in development, will be a plain client of it. The full endpoint reference is the Vertex API reference, rendered from entrosity-vertex.backend/api/openapi.yaml, the spec the server's router and request validation are generated from.

Conventions​

  • Base URL: https://hub.entrosity.com/vertex/api/v1 once Vertex is deployed (the proxy strips /vertex; Running Entrosity Vertex).
  • Authentication: Authorization: Bearer <product token>, a five-minute token from Entrosity Hub for the product vertex (POST /api/platform/v1/auth/product-token {"product":"vertex"} with the Hub's session, Hub API). Vertex has no sign-in of its own; users, tenants and roles come from the Hub. While Vertex is in beta, the Hub issues its tokens to platform admins only.
  • Access rules: every route has a rule in entrosity-vertex.backend/internal/http/portal/access.go: public, signed in, global admin, or a tenant permission (Roles and permissions). Tenant users may only call /tenants/{their tenant id}/…; any other tenant answers 404. A missing permission answers 403 forbidden. Object routes (/objects/{objectID}, membership, bulk actions) are routed with the weakest permission and the handler checks the one the operation needs (directory.RequiredPermission): for example the helpdesk may PATCH a user's contact attributes but nothing else.
  • JSON bodies with snake_case keys. Request schemas refuse unknown fields (422).
  • Objects are addressed by their objectGUID (objectID), GPOs by their GUID (gpoID); distinguished names appear in bodies (ou, target_ou, group and member DNs).
  • Attributes are maps of LDAP display names to string arrays; binary values are b64:<base64> (Users → Changing attributes).
  • Lists take ?page=&page_size= (default 50, maximum 500) and return items, page, page_size and total; the OU, GPO and password policy lists return all items.
  • Rate limits: 20 requests per second per client IP, burst 60 (VERTEX_API_RATE_PER_SECOND, VERTEX_API_RATE_BURST). Changes also count against 600 per user and 2,000 per tenant per minute (429 rate_limited).
  • Every response carries X-Request-ID.

Errors​

Errors are RFC 7807 application/problem+json with a stable code:

{
"type": "about:blank",
"title": "Conflict",
"status": 409,
"code": "writes_disabled",
"detail": "gpo changes are switched off in the directory settings",
"request_id": "…"
}

Validation errors have code: "validation" and fields with a message per field. All codes and what to do about them: Vertex troubleshooting.

Operations​

Reads of lists and objects come from Vertex's mirror and answer at once. Everything that reaches Active Directory (changes, the test, syncs, live reads, GPO reports and backups) is an operation and answers 202 with it:

POST /tenants/{tenantID}/users/{objectID}/password
{"password": "…", "must_change": true, "unlock": true}
{ "id": "0192…", "op": "user.password", "class": "user", "is_delete": false,
"target_kind": "user", "target_id": "3f1c…", "target_dn": "CN=Ivan Petrov,OU=Students,…",
"summary": "Reset the password of ipetrov", "status": "queued", … }

Endpoints that act on several groups or users (…/users/{objectID}/groups, …/users/bulk-actions) answer 202 with {items: [Operation…]}.

Follow an operation:

  1. GET /tenants/{tenantID}/operations/{operationID}?wait=20 answers as soon as it has finished, or after wait seconds (0 to 25);
  2. or the vertex.operation event of the live stream.

status goes pending → queued → running → succeeded, failed, cancelled or timeout, with progress_pct and progress_message for long ones. A failed operation has error_code and error. result holds what the connector returned: the changed object (all its attributes), the gpo, the deleted GUID, a GPO backup_id, the test result or counts. params repeats the request, never with passwords.

POST …/operations/{operationID}/cancel cancels an operation that has not finished (best effort once it runs; 409 operation_finished otherwise). GET …/operations lists them newest first, filtered by target_id, status, class (read, user, group, ou, gpo, pso) and changes_only.

Step-up​

Saving the directory settings (step_up_token in the body), deletes (X-Step-Up-Token header on DELETE …/objects/{objectID} and DELETE …/gpos/{gpoID}; step_up_token in a bulk delete) and committing an import (step_up_token) need a step-up token from the Hub for the caller's password (POST /api/platform/v1/auth/step-up, product vertex). Each token is used once; without one the answer is 403 step_up_required.

Secrets​

The AD account's password (ad_password in the settings) and passwords of new users, password resets and imports are write-only: no endpoint returns them, operations and the audit log never contain them, and they are stored encrypted (VERTEX_CREDENTIALS_KEY) only until the connector has fetched them. The settings answer has_password instead.

Imports​

POST /tenants/{tenantID}/imports {csv, filename, mode, options} (201) validates a CSV file into a preview; GET …/imports/{importID}/rows shows each row; POST …/commit {step_up_token} applies it; POST …/cancel discards it; GET …/result.csv returns the outcome; GET …/imports/template an example. Format and rules: Bulk import.

Live updates​

GET /tenants/{tenantID}/stream is a text/event-stream. Browsers authenticate with ?sse_token= from POST /auth/sse-token {"tenant_id": "…"} (valid 60 seconds; keeps the access token out of URLs). Events:

EventPayloadMeaning
vertex.operation{id, op, status, progress_pct?, progress_message?, target_id?, error_code?}An operation was queued, progressed or finished.
vertex.directory{kinds: […]}The mirror changed for these kinds (user, group, ou, pso, gpo): reload them.
vertex.import{import_id}An import's rows or counters changed.
vertex.settings{}The directory settings changed.

Internal API (Entrosity Axis)​

Vertex reaches the connectors through Axis, and Axis relays the connectors' secrets requests and results back, over two internal listeners that are never routed publicly and share one bearer token (VERTEX_AXIS_TOKEN = Axis's RMM_VERTEX_AXIS_TOKEN). Endpoints and rules: Vertex protocol → The bridge.