API reference

Generated from the running server — API v1, OpenAPI 3.0.0.

Authentication

Public API endpoints take an organization API key as a bearer token. Everything else is reached by the portal or by a desktop agent with its own session token.

Authorization: Bearer sk_…

Privacy-first, consent-based interview-integrity platform for secure remote interviews and technical assessments.

Public API (`/v1/api/*`)

Authenticate with an org API key: Authorization: Bearer sk_…. A key's authority is exactly its scope set — it holds no org role. Keys are created in the portal under Developers → API keys and the secret is shown once.

Environments. A sk_test_… key is a sandbox credential: every session it creates is flagged sandbox and every read it makes is filtered to sandbox rows. Live and test data never meet.

Versioning. v1 is additive-only: new endpoints and new optional request/response fields may appear at any time and are not breaking — ignore response fields you do not know. A change that would remove or re-type an existing field ships as a new version instead.

Deprecation. Every response carries X-Proctor-Api-Version. When something is deprecated its responses also carry Deprecation: true and a Sunset date at least 180 days out. It keeps working, unchanged, until that date.

Rate limits. 120 requests/60s per key and 600/60s per org. Every response reports RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset and RateLimit-Scope (which ceiling is closest); a 429 adds Retry-After.

Idempotency. Send Idempotency-Key: <unique> on any write. A retry with the same key and the same body replays the first response (Idempotency-Replayed: true); the same key with a different body is refused with idempotency_key_reuse. Keys are remembered for 24h.

Pagination. Lists take limit (default 20, max 100) and offset, and answer with { items, total, limit, offset }.

Errors. { success: false, error: { code, message }, requestId } — branch on code, never on the message. Codes: invalid_request, unauthorized, insufficient_scope, forbidden, not_found, conflict, idempotency_key_reuse, rate_limited, service_unavailable, internal_error.

Events, webhooks and the stream. The same catalog is delivered two ways: signed webhook POSTs to endpoints you register (/v1/api/webhooks), and a live SSE subscription (/v1/api/events/stream). Both carry the same envelope with the same id, so dedupe on the event id — delivery is at-least-once — and ignore event types you do not know.

Webhook signatures. Every delivery carries X-Proctor-Signature: t=<unix>,v1=<hex> — an HMAC-SHA256 over "<timestamp>.<raw body>" keyed by the endpoint's secret. Verify it, and reject any timestamp more than 300s from your clock.

Webhook retries. 6 attempts, waiting 10s, 60s, 300s, 1800s, 7200s between them, then a dead letter you can replay from the delivery log. An endpoint that dead-letters 10 deliveries in a row is disabled and its org admins are emailed.

What this API will not do. It reports observations — event counts, evidence, transcripts — and never a verdict about a candidate. Scoring or judging a person from these signals is the integrator's own act, taken on its own authority; a human decides (PRD hard rule 4).

Node SDK

@proctor/sdk v1.0.0 — a typed client whose types are generated from this document, so a shape that compiles is a shape the API serves. It handles retries, idempotency keys, pagination and webhook signature verification for you.

Install

One API key, one base URL. The client speaks API v1 and reports its rate-limit budget on every response.

pnpm add @proctor/sdk

export PROCTOR_API_KEY=sk_test_…
export PROCTOR_BASE_URL=http://localhost:4000

Schedule a session and fetch its results

examples/schedule-and-fetch.ts

/**
 * Schedule a session, hand out its join link, and read the results.
 *
 * Run: PROCTOR_API_KEY=sk_test_… PROCTOR_BASE_URL=http://localhost:18410 tsx schedule-and-fetch.ts
 */
import { Proctor } from "@proctor/sdk";

const proctor = new Proctor({
  apiKey: process.env.PROCTOR_API_KEY ?? "",
  baseUrl: process.env.PROCTOR_BASE_URL ?? "http://localhost:18410",
});

// 1 — Schedule it. `externalId` is your own handle (a requisition, a ticket); we never invent one.
const { session } = await proctor.sessions.create({
  externalId: `req-${Date.now()}`,
  candidateLabel: "Candidate A",
  config: { retentionDays: 30, capture: { enabled: true } },
});
console.log(`session ${session.id} · ${session.state}`);

// 2 — Mint a single-use link. The candidate's desktop agent redeems it; consent is asked there.
const link = await proctor.sessions.createJoinLink(session.id, {
  role: "candidate",
});
console.log(`join code ${link.joinCode} · expires ${link.expiresAt}`);

// 3 — Wait for it to end. Production would use a webhook; a script can poll.
const finished = await proctor.sessions.waitForState(session.id, ["ended"], {
  timeoutMs: Number(process.env.PROCTOR_WAIT_MS ?? 120_000),
  throwOnTimeout: false,
});
console.log(`state ${finished.state} · ${finished.eventCount} integrity events`);

// 4 — Read what came out. Counts and artifacts: observations, never a verdict — a human decides.
const report = await proctor.sessions.report(session.id);
console.log(`report · ${report.signalTotal} signals · ${report.inventoryObjects} objects`);

for await (const evidence of proctor.sessions.iterateEvidence(session.id)) {
  console.log(`evidence ${evidence.id} · ${evidence.evidenceType} · ${evidence.sizeBytes} bytes`);
}

Receive and verify a webhook

examples/webhook-receiver.ts

/**
 * A webhook receiver: verify the signature, then act on the event.
 *
 * Run: PROCTOR_WEBHOOK_SECRET=whsec_… tsx webhook-receiver.ts   (listens on PORT, default 4300)
 */
import { createServer } from "node:http";
import { constructWebhookEvent, ProctorWebhookSignatureError } from "@proctor/sdk";
import { WEBHOOK_SIGNATURE } from "@proctor/protocol";

const secret = process.env.PROCTOR_WEBHOOK_SECRET ?? "";
const seen = new Set<string>();

createServer((req, res) => {
  // The signature covers the RAW bytes — verify before parsing, never after.
  const chunks: Buffer[] = [];
  req.on("data", (chunk: Buffer) => chunks.push(chunk));
  req.on("end", () => {
    const body = Buffer.concat(chunks).toString("utf8");
    const signature = req.headers[WEBHOOK_SIGNATURE.header.toLowerCase()];

    let event;
    try {
      event = constructWebhookEvent(body, String(signature ?? ""), secret);
    } catch (error) {
      // A body that cannot prove where it came from is not a body. 400, and nothing else happens.
      if (error instanceof ProctorWebhookSignatureError) {
        console.warn(`rejected delivery: ${error.reason}`);
        res.writeHead(400).end();
        return;
      }
      throw error;
    }

    // Delivery is at-least-once and a stream resume can repeat one: dedupe on the event id.
    if (!seen.has(event.id)) {
      seen.add(event.id);
      console.log(`${event.type} · session ${event.sessionId ?? "—"} · ${event.createdAt}`);
    }

    // Answer 2xx immediately; do the slow work elsewhere, or the retry policy becomes your queue.
    res.writeHead(200).end();
  });
}).listen(Number(process.env.PORT ?? 4300), () => {
  console.log(`listening on :${process.env.PORT ?? 4300}`);
});

Tail the live event stream

examples/stream-events.ts

/**
 * Tail the live event stream and reconcile anything missed while the process was down.
 *
 * Run: PROCTOR_API_KEY=sk_test_… tsx stream-events.ts
 */
import { Proctor } from "@proctor/sdk";

const proctor = new Proctor({
  apiKey: process.env.PROCTOR_API_KEY ?? "",
  baseUrl: process.env.PROCTOR_BASE_URL ?? "http://localhost:18410",
});

// Where we stopped last time. A real receiver persists this; a script starts from the last event.
const [latest] = (await proctor.events.list({ limit: 1 })).items;
let cursor = latest?.id;

const stop = AbortSignal.timeout(Number(process.env.PROCTOR_STREAM_MS ?? 600_000));

// Resuming replays what was published while we were away, then goes live at the same seam.
for await (const event of proctor.events.stream({
  lastEventId: cursor,
  signal: stop,
})) {
  cursor = event.id;
  console.log(`${event.type} · session ${event.sessionId ?? "—"} · ${event.createdAt}`);
}

console.log(`stream closed · resume from ${cursor ?? "the beginning"}`);

The SDK moves observations, evidence and transcripts between this API and your systems. It never scores or judges a candidate — that decision is yours, and a human makes it.

Events, webhooks and the stream

The push side of the API. Every event below is delivered identically by webhook and by the live stream — same envelope, same id. Catalog version 2026-09-04; new types may appear at any time, so ignore ones you do not recognise rather than failing.

TypeWhat it means
session.scheduledwebhooks.events.session.scheduled
session.startedwebhooks.events.session.started
session.endedwebhooks.events.session.ended
evidence.readywebhooks.events.evidence.ready
companion.pairedwebhooks.events.companion.paired
companion.placement_confirmedwebhooks.events.companion.placement_confirmed
companion.recording_startedwebhooks.events.companion.recording_started
companion.recording_stoppedwebhooks.events.companion.recording_stopped
companion.interruptedwebhooks.events.companion.interrupted
companion.resumedwebhooks.events.companion.resumed
source.health_changedwebhooks.events.source.health_changed
report.finalizedwebhooks.events.report.finalized
report.stalewebhooks.events.report.stale
webhook.testwebhooks.events.webhook.test

Delivery and retries

Delivery is at-least-once: dedupe on the event id. A failed delivery is retried up to 6 times, waiting 10s, 60s, 300s, 1800s, 7200s between attempts, then kept as a dead letter you can replay. An endpoint that dead-letters 10 deliveries in a row is disabled and its org admins are emailed.

Every delivery carries: X-Proctor-Signature, X-Proctor-Event-Id, X-Proctor-Event-Type, X-Proctor-Delivery-Id, X-Proctor-Delivery-Attempt.

Verifying a delivery

Check X-Proctor-Signature before you trust a body. It is an HMAC-SHA256 over "<timestamp>.<raw body>" keyed by the endpoint's signing secret, presented as t=<unix>,v1=<hex>. Reject anything whose timestamp is more than 300 seconds from your clock — that is what makes a captured delivery useless to replay. Ignore key/value pairs you do not know; that is how a future scheme version ships without breaking you.

import { createHmac, timingSafeEqual } from "node:crypto";

// body must be the RAW request bytes, before any JSON parsing.
export function verify(body, header, secret) {
  const parts = new Map(header.split(",").map((p) => p.trim().split("=")));
  const timestamp = Number(parts.get("t"));
  const presented = parts.get("v1");
  if (!Number.isFinite(timestamp) || !presented) return false;

  // Reject anything older than the tolerance — this is what stops a captured replay.
  const age = Math.abs(Math.floor(Date.now() / 1000) - timestamp);
  if (age > 300) return false;

  const expected = createHmac("sha256", secret)
    .update(`${timestamp}.${body}`)
    .digest("hex");
  const a = Buffer.from(expected);
  const b = Buffer.from(presented);
  return a.length === b.length && timingSafeEqual(a, b);
}

Live stream

The same catalog as Server-Sent Events, authenticated by the same API key with the events:read scope. Filter with ?types= and ?sessionId=. Reconnect with Last-Event-ID to replay what you missed, up to 200 events — further behind than that, reconcile over GET /v1/api/events instead.

curl -N "http://localhost:4000/v1/api/events/stream?types=session.started,session.ended" \
  -H "Authorization: Bearer $PROCTOR_API_KEY"

health

  • GET/v1/healthPortal / agent

    Liveness probe

  • GET/v1/health/readyPortal / agent

    Readiness probe

storage

  • GET/v1/orgs/{orgId}/storagePortal / agent

    Where this org's evidence is stored (owner/admin only)

    Parameters: orgId (path, required)

  • PUT/v1/orgs/{orgId}/storagePortal / agent

    Set the storage provider. Validated against the provider before it is accepted.

    Parameters: orgId (path, required) — Takes a JSON body.

  • POST/v1/orgs/{orgId}/storage/validatePortal / agent

    Re-probe the stored configuration and record whether it still works

    Parameters: orgId (path, required)

  • POST/v1/orgs/{orgId}/storage/migratePortal / agent

    Run or resume the move of existing evidence to the current provider (bounded per call)

    Parameters: orgId (path, required) — Takes a JSON body.

  • GET/v1/orgs/{orgId}/storage/migrationPortal / agent

    The latest migration's progress

    Parameters: orgId (path, required)

orgs

  • GET/v1/orgsPortal / agent

    List the orgs the caller belongs to

  • POST/v1/orgsPortal / agent

    Create an org (caller becomes owner)

    Takes a JSON body.

  • GET/v1/orgs/{orgId}Portal / agent

    Org detail (members only)

    Parameters: orgId (path, required)

  • GET/v1/orgs/{orgId}/membersPortal / agent

    List org members (members only)

    Parameters: orgId (path, required)

  • POST/v1/orgs/{orgId}/membersPortal / agent

    Add/provision a member (owner/admin only)

    Parameters: orgId (path, required) — Takes a JSON body.

  • PATCH/v1/orgs/{orgId}/members/{membershipId}Portal / agent

    Change a member's role and/or active status (owner/admin only)

    Parameters: orgId (path, required) · membershipId (path, required) — Takes a JSON body.

  • GET/v1/orgs/{orgId}/invitesPortal / agent

    List invites, any status (owner/admin only)

    Parameters: orgId (path, required)

  • POST/v1/orgs/{orgId}/invitesPortal / agent

    Invite a member by email (owner/admin only)

    Parameters: orgId (path, required) — Takes a JSON body.

  • POST/v1/orgs/{orgId}/invites/{inviteId}/resendPortal / agent

    Rotate + resend a pending invite (owner/admin only)

    Parameters: orgId (path, required) · inviteId (path, required)

  • DELETE/v1/orgs/{orgId}/invites/{inviteId}Portal / agent

    Revoke a pending invite (owner/admin only)

    Parameters: orgId (path, required) · inviteId (path, required)

  • POST/v1/invites/acceptPortal / agent

    Accept an org invite by token

    Takes a JSON body.

roles

  • GET/v1/orgs/{orgId}/rolesPortal / agent

    The org's custom roles plus the permission matrix they compose from

    Parameters: orgId (path, required)

  • POST/v1/orgs/{orgId}/rolesPortal / agent

    Define a custom role

    Parameters: orgId (path, required) — Takes a JSON body.

  • PATCH/v1/orgs/{orgId}/roles/{roleId}Portal / agent

    Edit a custom role's name, description or permissions

    Parameters: orgId (path, required) · roleId (path, required) — Takes a JSON body.

  • DELETE/v1/orgs/{orgId}/roles/{roleId}Portal / agent

    Delete a custom role — holders return to their built-in role, they are not locked out

    Parameters: orgId (path, required) · roleId (path, required)

  • PUT/v1/orgs/{orgId}/roles/assignments/{membershipId}Portal / agent

    Assign a custom role to a member, or clear it back to their built-in role

    Parameters: orgId (path, required) · membershipId (path, required) — Takes a JSON body.

billing

  • GET/v1/billing/plansPortal / agent

    Self-serve plan ladder, priced for a billing country

    Parameters: country (query, required)

  • GET/v1/billing/statusPortal / agent

    Configured provider per billing leg

  • GET/v1/orgs/{orgId}/billing/entitlementsPortal / agent

    Plan limits, usage against them, and warn/block state

    Parameters: orgId (path, required)

  • GET/v1/orgs/{orgId}/billing/subscriptionPortal / agent

    The org's current subscription

    Parameters: orgId (path, required)

  • GET/v1/orgs/{orgId}/billing/historyPortal / agent

    Charges raised against this org, newest first

    Parameters: orgId (path, required) · limit (query) · offset (query)

  • POST/v1/orgs/{orgId}/billing/checkoutPortal / agent

    Open a hosted checkout — routed to Razorpay (India) or PayPal (rest of world)

    Parameters: orgId (path, required) — Takes a JSON body.

  • PATCH/v1/orgs/{orgId}/billing/planPortal / agent

    Upgrade or downgrade the current subscription

    Parameters: orgId (path, required) — Takes a JSON body.

  • POST/v1/orgs/{orgId}/billing/cancelPortal / agent

    Cancel — at period end by default, so paid time is kept

    Parameters: orgId (path, required) — Takes a JSON body.

  • POST/v1/orgs/{orgId}/billing/metering/runPortal / agent

    Meter the closed period and push overage to the provider

    Parameters: orgId (path, required)

usage

  • GET/v1/orgs/{orgId}/usagePortal / agent

    Storage usage for an org — totals, per-type breakdown, daily trend, heaviest sessions

    Parameters: orgId (path, required) · from (query) · to (query)

audit

  • GET/v1/orgs/{orgId}/audit-logsPortal / agent

    Browse an org's immutable audit trail — newest first, filterable by action/session/member/date

    Parameters: orgId (path, required) · limit (query) · offset (query) · action (query) · sessionId (query) · userId (query) · from (query) · to (query)

  • GET/v1/orgs/{orgId}/audit-logs/verifyPortal / agent

    Verify the trail's hash chain — recomputes every row and names the first that does not hold

    Parameters: orgId (path, required)

  • GET/v1/orgs/{orgId}/audit-logs/exportPortal / agent

    Stream the org's audit trail as JSON Lines for a SIEM, cursored by chain sequence

    Parameters: orgId (path, required) · afterSeq (query) · limit (query) · action (query) · sessionId (query) · from (query) · to (query)

auth

  • POST/v1/auth/loginPortal / agent

    Log in (sets httpOnly auth cookies)

    Takes a JSON body.

  • POST/v1/auth/refreshPortal / agent

    Rotate tokens from the refresh cookie

  • POST/v1/auth/logoutPortal / agent

    Log out (clears auth cookies + server session)

  • GET/v1/auth/mePortal / agent

    Current user identity

  • POST/v1/auth/password/forgotPortal / agent

    Ask for a password-reset link (same answer whether or not the address has an account)

    Takes a JSON body.

  • POST/v1/auth/password/resetPortal / agent

    Set a new password from a reset link (signs the account out everywhere)

    Takes a JSON body.

sessions

  • GET/v1/orgs/{orgId}/sessionsPortal / agent

    List org sessions (members only)

    Parameters: orgId (path, required) · limit (query) · offset (query) · state (query) · from (query) · to (query) · provisionedBy (query) · sandbox (query)

  • POST/v1/orgs/{orgId}/sessionsPortal / agent

    Provision a session + mint the agent join token (owner/admin/interviewer; idempotent with `Idempotency-Key`)

    Parameters: orgId (path, required) — Takes a JSON body.

  • PUT/v1/orgs/{orgId}/sessions/{id}/meetingPortal / agent

    Link the Zoom/Meet meeting this session is held in (owner/admin/interviewer) — the agent is told which app to expect on its platform

    Parameters: orgId (path, required) · id (path, required) — Takes a JSON body.

  • DELETE/v1/orgs/{orgId}/sessions/{id}/meetingPortal / agent

    Remove the meeting link — the required apps the interviewer chose are left untouched

    Parameters: orgId (path, required) · id (path, required)

  • PATCH/v1/orgs/{orgId}/sessions/{id}/configPortal / agent

    Update a session's capture policy (owner/admin/interviewer) — the agent picks it up on its next GET /config

    Parameters: orgId (path, required) · id (path, required) — Takes a JSON body.

  • GET/v1/sessions/{id}Portal / agent

    Session detail (org member)

    Parameters: id (path, required)

  • POST/v1/sessionsPortal / agent

    Register a session (consent-gated) — agent join token

    Takes a JSON body.

  • POST/v1/sessions/{id}/eventsPortal / agent

    Ingest integrity events (batch, idempotent) — agent join token

    Parameters: id (path, required) — Takes a JSON body.

  • GET/v1/sessions/{id}/configPortal / agent

    Session config — agent join token

    Parameters: id (path, required)

  • POST/v1/sessions/{id}/endPortal / agent

    End a session — agent join token

    Parameters: id (path, required) — Takes a JSON body.

  • GET/v1/sessions/{id}/access-logPortal / agent

    Who has read this session's evidence (owner/admin/reviewer) — newest first

    Parameters: id (path, required) · limit (query) · offset (query)

  • GET/v1/sessions/{id}/exportPortal / agent

    Export this session's timeline as a JSON bundle

    Parameters: id (path, required)

  • POST/v1/sessions/joinPortal / agent

    Redeem a single-use join ticket for a scoped session token

    Takes a JSON body.

  • POST/v1/sessions/{id}/joinPortal / agent

    Mint a single-use join ticket for a session role (owner/admin/interviewer)

    Parameters: id (path, required) — Takes a JSON body.

  • GET/v1/sessions/{id}/livePortal / agent

    A session's live snapshot — state, recent signals, permission states, latest frame. Poll with `since` when the realtime channel is unavailable.

    Parameters: id (path, required) · since (query) · limit (query)

  • GET/v1/orgs/{orgId}/sessions/{id}/schedulingPortal / agent

    The session's schedule and invitations

    Parameters: orgId (path, required) · id (path, required)

  • PUT/v1/orgs/{orgId}/sessions/{id}/schedulePortal / agent

    Set or move the appointment; a live invitation is re-sent with a new link (session managers)

    Parameters: orgId (path, required) · id (path, required) — Takes a JSON body.

  • POST/v1/orgs/{orgId}/sessions/{id}/schedule/cancelPortal / agent

    Cancel the appointment and tell the invited candidate (session managers)

    Parameters: orgId (path, required) · id (path, required)

  • GET/v1/orgs/{orgId}/sessions/{id}/schedule.icsPortal / agent

    The appointment as an iCalendar file (no candidate link)

    Parameters: orgId (path, required) · id (path, required)

  • POST/v1/orgs/{orgId}/sessions/{id}/invitationsPortal / agent

    Invite the candidate by email (session managers)

    Parameters: orgId (path, required) · id (path, required) — Takes a JSON body.

  • POST/v1/orgs/{orgId}/sessions/{id}/invitations/{invitationId}/resendPortal / agent

    Resend the invitation with a new link; earlier links stop working

    Parameters: orgId (path, required) · id (path, required) · invitationId (path, required)

  • POST/v1/orgs/{orgId}/sessions/{id}/invitations/{invitationId}/revokePortal / agent

    Revoke the invitation's link without emailing anyone (idempotent)

    Parameters: orgId (path, required) · id (path, required) · invitationId (path, required)

  • GET/v1/sessions/{id}/reportPortal / agent

    One session summarized — durations, signal counts, evidence inventory, reviewer notes

    Parameters: id (path, required)

  • GET/v1/sessions/{id}/report/exportPortal / agent

    Download this session's report as PDF or JSON (owner/admin)

    Parameters: id (path, required) · format (query)

  • POST/v1/sessions/{id}/report/revisionsPortal / agent

    Sign off the report as a new revision — the review's owner or a queue manager; supersedes the previous revision (PRO-2107)

    Parameters: id (path, required) — Takes a JSON body.

  • GET/v1/sessions/{id}/notesPortal / agent

    This session's reviewer notes, oldest first

    Parameters: id (path, required)

  • POST/v1/sessions/{id}/notesPortal / agent

    Attach a note, optionally anchored to a moment — anyone who can see the session, with their role frozen onto it; notes are never edited or deleted

    Parameters: id (path, required) — Takes a JSON body.

  • GET/v1/sessions/{id}/coveragePortal / agent

    Expected versus observed collection per lane, the moments worth opening, and what humans wrote about them

    Parameters: id (path, required) · limit (query) · offset (query)

  • POST/v1/sessions/{id}/coverage/annotationsPortal / agent

    Explain one moment — benign, or needing context. Attributed, audited, and never edited.

    Parameters: id (path, required) — Takes a JSON body.

session-policies

  • GET/v1/orgs/{orgId}/policiesPortal / agent

    List the org's integrity policies (active by default)

    Parameters: orgId (path, required) · limit (query) · offset (query) · state (query)

  • POST/v1/orgs/{orgId}/policiesPortal / agent

    Save a new integrity policy as version 1

    Parameters: orgId (path, required) — Takes a JSON body.

  • GET/v1/orgs/{orgId}/policies/{policyId}Portal / agent

    One policy with its version history (newest first)

    Parameters: orgId (path, required) · policyId (path, required)

  • PATCH/v1/orgs/{orgId}/policies/{policyId}Portal / agent

    Rename or re-describe a policy (content changes are new versions)

    Parameters: orgId (path, required) · policyId (path, required) — Takes a JSON body.

  • POST/v1/orgs/{orgId}/policies/{policyId}/versionsPortal / agent

    Edit a policy by writing its next version — existing sessions keep theirs

    Parameters: orgId (path, required) · policyId (path, required) — Takes a JSON body.

  • POST/v1/orgs/{orgId}/policies/{policyId}/duplicatePortal / agent

    Copy a policy's latest version into a new policy

    Parameters: orgId (path, required) · policyId (path, required) — Takes a JSON body.

  • POST/v1/orgs/{orgId}/policies/{policyId}/archivePortal / agent

    Stop offering a policy for new sessions — every version stays readable

    Parameters: orgId (path, required) · policyId (path, required) — Takes a JSON body.

pairings

  • POST/v1/pairings/{joinCode}/claimPortal / agent

    Pair a mobile companion to a session by join code

    Parameters: joinCode (path, required) — Takes a JSON body.

  • POST/v1/pairings/{sessionId}/consentPortal / agent

    Record companion side-view consent — companion token

    Parameters: sessionId (path, required) — Takes a JSON body.

  • POST/v1/pairings/{sessionId}/presencePortal / agent

    Report companion presence (batch, idempotent) — companion token

    Parameters: sessionId (path, required) — Takes a JSON body.

  • POST/v1/pairings/{sessionId}/unpairPortal / agent

    Unpair the companion — companion token

    Parameters: sessionId (path, required)

screenshots

  • GET/v1/sessions/{id}/screenshotsPortal / agent

    List a session's screenshots (org members)

    Parameters: id (path, required) · limit (query) · offset (query)

  • POST/v1/sessions/{id}/screenshotsPortal / agent

    Upload a screenshot (consent-gated, policy-checked) — agent join token

    Parameters: id (path, required) — Takes a JSON body.

audio

  • GET/v1/sessions/{id}/audio-chunksPortal / agent

    List a session's audio chunks (org members)

    Parameters: id (path, required) · limit (query) · offset (query)

  • POST/v1/sessions/{id}/audio-chunksPortal / agent

    Upload an audio chunk (consent-gated, policy-checked) — agent join token

    Parameters: id (path, required) — Takes a JSON body.

  • GET/v1/sessions/{id}/transcriptPortal / agent

    Read a session's assembled transcript — ordered, gap-aware, pollable (org members)

    Parameters: id (path, required) · since (query) · limit (query) · offset (query)

  • POST/v1/sessions/{id}/transcriptPortal / agent

    Upsert transcript segments (consent-gated, policy-checked) — agent join token

    Parameters: id (path, required) — Takes a JSON body.

  • GET/v1/sessions/{id}/timelinePortal / agent

    Read a session's unified timeline — speech turns + screenshots + events (org members)

    Parameters: id (path, required) · kind (query) · limit (query) · offset (query)

system-audio

  • GET/v1/sessions/{id}/system-audio-chunksPortal / agent

    List a session's system-audio chunks (org members)

    Parameters: id (path, required) · limit (query) · offset (query)

  • POST/v1/sessions/{id}/system-audio-chunksPortal / agent

    Open a resumable system-audio chunk upload (consent-gated, policy-checked) — agent join token

    Parameters: id (path, required) — Takes a JSON body.

camera

  • GET/v1/sessions/{id}/camera/framesPortal / agent

    List a session's webcam photos (org members)

    Parameters: id (path, required) · limit (query) · offset (query)

  • POST/v1/sessions/{id}/camera/framesPortal / agent

    Upload a webcam photo (consent-gated, policy-checked) — agent join token

    Parameters: id (path, required) — Takes a JSON body.

  • GET/v1/sessions/{id}/camera/clipsPortal / agent

    List a session's webcam clips (org members)

    Parameters: id (path, required) · limit (query) · offset (query)

  • POST/v1/sessions/{id}/camera/clipsPortal / agent

    Upload a webcam clip (consent-gated, policy-checked) — agent join token

    Parameters: id (path, required) — Takes a JSON body.

evidence

  • GET/v1/sessions/{id}/evidencePortal / agent

    List a session's evidence (org members)

    Parameters: id (path, required) · limit (query) · offset (query) · evidence_type (query)

  • POST/v1/sessions/{id}/evidencePortal / agent

    Begin (or dedupe) a chunked evidence upload — agent join token

    Parameters: id (path, required) — Takes a JSON body.

  • POST/v1/uploads/{uploadId}/partsPortal / agent

    Upload one chunk (resume-safe) — agent join token

    Parameters: uploadId (path, required) — Takes a JSON body.

  • GET/v1/uploads/{uploadId}Portal / agent

    Resume/status read — which chunks survived a crash

    Parameters: uploadId (path, required)

  • POST/v1/uploads/{uploadId}/completePortal / agent

    Finalize: reassemble, verify sha256, encrypt, store

    Parameters: uploadId (path, required)

  • POST/v1/uploads/{uploadId}/abortPortal / agent

    Discard an in-flight upload and its temp chunks

    Parameters: uploadId (path, required)

  • GET/v1/evidence/{id}Portal / agent

    Read one evidence object's metadata (org members, audited)

    Parameters: id (path, required)

  • GET/v1/evidence/{id}/contentPortal / agent

    Download one evidence object's decrypted bytes (org members, audited)

    Parameters: id (path, required)

session-compositions

  • GET/v1/sessions/{id}/compositionsPortal / agent

    List post-session picture-in-picture compositions (org reviewers)

    Parameters: id (path, required)

  • POST/v1/sessions/{id}/compositions/{compositionId}/renderPortal / agent

    Request a PIP composition render (org reviewers with evidence export)

    Parameters: id (path, required) · compositionId (path, required)

  • GET/v1/sessions/{id}/compositions/{compositionId}/contentPortal / agent

    Download one ready PIP composition (explicit evidence export)

    Parameters: compositionId (path, required)

session-reviews

  • GET/v1/orgs/{orgId}/reviewsPortal / agent

    The org's review queue — open work, oldest backlog first

    Parameters: orgId (path, required) · state (query) · assignee (query) · readiness (query) · sessionId (query) · sort (query) · limit (query) · offset (query)

  • GET/v1/orgs/{orgId}/reviews/assigneesPortal / agent

    Members this queue may be assigned to, with their open workload

    Parameters: orgId (path, required)

  • GET/v1/orgs/{orgId}/reviews/{reviewId}Portal / agent

    One review work item

    Parameters: orgId (path, required) · reviewId (path, required)

  • POST/v1/orgs/{orgId}/reviews/{reviewId}/assignmentPortal / agent

    Assign, claim or hand back a review (409 on a lost race)

    Parameters: orgId (path, required) · reviewId (path, required) — Takes a JSON body.

  • POST/v1/orgs/{orgId}/reviews/{reviewId}/statePortal / agent

    Move a review's workflow state — always an explicit human action, never inferred

    Parameters: orgId (path, required) · reviewId (path, required) — Takes a JSON body.

companion

  • GET/v1/sessions/{id}/companionPortal / agent

    Side-view status for this session — agent or companion session token

    Parameters: id (path, required)

  • POST/v1/sessions/{id}/companion/placementPortal / agent

    Confirm the side-view placement (steps + confirmation photo) — companion token

    Parameters: id (path, required) — Takes a JSON body.

  • GET/v1/sessions/{id}/companion/previewPortal / agent

    The newest side-view preview still (org members)

    Parameters: id (path, required)

  • POST/v1/sessions/{id}/companion/previewPortal / agent

    Push a live side-view preview still (consent-gated, never stored) — companion token

    Parameters: id (path, required) — Takes a JSON body.

rooms

  • POST/v1/rooms/{sessionId}/consentPortal / agent

    Record the browser room's webcam-still consent — room token. Nothing is accepted before it.

    Parameters: sessionId (path, required) — Takes a JSON body.

  • POST/v1/rooms/{sessionId}/releasePortal / agent

    Release the room device — room token. Idempotent.

    Parameters: sessionId (path, required)

retention

  • GET/v1/orgs/{orgId}/retentionPortal / agent

    The org's retention policy, the window actually in force, and the plan ceiling (owner/admin)

    Parameters: orgId (path, required)

  • PUT/v1/orgs/{orgId}/retentionPortal / agent

    Set the org's default retention window. A window longer than the plan allows is stored and reported as capped, never silently rewritten.

    Parameters: orgId (path, required) — Takes a JSON body.

  • PUT/v1/orgs/{orgId}/retention/legal-holdPortal / agent

    Place or release an org-wide legal hold — blocks every deletion while on

    Parameters: orgId (path, required) — Takes a JSON body.

  • PUT/v1/orgs/{orgId}/retention/sessions/{sessionId}/legal-holdPortal / agent

    Place or release a legal hold on one session's evidence

    Parameters: orgId (path, required) · sessionId (path, required) — Takes a JSON body.

  • GET/v1/orgs/{orgId}/retention/previewPortal / agent

    What the next sweep would delete inside the given horizon, held sessions included

    Parameters: orgId (path, required) · days (query) · limit (query) · offset (query)

  • POST/v1/orgs/{orgId}/retention/runPortal / agent

    Run (or resume) the deletion sweep, bounded per call. Explicitly triggered — never on a timer.

    Parameters: orgId (path, required) — Takes a JSON body.

  • GET/v1/orgs/{orgId}/retention/sweepPortal / agent

    The latest sweep's outcome

    Parameters: orgId (path, required)

invitations

  • POST/v1/invitations/inspectPortal / agent

    What an invitation link is for: the appointment

    Takes a JSON body.

  • POST/v1/invitations/calendarPortal / agent

    The appointment as an iCalendar file

    Takes a JSON body.

  • POST/v1/invitations/ticketPortal / agent

    A single-use join ticket for the desktop app — the only credential a link yields

    Takes a JSON body.

  • POST/v1/invitations/readinessPortal / agent

    How far the candidate's preparation has got — server-held facts only (PRO-2104)

    Takes a JSON body.

  • POST/v1/invitations/declinePortal / agent

    Decline the invitation — the link stops working

    Takes a JSON body.

  • POST/v1/invitations/contactPortal / agent

    Write to the hiring team (accommodation, question, new time) — emailed, not stored

    Takes a JSON body.

api-keys

  • GET/v1/orgs/{orgId}/api-keysPortal / agent

    List the org's API keys (owner/admin) — never the secrets

    Parameters: orgId (path, required)

  • POST/v1/orgs/{orgId}/api-keysPortal / agent

    Mint an API key — the plaintext token is returned once and never again

    Parameters: orgId (path, required) — Takes a JSON body.

  • POST/v1/orgs/{orgId}/api-keys/{keyId}/rotatePortal / agent

    Replace a key's secret in place — the previous token stops working immediately

    Parameters: orgId (path, required) · keyId (path, required)

  • DELETE/v1/orgs/{orgId}/api-keys/{keyId}Portal / agent

    Revoke a key (idempotent; the row is kept as a tombstone)

    Parameters: orgId (path, required) · keyId (path, required)

public-api

  • GET/v1/api/orgs/selfAPI key

    The org this API key belongs to

    Requires:org:read

  • GET/v1/api/meAPI key

    Introspect the presented API key — its org, label, environment and granted scopes

    Requires:org:read

  • GET/v1/api/sessionsAPI key

    List this org's sessions (newest first)

    Requires:sessions:read

    Parameters: limit (query) · offset (query) · state (query) · from (query) · to (query) · provisionedBy (query) · sandbox (query)

  • POST/v1/api/sessionsAPI key

    Schedule a session and mint its agent join token (idempotent with `Idempotency-Key`)

    Requires:sessions:write

    Takes a JSON body.

  • GET/v1/api/sessions/{id}API key

    One session's state, config and consent summary

    Requires:sessions:read

    Parameters: id (path, required)

  • PATCH/v1/api/sessions/{id}API key

    Update a session's capture / audio / camera / side-view policy (partial; the agent picks it up on its next config read)

    Requires:sessions:write

    Parameters: id (path, required) — Takes a JSON body.

  • POST/v1/api/sessions/{id}/endAPI key

    End a session (idempotent — a re-end is the same answer)

    Requires:sessions:write

    Parameters: id (path, required) — Takes a JSON body.

  • POST/v1/api/sessions/{id}/eraseAPI key

    Erase a session's captured evidence for a data-subject request — idempotent; 409 while live or under legal hold

    Requires:sessions:write

    Parameters: id (path, required)

  • POST/v1/api/sessions/{id}/join-linksAPI key

    Mint a single-use join link for a candidate or companion device

    Requires:sessions:write

    Parameters: id (path, required) — Takes a JSON body.

  • POST/v1/api/sessions/{id}/room-devicesAPI key

    Mint the browser interview room's camera-only device credential

    Requires:sessions:write

    Parameters: id (path, required) — Takes a JSON body.

  • GET/v1/api/sessions/{id}/eventsAPI key

    A session's integrity events plus whole-session counts per kind — observations, never a verdict

    Requires:sessions:read

    Parameters: id (path, required) · limit (query) · offset (query)

  • GET/v1/api/sessions/{id}/transcriptAPI key

    The session's assembled transcript — ordered, gap-aware, pollable

    Requires:sessions:read

    Parameters: id (path, required) · since (query) · limit (query) · offset (query)

  • GET/v1/api/sessions/{id}/evidenceAPI key

    The session's evidence objects. Fetch bytes via `POST /v1/api/evidence/:id/download-url`.

    Requires:evidence:read

    Parameters: id (path, required) · limit (query) · offset (query) · evidence_type (query)

  • GET/v1/api/sessions/{id}/compositionsAPI key

    Post-session picture-in-picture composition status and integrity metadata.

    Requires:evidence:read

    Parameters: id (path, required)

  • GET/v1/api/sessions/{id}/system-audio-chunksAPI key

    The session's system-audio chunks in playback order, with duration and codec. A separate lane from the microphone: this is the machine's output audio, consented under `system_audio`, and it is never mixed into the transcript or the audio listing.

    Requires:evidence:read

    Parameters: id (path, required) · limit (query) · offset (query)

  • GET/v1/api/sessions/{id}/review-statusAPI key

    Where the session's human review stands — the approved status and revision, and what evidence remains. No notes, no observations, no verdict.

    Requires:sessions:read

    Parameters: id (path, required)

  • GET/v1/api/sessions/{id}/reportAPI key

    The session's report — counts, inventory and reviewer notes. Assistive: it states what was observed, never a conclusion.

    Requires:reports:read

    Parameters: id (path, required)

  • GET/v1/api/evidence/{id}API key

    One evidence object's metadata (audited)

    Requires:evidence:read

    Parameters: id (path, required)

  • POST/v1/api/evidence/{id}/download-urlAPI key

    Mint a short-lived, self-authenticating download URL for this evidence object

    Requires:evidence:read

    Parameters: id (path, required)

  • GET/v1/api/evidence/{id}/contentPortal / agent

    Download an evidence object's bytes using a download link token

    Parameters: id (path, required) · token (query, required)

  • GET/v1/api/compositions/{id}API key

    One post-session PIP composition's status and integrity metadata (audited)

    Requires:evidence:read

    Parameters: id (path, required)

  • POST/v1/api/compositions/{id}/renderAPI key

    Request a render of a post-session PIP composition (rendered on demand, kept for a fixed lifetime)

    Requires:evidence:read

    Parameters: id (path, required)

  • POST/v1/api/compositions/{id}/download-urlAPI key

    Mint a short-lived, self-authenticating download URL for a ready PIP composition

    Requires:evidence:read

    Parameters: id (path, required)

  • GET/v1/api/compositions/{id}/contentPortal / agent

    Download a PIP composition's bytes using a download link token

    Parameters: id (path, required) · token (query, required)

  • GET/v1/api/webhooksAPI key

    List this key's environment's webhook endpoints

    Requires:webhooks:read

  • POST/v1/api/webhooksAPI key

    Register an endpoint. The signing secret is returned once and never again.

    Requires:webhooks:write

    Takes a JSON body.

  • GET/v1/api/webhooks/{id}API key

    One endpoint's configuration and delivery health

    Requires:webhooks:read

    Parameters: id (path, required)

  • PATCH/v1/api/webhooks/{id}API key

    Update the URL, the subscribed types, or the status (re-enabling clears the failure count)

    Requires:webhooks:write

    Parameters: id (path, required) — Takes a JSON body.

  • DELETE/v1/api/webhooks/{id}API key

    Delete an endpoint. Queued deliveries stop.

    Requires:webhooks:write

    Parameters: id (path, required)

  • POST/v1/api/webhooks/{id}/rotate-secretAPI key

    Replace the signing secret — the previous one stops signing immediately

    Requires:webhooks:write

    Parameters: id (path, required)

  • POST/v1/api/webhooks/{id}/testAPI key

    Publish a `webhook.test` event — a real, signed delivery, so a receiver can be verified before a real session exists

    Requires:webhooks:write

    Parameters: id (path, required)

  • GET/v1/api/webhooks/{id}/deliveriesAPI key

    This endpoint's delivery log — every attempt, its outcome, and when the next one is due

    Requires:webhooks:read

    Parameters: id (path, required) · limit (query) · offset (query) · status (query) · eventType (query)

  • POST/v1/api/webhooks/{id}/deliveries/{deliveryId}/replayAPI key

    Re-send a finished delivery as a new one — the original's history is kept

    Requires:webhooks:write

    Parameters: id (path, required) · deliveryId (path, required)

  • GET/v1/api/eventsAPI key

    The org's published events, newest first — the catalog as a bounded, filterable list

    Requires:events:read

    Parameters: types (query) · sessionId (query) · limit (query) · offset (query)

  • GET/v1/api/events/streamAPI key

    Server-Sent Events over the same catalog. Resume with `Last-Event-ID`; dedupe on the event id.

    Requires:events:read

    Parameters: types (query) · sessionId (query) · lastEventId (query)

webhooks

  • GET/v1/orgs/{orgId}/webhooksPortal / agent

    List the org's webhook endpoints (owner/admin) — never the secrets

    Parameters: orgId (path, required)

  • POST/v1/orgs/{orgId}/webhooksPortal / agent

    Register an endpoint — the signing secret is shown once

    Parameters: orgId (path, required) — Takes a JSON body.

  • PATCH/v1/orgs/{orgId}/webhooks/{endpointId}Portal / agent

    Update an endpoint's URL, subscriptions or status

    Parameters: orgId (path, required) · endpointId (path, required) — Takes a JSON body.

  • DELETE/v1/orgs/{orgId}/webhooks/{endpointId}Portal / agent

    Delete an endpoint (queued deliveries stop)

    Parameters: orgId (path, required) · endpointId (path, required)

  • POST/v1/orgs/{orgId}/webhooks/{endpointId}/rotate-secretPortal / agent

    Replace the signing secret — the previous one stops signing immediately

    Parameters: orgId (path, required) · endpointId (path, required)

  • POST/v1/orgs/{orgId}/webhooks/{endpointId}/testPortal / agent

    Send a real, signed `webhook.test` delivery to this endpoint

    Parameters: orgId (path, required) · endpointId (path, required)

  • GET/v1/orgs/{orgId}/webhooks/{endpointId}/deliveriesPortal / agent

    This endpoint's delivery log, newest first

    Parameters: orgId (path, required) · endpointId (path, required) · limit (query) · offset (query) · status (query) · eventType (query)

  • POST/v1/orgs/{orgId}/webhooks/{endpointId}/deliveries/{deliveryId}/replayPortal / agent

    Re-send a finished delivery — the original's history is kept

    Parameters: orgId (path, required) · endpointId (path, required) · deliveryId (path, required)

compliance

  • GET/v1/orgs/{orgId}/compliance/data-processingPortal / agent

    What this deployment collects about a candidate, who can read it, where it goes and for how long — generated from the protocol registry and the org's live configuration

    Parameters: orgId (path, required)

sso

  • POST/v1/auth/sso/discoverPortal / agent

    Resolve the SSO entry point for an email address

    Takes a JSON body.

  • GET/v1/auth/sso/{orgSlug}/loginPortal / agent

    Start an SP-initiated SSO login

    Parameters: orgSlug (path, required)

  • GET/v1/auth/sso/{orgSlug}/metadataPortal / agent

    SAML SP metadata for an organization

    Parameters: orgSlug (path, required)

  • POST/v1/auth/sso/ldapPortal / agent

    Sign in against an organization's LDAP directory

    Takes a JSON body.

  • GET/v1/auth/sso/{orgSlug}/logout-urlPortal / agent

    The IdP's single-logout URL, if one is configured

    Parameters: orgSlug (path, required)

  • GET/v1/orgs/{orgId}/ssoPortal / agent

    The org's SSO configuration (owner only)

    Parameters: orgId (path, required)

  • PUT/v1/orgs/{orgId}/ssoPortal / agent

    Create or replace the org's SSO connection

    Parameters: orgId (path, required) — Takes a JSON body.

  • PUT/v1/orgs/{orgId}/sso/enforcementPortal / agent

    Require single sign-on, or make it optional again

    Parameters: orgId (path, required) — Takes a JSON body.

  • POST/v1/orgs/{orgId}/sso/domainsPortal / agent

    Claim an email domain (inert until verified)

    Parameters: orgId (path, required) — Takes a JSON body.

  • POST/v1/orgs/{orgId}/sso/domains/{domain}/verifyPortal / agent

    Check the org's proof of control over a claimed domain

    Parameters: orgId (path, required) · domain (path, required)

  • DELETE/v1/orgs/{orgId}/sso/domains/{domain}Portal / agent

    Drop a claimed domain

    Parameters: orgId (path, required) · domain (path, required)

  • POST/v1/orgs/{orgId}/sso/testPortal / agent

    Probe the configured IdP or directory

    Parameters: orgId (path, required)

  • POST/v1/orgs/{orgId}/sso/scim/tokenPortal / agent

    Issue or rotate the SCIM provisioning token

    Parameters: orgId (path, required)

  • DELETE/v1/orgs/{orgId}/sso/scim/tokenPortal / agent

    Turn SCIM off and destroy the token

    Parameters: orgId (path, required)

branding

  • GET/v1/orgs/{orgId}/branding/logoPortal / agent

    The org's logo (public — rendered before sign-in)

    Parameters: orgId (path, required)

  • PUT/v1/orgs/{orgId}/branding/logoPortal / agent

    Upload or replace the org's logo (base64, raster only)

    Parameters: orgId (path, required) — Takes a JSON body.

  • DELETE/v1/orgs/{orgId}/branding/logoPortal / agent

    Remove the org's logo (idempotent)

    Parameters: orgId (path, required)

  • GET/v1/orgs/{orgId}/branding/publicPortal / agent

    The org's brand as a candidate sees it (public). An unbranded org answers with the product's.

    Parameters: orgId (path, required)

  • GET/v1/orgs/{orgId}/brandingPortal / agent

    The org's branding config and what it resolves to (members)

    Parameters: orgId (path, required)

  • PUT/v1/orgs/{orgId}/brandingPortal / agent

    Replace the branding config. A palette below the contrast minimum is refused with the failing pairs.

    Parameters: orgId (path, required) — Takes a JSON body.

integrations

  • GET/v1/orgs/{orgId}/integrations/ats/capabilitiesPortal / agent

    Which ATS providers this deployment can connect, and whether it is configured to

  • GET/v1/orgs/{orgId}/integrations/atsPortal / agent

    The org's ATS integrations — never their credentials or inbound secrets

    Parameters: orgId (path, required)

  • POST/v1/orgs/{orgId}/integrations/atsPortal / agent

    Connect an ATS — the inbound webhook secret is shown once

    Parameters: orgId (path, required) — Takes a JSON body.

  • PATCH/v1/orgs/{orgId}/integrations/ats/{configId}Portal / agent

    Update credentials, settings, trigger stages, mapping or status

    Parameters: orgId (path, required) · configId (path, required) — Takes a JSON body.

  • DELETE/v1/orgs/{orgId}/integrations/ats/{configId}Portal / agent

    Disconnect (the sync log is kept — it records real sessions' provenance)

    Parameters: orgId (path, required) · configId (path, required)

  • POST/v1/orgs/{orgId}/integrations/ats/{configId}/rotate-secretPortal / agent

    Re-mint the inbound webhook secret — the previous one stops verifying immediately

    Parameters: orgId (path, required) · configId (path, required)

  • POST/v1/orgs/{orgId}/integrations/ats/{configId}/testPortal / agent

    Probe the connection with a read — changes nothing in the ATS

    Parameters: orgId (path, required) · configId (path, required)

  • GET/v1/orgs/{orgId}/integrations/ats/{configId}/syncPortal / agent

    The integration's sync log, newest first

    Parameters: orgId (path, required) · configId (path, required) · status (query) · direction (query) · limit (query) · offset (query)

  • POST/v1/orgs/{orgId}/integrations/ats/{configId}/sync/{syncId}/replayPortal / agent

    Re-run a failed outbound push — the original's history is kept

    Parameters: orgId (path, required) · configId (path, required) · syncId (path, required)

  • GET/v1/orgs/{orgId}/integrations/comms/capabilitiesPortal / agent

    Which chat platforms this deployment can install, and whether it is configured to

  • GET/v1/orgs/{orgId}/integrations/commsPortal / agent

    The org's chat apps — never their workspace tokens

    Parameters: orgId (path, required)

  • POST/v1/orgs/{orgId}/integrations/comms/installPortal / agent

    Begin an install — returns where to send the admin's browser to approve it

    Parameters: orgId (path, required) — Takes a JSON body.

  • GET/v1/orgs/{orgId}/integrations/comms/{integrationId}/channelsPortal / agent

    The channels this app can post into — the picker's options

    Parameters: orgId (path, required) · integrationId (path, required)

  • PATCH/v1/orgs/{orgId}/integrations/comms/{integrationId}Portal / agent

    Choose the channel, which events are announced, and the review threshold

    Parameters: orgId (path, required) · integrationId (path, required) — Takes a JSON body.

  • DELETE/v1/orgs/{orgId}/integrations/comms/{integrationId}Portal / agent

    Disconnect — revokes at the provider where that is possible, and says so when it is not

    Parameters: orgId (path, required) · integrationId (path, required)

  • GET/v1/orgs/{orgId}/integrations/comms/{integrationId}/deliveriesPortal / agent

    What was announced, and what failed to be — newest first

    Parameters: orgId (path, required) · integrationId (path, required) · status (query) · limit (query) · offset (query)

  • POST/v1/orgs/{orgId}/integrations/comms/{integrationId}/deliveries/{deliveryId}/replayPortal / agent

    Re-send a finished notification — the original's history is kept

    Parameters: orgId (path, required) · integrationId (path, required) · deliveryId (path, required)

updates

  • GET/v1/updates/manifestPortal / agent

    The signed update manifest for one app and channel — latest build, the operator's minimum supported version, and the recent builds that remain installable

    Parameters: app (query, required) · channel (query)

security-policy

  • GET/v1/security-policyPortal / agent

    The signed pin kill-switch policy — whether certificate pinning should stay enforced

access-requests

  • POST/v1/access-requests/owner-invite/inspectPortal / agent

    Describe an owner invitation link for its holder

    Takes a JSON body.

  • POST/v1/access-requests/owner-invite/acceptPortal / agent

    Accept an owner invitation: create the organization and its owner (signs a new account in)

    Takes a JSON body.

  • POST/v1/access-requests/owner-invite/renewPortal / agent

    Send a fresh invitation for an expired one

    Takes a JSON body.

  • GET/v1/access-requests/insightsPortal / agent

    Access-desk activation funnel (access-desk operators only)

    Parameters: from (query) · to (query)

  • GET/v1/access-requests/availabilityPortal / agent

    Whether the public request form is open in this deployment

  • GET/v1/access-requestsPortal / agent

    The review queue (access-desk operators only)

    Parameters: status (query) · limit (query) · cursor (query)

  • POST/v1/access-requestsPortal / agent

    Request access for a new organization (public, rate-limited)

    Takes a JSON body.

  • POST/v1/access-requests/{id}/approvePortal / agent

    Approve a pending request and email its first-owner invitation

    Parameters: id (path, required) — Takes a JSON body.

  • POST/v1/access-requests/{id}/declinePortal / agent

    Decline a pending request

    Parameters: id (path, required) — Takes a JSON body.

  • POST/v1/access-requests/{id}/resend-invitePortal / agent

    Rotate and resend an approved request's owner invitation

    Parameters: id (path, required)

insights

  • GET/v1/orgs/{orgId}/insightsPortal / agent

    Activation milestones, the session funnel, invitation outcomes and review turnaround/backlog

    Parameters: orgId (path, required) · from (query) · to (query)

candidate-requests

  • POST/v1/candidate-requests/linksPortal / agent

    Email a request link to the address a candidate was invited with — answers the same either way

    Takes a JSON body.

  • POST/v1/candidate-requests/links/invitationPortal / agent

    Exchange a live invitation handle for a request link — no second email needed

    Takes a JSON body.

  • POST/v1/candidate-requests/viewPortal / agent

    The candidate's requests for the link's session

    Takes a JSON body.

  • POST/v1/candidate-requests/submitPortal / agent

    Send a context statement or a data request — an open request of the same kind is returned instead of duplicated

    Takes a JSON body.

  • POST/v1/candidate-requests/exportPortal / agent

    Download an approved access copy (JSON) while it has not expired

    Takes a JSON body.

  • GET/v1/orgs/{orgId}/candidate-requestsPortal / agent

    The org's candidate requests, newest first (open by default)

    Parameters: orgId (path, required) · status (query) · kind (query) · limit (query) · offset (query)

  • GET/v1/orgs/{orgId}/candidate-requests/{requestId}Portal / agent

    CandidateRequestQueueController_get

    Parameters: orgId (path, required) · requestId (path, required)

  • POST/v1/orgs/{orgId}/candidate-requests/{requestId}/acknowledgePortal / agent

    CandidateRequestQueueController_acknowledge

    Parameters: orgId (path, required) · requestId (path, required)

  • POST/v1/orgs/{orgId}/candidate-requests/{requestId}/respondPortal / agent

    Write to the candidate; they are emailed a fresh link to read it

    Parameters: orgId (path, required) · requestId (path, required) — Takes a JSON body.

  • POST/v1/orgs/{orgId}/candidate-requests/{requestId}/approvePortal / agent

    Approve an access copy or an erasure — erasure goes through the retention erasure service

    Parameters: orgId (path, required) · requestId (path, required) — Takes a JSON body.

  • POST/v1/orgs/{orgId}/candidate-requests/{requestId}/declinePortal / agent

    CandidateRequestQueueController_decline

    Parameters: orgId (path, required) · requestId (path, required) — Takes a JSON body.

  • POST/v1/orgs/{orgId}/candidate-requests/{requestId}/completePortal / agent

    Mark a context statement as read

    Parameters: orgId (path, required) · requestId (path, required) — Takes a JSON body.

  • POST/v1/orgs/{orgId}/candidate-requests/{requestId}/reopen-reviewPortal / agent

    Reopen the session's signed-off review for this statement (needs session.review.assign)

    Parameters: orgId (path, required) · requestId (path, required) — Takes a JSON body.

  • GET/v1/orgs/{orgId}/session-candidate-context/{sessionId}Portal / agent

    The candidate's context statements on one session (evidence.view)

    Parameters: orgId (path, required) · sessionId (path, required)