API Endpoints (Overview)
This page lists available endpoint groups, routing rules, auth model, and practical request examples.
Authentication
- API access uses API keys generated in Configuration → API Keys (UI).
- Tokens are shown once; store securely.
- Header format:
Authorization: ApiKey <token>for API key calls
- API keys sent with
Bearerare rejected.
Tenant routing (important)
The backend resolves the tenant/workspace from the request Host header:
- the tenant is inferred from the subdomain (the first
.-separated segment)
Recommended production pattern:
https://<tenant-subdomain>.invymate.com/api/v1/...
Local/test hosts depend on your deployment setup, but tenant is always host/subdomain-derived.
Common patterns
- Pagination/filtering/sorting vary by endpoint; see per-endpoint sections below.
- Standard error responses include
messageand optionaldetails. - Webhook management routes are JWT-only even when API Access is enabled.
Contract docs
Use these docs together:
- API Access: key creation and auth setup
- API Endpoints (Overview): endpoint groups, auth model, and query patterns (this page)
- Webhooks: delivery model and webhook signatures
Endpoints available via API key
All endpoints below are under the /api/v1 prefix and accept API key auth unless noted.
Categories
Base: /categories
GET /categoriesGET /categories/defaultPOST /categoriesPATCH /categories/:categoryIdDELETE /categories/:categoryIdPOST /categories/:categoryId/restore
Locations
Base: /locations
GET /locationsGET /locations/defaultPOST /locationsPATCH /locations/:locationIdDELETE /locations/:locationIdPOST /locations/:locationId/restore
Assets (Inventory items)
Base: /inventory-items
GET /inventory-itemsPOST /inventory-itemsGET /inventory-items/:inventoryItemIdPATCH /inventory-items/:inventoryItemIdDELETE /inventory-items/:inventoryItemIdPOST /inventory-items/:inventoryItemId/restoreGET /inventory-items/:inventoryItemId/assignment-historyGET /inventory-items/:inventoryItemId/auditGET /inventory-items/:inventoryItemId/allowed-status-transitionsGET /inventory-items/:inventoryItemId/status-eventsGET /inventory-items/:inventoryItemId/timelineGET /inventory-items/:inventoryItemId/healthPOST /inventory-items/health/batchPOST /inventory-items/:inventoryItemId/statusPOST /inventory-items/:inventoryItemId/checkoutPOST /inventory-items/:inventoryItemId/checkinPOST /inventory-items/quick-add/events(JWT auth)
GET /inventory-items list view now includes per-item health:
health.score(0..100)health.badge(HEALTHY|ATTENTION|AT_RISK)health.reasons[]
GET /inventory-items supports health list controls:
healthBadge(HEALTHY|ATTENTION|AT_RISK)healthSort(risk_first|healthy_first) — used by the Assets table Health column sort
GET /inventory-items/:inventoryItemId/timeline query params:
limit(default50, max100)cursor(opaque pagination cursor from previous response)types(optional comma-separated list):CREATEDASSIGNEDUNASSIGNEDMOVEDMAINTENANCE_COMPLETEDVERIFIEDSTATUS_CHANGEDRETIRED
GET /inventory-items/:inventoryItemId/health returns:
score(0..100)badge(HEALTHY|ATTENTION|AT_RISK)reasons[]with reason codes and optional links
POST /inventory-items/health/batch accepts:
ids[](asset ids, 1..200)
Returns:
items[]withid,score,badge,reasons
POST /inventory-items/:inventoryItemId/status accepts:
toStatusreason(required forretired)meta(optional context, e.g. reservation details)
Example:
{
"toStatus": "reserved",
"reason": "Reserved for onboarding",
"meta": {
"reservedUntil": "2026-03-01T09:00:00.000Z",
"reservationReason": "New hire starts Monday"
}
}
For maintenance, optional meta keys include:
- no special keys are required; completion is tracked via
POST /maintenance/logs
POST /inventory-items/:inventoryItemId/checkout accepts:
personId(required)dueBackAt(optional ISO date/time)
POST /inventory-items/:inventoryItemId/checkin:
- clears assignee and records check-in timestamps/history
- keeps location unchanged
POST /inventory-items/quick-add/events accepts:
event(quick_add_opened|asset_created_quick|asset_assigned|advanced_opened)flowId- optional
itemId - optional
meta
Ad-hoc maintenance completion example:
{
"itemId": "<inventory-item-id>",
"type": "repair",
"completedDate": "2026-02-22T10:00:00.000Z",
"notes": "Fan replaced and thermal test passed"
}
People
Base: /people
GET /peoplePOST /peopleGET /people/:personIdPATCH /people/:personIdDELETE /people/:personIdPOST /people/:personId/restoreGET /people/:personId/assignment-history
Inventory sessions (audits)
Base: /sessions
GET /sessionsGET /sessions/activeGET /sessions/:sessionIdPOST /sessionsPATCH /sessions/:sessionIdDELETE /sessions/:sessionIdGET /sessions/:id/itemsGET /sessions/:id/items/:itemIdPOST /sessions/:id/items/:itemId/includePOST /sessions/:id/items/:itemId/excludeGET /sessions/:id/missingGET /sessions/:id/reportPOST /sessions/:id/scanPOST /sessions/:id/unscanGET /sessions/:id/mobile
POST /sessions/:id/scan is idempotent and returns:
acceptedalready_scannednot_in_sessionwrong_location(for location-scoped sessions unlessallowMarkAnywayis true)
Mobile/client scan payload accepts either:
itemId, orcode(QR value such as an asset URL)
Optional scan flags:
allowMarkAnyway(for location mismatch override)allowRescan(explicitly re-write an already scanned item event)
GET /sessions/:id/mobile returns a fast mobile payload:
- session identity/status/location
- progress counts (
scanned,total) - recent scans list for scan-loop UI
Stats / analytics
Base: /stats/analytics
GET /stats/analytics/overviewGET /stats/analytics/sessionsGET /stats/analytics/lifecycleGET /stats/analytics/maintenanceGET /stats/analytics/depreciationGET /stats/analytics/replacement-lossGET /stats/analytics/reports
GET /stats/analytics/replacement-loss provides:
- age buckets + age-by-category + oldest assets
- warranty expiry counts/lists (30/60/90 days)
- long-assigned assets and threshold counts
- missing-rate trends (location/category) + repeatedly unscanned assets
Custom fields
Base: /custom-fields
GET /custom-fieldsPOST /custom-fieldsPATCH /custom-fields/:customFieldIdDELETE /custom-fields/:customFieldIdPOST /custom-fields/:customFieldId/restore
Maintenance
Base: /maintenance
Schedules:
POST /maintenance/schedulesGET /maintenance/schedules/due/allGET /maintenance/schedules/item/:itemIdGET /maintenance/schedules/:idPATCH /maintenance/schedules/:idDELETE /maintenance/schedules/:id
GET /maintenance/schedules/due/all query params:
lookaheadDays(1..60, default7)- Alias also accepted:
reminderDays
Reminder classification:
overdue:nextDueDate < nowdue today:nextDueDateis todayupcoming:nextDueDate > nowand within schedulereminderDays
Logs:
POST /maintenance/logsGET /maintenance/logs/item/:itemIdGET /maintenance/logs/schedule/:scheduleIdGET /maintenance/logs/:idPATCH /maintenance/logs/:idDELETE /maintenance/logs/:id
Webhooks (management API)
Base: /webhooks
Auth:
- Requires JWT auth (
Authorization: Bearer <jwt>) - API key auth is not supported on webhook management routes
- Pro feature gate applies
Endpoints:
GET /webhooks/endpointsPOST /webhooks/endpointsPATCH /webhooks/endpoints/:idDELETE /webhooks/endpoints/:idPOST /webhooks/endpoints/:id/verifyGET /webhooks/healthGET /webhooks/deliveriesGET /webhooks/deliveries/:idPOST /webhooks/deliveries/:id/replayPOST /webhooks/events/:id/replay
GET /webhooks/deliveries query params:
endpointId(optional)status(optional)eventType(optional)dateFrom(optional ISO date/time)dateTo(optional ISO date/time)limit(1..100, optional)
GET /webhooks/health query params:
windowMinutes(5..1440, optional, default60)
Trash (restore / permanent delete)
Base: /trash
GET /trashPOST /trash/restorePOST /trash/permanent-delete
Admin diagnostics (JWT admin cookie)
The admin API includes a TT10 report endpoint for quick-add onboarding diagnostics:
GET /admin/tenants/:tenantId/tt10-report?from=<ISO>&to=<ISO>
Response includes per-user entries with:
- first created time
- tenth assigned time
- computed
tt10Minutes meetsTarget(tt10Minutes < 10)