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.
| Group | Purpose |
|---|---|
/auth | Register, login, and MFA (TOTP) challenge and verification. |
/auth/devices | Registered device sessions and per-device trust. |
/auth/webauthn | Passkey (WebAuthn) registration and authentication. |
/auth/sso | Enterprise SSO login and callback flows. |
/vault | Stored secrets: logins, keys, env files, TOTP seeds, notes, cards. |
/ssh | Brokered SSH/terminal access; includes the SSH certificate authority. |
/terminal | Interactive terminal sessions and session lifecycle. |
/rdp | Brokered RDP sessions and session recordings. |
/audit | The tamper-evident audit trail. |
/compliance | Compliance reporting and posture summaries. |
/ai and /ai/access | Privacy-first AI assistance and AI access controls. |
/jit | Just-in-time access requests, approvals, and revocation. |
/fleet | Fleet-wide command execution across hosts. |
/rotation | Credential rotation jobs and schedules. |
/exposure | Credential exposure and breach detection results. |
/integrations | Outbound security-event integrations (Slack, SIEM, webhook). |
/hashicorp | HashiCorp Vault sync connections and operations. |
/posture | Device posture policies and evaluation. |
/org | Organization settings and membership. |
/teams | Teams within an org and their membership. |
/api-tokens | Scoped API tokens for programmatic access. |
/scim/v2 | SCIM 2.0 user and group provisioning. |
/events/v1 | Paginated pull export of the audit event stream. |
/billing | Subscription, plan, and billing operations. |
/license | License activation and status (self-hosted). |
/health | Liveness check. |
/readyz | Readiness check (dependencies reachable). |
/metrics | Prometheus 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:
| Code | Meaning | What a client should do |
|---|---|---|
401 | No token, or an expired one. | Refresh the token and retry. |
402 | Your plan does not include this capability. | Surface the upgrade path. |
403 forbidden | You 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_frozen | The 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_found | The vault does not exist or you hold no role on it. | Treat as unavailable. Do not report it to the user as deleted. |
409 | The 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
- API tokens and SCIM — scoped tokens and identity provisioning.
- Events API — pull the audit stream as paginated JSON.
- Integrations — push real-time security events to your own systems.