Skip to content

Scenarios: which one are you? ​

Every product that uses Calloop is one of a few shapes. Find yours below and follow its page: each one lists, in order, the steps for that kind of product, marks every step Required or Optional, and shows the actual requests. The integration guide explains the concepts behind them; the Management API, events and agent protocol references have every field.

Your productExampleScenario
One business's team answers customers who call a WhatsApp number or a phone numberA company's support desk, a clinic's front desk, a sales teamContact center
A platform serving many businesses, each with its own team and numbersA helpdesk, CRM or messaging SaaS adding calls for its customersMulti-business platform
Each of your users has their own number, rings only them and calls out from itAn eSIM app, a virtual-number or second-line appPersonal numbers
Your users call out to contacts from your product, mostly outboundA CRM's "Call" button, a sales dialer, appointment reminders by a personClick-to-call

Mixed products. Pick the closest page and add the pieces you need from another: a personal-number app with its own support line follows Personal numbers and adds a queue and a shared line from Contact center, ideally in a separate tenant (so its end users never see the support team's board). A contact center that also calls customers back adds the outbound steps from Click-to-call.

What every integration has ​

Whatever the scenario, these pieces are the same. Each scenario page points back here.

PieceRequired?What it is
Your consumer and its keysRequiredThe Calloop operator creates your consumer and sends you, once, an API key (your backend), a signing key (kid + secret, for agent tokens) and, if they set a webhook or lookup URL for you, a webhook secret (otherwise the first PUT /v1/webhook that sets a URL returns it, once). Keep them in a secrets manager
A tenantRequiredPUT /v1/tenants/{ref}: a workspace (one business, or your whole product)
AgentsRequiredPUT /v1/tenants/{t}/agents/{ref}: the people who take calls (your user id as the ref)
At least one lineRequiredPUT /v1/tenants/{t}/channels/{ref}: a WhatsApp number or a phone number (DID) on a SIP trunk
A token endpointRequiredYour backend signs a short-lived JWT for the logged-in user; the app connects with it
The agent appRequiredYour app on the Calloop SDK (JavaScript, React or Flutter): rings, answers, calls out
The webhookRecommendedPUT /v1/webhook: Calloop tells your backend what happened (call.ended for history, billing, CRM)
Push credentials and device tokensRequired for mobile appsSo a phone in the background rings; not needed for a browser-only app
Everything elseOptionalIVR, overflow, supervisors, recording, reports, the lookup hook, the dashboard

The token endpoint (every scenario) ​

Your app never holds a key: your backend signs a token for the user who is logged in, for their own tenant, valid a few minutes. The SDK fetches a fresh one on every reconnect.

js
// Node (jsonwebtoken) — GET /api/calloop-token
const token = jwt.sign(
  { iss: 'yourproduct', tnt: tenantRef, sub: user.id, name: user.name, role: 'AGENT' },
  process.env.CALLOOP_SIGNING_SECRET,
  { algorithm: 'HS256', keyid: process.env.CALLOOP_SIGNING_KID, expiresIn: '10m' },
);

role is AGENT or SUPERVISOR. Calloop creates the agent on first connect if you haven't, but creating agents ahead with PUT is better: queues and lines can name them before they sign in. The token's name and role update the agent on every connect, so make them agree with your PUT: always send name (without it the agent is renamed to its ref), and sign the same role (a role in the token replaces the one you PUT). More, including PHP: integration guide → Sign agent tokens.

The webhook (every scenario) ​

http
PUT /v1/webhook
{ "url": "https://api.example.com/calloop/events",
  "event_types": ["call.created", "call.answered", "call.ended"] }

The first time a URL is set (if the operator didn't send you a webhook secret), the response returns { "webhook": { … }, "secret": "…" }: the secret, once — store it. The PUT replaces all your webhook settings: a URL you leave out (url, lookup_url) is removed, and no event_types means every type.

Then, on every request: verify the X-Calloop-Signature header, answer 2xx at once, process afterwards, and ignore an event_id you have already seen (delivery is at least once) (events → Verifying requests). call.ended alone is enough for history and billing; it carries the whole call.

Rules for every API call ​

  • Authorization: Bearer <API key> on every request, from your backend only.
  • PUT creates or replaces: send the whole object every time.
  • Send an Idempotency-Key header (a new UUID per action) on every POST, so a retry never places a second call.
  • Errors are always { "error": { "code", "message" } }; at most 1200 requests a minute.

Calloop — the call engine behind your product.