Skip to content
VaultTerm
Browse docs

api-integrations

API overview

VaultTerm exposes a tenant REST API: authenticate with a bearer JWT, and every call is row-level-security scoped to the caller's organization.

Updated Aug 14, 2026

VaultTerm’s backend is a single Fastify service that serves the web app, the native and CLI clients, and a programmable REST API. The same API you build against is the one the first-party clients use, so anything you can do in the product you can do over HTTP.

Authentication and tenancy

Every request authenticates with a bearer JWT in the Authorization header:

curl -H "Authorization: Bearer $TOKEN" https://your-host.example.com/api/vault

The token carries the caller’s identity and organization. All data access is row-level-security (RLS) scoped to that org in the database — there is no cross-tenant read path in the API layer. For unattended access (CI, scripts, SIEM export), use a scoped API token instead of a user JWT; token-authenticated routes still establish the same tenant context server-side. See API tokens and SCIM.

This is the audited-broker model in practice: the server decrypts a secret in memory only for a specific authorized call, and the call lands on the tamper-evident audit trail.

Route groups

The API is organized into route groups by module. The table below is high level — each group has its own endpoints for list, fetch, create, and action operations.

GroupPurpose
/authRegister, login, and MFA (TOTP) challenge and verification.
/auth/devicesRegistered device sessions and per-device trust.
/auth/webauthnPasskey (WebAuthn) registration and authentication.
/auth/ssoEnterprise SSO login and callback flows.
/vaultStored secrets: logins, keys, env files, TOTP seeds, notes, cards.
/sshBrokered SSH/terminal access; includes the SSH certificate authority.
/terminalInteractive terminal sessions and session lifecycle.
/rdpBrokered RDP sessions and session recordings.
/auditThe tamper-evident audit trail.
/complianceCompliance reporting and posture summaries.
/ai and /ai/accessPrivacy-first AI assistance and AI access controls.
/jitJust-in-time access requests, approvals, and revocation.
/fleetFleet-wide command execution across hosts.
/rotationCredential rotation jobs and schedules.
/exposureCredential exposure and breach detection results.
/integrationsOutbound security-event integrations (Slack, SIEM, webhook).
/hashicorpHashiCorp Vault sync connections and operations.
/postureDevice posture policies and evaluation.
/orgOrganization settings and membership.
/teamsTeams within an org and their membership.
/api-tokensScoped API tokens for programmatic access.
/scim/v2SCIM 2.0 user and group provisioning.
/events/v1Paginated pull export of the audit event stream.
/billingSubscription, plan, and billing operations.
/licenseLicense activation and status (self-hosted).
/healthLiveness check.
/readyzReadiness check (dependencies reachable).
/metricsPrometheus metrics endpoint.

Authorization and error codes

Access to a vault-scoped resource is decided in one place, so every endpoint that touches a vault answers the same way. Two refusals are worth understanding before you write error handling:

CodeMeaningWhat a client should do
401No token, or an expired one.Refresh the token and retry.
402Your plan does not include this capability.Surface the upgrade path.
403 forbiddenYou hold a role on the vault, but that role does not permit this action.Tell the caller they need a higher role, and from whom.
403 vault_frozenThe vault is read-only after a plan downgrade exceeded its vault limit.Reads still work; offer the upgrade or a vault clean-up.
404 not_foundThe vault does not exist or you hold no role on it.Treat as unavailable. Do not report it to the user as deleted.
409The resource is still referenced by something else.Explain what must be removed first.

The last two rows are the ones that surprise people, so they are stated explicitly:

A caller with no role on a vault gets 404, never 403. “This vault exists but is not yours” and “this vault does not exist” are deliberately the same response. A 403 would let anyone with a token confirm that a given vault id is real, which is an org-membership and inventory leak that costs nothing to close. The same rule governs refusals elsewhere in the API — an unknown partner or organization is a 404 rather than a distinguishable error — so a client can rely on it generally rather than per endpoint.

403 therefore always means you already have access to the resource, just not enough of it. That makes the two codes genuinely useful to branch on: 403 is worth telling a user about and suggesting a route to resolve, while 404 is not something they can act on and should not be rendered as though the resource was deleted out from under them.

Where to go next