Arendajale

Hallake agente, numbreid ja kõnesid oma süsteemidest ning lisage häälkõne oma veebilehele.

Ülevaade

Tegemist on REST API-ga. Päringute ja vastuste sisu on JSON (UTF-8), ajatemplid on unix-sekundites ja summad USD-s. Baas-URL on:

https://hubvocal.com/v1

API-võti kuulub ühele organisatsioonile ja toimib selles administraatori õigustega. Kõike, mida saab teha juhtpaneelil, saab teha ka API-ga:

RessurssOtspunktid
Agendid/v1/agents, /v1/agents/{id}
Teadmusbaas/v1/knowledge, /v1/knowledge/{id}, /v1/knowledge/search
Tööriistad/v1/tools, /v1/tools/{id}, /v1/tools/{id}/test
MCP-serverid/v1/mcp-servers, /v1/mcp-servers/{id}, /v1/mcp-servers/{id}/sync
Webhookid/v1/webhooks, /v1/webhooks/{id}, /v1/webhooks/{id}/deliveries
Hääled ja mootorid/v1/voices
Veebikõned/v1/web-calls
Kõned ja väljuvad kõned/v1/calls, /v1/calls/{room}
Numbrid/v1/numbers, /v1/numbers/{number}
Kasutus/v1/usage

Masinloetav OpenAPI 3.1 dokument on saadaval aadressil GET /v1/openapi.json ja ei vaja võtit. Kõigi otspunktide üksikasjad leiate API viitest.

Kiirjuhend

  1. Looge API-võti

    Avage juhtpaneelil Seaded > API-võtmed ja andke võtmele nimi, mis ütleb, milleks see on. Võtmeid saavad luua ainult organisatsiooni omanikud ja administraatorid. Saladust (vt_live_…) näidatakse ühe korra; salvestage see kohe saladuste haldurisse.

    shell
    export VT_API_KEY="vt_live_…"
  2. Kuvage oma agendid

    Kiireim viis kontrollida, kas võti töötab. Vastuses olevat id-d läheb vaja järgmistes sammudes.

    curl
    curl "https://hubvocal.com/v1/agents" \
      -H "Authorization: Bearer $VT_API_KEY"
  3. Looge agent

    Mootor, keel, hääl ja juhised ühes objektis. Lubatud häälenimed ja piirangud tagastab GET /v1/voices.

    curl
    curl -X POST "https://hubvocal.com/v1/agents" \
      -H "Authorization: Bearer $VT_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "name": "Front desk",
      "lang": "en",
      "engine": "live",
      "instructions": "You are the front desk assistant for a dental clinic. Help callers book appointments and answer general questions briefly. Never make things up; offer a callback from the team instead.",
      "greeting": "Hello, thanks for calling the clinic. How can I help you today?",
      "voice": {
        "voice": "marin",
        "speed": 1
      },
      "tools": {
        "builtins": [
          "end_call",
          "take_message"
        ],
        "webhooks": [
          "tl_8f3a2c"
        ]
      },
      "turn": {
        "first_speaker": "agent",
        "idle_check_s": 30
      },
      "recording": {
        "enabled": false,
        "announce": true
      },
      "post_call": {
        "summary": true,
        "fields": [
          {
            "name": "appointment_date",
            "type": "date",
            "description": "Requested appointment date, if any"
          },
          {
            "name": "callback",
            "type": "boolean",
            "description": "Does the caller want a callback?"
          }
        ]
      },
      "knowledge": {
        "doc_ids": [
          "kb_7d21e4"
        ],
        "mode": "tool"
      }
    }'
  4. Alustage veebikõnet

    Brauserist ühendute vastuses olevate väärtustega server_url ja token; üksikasjad allpool.

    curl
    curl -X POST "https://hubvocal.com/v1/web-calls" \
      -H "Authorization: Bearer $VT_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "agent_id": "front-desk"
    }'

Autentimine

Saatke võti igas päringus Bearer-tokenina päises Authorization:

HTTP
Authorization: Bearer vt_live_…
  • Võti toimib teie organisatsioonis administraatori õigustega: loob agente, määrab numbreid ja teeb kõnesid. Hoidke seda nagu parooli.
  • Ärge kunagi pange võtit brauseri koodi, mobiilirakendusse ega repositooriumi. Brauserikõnede jaoks hankige oma serveris lühiajaline token.
  • Loendis Seaded > API-võtmed on näha, millal iga võtit viimati kasutati. Tühistatud võti lakkab kohe töötamast.
  • Kasutage iga integratsiooni jaoks eraldi võtit, et ühe tühistamine teisi ei lõhuks.

Veebikõne lehele

Teie külastajad saavad agendiga rääkida otse teie lehel, brauseris. Selleks on kolm sammu:

  1. Külastaja vajutab nuppu ja teie leht pöördub teie enda serveri poole.
  2. Teie server kutsub API-võtmega välja POST /v1/web-calls ja edastab vastuse (server_url, token, room, max_seconds) lehele.
  3. Leht ühendub ruumiga teegi livekit-client abil ja lülitab mikrofoni sisse. Agent liitub ise ja ütleb tervituse.

1. Server: hankige token

Node (Express)
// server.js (Node 18+, Express)
import express from "express";

const app = express();

app.post("/voice/session", async (req, res) => {
  // Lisage siia oma autentimine ja päringupiirang.
  const r = await fetch("https://hubvocal.com/v1/web-calls", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.VT_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ agent_id: "front-desk" }),
  });
  res.status(r.status).json(await r.json());
});

app.listen(3000);

2. Brauser: ühenduge

Kui kasutate komplekteerijat, paigaldage npm install livekit-client@2.23.0 ja importige samad nimed. Allolev näide laadib CDN-ist kindla versiooni.

index.html
<button id="talk" type="button">Alusta vestlust</button>

<script type="module">
  import { Room, RoomEvent, Track } from "https://cdn.jsdelivr.net/npm/livekit-client@2.23.0/dist/livekit-client.esm.mjs";

  const button = document.getElementById("talk");
  let room;

  button.addEventListener("click", async () => {
    if (room) {
      await room.disconnect();
      return;
    }
    button.disabled = true;
    // Teie server tagastab POST /v1/web-calls vastuse muutmata kujul.
    const res = await fetch("/voice/session", { method: "POST" });
    const session = await res.json();
    if (!res.ok) {
      button.disabled = false;
      alert(session.detail);
      return;
    }

    room = new Room();
    // Kui agendi heli saabub, ühendage see <audio> elemendiga.
    room.on(RoomEvent.TrackSubscribed, (track) => {
      if (track.kind === Track.Kind.Audio) document.body.appendChild(track.attach());
    });
    room.on(RoomEvent.Disconnected, () => {
      room?.remoteParticipants.forEach((p) =>
        p.audioTrackPublications.forEach((pub) => pub.track?.detach().forEach((el) => el.remove())),
      );
      room = undefined;
      button.textContent = "Alusta vestlust";
    });

    await room.connect(session.server_url, session.token);
    await room.localParticipant.setMicrophoneEnabled(true);
    button.disabled = false;
    button.textContent = "Lõpeta kõne";
  });
</script>

Alustage ühendust kasutaja tegevuse (klõpsu) peale: brauserid seovad sellega mikrofoni loa ja heli automaatse esitamise. Leht peab olema avatud üle HTTPS-i.

Kõne kestab kõige rohkem max_seconds, seejärel agent lõpetab kõne. Kui kõne on lõppenud, hankige selle kirje päringuga GET /v1/calls/{room}.

Väljuvad kõned

Helistage numbrile mõnelt oma organisatsiooni numbrilt; agent räägib, kui kõnele vastatakse. Number from peab olema loendis GET /v1/numbers. Ilma väljata agent_id kasutatakse sellele numbrile määratud agenti. Numbrid on E.164 vormingus (+90…).

curl
curl -X POST "https://hubvocal.com/v1/calls" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "from": "+908501234567",
  "to": "+905321234567",
  "agent_id": "front-desk"
}'

Vastus

JSON
{
  "room": "tel-out-9c41e0b7",
  "provider": "didww",
  "sip_call_id": "SCL_7mVt2kQb9xRa"
}

Vastuses olev room tähistab kõnet. Kui kõne on lõppenud, on selle kirje (ärakiri, kulu, kes kõne lõpetas) saadaval päringuga GET /v1/calls/{room}. Vastamata kõned lõpevad nii, et ended_by väärtus on no_answer.

Sissetulevad kõned

Teie numbritele saabuvatele kõnedele vastab numbrile määratud agent. Numbrid tulevad DIDWW, Twilio või teie oma SIP-trungi kaudu (Asterisk jt) ja platvormi meeskond lisab need teie organisatsiooni. Teie valite, milline agent vastab:

curl
curl -X PUT "https://hubvocal.com/v1/numbers/%2B908501234567" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "front-desk",
  "label": "Main line"
}'

Versioonid ja turvaline avaldamine

Agendi muutmisel muutub selle mustand. Kõned teie numbritele, veebikõned ja väljuvad kõned kasutavad avaldatud versiooni, nii et saate mustandiga töötada ilma päris kõnesid mõjutamata.

  1. Muutke agenti päringuga PUT /v1/agents/{id}. See muudab ainult mustandit; draft_changed saab väärtuseks true.
  2. Testige mustandit: alustage veebikõnet parameetriga version: "draft".
  3. Avaldage päringuga POST /v1/agents/{id}/publish, soovi korral märkusega. Mustandist saab uus nummerdatud versioon, mida kõned hakkavad kasutama.
  4. Kui midagi läks valesti, avaldab POST /v1/agents/{id}/rollback koos varasema versiooni numbriga selle versiooni uuesti, uue versioonina.
curl
curl -X POST "https://hubvocal.com/v1/agents/front-desk/publish" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "note": "Shorter greeting"
}'

POST /v1/web-calls ja POST /v1/calls võtavad vastu välja version: "live" (vaikimisi), "draft" või versiooni number. Agent, mida pole kunagi avaldatud, kasutab oma mustandit.

curl
curl -X POST "https://hubvocal.com/v1/web-calls" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "agent_id": "front-desk",
  "version": "draft"
}'

Testimine enne avaldamist

Testilabor viib läbi tekstivestlusi simuleeritud helistaja ja teie agendi vahel, et saaksite muudatust kontrollida enne, kui päris helistajad seda kuulevad.

  1. Kirjutage stsenaarium: kes helistab (persona), mida ta soovib (goal) ja kuni 20 repliiki.
  2. Lisage reeglid, millele hea kõne peab vastama (expect), näiteks „küsib enne broneerimist helistaja nime“.
  3. Andke tööriistadele näidistulemused (mocks); päris tööriistu ega webhooke välja ei kutsuta.
  4. Käivitage stsenaariumid mustandi peal. Eraldi mudel kontrollib iga reeglit ja selgitab, miks see täideti või jäi täitmata.
JSON
{
  "scenarios": [
    {
      "name": "Booking without a name",
      "persona": "A caller in a hurry who gives short answers",
      "goal": "Book an appointment tomorrow afternoon",
      "max_turns": 12,
      "expect": [
        "Asks for the caller's name before booking",
        "Reads the time back and asks for confirmation"
      ],
      "mocks": {
        "check_availability": {
          "ok": true,
          "slots": [
            "2026-11-06T14:00",
            "2026-11-06T15:30"
          ]
        }
      }
    }
  ],
  "version": "draft"
}

Vestlused toimuvad tekstirežiimis, seega testitakse juhiseid ja tööriistade kasutust, mitte häält ega viivitust. Simulatsioone käivitatakse juhtpaneelist; nende jaoks /v1 otspunkti veel pole.

Tööriistad

Tööriistad lasevad agendil kõne ajal tegutseda. Sama kirjeldus töötab kõigi nelja mootoriga; GPT-Live'is käivitab need taustamudel. Tööriistad lülitatakse sisse iga agendi jaoks eraldi väljal tools.

Sisseehitatud tööriistad

NimiMida see teeb
end_callAgent jätab hüvasti ja lõpetab kõne 0,75 s pärast seda, kui on rääkimise lõpetanud. Kui helistaja vahepeal räägib, kõne lõpetamine tühistatakse. Kõne kirjes on ended_by: "agent".
take_messageVõtab vastu name, phone, message ja callback_requested ning kirjutab need kõne kirje välja outcomes[]. Kinnitust ei küsi.
search_knowledgeLisatakse automaatselt, kui agendil on väljal knowledge dokumendid. Otsib neist ja salvestab allikad kõne kirjesse.
check_availabilityTüüp read. Tagastab vabad ajad vahemikus date_from kuni date_to agendi tööaja piires. Lisatakse, kui calendar on määratud.
book_appointmentTüüp write, läbib kinnitusetapi. Broneerib aja start nimele name ja numbrile phone, soovi korral märkusega note. Broneering lisatakse välja outcomes[].
cancel_appointmentTüüp write, läbib kinnitusetapi. Tühistab broneeringu selle booking_ref järgi.

Webhook-tööriistad

Webhook-tööriist on HTTPS-otspunkt teie poolel. Määrake see organisatsioonile üks kord juhtpaneeli jaotises Tööriistad või päringuga POST /v1/tools, seejärel lisage selle id agendi välja tools.webhooks (kuni 16 agendi kohta).

curl
curl -X POST "https://hubvocal.com/v1/tools" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "check_order",
  "description": "Looks up the shipping status of an order by its number.",
  "kind": "read",
  "url": "https://crm.example.com/hooks/order",
  "parameters": {
    "type": "object",
    "properties": {
      "order_id": {
        "type": "string",
        "description": "Order number"
      }
    },
    "required": [
      "order_id"
    ]
  },
  "timeout_s": 8,
  "enabled": true,
  "secret": "whsec_2b7f…"
}'
  • name: väiketähed, numbrid ja alakriipsud, 3 kuni 41 märki, algab tähega ja on organisatsioonis unikaalne. end_call ja take_message on reserveeritud.
  • description ütleb mudelile, millal tööriista kasutada. Kirjutage see nagu juhis kolleegile.
  • parameters on JSON Schema objekt kuni 20 väljaga, mille tüüp on string, number, integer või boolean (enum on lubatud).
  • kind on read või write; timeout_s on 2 kuni 15 sekundit.

Päring, mille saadame

Kui mudel tööriista kutsub, saadab API teie URL-ile POST-päringu. Sisus on tööriista nimi, mudeli valitud argumendid ja veidi kõne konteksti:

HTTP
POST /hooks/order HTTP/1.1
Host: crm.example.com
Content-Type: application/json
X-VT-Timestamp: 1793832421
X-VT-Signature: sha256=5f0c9a…

{
  "tool": "check_order",
  "arguments": {
    "order_id": "A-10234"
  },
  "call": {
    "room": "tel-6b1f04d2",
    "org_id": "6f1c2a40-3b7e-4d0c-9a51-2f8e7c1d9b03",
    "agent": "front-desk",
    "channel": "phone_in",
    "caller": "+905321234567",
    "called": "+908501234567",
    "lang": "en"
  }
}

Iga päring allkirjastatakse tööriista saladusega. X-VT-Timestamp on unix-aeg; X-VT-Signature on sha256=, millele järgneb timestamp + "." + body HMAC-SHA256 kuueteistkümnendkujul (hex). Kontrollige allkirja toorese sisu põhjal enne parsimist ja lükake tagasi ajatemplid, mis on vanemad kui paar minutit.

Allkirja kontrollimine

Node (Express)
// server.js (Node 18+, Express)
import crypto from "node:crypto";
import express from "express";

const app = express();
const SECRET = process.env.VT_TOOL_SECRET;

// Allkiri katab täpsed baidid: lugege toorest sisu.
app.post("/hooks/order", express.raw({ type: "*/*" }), (req, res) => {
  const ts = req.get("X-VT-Timestamp") ?? "";
  const sig = req.get("X-VT-Signature") ?? "";

  // Lükake vanad päringud tagasi (kaitse korduspäringute eest).
  if (!/^\d+$/.test(ts) || Math.abs(Date.now() / 1000 - Number(ts)) > 300) return res.sendStatus(401);

  const expected = "sha256=" + crypto.createHmac("sha256", SECRET).update(ts + ".").update(req.body).digest("hex");
  const a = Buffer.from(sig);
  const b = Buffer.from(expected);
  if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) return res.sendStatus(401);

  const { tool, arguments: args, call } = JSON.parse(req.body.toString("utf8"));
  // Hoidke vastus lühike: mudelini jõuavad ainult esimesed 4 KB.
  res.json({ order_id: args.order_id, status: "shipped", eta: "2026-11-07" });
});

app.listen(3000);

Teie vastus

Vastake 2xx olekukoodiga ning JSON-i või lihttekstiga. Mudelini jõuavad ainult esimesed 4 KB, seega tagastage ainult see, mida agent peab ütlema. Muu kui 2xx olek või aegumine annab mudelile teada, et tööriist ebaõnnestus, ja agent lahendab olukorra vestluses.

Lugemis- ja kirjutustööriistad

  • read tööriistad käivituvad kohe, näiteks tellimuse oleku või lahtiolekuaegade päringuteks.
  • write tööriistad läbivad kinnitusetapi. Esimest kutset ei täideta: agent loeb üksikasjad helistajale ette ja küsib jah- või ei-vastust. Tööriist käivitub ainult siis, kui helistaja järgmises repliigis on kõne keeles selge jah.
  • Sama kutse (nimi ja argumendid) käivitub ühe vestluse jooksul kõige rohkem üks kord.

Turvalisus

  • URL-id peavad kasutama https://. Kohalikud ja privaatvõrgu aadressid lükatakse tagasi.
  • Saladus salvestatakse krüpteeritult ja API ei tagasta seda kunagi (has_secret näitab, kas see on määratud). Agent ei näe seda; päringu teeb API.
  • Argumente ja vastuseid ei salvestata. Kõne kirjes säilib tools[] nime, tüübi, tulemuse ja kestusega ning ajateljel TOOL-rada.

Päringuga POST /v1/tools/{id}/test saate saata näidisargumentidega päris päringu ning näha olekut, kestust ja vastuse sisu.

curl
curl -X POST "https://hubvocal.com/v1/tools/tl_8f3a2c/test" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "arguments": {
    "order_id": "A-10234"
  }
}'

Teadmusbaas

Teadmusbaasis hoitakse teie organisatsiooni dokumente. Kui agendile on dokumendid valitud, saab ta tööriista search_knowledge ja vastab leitu põhjal. Agendile on antud juhis mitte välja mõelda seda, mida dokumentides pole.

Dokumendi lisamine

Saatke fail multipart-vormingus (file), lihttekst JSON-ina (title, text) või üks veebileht JSON-ina (url). Töötlemine toimub taustal: dokumendi olek on alguses processing ja muutub seejärel olekuks ready või failed.

curl
curl -X POST "https://hubvocal.com/v1/knowledge" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -F "file=@price-list-2026.pdf"
  • Failid: pdf, docx, txt, md või html, igaüks kuni 10 MB.
  • Organisatsiooni kohta kuni 200 dokumenti ja kokku 200 MB.
  • URL-id: üks leht, ainult https; kohalikud ja privaatvõrgu aadressid lükatakse tagasi.

Dokumentide andmine agendile

Loetlege dokumentide id-d agendi väljal knowledge.doc_ids (kuni 50). Enne kasutuselevõttu proovige otsingut päringuga POST /v1/knowledge/search.

curl
curl -X POST "https://hubvocal.com/v1/knowledge/search" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "query": "how much is a scale and polish"
}'

Kõne kirjes on iga otsing väljal tools[] nimega search_knowledge koos allikatega sources (dokument, pealkiri ja lõik).

Kalender ja broneeringud

Kui kalender on ühendatud, saab agent kõne ajal vabu aegu kontrollida ning aegu broneerida või tühistada.

Kalendrid ühendatakse juhtpaneeli jaotises Integratsioonid (Google Calendar). Integratsioonide jaoks /v1 otspunkti pole; API-s määrate agendile ainult, millist integratsiooni see kasutab.

Agendi seaded

Määrake agendi objekt calendar: integratsioon ja kalender, broneeringu pikkus (15–240 min), puhver (0–60 min), ajavöönd, tööaeg, minimaalne etteteatamisaeg (0–72 h) ja kui kaugele ette saab broneerida (1–90 päeva).

PUT /v1/agents/front-desk
{
  "calendar": {
    "integration_id": "int_4a7c10",
    "calendar_id": "primary",
    "duration_min": 30,
    "buffer_min": 10,
    "timezone": "Europe/Istanbul",
    "working_hours": {
      "mon": [
        [
          "09:00",
          "18:00"
        ]
      ],
      "tue": [
        [
          "09:00",
          "18:00"
        ]
      ],
      "wed": [
        [
          "09:00",
          "18:00"
        ]
      ],
      "thu": [
        [
          "09:00",
          "18:00"
        ]
      ],
      "fri": [
        [
          "09:00",
          "17:00"
        ]
      ]
    },
    "min_notice_h": 2,
    "max_days_ahead": 30
  }
}

Seejärel saab agent kolm sisseehitatud tööriista: check_availability (read), book_appointment ja cancel_appointment (mõlemad write). Kirjutamised läbivad kinnitusetapi: agent loeb kellaaja, nime ja telefoninumbri üle ning broneerib alles pärast selget jah-vastust.

Iga broneering salvestatakse kõne kirjesse väljale outcomes[] kujul {kind: "appointment", start, name, phone, ref}.

MCP

HubVocal toetab protokolli Model Context Protocol kahel viisil: teie agendid saavad kasutada teie enda MCP-serverite tööriistu ja MCP-kliendid saavad platvormi hallata.

MCP-serveri ühendamine agentidega

Lisage server päringuga POST /v1/mcp-servers või juhtpaneelil. Me laadime selle tööriistade loendi (tools/list); uued tööriistad on alguses välja lülitatud. Lülitage vajalikud sisse, märkige igaüks kas read või write ja loetlege need agendi väljal tools.mcp.

curl
curl -X POST "https://hubvocal.com/v1/mcp-servers" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "crm",
  "url": "https://mcp.example.com/mcp",
  "auth": "bearer",
  "secret": "sk_live_…"
}'
  • Ühenduse loob API, mitte agent, seega ei näe agent kunagi teie serveri saladust.
  • URL-id peavad olema https; kohalikud ja privaatsed aadressid lükatakse tagasi, ka ühendamise hetkel.
  • write tööriistad läbivad kinnitusetapi: agent loeb üksikasjad üle ja käivitab tööriista alles pärast selget jah-vastust, kõne jooksul kõige rohkem üks kord.
  • Iga kutse aegub 10 sekundiga; mudelini jõuab tulemusest kuni 4 KB.
  • Organisatsiooni kohta kuni 10 serverit ja serveri kohta kuni 50 tööriista. MCP-tööriistad arvestatakse agendi 16 tööriista piirangu sisse.

Vestluses ja kõne kirjes on MCP-tööriista nimi kujul <server>.<tool>, näiteks crm.find_customer.

Platvormi haldamine MCP-kliendist

HubVocal on ka ise MCP-server aadressil https://hubvocal.com/mcp (streamable HTTP). Autentige organisatsiooni API-võtmega, saates selle Bearer-tokenina. Päringupiirang on ühine /v1-ga.

Kliendi ühendamine

Asendage vt_live_… oma võtmega. Andke kliendile võti, millel on ainult need õigused, mida klient vajab.

Claude Code
claude mcp add --transport http hubvocal https://hubvocal.com/mcp \
  --header "Authorization: Bearer vt_live_…"

ChatGPT rakenduses lisatakse kohandatud MCP-konnektorid arendajarežiimis; kas API-võtit saab päises kasutada, sõltub teie paketist ja konnektori seadetest. OpenAI API kaudu saate võtme otse kaasa anda, nagu allpool näidatud.

Tööriistad

TööriistÕigusMida teeb
list_agentsreadLoetleb teie agendid.
get_agentreadTagastab ühe agendi.
list_callsreadLoetleb kõned, filtriga since, outcome või agent_id järgi (kuni 50).
get_callreadTagastab kõne koos ärakirja ja kokkuvõttega.
list_numbersreadLoetleb teie telefoninumbrid.
list_knowledgereadLoetleb teadmusbaasi dokumendid.
search_knowledgereadOtsib teadmusbaasist.
get_usagereadSelle kuu kulu ja minutid.
create_agentwriteLoob agendi.
update_agentwriteMuudab agendi mustandit.
publish_agentwriteAvaldab agendi mustandi.
add_knowledge_textwriteLisab teadmusbaasi tekstidokumendi.
start_outbound_callcallsTeeb väljuva kõne (agent_id, to). Kehtivad tavalised väljuvate kõnede reeglid ja piirangud.

Ressursid ja viibad

  • agent://{id}: agendi seaded.
  • call://{id}: kõne ärakiri tekstina.
  • Viip daily_call_report: päeva kõnede kokkuvõte.

Õigused ja auditilogi

Igal API-võtmel on õigused, mille valite võtme loomisel juhtpaneelil:

  • read: ainult lugemiseks mõeldud tööriistad ja otspunktid.
  • write: lisaks agentide ja dokumentide loomine ja muutmine.
  • calls: lisaks väljuvad kõned.

Võtmetel, mis loodi enne õiguste kasutuselevõttu, on kõik kolm. Iga MCP-tööriista kutse kirjutatakse auditilogisse koos võtme, tööriista, aja ja tulemusega.

Veebividin

Vidin lisab teie veebisaidile kõnenupu. Külastajad räägivad teie agendiga otse brauseris; teie poolel pole serverikoodi vaja.

Looge avalik võti

Avage juhtpaneelis agent ja looge avalik võti (pk_…). Avalik võti kuulub ühele agendile ja selle võib turvaliselt lehele panna, sest see lubab ainult selle agendiga veebikõnesid ja ainult teie lubatud domeenidelt.

  • Lubatud domeenid (allowed_origins): teistelt saitidelt tulevad kõned lükatakse tagasi.
  • Iga kõne ajapiirang.
  • Samalt IP-aadressilt kuni 10 kõnet tunnis.

Lisage skript

Kleepige see enne lõpetavat silti </body>:

HTML
<script src="https://hubvocal.com/widget.js" data-agent="pk_…" async></script>

Nupu värv, asukoht ja tekst (külastaja keeles) tulevad agendi widget seadetest: color, position, label.

JSON
{
  "widget": {
    "color": "#2563eb",
    "position": "bottom-right",
    "label": "Talk to us"
  }
}

Vidin kutsub avaliku võtmega välja POST /api/public/web-calls; teie API-võtit see kunagi ei näe. Avalikke võtmeid hallatakse juhtpaneelis.

Struktureeritud väljad CRM-i

Struktureeritud väljad muudavad vestluse andmeteks, mida teie süsteemid saavad kasutada, näiteks broneeringu kuupäev, toode, mille kohta küsiti, või soov tagasihelistamiseks.

Määrake väljad

Lisage agendi väljale post_call.fields kuni 24 välja. Igal väljal on name (väiketähed, numbrid ja allkriipsud), type (string, number, boolean, enum või date), description, mis ütleb mudelile, mida otsida, ning soovi korral enum väärtused ja required.

JSON
{
  "post_call": {
    "summary": true,
    "fields": [
      {
        "name": "appointment_date",
        "type": "date",
        "description": "Requested appointment date"
      },
      {
        "name": "service",
        "type": "enum",
        "enum": [
          "checkup",
          "cleaning",
          "whitening"
        ],
        "description": "Service the caller asked about"
      },
      {
        "name": "callback",
        "type": "boolean",
        "required": true,
        "description": "Does the caller want a callback?"
      }
    ]
  }
}

Pärast kõnet täidab väljad sama mudel, mis kirjutab kokkuvõtte. Väärtused, mida vestluses ei mainitud, on null. Saate need väljana extracted päringu GET /v1/calls/{room} vastuses ja kõnede loendis ning call.ended webhooki sisus.

JSON
{
  "extracted": {
    "appointment_date": "2026-11-12",
    "service": "cleaning",
    "callback": true
  }
}

CSV-ekspordis on iga väli eraldi veerus.

Kõne webhookid

Webhook saadab teie süsteemi sündmuse call.ended, kui kõne on lõppenud ja selle kirje koos kokkuvõttega on valmis. Selle abil saate luua pöördumise, uuendada CRM-i kontakti või saata kliendile järelsõnumi.

Kui kõnekvaliteedi hinded on sisse lülitatud, saate tellida ka sündmuse call.quality_low. See saadetakse iga kõne kohta üks kord, kui hinne langeb alla teie organisatsiooni läve.

Lisage organisatsioonile kuni 5 webhooki juhtpaneelis või päringuga POST /v1/webhooks. Kui te secret väärtust ei saada, luuakse see automaatselt ja tagastatakse ainult selles vastuses. URL peab olema https; kohalikud ja privaatsed aadressid lükatakse tagasi.

curl
curl -X POST "https://hubvocal.com/v1/webhooks" \
  -H "Authorization: Bearer $VT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://crm.example.com/hooks/voice",
  "events": [
    "call.ended"
  ]
}'

Sündmus

data on sama kõneobjekt, mille tagastab GET /v1/calls/{room}, koos ärakirja ja kokkuvõttega:

HTTP
POST /hooks/voice HTTP/1.1
Host: crm.example.com
Content-Type: application/json
X-VT-Event: call.ended
X-VT-Delivery: dl_51b7a9
X-VT-Timestamp: 1793832440
X-VT-Signature: sha256=9b1e44…

{
  "id": "evt_8a41f0c2",
  "type": "call.ended",
  "created_at": "2026-11-05T09:47:20Z",
  "data": {
    "room": "demo-8585522d",
    "org_id": "6f1c2a40-3b7e-4d0c-9a51-2f8e7c1d9b03",
    "org_name": "Example Clinic",
    "channel": "web",
    "profile": "Front desk",
    "engine": "live",
    "lang": "en",
    "voice": "marin",
    "started_at": 1793832409.1,
    "ended_at": 1793832434.2,
    "duration_s": 25.1,
    "total_usd": 0.021215,
    "ended_by": "caller",
    "outcome": "message_taken",
    "summary_text": "The caller asked for an appointment on Thursday afternoon; a message was taken for a callback.",
    "extracted": {
      "appointment_date": "2026-11-12",
      "callback": true
    },
    "first_audio_s": 2.43,
    "turns": 4,
    "source_gaps": {
      "count": 2,
      "total_ms": 230,
      "max_ms": 141,
      "agent_audio_s": 31.2,
      "events": [
        [
          16.4,
          141
        ],
        [
          40.1,
          89
        ]
      ]
    },
    "quality": {
      "verdict": "Clean: no loss, no gaps.",
      "protocol": "UDP",
      "loss_pct": 0,
      "conceal_pct": 0,
      "jitter_ms": 4,
      "rtt_ms": 38
    },
    "cost": {
      "live": {
        "billed_s": 25.1,
        "reported": true,
        "voice_usd": 0.020917,
        "backend": {
          "in": 1840,
          "cached": 1024,
          "out": 96
        },
        "backend_usd": 0.000298
      },
      "llm": {
        "input_tokens": 1840,
        "cached_tokens": 1024,
        "output_tokens": 96,
        "usd": 0.000298
      },
      "tts": {
        "input_tokens": 0,
        "audio_tokens": 0,
        "audio_s": 25.1,
        "usd": 0.020917
      },
      "stt": {
        "audio_s": 0,
        "usd": 0
      }
    },
    "tools": [
      {
        "t": 14.2,
        "name": "check_order",
        "kind": "read",
        "ok": true,
        "ms": 412,
        "status": 200
      }
    ],
    "outcomes": [],
    "summary": {
      "text": "The caller asked for an appointment on Thursday afternoon; a message was taken for a callback.",
      "language": "en",
      "outcome": "message_taken",
      "sentiment": "neutral",
      "topics": [
        "appointment"
      ],
      "action_items": [
        "Call the caller back on Thursday morning"
      ]
    },
    "recording": {
      "available": true,
      "duration_s": 25.1,
      "size_bytes": 201344
    },
    "supervisors": [
      {
        "user": "ayse@example.com",
        "joined_at": 1793832420.4,
        "left_at": 1793832431,
        "modes": [
          "listen",
          "whisper"
        ]
      }
    ],
    "greeting": {
      "connect_s": 0.15,
      "session_started_s": 0.05,
      "reply_requested_s": 0.05,
      "first_audio_s": 2.4,
      "reply_done_s": 7.1
    },
    "transcript": [
      {
        "role": "assistant",
        "text": "Hello, thanks for calling the clinic. How can I help you today?",
        "t": 2.4,
        "interrupted": false
      },
      {
        "role": "user",
        "text": "I would like an appointment on Thursday afternoon.",
        "t": 9.8
      }
    ]
  }
}

Päringud allkirjastatakse täpselt samamoodi nagu tööriistade päringud: X-VT-Timestamp ja X-VT-Signature. Lisaks on kaks päist: X-VT-Event (sündmuse tüüp) ja X-VT-Delivery (selle edastuse unikaalne id).

Korduskatsed

Edastus loetakse õnnestunuks, kui 10 sekundi jooksul tuleb mis tahes 2xx vastus. Muul juhul proovime uuesti:

  1. 1 minuti pärast
  2. 5 minuti pärast
  3. 30 minuti pärast
  4. 2 tunni pärast

Pärast kokku 5 katset märgitakse edastus olekuga failed. Kõiki katseid näete päringuga GET /v1/webhooks/{id}/deliveries ja ebaõnnestunud edastuse saate uuesti järjekorda panna päringuga POST /v1/webhooks/deliveries/{id}/retry.

Duplikaatide käsitlemine

Korduskatse võib saabuda ka siis, kui teie varasem vastus läks teel kaduma, nii et sama sündmus võib tulla mitu korda. Salvestage X-VT-Delivery id ja jätke juba töödeldud id-d vahele. Vastake kiiresti ja tehke aeganõudev töö taustal.

Node (Express)
// Kõigepealt kontrollige allkirja (sama kood mis tööriistade puhul).
app.post("/hooks/voice", express.raw({ type: "*/*" }), async (req, res) => {
  if (!verify(req)) return res.sendStatus(401);

  // Kas see edastus on juba töödeldud? Kinnitage ja lõpetage.
  const delivery = req.get("X-VT-Delivery");
  if (await db.deliveries.exists(delivery)) return res.sendStatus(200);
  await db.deliveries.insert(delivery);

  // Vastake kiiresti; aeganõudev töö tehke taustal.
  res.sendStatus(200);
  const event = JSON.parse(req.body.toString("utf8"));
  queue.add("call-ended", event.data);
});

POST /v1/webhooks/{id}/test saadab näidissündmuse call.ended ning tagastab oleku, ajakulu ja vastuse sisu.

Toetatud vestluskeeled

Millistes keeltes iga mootor vestlust pidada saab. Agendi keele määrate väljaga lang, kasutades allolevaid koode.

  • Toetatud
  • Katseline Mootor ei loetle seda keelt ametlikult. See töötab juhiste järgi, kuid kvaliteeti me mõõtnud ei ole.
Keel lang GPT-Live 1Gemini LiveOpenAI RealtimeKlassikaline
Türkçetr tr Katseline Toetatud Katseline Toetatud
Englishen en Toetatud Toetatud Katseline Toetatud
Deutschde de Toetatud Toetatud Katseline Toetatud
Françaisfr fr Toetatud Toetatud Katseline Toetatud
Españoles es Katseline Toetatud Katseline Toetatud
Italianoit it Katseline Toetatud Katseline Toetatud
Portuguêspt pt Toetatud Toetatud Katseline Toetatud
Nederlandsnl nl Katseline Toetatud Katseline Toetatud
Русскийru ru Katseline Toetatud Katseline Toetatud
Українськаuk uk Katseline Toetatud Katseline Toetatud
Polskipl pl Katseline Toetatud Katseline Toetatud
Românăro ro Katseline Toetatud Katseline Toetatud
Ελληνικάel el Katseline Toetatud Katseline Toetatud
Българскиbg bg Katseline Toetatud Katseline Toetatud
Češtinacs cs Katseline Toetatud Katseline Toetatud
Slovenčinask sk Katseline Toetatud Katseline Toetatud
Magyarhu hu Katseline Toetatud Katseline Toetatud
Hrvatskihr hr Katseline Toetatud Katseline Toetatud
Српскиsr sr Katseline Toetatud Katseline Toetatud
Bosanskibs bs Katseline Toetatud Katseline Toetatud
Slovenščinasl sl Katseline Toetatud Katseline Toetatud
Македонскиmk mk Katseline Toetatud Katseline Toetatud
Svenskasv sv Katseline Toetatud Katseline Toetatud
Danskda da Katseline Toetatud Katseline Toetatud
Norskno no Katseline Toetatud Katseline Toetatud
Suomifi fi Katseline Toetatud Katseline Toetatud
Eestiet et Katseline Toetatud Katseline Toetatud
Latviešulv lv Katseline Toetatud Katseline Toetatud
Lietuviųlt lt Katseline Toetatud Katseline Toetatud
Catalàca ca Katseline Toetatud Katseline Toetatud

Proovige katselisi keeli enne telefoniliinile panemist brauseris.

Piirangud ja vead

Päringupiirang on 120 päringut minutis võtme kohta. Selle ületamisel saate vastuse 429 koos päisega Retry-After sekundites. Vigadel on HTTP olekukood ja alati sama sisu; detail on inimloetav teade.

402
{
  "detail": "Monthly spending limit reached"
}
KoodTähendusMillal
400Vigane päringPäringu sisu ei õnnestunud lugeda, kohustuslik väli puudub või väärtus on vigane (näiteks number pole E.164 vormingus või püütakse kustutada viimast agenti).
401AutentimataAuthorization päis puudub, võti ei alga eesliitega vt_live_ või see on tühistatud.
402Limiit täisOrganisatsioon on jõudnud kuu kululimiidini; uusi kõnesid ei saa alustada.
403PeatatudOrganisatsioon on peatatud; uusi kõnesid ei saa alustada.
404Ei leitudSellist agenti, kõnet, numbrit või otspunkti pole.
409KonfliktPOST /v1/agents saadeti juba olemasoleva id-ga.
429Liiga palju päringuidÜle 120 päringu minutis ühe võtmega. Oodake Retry-After päises toodud arv sekundeid.
502Teenusepakkuja vigaTelefoniteenuse pakkuja lükkas väljuva kõne tagasi või ei vastanud.
500Serveri vigaJuhtus midagi ootamatut. Proovige uuesti; kui viga püsib, kirjutage meile.

Korrake ainult vastuseid 429 ja 5xx. 4xx tähendab, et viga on päringus endas; uuesti saatmine tulemust ei muuda.

Kordamine Retry-After järgi
async function vt(path, init = {}, attempt = 0) {
  const res = await fetch(`https://hubvocal.com/v1${path}`, {
    ...init,
    headers: {
      Authorization: `Bearer ${process.env.VT_API_KEY}`,
      "Content-Type": "application/json",
      ...init.headers,
    },
  });
  if (res.status === 429 && attempt < 3) {
    const wait = Number(res.headers.get("Retry-After") ?? 60);
    await new Promise((r) => setTimeout(r, wait * 1000));
    return vt(path, init, attempt + 1);
  }
  const data = await res.json();
  if (!res.ok) throw new Error(`${res.status}: ${data.detail}`);
  return data;
}