API Reference

API Reference · v1

A real API, not just a UI.

This platform is API-driven: every screen you see is backed by the /api/v1 endpoints documented below. Authentication is a signed, HTTP-only session cookie set at login, and access is enforced server-side by role — the same RBAC model the UI uses to decide what to show.

Authentication

Sign in with POST /api/v1/auth/login. Credentials are verified against scrypt-hashed records (constant-time comparison). On success the server returns the session user and sets an HTTP-only, Secure, SameSite=Lax cookie (hsg_session) — an HMAC-SHA256-signed, stateless token that carries the user's id, role, and facility scope, and expires after 8 hours.

HTTP-only cookie

Not readable from JavaScript — no token handling in the client.

scrypt + timing-safe

Passwords are never stored; hashes compared in constant time.

8-hour signed session

HMAC-SHA256 over the payload; tamper- and expiry-checked on every request.

In production these seed users are replaced by the VA identity provider (VA SSOi / PIV); the session and RBAC contract stays the same. Read-only endpoints below work without signing in (as the guest role).

Roles & permissions

Every endpoint checks a named permission against the caller's role with can(role, permission). This matrix is generated directly from rbac.ts — it is the live source of truth.

PermissionAdminPMHR SpecialistCoordinatorObserverGuest
submissions:read:all
Read all facility submissions
·
surveys:read
Read the survey library
·
surveys:write
Manage survey selections
····
jobs:read
Read job-architecture mappings
···
jobs:write
Write job-architecture mappings
····
audit:read
Read the audit trail
·
exports:read
Generate report exports
·
submissions:approve
Approve facility submissions
····
determinations:read
Read pay determinations
··
determinations:write
Write pay determinations
····
versions:read
Read catalog versions
··
versions:write
Publish catalog versions
····
submissions:read:own
Read own-facility submissions
····
submissions:write
Create / submit facility surveys
····

Admin holds the admin:all wildcard — every permission above resolves to allowed, including any added later.

Endpoints

All endpoints accept and return JSON. The required permission is enforced on the server — an unauthenticated caller gets 401, an authenticated caller missing the permission gets 403 (with the needed permission named in the body).

Auth

Establish and inspect the signed session. Login sets the cookie; every other call reads it.

POST/api/v1/auth/login
Exchange email + password for a signed session cookie. public
POST/api/v1/auth/logout
Clear the session cookie (expires it immediately). public
GET/api/v1/auth/session
Return the current session user, or null when signed out. public

Data

The platform's records. Reads are role-gated; writes require the listed permission server-side.

GET/api/v1/submissions
List facility §7451 survey submissions. Coordinators see only their own facility. submissions:read:all
POST/api/v1/submissions
Create a facility survey submission (coordinator-scoped to their facility). submissions:write
GET/api/v1/determinations
List pay determinations across the enterprise. determinations:read
POST/api/v1/determinations
Record a localized pay determination to the system-of-record. determinations:write
GET/api/v1/versions
List occupation-catalog versions and their change summaries. versions:read
POST/api/v1/versions
Publish (or draft) a new occupation-catalog version. versions:write
GET/api/v1/audit
Return the immutable audit / lineage event trail. audit:read

Operations

Job-architecture mapping, report exports, and the unauthenticated health probe.

GET/api/v1/jobs
List occupation-to-benchmark job-architecture mappings. jobs:read
POST/api/v1/jobs
Create or update a job-architecture mapping with confidence scoring. jobs:write
GET/api/v1/exports/{kind}
Generate a report export ({kind} = pdf | xlsx | csv) for the requested view. exports:read
GET/api/v1/health
Liveness + dependency check. 200 operational, 503 degraded. Public. public

Login · request

POST /api/v1/auth/login
Content-Type: application/json

{
  "email": "hr@va.gov",
  "password": "••••••••"
}

Login · response

200 OK
Set-Cookie: hsg_session=<signed>; HttpOnly; Secure; SameSite=Lax

{
  "user": {
    "id": "u-hr",
    "email": "hr@va.gov",
    "name": "VA HR Specialist (OCHCO)",
    "role": "hr_specialist"
  }
}

Submissions · GET

GET /api/v1/submissions

{
  "items": [
    {
      "id": "sub-…",
      "facility": "James A. Haley Veterans' Hospital",
      "visn": "VISN 8",
      "rnMedian": 96400,
      "comparators": 12,
      "status": "submitted"
    }
  ],
  "scopedTo": null
}

Submissions · POST

POST /api/v1/submissions     (needs submissions:write)
Content-Type: application/json

{
  "facility": "James A. Haley Veterans' Hospital",
  "rnMedian": 96400,
  "comparators": 12
}

201-style → { "item": { … }, "items": [ … ] }

Health · GET (public)

GET /api/v1/health

{
  "status": "operational",
  "version": "v1",
  "ts": 1750000000000,
  "services": {
    "api":   { "ok": true, "detail": "REST API responding" },
    "auth":  { "ok": true, "detail": "signed-session auth online" },
    "store": { "ok": true, "detail": "…", "bucket": "…", "region": "…" }
  }
}

Try it live

These two calls are read-only and work right now as the guest role — no sign-in required. They hit the real endpoints and render the exact JSON returned.

GET /api/v1/health

Press Send to call the endpoint.

GET /api/v1/audit

Press Send to call the endpoint.

Write endpoints require an authenticated role.

Any POST above is gated by the permission shown next to it (for example, submissions:write or determinations:write). Sign in as one of the demo roles to exercise them — the matrix above shows which role gets which capability.

This reference documents the platform's live /api/v1 surface. The Try-it calls invoke the real endpoints; JSON examples are illustrative shapes. In production the seed-user roster is replaced by VA SSOi / PIV, leaving the session and RBAC contract unchanged.