If you don't see a native connector for your stack, push conversations in via REST. Single, bulk (up to 200), or CSV. Scoped tokens, idempotency, deterministic IDs. Genesys, NICE, Five9, Talkdesk, Webex, ServiceNow, Jira, and anything home-grown live here.
POST /api/v1/ingest/conversations Authorization: "Bearer btr_••••" Idempotency-Key: "gen_847b21" { "external_id": "genesys_a8d2", "channel": "chat", "brand": "aurora", "agent": { "email": "[email protected]" }, "customer": { "id": "c_4127" }, "messages": [ { "role": "customer", "text": "Can't access cPanel" }, { "role": "agent", "text": "On it — give me 2 mins." } ] } // → 202 Accepted · evaluation queued
Push one, push up to 200, or paste in a CSV — Belter normalizes everything into the same conversation + message + customer schema before evaluation.
| Verb | Endpoint | Purpose | Limit |
|---|---|---|---|
| POST | /api/v1/ingest/conversations |
Single conversation ingest. Idempotent by external_id or Idempotency-Key. |
1 |
| POST | /api/v1/ingest/conversations/bulk |
Bulk array ingest. Each item evaluated independently — partial success returned. | 200 |
| POST | /api/v1/ingest/conversations/csv |
CSV upload for historical backfills. Streamed, no chunk limit. | — |
| POST | /api/v1/ingest/amazon-connect |
Dedicated ingest for Amazon Connect Contact Lens / CTR payloads. | 1 |
| GET | /api/v1/conversations/{id} |
Fetch a conversation incl. score, criteria reasoning, sentiment timeline. | — |
| GET | /api/v1/evaluations |
List evaluations with filters: agent, brand, score range, date. | — |
| POST | /api/v1/csat |
Single CSAT score. Correlated to conversation by external_id. |
1 |
| POST | /api/v1/csat/bulk |
Bulk CSAT — drain a Qualtrics, SurveyMonkey, or Typeform export. | 500 |
| POST | /api/v1/csat/webhook |
Endpoint your survey tool calls. Auth via header token. | — |
Every token is bound to one org and one or more scopes. conversations.write for ingest, evaluations.read for reporting, etc. Mint a fresh token for each integration, rotate at will, revoke without affecting the others.
Authorization: Bearer btr_…Idempotency-Key header dedups retries. external_id deduplicates conversations.X-RateLimit-* headers.# conversation pipeline conversations.write # push new conversations.read # fetch + list evaluations.read # scores + reasoning evaluations.trigger # force re-evaluate # auxiliary signals csat.write # /api/v1/csat agents.read # roster alerts.read # smart alerts # administration webhooks.manage # subscribe events org.read # settings
Most QA platforms treat CSAT as an island. Belter ties survey scores back to the underlying conversation so you can compare what your customers thought with what your QA rubric thought.
{ "external_id": "genesys_a8d2", "score": 4, "scale": "1-5", "verbatim": "Sara was super patient", "received_at": "2026-06-08T14:32:00Z" } // → 200 OK · linked to conv_84291
Conversations, evaluations, agents, CSAT, alerts, webhooks — all listable and filterable via scoped read tokens. Plug into Looker, Mode, dbt, or whatever lives upstream of your dashboards.
GET /api/v1/evaluations ?brand=aurora &score_lt=70 &from=2026-06-01 &limit=100 // → 200 OK · 42 evaluations { "data": [ { "id": "eval_a8d2", "conversation_id": "conv_84291", "score": 62, "rubric_version": 7 } ], "next": "cursor_..." }
// includes: { "id": "conv_84291", "channel": "chat", "agent": { "name": "Jordan T." }, "messages": [ ... ], "evaluation": { "score": 94, "criteria": [ { "name": "empathy", "score": 97 }, { "name": "resolution", "score": 92 } ], "sentiment_timeline": [ ... ], "pii_flags": [] } }
Get a sandbox token, push a single conversation, watch it score. The whole loop, in less than the time it takes to write a JIRA ticket about it.