DOCS

Public API & webhooks

API keys, the REST surface, signed webhook events.

RepCue's control-plane API is the same one the console uses. Everything you see in the console is reachable with an API key.

API keys

Create keys in Settings → API keys. Each key has a name, a role (rep, manager or admin; it can't exceed yours), and shows its prefix only; the secret is displayed once.

Authorization: Bearer rk_live_3f9c…

Keys are scoped to your organisation. Revoke instantly from the same page; last used helps you find forgotten ones.

Base URL and envelope

https://api.repcue.io/v1

Every response is an envelope:

{ "success": true, "data": { … } }
{ "success": false, "error": { "code": "not_found", "message": "…" } }

Reference

The OpenAPI 3.1 document and an interactive explorer are served at https://api.repcue.io/docs for authenticated API keys and admin sessions. The main resources:

ResourceEndpoints
CallsGET /calls?q=&from=&to=&repUserId= · GET /calls/:id · GET /calls/:id/utterances · GET /calls/:id/artifacts · GET /calls/:id/recording · GET/PATCH /calls/:id/scorecard · DELETE /calls/:id
KnowledgeGET/POST /kb/documents · POST /kb/documents/upload · POST /kb/import/url · GET /kb/search?q=
Battlecards & playbooksGET/POST/PATCH/DELETE /battlecards, /battlecards/:id/versions, /playbooks
DealsGET/POST/PATCH /deals · GET /deals/:id/timeline · GET /deals/:id/risk · GET /deals/forecast
CRM diffsGET /crm/diffs · POST /crm/diffs/:id/approve · …/reject
AnalyticsGET /analytics/{suggestion-adoption,objection-frequency,talk-ratio,outcomes,roi,latency,leaderboard}; all accept from, to, repUserId, scope, format=csv
CoachingGET /calls/:id/comments · POST /calls/:id/snippets · GET /coaching/skills
TeamsGET/POST /teams · GET/PATCH/DELETE /teams/:id · POST /teams/:id/members · DELETE /teams/:id/members/:userId
GoalsGET/POST/PATCH/DELETE /goals · GET /goals/progress?scope=
NotificationsGET /notifications · POST /notifications/:id/read · POST /notifications/read-all · GET/PUT /notifications/prefs
Policies & rubricsGET/PUT /policies?teamId= · GET /policies/for-user/:userId · GET/POST/PATCH/DELETE /scorecard-templates · GET/POST/DELETE /vocabulary
Views & reportsGET/POST/PATCH/DELETE /saved-views · …/scheduled-reports
SearchGET /search?q=&types=calls,deals,people,documents
PeopleGET/PATCH/DELETE /users · POST /users/invite
AuditGET /audit?action=&actor=&from=&to=
AdminGET /admin/health-summary · POST /admin/view-as
WebhooksGET/POST/DELETE /webhooks · POST /webhooks/:id/test-delivery
OrgGET /orgs/me · GET /orgs/me/export

Rate limit: 300 requests/minute per key, with Retry-After on 429.

The scope parameter

List endpoints for calls, deals, analytics, coaching, usage events and search accept ?scope=me | org | team:<id>.

The server decides what that resolves to, based on the key's role. A rep key is always forced to its own records; a manager key is bounded by the teams it manages and is refused org; an admin key may request anything. Passing a scope you aren't entitled to does not widen access; see Roles & permissions.

Fetching a single record that is out of scope returns 404, not 403, so a response cannot confirm the record exists.

Webhooks

Register an HTTPS endpoint in Settings → Webhooks (or POST /webhooks) and choose events:

EventWhen
utterance.finalA final transcript turn (only when the policy permits transcript egress)
suggestion.shown · suggestion.usedHUD card lifecycle
call.completedPost-call pipeline finished; payload includes artifact ids
crm.syncedA diff was approved and written
email.sentFollow-up delivered
usage.recordedA live hour was metered
user.deleted · org.deletedGDPR erasure completed

Verifying signatures

Every delivery carries:

X-RepCue-Event: call.completed
X-RepCue-Delivery: evt_01J…
X-RepCue-Timestamp: 1755772800
X-RepCue-Signature: sha256=…

Compute HMAC_SHA256(secret, timestamp + "." + rawBody) and compare in constant time. Reject timestamps older than five minutes.

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

export function verify(secret, headers, rawBody) {
  const ts = headers["x-repcue-timestamp"];
  const expected = "sha256=" + createHmac("sha256", secret).update(`${ts}.${rawBody}`).digest("hex");
  const given = headers["x-repcue-signature"] ?? "";
  return expected.length === given.length && timingSafeEqual(Buffer.from(expected), Buffer.from(given));
}

Delivery

2xx within 10 s counts as delivered. Failures retry twice immediately, then hourly up to 10 attempts. Test delivery sends a signed ping event so you can check your verifier before going live. Endpoints resolving to private networks are rejected.