← All posts

The review queue over HTTP

v2.24.0 closes the API gap — fourteen new /api/v1 endpoints give review, feedback and learnings full parity with the dashboard, and admins can now mint API tokens without shell access.

Vocion Teamv2.24.0

Anything the Vocion review UI can do, an API client can now do. Until v2.24.0 the dashboard review screens talked to the server over the internal oRPC client, which only accepts a browser session — so eleven operations had no HTTP equivalent at all, and an external admin panel simply could not drive them. This release closes that gap and, in the same breath, makes issuing the token to call it a dashboard action rather than a shell one.

What's new

Why we built it

Pointing an outside admin panel at an install requires two things: the endpoints, and a credential you can create without SSH. Both were missing. The endpoints existed only as oRPC procedures behind a session cookie, and minting a vcn_live_… token meant running the manage-tokens CLI on the box.

How to use it

Mint a token in the dashboard: /dashboard/api-tokens → name it, choose how long it lives, copy the secret once. Then drive the queue:

curl -H "Authorization: Bearer $VOCION_TOKEN" \
  "https://your-install/api/v1/reviews?kind=personalization.enroll&includeSnoozed=false&limit=25"

GET /api/v1/reviews gains kind, assignedTo, includeSnoozed, limit and offset, and returns a real total. The rest of the new surface:

GET   /api/v1/reviews/:kind/:id            full record + proposal + card
GET   /api/v1/reviews/auto-executed        trust-ladder audit list
POST  /api/v1/reviews/signal               skip / save triage
POST  /api/v1/reviews/rewrite              rewrite a draft, unsaved
POST  /api/v1/reviews/propose              queue a proposed action
POST  /api/v1/feedback                     submit reviewer feedback
GET   /api/v1/feedback                     feedback jobs
GET   /api/v1/learnings                    steps with rule counts
GET   /api/v1/learnings/:step/rules        rules in a step
POST  /api/v1/learnings/:step/rules/check  dedupe pre-check
GET   /api/v1/learning-candidates          rules awaiting a person
GET   /api/v1/learning-candidates/:id
PATCH /api/v1/learning-candidates/:id      reword or retarget
POST  /api/v1/learning-candidates/:id/decide

POST /api/v1/reviews/decide now accepts editedInput for edit-then-approve — on a workflow, that is the resume input.

Learning candidates are the notable new object. The feedback worker classifies a job and, when the classification proposes a rule, records a pending candidate. It still never writes a live rule: a person approves it into one or rejects it with a reason, and the reason is kept. The dashboard learnings page grows the same queue, driven by the same endpoints.

About the tokens

api_token.expires_at is nullable, so every token issued before this migration keeps working, and verifyToken refuses a past expiry the same way it refuses a revoked one. The row is left in place so the dashboard can still show what expired and when.

One deliberate asymmetry: the token routes are oRPC procedures, not REST. oRPC has no bearer path, so minting is session-only — a leaked token cannot issue itself a replacement and outlive the revoke meant to kill it. The shell path stays available and now matches: manage-tokens grows --expires-in-days and reports expiry in its list.

Verification

759 unit tests, plus a 50-check live pass against a real server using only a tenant token. A specialist token returned 403 on every mutation; a second tenant returned 0 rows or 404 on every read; and both dashboard surfaces were walked in a signed-in browser.

What's next