ITDocs API Documentation
| Role | Description |
|---|---|
ADMIN | Full access including user management, settings, and destructive operations |
TECHNICIAN | Read/write access to all org data. Cannot manage users or settings |
VIEWER | Read-only. Blocked from vault entirely |
Returns which SSO providers are enabled.
{ "msEnabled": true, "googleEnabled": false }Redirects to Google OAuth2 authorization. Requires Google SSO to be configured in settings.
OAuth2 callback. Redirects to FRONTEND_URL/login with accessToken, refreshToken, and user (base64 JSON) as query params. Auto-creates account with VIEWER role on first login.
Redirects to Microsoft Entra ID authorization.
OAuth2 callback. Same redirect pattern as Google callback.
Creates a new user. First registration is always public and creates an ADMIN. Subsequent registrations require an authenticated ADMIN.
{
"email": "[email protected]",
"password": "minimum12chars",
"name": "Jane Smith",
"role": "TECHNICIAN"
}
{ "user": { "id": "...", "email": "...", "name": "...", "role": "TECHNICIAN" } }Rate limited to 10/min. Supports local auth, LDAP auth, and TOTP MFA. If MFA is enabled and mfaCode is omitted, returns 403 with { "requireMfa": true }.
{
"email": "[email protected]",
"password": "yourpassword",
"mfaCode": "123456"
}
{
"accessToken": "eyJ...",
"refreshToken": "uuid",
"user": { "id": "...", "email": "...", "name": "...", "role": "ADMIN", "mfaEnabled": true }
}Exchange a refresh token for a new access token.
{ "refreshToken": "uuid" }
{ "accessToken": "eyJ..." }Requires auth. Blacklists the current access token in Redis and deletes all refresh tokens for the user.
Returns the current authenticated user.
Returns a TOTP secret and QR code data URL for the authenticated user to scan with their authenticator app.
{ "secret": "BASE32SECRET", "qrCodeUrl": "data:image/png;base64,..." }Verifies the TOTP token against the secret and enables MFA for the user.
{ "token": "123456", "secret": "BASE32SECRET" }Requires the user’s current password (verified against LDAP for LDAP users). Clears MFA secret.
{ "password": "currentpassword" }All org routes accept either a UUID or 9-digit shortId as the :id parameter.
Returns paginated list of organizations.
{
"items": [{ "id": "...", "shortId": 482039471, "name": "Acme Corp", "logoUrl": "data:image/png;base64,..." }],
"total": 1, "page": 1, "limit": 20, "pages": 1
}Returns full organization with contacts and asset/vault counts.
Returns item counts for every sidebar section for a given org. Used to show badge counts in the sidebar without loading full data.
Creates a new organization. shortId is auto-generated (9-digit random integer, guaranteed unique).
Updates an organization. Saves a revision snapshot before updating. Fires push to ConnectWise or NinjaRMM if externalSource is set.
Hard deletes the org and all cascading records.
Contact CRUD scoped to an organization. PATCH saves a revision snapshot.
Upload a logo image (JPEG, PNG, GIF, WebP, SVG). Max 2MB. Stored as BYTEA.
Removes the org logo.
Configurations, servers, workstations, network devices, etc.
Types: SERVER WORKSTATION LAPTOP NETWORK_DEVICE PRINTER PHONE VM OTHER
Statuses: ACTIVE INACTIVE DECOMMISSIONED SPARE
Creates an asset. createdById is set from the JWT.
organizationId is immutable. Saves revision snapshot. Fires fire-and-forget push to ConnectWise or NinjaRMM if asset has externalSource set. Push failures are non-fatal and logged as warnings.
See [Organizations](#organizations) โ contacts are managed under /organizations/:id/contacts.
Fields: name (required), address, city, state, zip, country, phone, notes
Passwords are never returned in plaintext unless ?reveal=true is explicitly set. VIEWER role is blocked from all vault operations.
Bulk reveal is audited with the count of entries revealed.
Both read and reveal are individually audited.
TOTP secrets have spaces stripped before encryption. Passwords encrypted with AES-256-GCM.
organizationId is immutable. Saves revision snapshot (encrypted state). Pass empty string for totpSecret to clear it.
All document routes accept either a UUID or shortId as :orgId.
Returns all folders for an org (flat list, build tree client-side using parentId).
Cascades to child folders and files.
Returns metadata only โ never includes data bytes.
Returns file metadata including content (for MARKDOWN) and blocks (for block-based editor). Never returns binary data.
Creates a new Markdown document.
Multipart upload for binary files (PDF, DOCX, XLSX). Max 100MB. Stores binary data in data column.
Converts a DOCX/TXT/MD file to a Markdown block document. DOCX is converted via mammoth โ HTML โ Markdown.
Streams the binary file with appropriate Content-Disposition header. Only works for non-MARKDOWN types.
Updates name, folderId, or content (MARKDOWN only).
Saves the full block array for a block-based Markdown document.
DRAFT | PUBLISHED)Upload an image for a gallery block. HEIC/HEIF auto-converted to JPEG. Max 100MB.
Streams raw image bytes with 1-hour cache header.
Polymorphic โ can be attached to any record type via sourceType + sourceId.
Returns metadata only โ no binary data in list response (use /download for file bytes).
Streams the file with Content-Disposition: attachment header.
Multipart upload. Max 300MB. HEIC auto-converted to JPEG. Backward compatible: also accepts assetId field (translated to sourceType: asset).
Update the display label.
{ "label": "string" }Generic key-value infrastructure tracker. infraType is a free-form string key (e.g. firewall, wan, ad, email).
When infraType is omitted, results sort by updatedAt desc (for dashboard widgets). When specified, sorts by name asc.
organizationId and infraType are immutable. Saves revision snapshot.
Saves revision snapshot.
DNS and WHOIS data is automatically fetched on create (background, non-blocking) and refreshed weekly by the cron job.
Returns lightweight list (no raw WHOIS/DNS data).
Returns full record including all DNS and WHOIS fields.
Creates the record and immediately kicks off background DNS + WHOIS enrichment.
Only notes is updatable. Saves revision snapshot.
DV|OV|EV|WILDCARD)issuedAt (ISO datetime)expiresAt (ISO datetime)autoRenew (boolean)notesrelatedAssetIdSaves revision snapshot.
PER_SEAT|PER_DEVICE|VOLUME|SUBSCRIPTION)seatCountpurchaseDate (ISO)expiryDate (ISO)purchasePrice (decimal)notesSaves revision snapshot.
All routes return the last 3 revisions per record. Older revisions are pruned automatically.
Supported sourceTypes: asset vault application contact location domain certificate license organization infra
Returns up to 3 most recent revisions for a record, newest first.
Returns a specific revision’s full JSON snapshot.
Technician/ Decrypts and returns password and totpSecret from a vault revision snapshot.
Restores a record to the state captured in the revision. Before restoring, saves the current state as a new revision. Strips id, createdAt, and updatedAt from the restored data to avoid overwriting primary keys.
Runs 10 parallel queries across all record types. Returns up to 10 results per type (5 for organizations). Organization results only appear in global search (no orgId).
{
"results": {
"assets": [{ "id": "...", "name": "...", "type": "SERVER", "infraType": "firewall", "orgId": 482039471, "orgName": "Acme", "recordType": "asset" }],
"contacts": [...],
"passwords": [...],
"organizations": [...],
"locations": [...],
"applications": [...],
"domains": [...],
"certificates": [...],
"licenses": [...],
"infra": [...]
},
"total": 42
}Singleton configuration (id: global) controlling the navigation structure.
Returns the current sidebar config, or the default config if none has been saved.
Replaces the full sidebar config. Each item has: id, label, icon (Lucide icon name), linkType (filtered|markdown|builtin|custom), linkTarget, builtinPath, fields (for custom sections).
{ "config": [ ...sections ] }Resets to the default config.
Returns the global logo image with 1-hour cache header. 404 if no logo set.
Returns SSO and MFA config needed by the login page.
{ "ssoEnabled": true, "googleSsoEnabled": false, "localMfaEnabled": true }Multipart upload. Replaces the global logo.
Returns all settings. Sensitive fields (client secrets, private keys, LDAP bind password, enrollment token) are never returned โ only presence is indicated via has* boolean flags.
Secrets are only updated if a new non-masked value is provided. Passing an empty string explicitly clears a secret.
Triggers a full LDAP user sync. Returns count of synced users. Role mapping is applied only if ldapAdminGroup or ldapTechGroup is configured.
Paginated list. Query params: search, page, limit (max 100)
Updatable fields: name, role, isActive, resetMfa. Self-protection rules: – Cannot change your own role – Cannot deactivate your own account
Min 12 characters. Invalidates all existing refresh tokens for the user.
{ "password": "newpassword123" }Any authenticated user. Requires current password. Min 12 characters.
Soft delete โ sets isActive: false, never hard-deletes. Invalidates all refresh tokens.
Returns the current user’s preferences JSON blob.
Replaces the preferences blob. Body is any JSON object.
Paginated, newest first. Query params: search (action/resource/user name/email), page, limit (max implied 200 via take)
{
"items": [{
"id": "...", "action": "vault.reveal", "resource": "VaultEntry:uuid",
"ipAddress": "1.2.3.4", "userAgent": "...", "meta": {},
"createdAt": "...", "user": { "name": "Admin", "email": "admin@..." }
}],
"total": 500, "page": 1, "limit": 50, "pages": 10
}All integration routes are Admin only.
Returns enabled/configured status and last sync info for ConnectWise and NinjaRMM.
Tests ConnectWise credentials without saving. Hits /system/info.
cwCompanyIdcwServerUrlcwPublicKeycwPrivateKeySaves ConnectWise settings. Private key is AES-256-GCM encrypted at rest. Masked values (starting with โข) are not re-encrypted.
cwEnabledcwCompanyIdcwServerUrlcwPublicKeycwPrivateKeycwSyncScheduleTriggers a full pull sync (Companies โ Orgs, Contacts, Configurations โ Assets). Returns sync result counts. Creates a SyncLog entry.
Pushes a single record to ConnectWise. :type must be organization, contact, or asset.
Tests NinjaRMM OAuth2 client credentials.
ninjaClientIdninjaClientSecretninjaInstanceUrlninjaEnabledninjaClientIdninjaClientSecretninjaInstanceUrlninjaSyncScheduleFull pull sync (Organizations, Devices โ Assets, Contacts). Name-based deduplication against existing orgs.
endpoint โ pre-shared token auth, no JWT required. Called by the PowerShell enrollment script. Resolves org by shortId. Matches existing asset by hostname (case-insensitive) or auto-creates one. Asset type inferred from OS name (SERVER if contains “server”, otherwise WORKSTATION). Password stored AES-256-GCM encrypted in vault.
{
"enrollmentToken": "plain-token",
"orgShortId": 482039471,
"rustdeskId": "1571237679",
"password": "generated-password",
"hostname": "DESKTOP-ABC123",
"ipAddress": "192.168.1.10",
"osName": "Windows 10 Pro",
"osVersion": "10.0.19045",
"macAddress": "AA:BB:CC:DD:EE:FF"
}JWT auth. Returns RustDesk ID, decrypted password, and a ready-to-use rustdesk:// connect URI.
{
"rustdeskId": "1571237679",
"password": "decryptedpassword",
"connectUri": "rustdesk://1571237679?password=decryptedpassword"
}Returns current RustDesk settings. Enrollment token presence indicated by hasEnrollmentToken boolean โ the token itself is never returned.
Pass rotateToken: true to generate a new enrollment token. The new plain token is returned once in the response and never again.
rustdeskEnabledrustdeskServerUrlrustdeskConfigrotateTokenDownloads a pre-filled enroll-rustdesk.ps1 PowerShell script. All four variables (%%ITDOCS_URL%%, %%ENROLLMENT_TOKEN%%, %%ORG_SHORT_ID%%, %%RUSTDESK_CONFIG%%) are replaced server-side before delivery.
Clears rustdeskId from the asset and deletes the associated vault entry.
All backup routes are Admin only.
Exports an encrypted backup archive. Uses AES-256-GCM with PBKDF2-SHA512 key derivation (200,000 iterations, random 16-byte salt per backup). File format: [16B salt][12B IV][16B auth tag][ciphertext]. – db โ Full database export as JSON (includes all records, vault entries decrypted then re-encrypted for portability) – files โ Binary attachments, uploaded documents, and block images as raw files
Multipart. Auto-detects backup type from ZIP contents. – wipe โ Deletes all current data and replaces with backup – merge โ Upserts records, preserves existing data not in backup For file backups:
{ "success": true, "mode": "wipe" }
{ "success": true, "mode": "files", "restored": 12, "skipped": 2 }Returns the scheduled backup configuration plus env var status.
Updates DB backup schedule settings. Cron expression is validated before saving.
enabledcronExpressionretentionUpdates file backup schedule settings.
filesEnabledfilesCronExpressionfilesRetentionTriggers a scheduled DB backup immediately. Requires BACKUP_PATH and BACKUP_PASSWORD env vars.
Triggers an incremental file backup immediately. Requires BACKUP_FILES_PATH env var.
Lists .enc backup files in BACKUP_PATH, newest first.
{
"files": [{ "filename": "itdocs_db_backup_2026-03-25_020000.enc", "sizeBytes": 1048576, "createdAt": "..." }]
}Restores from a named .enc file on the server. Always wipe mode. Path traversal protected. Decrypts using BACKUP_PASSWORD env var.
Walks BACKUP_FILES_PATH and returns the directory tree grouped by org. Resolves shortId folder names to human-readable org names.
{
"orgs": [{
"org": "482039471 - Acme Corp",
"orgLabel": "Acme Corp",
"files": [{ "path": "482039471 - Acme Corp/attachments/photo.jpg", "name": "photo.jpg", "type": "attachments", "sizeBytes": 45000, "modifiedAt": "..." }]
}]
}Restores selected files from BACKUP_FILES_PATH back into the database. Uses .meta.json sidecars to upsert records โ works even if the original DB record was deleted. Falls back to name/ID matching for legacy backups without sidecars.
{ "paths": ["482039471 - Acme Corp/attachments/photo.jpg"] }| Endpoint category | VIEWER | TECHNICIAN | ADMIN |
|---|---|---|---|
| Read all org data | โ | โ | โ |
| Create/update records | โ | โ | โ |
| Delete records | โ | โ | โ |
| Vault read | โ | โ | โ |
| Vault reveal password | โ | โ | โ |
| User management | โ | โ | โ |
| Settings | โ | โ | โ |
| Audit logs | โ | โ | โ |
| Integrations | โ | โ | โ |
| Backups | โ | โ | โ |
| RustDesk connect | โ | โ | โ |
| RustDesk settings | โ | โ | โ |
All errors return a JSON body with an error field.
| Status | Meaning |
|---|---|
400 | Bad request / validation failed |
401 | Unauthenticated or token revoked |
403 | Authenticated but insufficient role |
404 | Record not found |
409 | Unique constraint violation (record already exists) |
422 | Zod validation failed โ includes issues field with field-level errors |
429 | Rate limit exceeded |
500 | Internal server error (internals not exposed) |
422):{
"error": "Validation failed",
"issues": {
"email": ["Invalid email"],
"password": ["String must contain at least 12 character(s)"]
}
}
| Variable | Required | Description |
|---|---|---|
DATABASE_URL | โ | PostgreSQL connection string |
REDIS_HOST | โ | Redis hostname |
REDIS_PORT | Redis port (default: 6379) | |
REDIS_PASSWORD | โ | Redis password |
JWT_SECRET | โ | Min 32 characters |
VAULT_ENCRYPTION_KEY | โ | 64 hex chars (32 bytes) โ generate with openssl rand -hex 32 |
CORS_ORIGIN | Allowed CORS origin (default: http://localhost:3000) | |
FRONTEND_URL | Used for SSO redirects | |
PORT | API port (default: 4000) | |
HOST | Bind address (default: 0.0.0.0) | |
LOG_LEVEL | Pino log level (default: info) | |
BACKUP_PATH | Server path for scheduled DB backups | |
BACKUP_PASSWORD | Encryption password for DB backups (min 8 chars) | |
BACKUP_FILES_PATH | Server path for incremental file backups | |
CW_CLIENT_ID | ConnectWise API client ID header (default: itdocs-integration) |
