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.
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.
/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"
}
Authentication
Create a new VendoTrack account. Returns a token immediately, no email verification step.
Body
| Field | Type | Required |
|---|---|---|
email | string | Required |
password | string | Required |
name | string | Required |
Response 201 Created
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"user": { "id": "u-a1b2c3", "email": "jan@company.com", "name": "Jan de Vries", "role": "contract_manager" }
}
Authenticate with email and password.
Body
| Field | Type | Required |
|---|---|---|
email | string | Required |
password | string | Required |
Response 200 OK
// Normal login { "token": "eyJhbGciOiJIUzI1NiIs...", "user": { ... } } // If MFA is enabled on this account { "mfaRequired": true, "userId": "u-a1b2c3" }
Completes login for an MFA-protected account by verifying the TOTP code.
Body
userId | string | Required |
code | string (6 digits) | Required |
Response 200 OK
{ "token": "eyJhbGciOiJIUzI1NiIs...", "user": { ... } }
Permanently enables MFA on the authenticated user's account after verifying the first code from their authenticator app.
Body
secret | string (base32 TOTP secret) | Required |
code | string (6 digits) | Required |
Response 200 OK
{ "ok": true }
Disables MFA on the authenticated user's account.
Response 200 OK
{ "ok": true }
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
email | string | Required |
Response
// 200, profile found { "token": "...", "user": { ... } } // 404, no profile (admin must create one first) { "error": "No VendoTrack account found for jan@company.com..." }
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
Returns all contracts, newest first. Supports optional filtering via query parameters.
Query Parameters
| Param | Type | |
|---|---|---|
status | string | e.g. active, expired, draft |
vendorId | string | filter by vendor |
search | string | matches 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"
}
]
Returns a single contract including its attached documents.
Creates a new contract.
Body
title | string | Required |
vendorId, vendor | string | Optional |
type | string | MSA, SLA, NDA, SOW, PO, SaaS, License… |
value | number | Default 0 |
currency | string | Default EUR |
startDate, endDate | string (YYYY-MM-DD) | Optional |
paymentSchedule | string | monthly, annual, one-time… |
status | string | Default active |
renewalAlert | number (days) | Default 60 |
tags | string[] | Optional |
notes, contractLink | string | Optional |
Response 201 Created, the created contract object.
Updates a contract. Send only the fields you want to change, unspecified fields keep their current value.
Permanently deletes a contract. Returns 204 No Content on success.
Returns active contracts currently within their renewal alert window, ordered by soonest expiry first. Each result includes a computed daysLeft field.
Vendors
Returns all vendors with computed contract count and total contract value.
Query Parameters
search | string | matches vendor name |
risk | string | low, 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
}
]
Returns a single vendor by ID.
Creates a new vendor.
Body
name | string | Required |
category, contact, phone, website, country | string | Optional |
risk | string | low / medium / high, default low |
compliance | string[] | e.g. ["ISO 27001","GDPR"] |
notes | string | Optional |
Updates a vendor. Send only changed fields.
Deletes a vendor. Returns 409 Conflict if any contracts still reference this vendor, remove or reassign those first.
Users (admin only)
Lists all users in the workspace. Requires super_admin or local_admin role.
Pre-provisions a user profile, required before that person can sign in via SSO, since SSO never auto-creates accounts.
Body
email | string | Required |
name | string | Required |
role | string | Default contract_manager |
password | string | Optional, omit for SSO-only accounts |
Updates a user's name, role, or status (e.g. to suspend an account).
Permanently deletes a user account. You cannot delete your own account this way.
Audit Log (admin only)
Returns a chronological log of create/update/delete actions across contracts and vendors, most recent first.
Query Parameters
entityType | string | contract / vendor |
limit | number | Default 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.
Retrieves a stored JSON value by key. Returns 404 if the key has never been set.
{ "key": "vt:org", "value": { "name": "MSF OCA", ... } }
Stores (or replaces) a JSON value under the given key.
Body
{ "value": { "anyKey": "any JSON-serialisable value" } }
Removes a stored key.
System
Simple uptime check, useful for monitoring and load balancer health probes.
{ "status": "ok", "time": "2026-06-30T14:22:01.000Z" }