API Documentation

This area is restricted to VendoTrack customers and partners. Enter the access password to continue.

Incorrect password. Please try again or contact your VendoTrack account manager.
← Back to vendotrack.nl

VendoTrack API

A REST API for vendor and contract management, covering authentication, contracts, vendors, user administration, and audit logging, backed by a SQLite database. Build integrations, automate renewals, or connect your own internal tools.

Introduction

The VendoTrack API follows standard REST conventions. All request and response bodies use application/json. Most endpoints require a Bearer token obtained via the authentication endpoints below.

Tech stack Node.js · Express · SQLite (better-sqlite3) · JWT authentication · bcrypt password hashing

Base URL

All endpoints below are relative to your VendoTrack API server's base URL.

# Local development
http://localhost:4000/api

# Production (replace with your deployment)
https://api.vendotrack.nl/api

Authentication

VendoTrack uses JSON Web Tokens (JWT). After logging in, include the returned token on every subsequent request:

Authorization: Bearer <token>

Tokens expire after 8 hours. There is no refresh-token endpoint currently, re-authenticate via /auth/login when a token expires.

MFA-protected accounts If a user has multi-factor authentication enabled, /auth/login returns { mfaRequired: true, userId } instead of a token. Call /auth/mfa/verify with the 6-digit TOTP code to complete login and receive the token.

Error Handling

Errors are returned as JSON with a single error field describing what went wrong.

{
  "error": "Incorrect email or password"
}
200 / 201
Success
204
Success, no content (deletes)
400
Invalid or missing fields
401
Missing, invalid, or expired token
403
Authenticated, but insufficient role
404
Resource not found
409
Conflict (e.g. duplicate email, vendor still referenced)
500
Server error

Authentication

POST/auth/registerNo auth

Create a new VendoTrack account. Returns a token immediately, no email verification step.

Body

FieldTypeRequired
emailstringRequired
passwordstringRequired
namestringRequired

Response 201 Created

{
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "user": { "id": "u-a1b2c3", "email": "jan@company.com", "name": "Jan de Vries", "role": "contract_manager" }
}
POST/auth/loginNo auth

Authenticate with email and password.

Body

FieldTypeRequired
emailstringRequired
passwordstringRequired

Response 200 OK

// Normal login
{ "token": "eyJhbGciOiJIUzI1NiIs...", "user": { ... } }

// If MFA is enabled on this account
{ "mfaRequired": true, "userId": "u-a1b2c3" }
POST/auth/mfa/verifyNo auth

Completes login for an MFA-protected account by verifying the TOTP code.

Body

userIdstringRequired
codestring (6 digits)Required

Response 200 OK

{ "token": "eyJhbGciOiJIUzI1NiIs...", "user": { ... } }
POST/auth/mfa/enrollAuth required

Permanently enables MFA on the authenticated user's account after verifying the first code from their authenticator app.

Body

secretstring (base32 TOTP secret)Required
codestring (6 digits)Required

Response 200 OK

{ "ok": true }
POST/auth/mfa/disableAuth required

Disables MFA on the authenticated user's account.

Response 200 OK

{ "ok": true }
POST/auth/sso-loginNo auth

Called after the frontend has completed an OAuth 2.0 PKCE flow with an identity provider (Azure AD, Google, or OIDC) and validated the identity token. Checks whether a VendoTrack profile exists for the email, and does not auto-create accounts.

Body

emailstringRequired

Response

// 200, profile found
{ "token": "...", "user": { ... } }

// 404, no profile (admin must create one first)
{ "error": "No VendoTrack account found for jan@company.com..." }
GET/auth/meAuth required

Returns the currently authenticated user, used to validate a stored token on app load.

Response 200 OK

{
  "id": "u-a1b2c3",
  "email": "admin@vendotrack.com",
  "name": "Admin User",
  "role": "super_admin",
  "status": "active",
  "initials": "AU",
  "mfaEnabled": false
}

Contracts

GET/contractsAuth required

Returns all contracts, newest first. Supports optional filtering via query parameters.

Query Parameters

ParamType
statusstringe.g. active, expired, draft
vendorIdstringfilter by vendor
searchstringmatches title or vendor name

Example

GET /api/contracts?status=active&search=cloud

Response 200 OK

[
  {
    "id": "c-9f8e7d",
    "title": "Cloud Infrastructure, Reserved Instances",
    "vendorId": "v-1a2b3c",
    "vendor": "AWS Europe",
    "type": "MSA",
    "value": 312000,
    "currency": "EUR",
    "startDate": "2024-07-05",
    "endDate": "2026-07-05",
    "paymentSchedule": "monthly",
    "status": "active",
    "renewalAlert": 60,
    "tags": ["cloud", "critical"],
    "contractLink": "",
    "owner": "Admin User",
    "created": "2026-01-14T09:30:00Z"
  }
]
GET/contracts/:idAuth required

Returns a single contract including its attached documents.

POST/contractsAuth required

Creates a new contract.

Body

titlestringRequired
vendorId, vendorstringOptional
typestringMSA, SLA, NDA, SOW, PO, SaaS, License…
valuenumberDefault 0
currencystringDefault EUR
startDate, endDatestring (YYYY-MM-DD)Optional
paymentSchedulestringmonthly, annual, one-time…
statusstringDefault active
renewalAlertnumber (days)Default 60
tagsstring[]Optional
notes, contractLinkstringOptional

Response 201 Created, the created contract object.

PUT/contracts/:idAuth required

Updates a contract. Send only the fields you want to change, unspecified fields keep their current value.

DELETE/contracts/:idAuth required

Permanently deletes a contract. Returns 204 No Content on success.

GET/contracts/alerts/expiringAuth required

Returns active contracts currently within their renewal alert window, ordered by soonest expiry first. Each result includes a computed daysLeft field.

Vendors

GET/vendorsAuth required

Returns all vendors with computed contract count and total contract value.

Query Parameters

searchstringmatches vendor name
riskstringlow, medium, high

Response 200 OK

[
  {
    "id": "v-1a2b3c",
    "name": "AWS Europe",
    "category": "Cloud Services",
    "contact": "support@aws.com",
    "country": "Luxembourg",
    "risk": "low",
    "compliance": ["ISO 27001", "SOC2"],
    "contractCount": 2,
    "totalValue": 312000
  }
]
GET/vendors/:idAuth required

Returns a single vendor by ID.

POST/vendorsAuth required

Creates a new vendor.

Body

namestringRequired
category, contact, phone, website, countrystringOptional
riskstringlow / medium / high, default low
compliancestring[]e.g. ["ISO 27001","GDPR"]
notesstringOptional
PUT/vendors/:idAuth required

Updates a vendor. Send only changed fields.

DELETE/vendors/:idAuth required

Deletes a vendor. Returns 409 Conflict if any contracts still reference this vendor, remove or reassign those first.

Users (admin only)

GET/usersAdmin only

Lists all users in the workspace. Requires super_admin or local_admin role.

POST/usersAdmin only

Pre-provisions a user profile, required before that person can sign in via SSO, since SSO never auto-creates accounts.

Body

emailstringRequired
namestringRequired
rolestringDefault contract_manager
passwordstringOptional, omit for SSO-only accounts
PUT/users/:idAdmin only

Updates a user's name, role, or status (e.g. to suspend an account).

DELETE/users/:idsuper_admin only

Permanently deletes a user account. You cannot delete your own account this way.

Audit Log (admin only)

GET/auditAdmin only

Returns a chronological log of create/update/delete actions across contracts and vendors, most recent first.

Query Parameters

entityTypestringcontract / vendor
limitnumberDefault 100

Workspace Data Store

A generic key-value store used internally by the VendoTrack frontend for workspace settings (notification preferences, organisation profile, templates, clause library, etc.). Documented here for completeness, most integrations should use the resource-specific endpoints above instead.

GET/kv/:keyAuth required

Retrieves a stored JSON value by key. Returns 404 if the key has never been set.

{ "key": "vt:org", "value": { "name": "MSF OCA", ... } }
PUT/kv/:keyAuth required

Stores (or replaces) a JSON value under the given key.

Body

{ "value": { "anyKey": "any JSON-serialisable value" } }
DELETE/kv/:keyAuth required

Removes a stored key.

System

GET/healthNo auth

Simple uptime check, useful for monitoring and load balancer health probes.

{ "status": "ok", "time": "2026-06-30T14:22:01.000Z" }
Need write access or a higher rate limit? Contact info@vendotrack.nl to discuss API integration support for your organisation.