Liigu sisu juurde

Ühendamine

REST API

v1 API täielik viide. Kõik on JSON ja vigadel on ühtne kuju. volai hinnad kasutavad täisarvulisi kroonisadasosi (järelliide Hal); ühendatud arved kasutavad oma märgitud valuuta väikseimaid ühikuid.

Autentimine

Iga päring kannab API-võtit päises Authorization: Bearer vk_... . Võtme saate portaalis jaotises Juurdepääs ja API (täpsemalt jaotises Kiirstart).

bash
curl https://volai.cz/v1/balance \
  -H "Authorization: Bearer vk_YOUR_KEY"

Sellel kogu API-l on ka masinloetav kirjeldus aadressil GET /openapi.json (OpenAPI 3.1, API-võtit ei vajata) - looge sellest klient, Postmani kollektsioon või ühendage see otse n8n-iga.

Vea kuju

Ebaõnnestumisel on alati sama kuju, olenemata sellest, mis katki läks:

json
{
  "error": {
    "code": "insufficient_credit",
    "cause": "account",
    "message": "Insufficient credit. Account balance is 3.00 CZK. Top up at volai.cz/en/credit and try again.",
    "action": "Top up the credit at https://volai.cz/en/credit (or ask the account owner to), then send the request again. Nothing was charged and volai itself is up.",
    "requestId": "req_9f2b7a1c4e6d8f0a",
    "docsUrl": "https://volai.cz/en/docs/api#errors"
  }
}

Need viis võivad ilmneda peaaegu kõikjal - allolev lõpp-punktide viide loetleb nende peale ainult olukorrapõhiseid koode:

HTTPKoodPõhjusTähendus
401unauthorizedrequestPäis Authorization puudub või on vigane.
402insufficient_creditaccountSelle toimingu jaoks ei ole saldot piisavalt.
403account_suspendedaccountvolai operaator on konto käsitsi peatanud - võtke ühendust volai toega. Maksudokumendid (GET /v1/billing/documents, /{id} ja /{id}/pdf, MCP tööriistad list_billing_documents ja get_billing_document) jäävad peatamise ajal kättesaadavaks.
429rate_limitedbusyPäringupiirang ületatud - API-võtme piirangu puhul oodake nii kaua, kui päis Retry-After ütleb. Mitte iga 429 ei kanna seda päist (näiteks päevane SMS-ide limiit, veel käimasolev ost või avalik GET /v1/changelog), seega järgige vea teadet.
500internal_errorserviceViga meie poolel - palun proovige uuesti.

400 (vigane sisend) ja 404 (kirjet ei leitud) võivad samuti ilmneda peaaegu kõikjal, kuid nende code on väljale või lõpp-punktile omane - täpne loend on alati allpool üksiku kõne juures. Mõned toimingud võivad tagastada ka 502 (väline teenusepakkuja viga - telefonivõrk, ElevenLabs) või 503 (ajutiselt kättesaamatu, proovige varsti uuesti).

Kelle probleem see on: cause ja action

Iga viga kannab ka cause (neli väärtust) ja action (üks ingliskeelne lause selle kohta, mida teha, mida võite kasutajale sõna-sõnalt ette lugeda). cause on masinloetav vastus küsimusele, kas vea peate parandama teie kood, teie konto, aeg või meie:

PõhjusKes selle parandab
requestPäringu keha, URL, päised või tööriista argumendid - sh puuduv või vigane API-võti. Parandage sisend ja saatke uuesti; volai töötab.
accountTeie konto olek: saldo, piirangud, numbri või agendi omand, e-posti kinnitus, seadistus või kirje, mida sellel kontol ei ole. Keha oli korras; muutke konto olekut (portaalis või teise kõnega) või võtke õige id loendist ja proovige uuesti.
busyAjutine lukk või selle hetke piirang (sama kirje teine toiming veel käib, päringupiirang). Oodake mõni sekund ja saatke SAMA päring uuesti, ärge muutke midagi.
serviceMeie või meie teenusepakkuja (telefonivõrk, häälplatvorm). Teie poolel pole midagi parandada; proovige hetke pärast uuesti ja kui see jätkub, kirjutage volai toele ja lisage requestId.

AI-agentidele (Claude Code, Cursor, teie enda skriptid): tehke cause järgi kindlaks, kes viga kasutajale parandab. Väärtuse request puhul nimetage väli väärtusest message, account puhul öelge, mida kontol muuta või millist id-d kontrollida, busy puhul oodake ja korrake ning ainult service puhul rääkige probleemist volai poolel. Ärge kunagi esitage request, account ega busy volai katkestusena.

Põhjuse määrab kood, mitte HTTP-olek: konto kvoodid (agent_limit, tool_limit, api_key_limit, relay_lease_limit) tagastavad 400 ja on endiselt account; kirje not_found on account (vastus ei tohi paljastada, kas kellegi teise id on olemas), tundmatu tee /v1 all on request. Täielik koodi ja põhjuse vastavus iga toimingu jaoks on aadressil GET /openapi.json (iga veavastuse kirjeldus).

Koodi validation teade nimetab välja (punktidega tee kehas, näiteks dataFields.0.type), tegeliku väärtuse ja lubatud maksimumi, näiteks Field "knowledge" is 210000 characters long, the maximum accepted is 200000. või Field "systemPrompt" is required. Tootepiirangud (60 / 6000 / 300 / 20000 märki agendi nime, juhiste, eesmärgi ja teadmiste jaoks) tulevad oma koodidega invalid_name, invalid_system_prompt, invalid_goal, invalid_knowledge täpse arvuga. Tundmatu väli ranges kehas (agendi mustand) tagastab Unknown field "revision". Remove it; the documentation lists the accepted fields.

requestId ja docsUrl

Iga v1 vastus (õnnestunud või veaga) kannab päises X-Request-Id unikaalset päringu ID-d (req_, millele järgneb 16 kuueteistkümnendsüsteemi märki) - viga kordab seda kehas ka kui requestId. Taasesitatud idempotentne vastus saab OMA praeguse requestId - päis ja keha ei lähe kunagi lahku, kuigi ülejäänud vastus on muidu identne esimesega. Saatke see ID toele ja nad leiavad logist täpselt selle ühe päringu.

Vea kehad kannavad ka docsUrl - linki otse sellesse jaotisse tagasi.

Agendi mustandite puhul (vt allolevat jaotist Agendi mustandid) kannab viga revision_conflict ka currentRevision - praegust revisjoni. Laadige see päringuga GET .../draft ja vaadake erinevus üle enne salvestamise kordamist - ärge saatke pimesi sama keha sama expectedRevision-iga uuesti.

json
{
  "error": {
    "code": "revision_conflict",
    "cause": "request",
    "message": "The draft has changed since you last read it. Fetch the latest revision and try again.",
    "action": "Reload the record you are changing - GET /v1/agents/{id}/draft (or the get_agent_draft tool) for an agent draft, GET /v1/tasks/{id} (or the get_task tool) for a task - reapply your change on top of its current revision and send the request again with that value in expectedRevision (agent draft) or revision (task). This is not a volai outage.",
    "currentRevision": 4,
    "requestId": "req_9f2b7a1c4e6d8f0a",
    "docsUrl": "https://volai.cz/en/docs/api#errors"
  }
}

Viga subscription_confirmation_required (409) kannab ka confirmUrl - linki portaalilehele, kus kontole sisse logitud isik kinnitab muudatuse, mis suurendab salvestatud kaardilt võidavat summat (vt PATCH /v1/subscription). Päring ei muutnud midagi; link kehtib 24 tundi ja seda saab kasutada ühe korra.

json
{
  "error": {
    "code": "subscription_confirmation_required",
    "cause": "request",
    "message": "This change was not applied, because it raises what may be charged to the saved card, and only a person signed in to the portal can confirm that. Nothing was changed. Open confirmUrl in a browser signed in to the account, review the change and confirm it; the link is valid for 24 hours and can be used once.",
    "action": "Nothing was changed, on purpose: either the change raises what may be charged to the saved card, or the account is a consumer who must make the request to start the plan in person, so only that person can confirm it. Give the confirmUrl from this error to the account owner to open while signed in to the volai portal; a confirmation link is valid for 24 hours and works once, a link to the plan form stays valid. Do not send the same request again: it only produces a new link. This is not a volai outage.",
    "confirmUrl": "https://volai.cz/kredit/pausal/potvrdit?t=eyJ1aWQiOiJ1X3NhbXBsZSJ9.4f1a9c0e",
    "requestId": "req_9f2b7a1c4e6d8f0a",
    "docsUrl": "https://volai.cz/en/docs/api#errors"
  }
}

Päised

Pärast võtme kontrollimist kannab IGA vastus (õnnestunud või veaga) päiseid RateLimit-Limit, RateLimit-Remaining ja RateLimit-Reset (sekundid praeguse akna lähtestamiseni) - API-võtme piirangust tulenev 429 lisab ka Retry-After sama sekundite arvuga. Väljaminevate kõnede piirangust (POST /v1/calls) tulenev 429 rate_limited kannab päises Retry-After oma ooteaega - kui kaua kulub selle piirangu vabanemiseni, kui see on teada.

401 kannab päist WWW-Authenticate: Bearer realm="volai", error="invalid_token" (RFC 6750), nii et HTTP-kliendi teek saab aru, miks see ebaõnnestus, keha parsimata.

Tundmatu tee ja vale meetod

Tundmatu tee /v1 all (sh paljas /v1) tagastab JSON-i 404 sama vea kujuga nagu kõikjal mujal - {"error":{"code":"not_found", ...}} - igale meetodile (GET, POST, PUT, PATCH, DELETE, OPTIONS ja HEAD). Erand: vale MEETOD OLEMASOLEVAL teel (näiteks DELETE /v1/balance) jääb tavaliseks Next.js 405-ks ilma JSON-kehata - ainus koht kogu v1-s, kus ebaõnnestumisel ei ole dokumenteeritud kuju.

Idempotentsus

POST /v1/messages, POST /v1/calls, POST /v1/rings, POST /v1/voice-messages, POST /v1/relay, POST /v1/numbers, POST /v1/numbers/orders, POST /v1/sms-numbers, POST /v1/voice-sms-numbers, POST /v1/agents, POST /v1/tools, POST /v1/agents/{id}/draft/publish, POST /v1/agents/{id}/test-call, POST /v1/integrations, POST /v1/tasks, POST /v1/tasks/{id}/start, POST /v1/tasks/{id}/process, POST /v1/credit/topup, POST /v1/credit/auto-topup/setup, POST /v1/subscription/checkout, POST /v1/subscription/pay ja POST /v1/subscription/card aktsepteerivad päist Idempotency-Key. Võti on globaalne selle API-võtme piires, olenemata HTTP-meetodist, teest või kehast. Andke igale eraldiseisvale loogilisele toimingule kõigi lõpp-punktide ja päringukehade lõikes uus väärtus; kasutage väärtust uuesti ainult täpselt sama loogilise päringu kordamisel, tavaliselt pärast ajalõppu, kui te ei tea, kas esimene katse läks läbi. 24 tunni jooksul saate siis tagasi täpselt sama vastuse nagu esimesel korral, sh veavastuse, kui esimene katse ebaõnnestus, ning midagi ei saadeta ega kutsuta kaks korda. Võite kasutada oma rakenduse tellimuse ID-d pluss konkreetse toimingu nime. Samaaegne päring sama võtmega, mis alles töötab (vastust ei ole veel salvestatud), tagastab 409 idempotency_in_progress - palun proovige varsti uuesti.

POST /v1/numbers/orders puhul seotakse võti püsivalt tellimusega enne operaatori poole pöördumist; selle taaskasutamine teise aadressiga tagastab 409 idempotency_conflict. Kui operaator annab pärast ostu ebaselge vastuse, võib tellimus vajada oleku ülevaatust.

bash
curl -X POST https://volai.cz/v1/messages \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: objednavka-4471" \
  -d '{"to": "+420777123456", "body": "Aitäh teie tellimuse eest."}'

Päringupiirangud

60 päringut minutis API-võtme kohta (MCP jagab sama piirangut - see kasutab sama võtit). Ületamisel tagastatakse 429 ja päis Retry-After sekundite arvuga järgmise katseni.

POST /v1/messages kohal on oma lisalimiit: kuni üks SMS iga 2 sekundi järel ja 100 SMS-i konto kohta päevas. Mobiilinumbrilt saatmisel (fromNumber) on lisaks päevane limiit konto kohta: 20 sõnumit esimese 30 päeva jooksul pärast numbri ostmist, pärast seda 50. GET /v1/sms-numbers näitab, kui palju on järel ja millal limiit lähtestub (dailySendRemaining, dailySendResetsAt).

Väljaminevad kõned (POST /v1/calls, relay ja testkõned) jagavad oma limiiti: 10 kõnet minutis ja 1000 päevas konto kohta, kusjuures korraga võib käia kuni 2 sisseehitatud agendi kõnet.

Kui palju 60/min piirangust teil järel on, näete juba enne 429 jõudmist - päistest RateLimit-Limit, RateLimit-Remaining ja RateLimit-Reset, mida iga vastus kannab (vt ülal jaotist Vea kuju > Päised).

Lehitsemine

GET /v1/messages ja GET /v1/calls võtavad limit (tagastatavate kirjete maksimum - vaikimisi 50, piiratud 200-ga, isegi kui küsite rohkem) ja before (millisekundi ajatempel - tagastab ainult vanemad kirjed).

hasMore ja nextBefore

Mõlemad vastused kannavad ka hasMore (tõeväärtus - vanem leht on olemas) ja nextBefore (viimase tagastatud kirje ajatempel või null, kui hasMore on false). Järgmise lehe jaoks saatke eelmise vastuse nextBefore uue before-ina - ilma käsitsi nihkearvutuseta.

before on EKSKLUSIIVNE (tagastab ainult rangelt vanemad kirjed, mitte kunagi sama vanu) - eelmise lehe viimane kirje ei kordu järgmisel. Harvaesineval juhul, kui kahel kirjel on lehe piiril täpselt sama millisekundi ajatempel, võib teine välja jääda. Deduplikeerige id järgi - ärge lootke, et lehed ei jäta kunagi midagi vahele.

GET /v1/calls?direction=in või ?direction=out skannib ajalugu partiidena kindla partiide arvu ülempiiriga - hasMore: true võib seetõttu tähendada kas "kindlasti on veel üks leht" või "skannisime partiisid kuni ülempiirini ega ole ajaloo lõpuni jõudnud". false tähendab alati, et ajalugu selles suunas tõesti lõppes.

Versioonimine

Avaliku liidese praegune versioon on 1.58.0 (GET /openapi.json, väli info.version - vt sissejuhatuses ülal lõiku masinloetava API kirjelduse kohta). Versiooni muutumist reguleerib kolm reeglit:

  1. v1 piires lisatakse ainult VALIKULISI välju ja uusi lõpp-punkte - olemasolevad väljad ei kao, ei muuda tüüpi ega tähendust. Integratsiooni, mis loeb ainult talle tuntud välju, uuendus kunagi katki ei tee. Ainus erand oli versioon 1.5.1, mis lõpetas SISSETULEVATE kõnede puhul välja answeredBy tagastamise - sellel väljal ei olnud seal kunagi tähendusrikast väärtust (vt allpool Muudatuste logi).
  2. Kohustuslik väli või olemasoleva välja tähenduse muutus tuleb ainult uue põhiversiooniga (v2) - mitte kunagi vaikse muudatusena v1-s.
  3. Agendi mustandite puhul (vt ülal Agendi mustandid) saatke alati tagasi täpselt see objekt, mille lugesite päringuga GET .../draft - PUT/POST keha on .strict(), seega tundmatu võti (näiteks uuemast versioonist, mida teie integratsioon veel ei tunne) tagastab 400 validation ega kao vaikselt.

Muudatuste logi

  • 5 Nov 2026 (1.58.0): The new POST /v1/voice-sms-numbers/countries/{country}/waitlist (no body) and the MCP tool join_voice_sms_country_waitlist sign the account up for the waitlist of a country that is not in the offer; the response is {country, joined: true, alreadyJoined} and nothing is charged. A country in the offer or outside the map returns validation. GET /v1/voice-sms-numbers/countries and MCP list_voice_sms_countries have a new waitlisted field (ISO codes of the countries the account signed up for). Ordering a number does not change.
  • 5 Nov 2026 (1.57.0): The agent language accepts 20 values: cs, sk, en, de, pl, nl, pt, sl, ro, da, et, lv, bg, fi, el, fr, it, hu, lt, sv. A number in another country can be routed to an ElevenLabs agent; the error el_outbound_trunk_not_configured (HTTP 503, cause service) means our outbound trunk is missing. REST and MCP messages stay in English.
  • 4 Nov 2026 (1.56.0): GET /v1/voice-sms-numbers/countries and the MCP tool list_voice_sms_countries return monthlyFeeHal for every country (hellers per 30 days excluding VAT). POST /v1/voice-sms-numbers with country orders the number at that country's fee from the offer; no fee confirmation is added. The MCP tool order_voice_sms_number requires confirmedMonthlyFeeHal equal to the fee of the chosen country; any other value is a validation error and nothing is ordered, while the Prague number still confirms 4900. A number record carries the monthlyFeeHal of its country and the same amount is charged by the first fee and every renewal. A country without a set fee does not appear in the offer.
  • 4 Nov 2026 (1.55.0): POST /v1/voice-sms-numbers accepts an optional country (ISO 3166-1 alpha-2, uppercase); without it the Prague number is ordered as before. The countries the account may order are returned by GET /v1/voice-sms-numbers/countries and the MCP tool list_voice_sms_countries; a country outside that list is rejected with country_not_offered and nothing is charged. Number records carry country and sms, and a number outside Czechia rejects sending SMS. Outbound calls go only to Czechia, and to the country of the number only where the country_and_cz zone is enabled; the gate rejects any other destination. At most 2 numbers per country.
  • 4 Nov 2026 (1.54.0): regions in GET /v1/numbers/available, the region parameter of POST /v1/numbers and the search_available_numbers and buy_number tools now know jihocesky, karlovarsky, kralovehradecky, liberecky, moravskoslezsky, olomoucky, pardubicky, plzensky, stredocesky, ustecky, vysocina, zlinsky. Regional stock is small, so pool_empty is more common there: use join_number_waitlist or order_number_from_region.
  • 4 Nov 2026 (1.53.0): The offer catalogue now knows all 14 regions. A regional offer (jihocesky, karlovarsky, kralovehradecky, liberecky, moravskoslezsky, olomoucky, pardubicky, plzensky, stredocesky, ustecky, vysocina, zlinsky) appears in regions of GET /v1/numbers/available and in the MCP descriptions only once it is on sale; until then it is rejected as an unknown region. The regionLabel text changes: a number from a region carries the English region name, such as Moravian-Silesian Region.
  • 4 Nov 2026 (1.52.1): A header value with three asterisks in a row (a leftover of the mask, such as Bear***abc) is rejected by PUT /v1/webhook and set_webhook with invalid_webhook_headers; previously only the whole mask was. The descriptions of get_webhook, send_test_webhook and the MCP server instructions mention headers, and the docs now say the test event carries custom headers. Value limits (1 to 1000 printable ASCII characters) added to OpenAPI and the webhooks page.
  • 3 Nov 2026 (1.52.0): PUT /v1/webhook and MCP set_webhook accept optional headers (at most 5 headers, values up to 1000 characters, printable ASCII only). GET/PUT /v1/webhook and get_webhook/set_webhook return a new headers field with masked values (Bear***, {} when none are set). Omitting headers keeps the stored ones, {} removes them, and a value equal to the mask keeps the stored one. Changing the URL to a different domain drops stored headers, and a mask is rejected there. host, content-type, content-length, volai-signature and hop-by-hop headers cannot be set. Headers go with every event including webhook.test and are not sent when a delivery is redirected to a different domain. New error invalid_webhook_headers (400).
  • 3 Nov 2026 (1.51.0): REST POST /v1/voice-messages with the body {to, text, repeat?} (text 1 to 500 characters, repeat 1 to 3, default 1; an unknown field including ringingTimeoutSecs is rejected with validation) returns {id, status, from} and accepts an Idempotency-Key header like POST /v1/calls. The MCP tool send_voice_message calls the same service. The result is in GET /v1/calls/{id} as kind: "voice_message" with a voiceMessage block (text, repeat, repeatPlayed, completed) and in the call.completed or call.no_answer webhook; the call summary e-mail is not sent for a voice message. New errors voice_messages_disabled (503, the feature is switched off), voice_message_unavailable (503, the voice engine cannot accept messages) and email_unverified (403).
  • 1 Nov 2026 (1.50.0): REST GET, PUT and DELETE /v1/account/spend-cap (response {spendCap: {enabled, capHal, warnShare, inboundAboveCap, month, monthSpendHal, remainingHal, reached, updatedAt}}; PUT takes capHal in whole hellers excluding VAT from 5,000 to 100,000,000, warnShare from 0.5 to 0.99 with a default of 0.8, and inboundAboveCap, which is not overwritten on a change when the field is omitted) and MCP get_spend_cap, set_spend_cap and clear_spend_cap, all over lib/service/spend-cap.ts like the Monthly spending cap section under Credit. Once the cap is reached, POST /v1/calls, /v1/messages, /v1/rings, /v1/relay, the test call and task dialling are refused with the new error spend_cap_reached (HTTP 402, nothing is charged); an inbound agent call without inboundAboveCap: true ends after one sentence and the call carries endReason: spend_cap. The month's spend (Europe/Prague) is counted on every account, also without a cap, and includes the part covered by the monthly plan credit. Number fees, the Done for you round and the monthly plan are not counted; the cap does not stop calls already running or CDRs booked after midnight, forwarding without an agent, or outbound calls from a number in Own SIP PBX mode with inboundAboveCap: true. Warning and reached e-mails go at most once a month and are released again when the cap changes. REST POST /v1/agents/{id}/draft/knowledge-import with a body of {url} or {text, filename} (a .txt or .md file up to 1 MB; the portal takes a file up to 800 kB), optionally mode (append by default, or replace), preview (only returns the result, writes nothing) and expectedRevision. The MCP tool import_agent_knowledge (id, url or text + filename, the same optional fields) calls the same service, lib/service/knowledge-import.ts. The text is written into knowledge of the DRAFT and the source into the new knowledgeSources field (at most 20 sources: url or filename, importedAt, chars), which the agent shape now also returns (GET /v1/agents/{id}, list and detail). What does not fit into 20,000 characters is summarized by a model (method: summarized) or cut (truncated). Errors: invalid_import_url, private_address, invalid_knowledge, import_too_large, revision_conflict, rate_limited (10 imports per hour per account). A fetched page is third-party text: the preview and the misuse check when the draft is saved guard against it, and REST saves it right away without preview. REST POST /v1/account/cancellation-request with a body of {reason, note?} (reason is one of too_expensive, callers_hang_up, missing_feature, not_needed, other; note at most 500 characters) and the MCP tool request_account_cancellation call lib/service/account-cancellation.ts, the same service as the form in Settings. Response {cancellationRequest: {reason, note, requestedAt, alreadyRequested}}; a repeated request returns the original record with alreadyRequested: true (HTTP 200) and sends no further e-mail. There is at most one request per account, it changes the account in no way and deletes nothing; the volai owner gets an alert with the reason and the customer a confirmation in the account language. Errors: validation, user_not_found. When you click thumbs down in the call e-mail, the rating is saved right away and on the page that opens you can pick a reason and add a note in a single form. Before, there were only five separate buttons and no note. When you write to podpora@volai.cz, you get an automatic confirmation that the message arrived, saying that we usually reply within one business day, with a link to the status page. At volai.cz/en/trust (in Czech volai.cz/duvera) you find in one place where the data of calls, SMS and your account lies, who touches it, how long we keep it, how we protect it and what we cannot do yet. The website gains a Call from your browser button that lets you try the volai demo agent with a call right from your browser, without signing up. The call is a demo, it is recorded and the agent speaks Czech. We are switching it on gradually, so it may appear only after a while. public/llms.txt, public/SKILL.md, /docs/api and /docs/mcp (cs and en) match the code: create_calendar_event creates an appointment only with confirm: true and the calendar deletes nothing; the number for calls and SMS is in pilot mode (voiceSmsNumbersMode() is admin), other accounts get voice_sms_numbers_unavailable (until 3 Nov 2026; since then the mode is on and any account orders the number itself). The trial call's remainingLine states that an unanswered call also counts towards the limit of 3 calls per 24 hours.
  • 1 Nov 2026 (1.49.1): CAMPAIGN_QUOTA_EXPIRES_AT in lib/service/call-quotas.ts is 2026-11-15T23:00:00+01:00 (22:00 UTC; previously 2026-11-14T23:00:00+01:00) and PETCENTER_REMINDER_DISPATCH_END stays 2026-11-21T19:55:00+01:00 (18:55 UTC). petcenterCampaignQuotaActive() and the runPetcenterOutboundTaskTick tick therefore dial the main campaign until 15 November 22:00 UTC and coupon_reminder tasks still until 21 November 18:55 UTC. The stored quota of the campaign agent (call-quota:agent) has its own validUntil, which is moved separately via PUT /api/admin/call-quotas from 2026-11-14T22:00:00Z to 2026-11-15T22:00:00Z. The other conditions of the exception (the VOLAI_PETCENTER_CALL_QUOTA_ENABLED switch, account, agent, outbound task, eight relay names) are unchanged.
  • 30 Oct 2026 (1.49.0): POST /v1/tools, PATCH /v1/tools/{id} and MCP create_tool and update_tool accept an optional requireConfirmation field (boolean, default false; any other type is 400 validation). Responses that carry a tool (GET /v1/tools, GET /v1/tools/{id}, POST, PATCH, MCP list_tools) always return it as a boolean; POST /v1/tools/test does not have it. A PATCH without the field keeps the stored value (neither an older client nor a stale portal page switches the gate off), false switches it off. The engine receives require_confirmation: true only for a tool with the gate on and only for an agent on the engine in cs or sk; false is never sent explicitly. An agent in en, de or pl and an ElevenLabs agent ignore the field, and saving the tool is not refused because of language, since a tool belongs to the account and is shared by several agents. Editing a tool does not rewrite agents on the engine: the flag reaches them at the agent's next save (PATCH /v1/agents/{id}) or publish (POST /v1/agents/{id}/draft/publish). With a running campaign, re-publishing an unchanged tested draft keeps the tested mark and the task carries on, now with a gate the test did not cover; a direct PATCH /v1/agents/{id} clears the mark and the task stops with agent_version_changed. A PATCH that changes only requireConfirmation does not call ElevenLabs and does not re-verify the tool address (no DNS lookup), so the gate can be switched even while the tool's domain is unreachable. The gate reads only the caller's last utterance and does not know the agent's question: it catches an unclear consent, not every “yes” given to a different question. Portal: the tool editor (/en/agent/tools/new and /en/agent/tools/[id]) stores the choice in the same field with the switch Require the caller's clear consent; a hidden form flag distinguishes an unchecked switch from a form that did not know the switch, so a stale page cannot silently switch the gate off, and after saving a changed gate the form says that for a running agent it takes effect only after that agent is published. The method, the parameter type and source are submitted from form state and the description is a controlled field, because React 19 resets the form after every form action and the second save after an error used to send the first option of a select and the old description. GET /v1/subscription and MCP get_subscription: available says whether a NEW plan can be started right now, and it is true only when the offer is on for the account and the account has no running plan (active, past_due); otherwise it is false. It used to be true for a subscriber too, although POST /v1/subscription/checkout returned 409 subscription_exists. It is true again once the plan has ended (canceled). A client that used available to tell whether the account has a plan should read subscription instead. recommendation does not depend on available and a subscriber still receives it. PATCH /v1/subscription and MCP update_subscription: a tier the account is already switching to (nextTier) counts as done (200, not 400 invalid_tier), so the same body can be sent again after an outage in the middle and finishes what is left. Exceptions: the current tier with no scheduled change stays invalid_tier; going back to the current tier (it cancels the scheduled change) does not count as done on a repeat and ends with invalid_tier; on a plan set to end a tier alone still returns invalid_state (with cancelAtPeriodEnd: true in the body it is a repeat and goes through). invalid_state is now also listed among the errors of PATCH /v1/subscription in OpenAPI and in the documentation. GET /v1/balance and MCP get_balance: the notices subscription_exhausted_topup, subscription_cap_reached and subscription_runway carry a new optional field cancelAtPeriodEnd: true (present only when true: the plan does not renew, renewsAt is the end of the plan and no new monthly credit arrives). The format of renewsAt (epoch ms) does not change and is documented as the same moment as subscription.periodEnd (ISO 8601). The e-mails about a failed renewal and about the end of a plan have their own wording when the account has no saved card (the card is missing, nothing was charged). An outbound agent call on the engine that stayed ringing or initiated without a conversationId and was closed as failed with price 0 by the watchdog (or by the task reconcile) after two hours now behaves in a task like relay_not_routed: the attempt has items[].attempts[].countsAsAttempt: false and errorCode: "no_provider_report", uses up neither maxAttempts nor the lorela_enterprise schedule, the budget reservation is released, nothing is charged, and the contact gets nextAttemptAt no sooner than 60 seconds later. relay_not_routed and no_provider_report attempts are added together in one series: after the third uncounted attempt in a row the contact goes to review with the reviewReason of the last one, that is call:no_provider_report; earlier only when the next attempt does not fit before expiresAt or the lorela_enterprise policy allows no further attempt. A call that a late post-call completed with a conversationId was seen by the engine, so it counts as before. Items that an earlier call of this kind had already sent to review (call:failed, or call:unknown with the policy) are not reopened automatically. errorCode and reviewReason are free strings, only a new value was added; an integration that reads reports from tasks should expect one more uncounted attempt and one more review reason. A pause (POST .../pause, the batch pause for a campaign) between the dial intent being written and the provider request used to leave reviewReason: "dispatch_in_flight", the active claim, the reservation and an in_progress item with no call and no attempt; start then returned task_needs_attention, resolve returned item_not_resolvable, DELETE returned task_not_deletable and reconcile changed nothing. After such a pause the task processing now releases the intent, the claim and the reservation itself and returns task_paused (no call was placed): the contact is pending again (or failed with a free attempt) and the task is paused without a reviewReason, so the first start succeeds. The cleanup is retried up to three times on a concurrent write (revision_conflict), as is the cleanup at the last gate before the provider, whose result used to be discarded. reconcile (the cron, POST /v1/tasks/{id}/reconcile, MCP reconcile_task) additionally releases an intent that has no call record and no attempt result and whose claim and five-minute margin after it have both expired, that is at the earliest 15 minutes after the dial began (the claim lives for 10 minutes): it returns the reservation and puts the contact back to waiting, or completes it after a verified callback. A task that the expired claim had meanwhile stopped (dispatch_claim_expired) ends paused without a reason and has to be started again (start); a task the claim did not stop keeps running. An uncertain dial and a call that may have been created are left as they are. Tasks that got stuck earlier are repaired by a single reconcile and end as paused without a reason (the pause was intentional), they do not restart on their own. Response shapes do not change. POST /v1/dnc and MCP add_to_dnc accept either e164 (one number, the response { "added": true, "e164": ... } is unchanged) or the new field e164s (1 to 500 numbers, written with a single SADD command). Both fields together, neither, an empty array and more than 500 entries are 400 validation; in OpenAPI both fields are optional and the rule "exactly one of them" is enforced by validation only. An entry of e164s must be a string of at most 256 characters, any other entry fails the whole request with 400. The response to e164s carries addedCount, alreadyOnListCount, rejectedCount and rejected (entries { index, input, reason: "invalid_number" }, where input is the entry as sent, cut to 32 characters). addedCount + alreadyOnListCount + rejectedCount always equals the number of entries sent; a number repeated in the request or written in another format counts as already on the list. An entry that is not a valid number (including longer text, for example two numbers in one cell) does not fail the request, the valid entries are always added, and an input of only invalid entries is still 200, so check rejectedCount after every response. The request is idempotent (repeating it returns addedCount: 0). In OpenAPI the response of POST /v1/dnc is an anyOf of both shapes and the boolean added stays only in the single-number response. Numbers are still removed one at a time (DELETE /v1/dnc/{e164}). The destination check at dial time reads one SISMEMBER instead of the whole set, so a list with thousands of numbers no longer transfers tens of kB on every dial; the listings GET /v1/dnc and list_dnc are unchanged. REST POST /v1/tasks/{id}/items/{itemId}/resolve and MCP resolve_task_item accept reason with the value customer_purchased or, new, unsubscribed on the audited skip (action: "skip" with operationId and evidenceRef). evidenceRef is an opaque reference to the purchase or unsubscribe record, never a phone number or e-mail. Conditions are unchanged: a draft task (contact pending) or a paused task (contact pending or failed), no active claim, dial intent or reservation, and the skip does not resolve contacts in review. Attempts, costs and the do-not-call list stay as they are. The reason is part of the fingerprint (resolution.fingerprint), so repeating the same operation writes nothing and the same operationId with a different reason or evidenceRef returns 409 revision_conflict. items[].resolution.reason in every response that carries a task (GET /v1/tasks, GET /v1/tasks/{id}, POST .../resolve, MCP list_tasks, get_task, resolve_task_item) is now the enum customer_purchased | unsubscribed (a constant in OpenAPI before): a client that validates responses against the old specification must allow unsubscribed. An unknown reason in the request returns 400 validation. Descriptions in OpenAPI, MCP and the API, MCP and Tasks documentation are updated.
  • 26 Oct 2026 (1.48.0): REST: GET /v1/voice-sms-numbers, POST /v1/voice-sms-numbers (no body, Idempotency-Key supported, returns 202 with the number in the awaiting_registration state), GET /v1/voice-sms-numbers/{e164}, PATCH /v1/voice-sms-numbers/{e164} (routing: agent on the in-house engine, or none), POST /v1/voice-sms-numbers/{e164}/cancel (cancelling before the registration is approved is free) and DELETE /v1/voice-sms-numbers/{e164} (releasing an active number is irreversible and the period already paid is not refunded; when the cancellation with the carrier fails, the number stays in the releasing state and the response is 502 release_failed). MCP: list_voice_sms_numbers, order_voice_sms_number (confirmedMonthlyFeeHal must be 39000, otherwise nothing is ordered), set_voice_sms_number_routing and cancel_voice_sms_number; releasing is deliberately not available over MCP. Number states: awaiting_registration, active, rejected, releasing. SMS from the number are sent with fromNumber in POST /v1/messages and send_sms (+420 recipients only, no deliveryStatus), received SMS are still read with GET /v1/messages?direction=in and the message.received webhook; calls from the number are placed by an agent (POST /v1/calls with agentId, to +420 only, one outbound call at a time); a bridge between two numbers with from and a ring from it are not available (unsupported_for_number_type). New error codes: voice_sms_numbers_unavailable, voice_sms_number_limit (at most 2 numbers per account, ordering needs a first top-up), voice_sms_order_limit, voice_sms_number_out_of_stock, unsupported_for_number_type (forward and sip are not supported for this number) and destination_not_allowed (the number can call +420 numbers only). The fee of 390 CZK per 30 days is charged as number_fee; the number_fee notice in GET /v1/balance and MCP get_balance counts these numbers too, and a debt older than 7 days releases the number just like other numbers.
  • 26 Oct 2026 (1.47.0): GET /v1/account and MCP get_account return a new testCalls field next to account, with max (3), remaining (test calls left in the current window) and resetAt (when the window ends, epoch ms; the window runs 24 hours from the first attempt; null when there was no attempt in the last 24 hours). POST /v1/agents/{id}/test-call and MCP test_call carry the same field right after dialing. Every dialed attempt counts, including an unanswered one, which is not charged; an attempt that never dialed (agent, credit or capacity error) does not count. The field is additive, existing response shapes do not change. PATCH /v1/account does not return it.
  • 23 Oct 2026 (1.46.1): POST /v1/tasks/{id}/reconcile, MCP reconcile_task and the task cron settle a task after recovery by the work that is left: paused while any contact is waiting for another attempt (pending, failed, in_progress), even if other contacts are in review; needs_attention only when nothing is left to dial but a contact in review (the task's reviewReason is the reason of the first such item); completed when nothing is left. reviewReason is set only for needs_attention and empty otherwise; after a pause in the middle of a dial and after an expired claim activeItemId, activeClaimToken and activeClaimUntil are released as well. It applies to four recoveries: after a pause in the middle of a dial (dispatch_in_flight), after an expired claim (dispatch_claim_expired), after a call with a previously unknown price is settled (billing_unknown) and after an uncertain dial is resolved (dial:*). Before, recovery put review before work, so pausing a running task sent a task with hundreds of waiting contacts to needs_attention, which start and PATCH (task_not_editable) refused. An uncertain dial for which no call can be found keeps the task in needs_attention (the contact holds an unresolved dial intent and start would refuse it) until POST .../items/{itemId}/resolve decides that contact; the same applies after a call with an unknown price is settled (billing_unknown) while another contact holds an unresolved dial intent. A running task and task-level reasons (for example variables_limit) are not changed by reconcile. With the retryPolicy: "lorela_enterprise" policy the state of a contact after the last allowed attempt (maxAttempts) changes too: a no_answer, missed, busy, completed voicemail without a human or an answered call in which the person said nothing closes it as skipped with reviewReason: "retry_policy_exhausted", like retry_age_expired when the horizon runs out (before: review); the link to the last call (providerCallId) stays. An uncertain result of the last attempt stays in review with the same reason, and the policy still rejects a manual resolve with retry. A verified human callback after this closing turns the contact into completed (after retry_age_expired and task_expired it stays skipped with callbackContactCallId). Tasks without the policy do not change. POST .../items/{itemId}/resolve does not change: the last resolved item in review turns a task with work left into paused. Tasks that got stuck in needs_attention before the rollout do not repair themselves (their reason is derived from an item): resolve with skip over the items in review frees them once.
  • 23 Oct 2026 (1.46.0): POST /v1/tasks, PATCH /v1/tasks/{id}, MCP create_task and update_task accept optional retryMaxAgeDays: a whole number 1 to 30, the retry horizon of the retryPolicy: "lorela_enterprise" policy in days from the recipient's first counted attempt. The public task (GET /v1/tasks, GET /v1/tasks/{id}, the create and PATCH responses, MCP get_task and list_tasks) returns it only when it was set; an absent field means the default 5 days as before, so tasks without the field behave unchanged. The field needs the policy (in the same body at creation, in the body or already stored on the task on PATCH), otherwise validation is returned with the field retryMaxAgeDays; so is a value outside 1 to 30 or a non-integer. Omitting it on PATCH preserves the value. Unlike retryPolicy, it can be changed after attempts have started, in the states PATCH has always accepted (running and completed still not: task_not_editable). Raising the value on a paused task returns items that are skipped with reviewReason: "retry_age_expired" to pending with a new nextAttemptAt when they have a counted attempt, a free attempt below maxAttempts, no verified callback and their first counted attempt + the new horizon (and expiresAt, when set) is in the future; lowering it reopens nothing and contacts outside the new horizon stay skipped. The attempt ladder (8 minutes after the first, the 08:00-09:00 and 17:00-19:00 windows, four attempts) does not change, only the horizon does. Portal: the task detail of a task with the policy shows a line about the retry schedule and horizon, the calling rules have a Retry horizon (days) field and offer four attempts for a task with the policy. OpenAPI, the MCP tool descriptions, SKILL.md and the Tasks guide are updated.
  • 23 Oct 2026 (1.45.1): CAMPAIGN_QUOTA_EXPIRES_AT in lib/service/call-quotas.ts is 2026-11-14T23:00:00+01:00 (22:00 UTC; previously 2026-10-31T23:00:00Z) and PETCENTER_REMINDER_DISPATCH_END is 2026-11-21T19:55:00+01:00 (18:55 UTC; previously 5 November). petcenterCampaignQuotaActive() and the runPetcenterOutboundTaskTick tick therefore dial the main campaign until 14 November 22:00 UTC and coupon_reminder tasks until 21 November 18:55 UTC. The stored quota of the campaign agent (call-quota:agent) has its own validUntil and is moved separately via PUT /api/admin/call-quotas. The other conditions of the exception (the VOLAI_PETCENTER_CALL_QUOTA_ENABLED switch, account, agent, outbound task, eight relay names) are unchanged.
  • 23 Oct 2026 (1.45.0): The number's relay names are set up in the background right after purchase (POST /v1/numbers, buy_number, portal) and after an order is fulfilled (POST /v1/numbers/orders, order_number_from_region), whatever the number's routing. A lease (POST /v1/relay, create_relay_lease), an agent call or a transfer from a number that does not have them yet triggers the setup again. The create_relay_lease description spells out a rule that already applied: a lease connects exactly one call, dialing the same sipName again is rejected with SIP 603, so create a new lease before every attempt and turn off automatic redialing in your platform. Response shapes are unchanged.
  • 22 Oct 2026 (1.43.0): New agent field recordingNotice (boolean) in POST/PATCH /v1/agents, MCP create_agent/update_agent and agent drafts (PUT /v1/agents/{id}/draft, save_agent_draft). The response always carries it (false when unset). The sentence is appended only with recordingNotice: true and recordCalls on; in a draft an absent key means unchanged. The greeting length estimate (first_message_too_long) counts the sentence only when it is on. This changes what recordCalls implies: recording alone no longer adds the sentence. It was removed on 22 Oct 2026 from existing agents that had it added automatically; a sentence written into firstMessage itself stays as it is.
  • 22 Oct 2026 (1.42.3): An attempt's reservation (reservedBudgetHal, the item's estimatedCostHal) is the call leg plus the agent leg, each rounded up to a heller exactly as billing does (previously a single rounding of the combined rate, which came out one heller lower for some caps). A call with a duration cap (outbound task) is billed for min(durationSecs, maxDurationSecs); the stored durationSecs stays as measured. A transferred leg of such a call gets at most the remainder up to the attempt's highest price. An agent with recordCalls: false on volai's engine (provider: "engine") has no recording: hasRecording is false and GET /v1/calls/{id}/recording returns no_recording. Saving such an agent requires an engine that knows the flag; otherwise the engine write fails instead of recording silently.
  • 21 Oct 2026 (1.42.2): checkCallRateLimit (POST /v1/calls, MCP make_call, outbound tasks) counts the attempts per 24 hours of a call covered by an agent's stored quota (call-quota:agent:{agentId}) or by the PetCenter campaign exception with a daily limit above 1,000 in its own counter ratelimit:callsday-agent:{userId}:{agentId} and compares them with the quota's daily limit. Calls with the default limits, calls without an agent (the website test call, bridge, relay) and calls with a quota that does not raise the daily limit (1,000 or less) still share the account counter ratelimit:callsday:{userId}; a call of the same agent outside the quota's scope (outboundTaskOnly, taskPurposes, after validUntil) follows the campaign exception when it applies, and otherwise uses the default limit of 1,000 and the account counter. The concurrency slots agentcallslot:{userId} (relay_lease_limit) and the per-minute counter ratelimit:calls:{userId} stay shared per account. The code rate_limited, HTTP status 429, the message texts and the default limits of 2 concurrent, 10 per minute and 1,000 per 24 hours do not change; only an admin stores a quota. resolveAgentCallLimitsWithSource in lib/service/call-quotas.ts returns the source of the limits (stored, campaign, default) next to them from a single quota read, and usesAgentDailyCounter picks the counter from them.
  • 18 Oct 2026 (1.42.1): An inbound call that the voice engine turned away because the cap on concurrent calls was used up now has status: "missed", endReason: "capacity", durationSecs: 0 and priceHal: 0 in REST (GET /v1/calls, GET /v1/calls/{id}) and MCP (list_calls, get_call); no credit is charged. The call.missed webhook is sent once per call, and an SMS to the caller only for an agent with missedCallSms turned on (as for every missed inbound call); no summary e-mail is sent for it. When the carrier reported the unanswered call first, call.missed is sent at that moment (possibly without endReason) and the existing record is then completed with endReason: "capacity"; no second record and no second webhook are created. Until now such a call stayed in status: "in_progress" forever, because the engine sends no post-call for it. The record is now created by the reconciliation of engine calls, within a few minutes of the rejection. Existing stuck records from the last seven days that are older than two hours are closed retroactively by the hourly check, only with evidence from the engine's call log and without a webhook; if the carrier created its own record for them, they are merged into it. The values missed and capacity already existed in the enumerations, and the response shapes do not change. In the outcome filter (GET /v1/calls, list_calls) such a call counts as no_answer; for an outbound call nothing changes about capacity (relay pool full).
  • 18 Oct 2026 (1.42.0): GET /v1/subscription and MCP get_subscription: recommendation has a new field steady, whether the spend is not just a one-off peak: usage over the last 14 Prague days scaled to 30 days, plus the monthly number fees of the 30-day window counted once, reaches at least the price of the recommended tier. The portal offers the plan personally and the MCP sentence suggests it only when worthIt and steady are both true; worthIt and the other fields do not change. The recommendation comes from one function for the portal, REST and MCP; for REST and MCP it is cached next to the credit runway (10 minutes, cleared by every credit movement). Nothing else in the API changes.
  • 18 Oct 2026 (1.41.0): GET /v1/subscription and MCP get_subscription: new field previousPeriod, a summary of the paid period before the current one (subscription.periodStart) with the same figures as the renewal e-mail: tier, periodStart and periodEnd (ISO 8601), creditHal, usedHal, usedPercent (rounded down), overHal (spending beyond the monthly credit; with top-ups without debt that the next credit paid off, with the cap including debt; null when the credit history cannot prove it), expiredHal, exhaustionMode and exhaustedAt (ISO 8601, null when the credit did not run out or the history cannot show when). It is saved at every renewal, by card (also when the payment_intent.succeeded webhook completes it) or by a manual payment, and kept for 45 days; it is returned only while the plan is active, whatever available says, and is null without a plan, with status past_due or canceled, in the first period and when the usage cannot be proven. MCP get_subscription also adds a sentence about the last period with Prague dates. GET /v1/balance and MCP get_balance: on an active plan the notice {kind:"subscription_runway",renewsAt,runsOutAt} now computes runsOutAt from the plan's cautious pace, the same as the outlook on the plan card in the portal: the highest of the 28-day average (with a complete credit history), the average usage over the last 7 Prague days without number fees and the average since the current period started (after its first week), instead of the 28-day average. The shape and conditions of the notice do not change (nothing while auto top-up is on) and runway.dailyAverageHal and runway.runwayDays stay the 28-day average. The renewal e-mail for a renewal that the webhook completes now also leaves out the advice when a tier change is scheduled. Nothing else in the API changes.
  • 18 Oct 2026 (1.40.1): POST /v1/outbound/dispatch-scopes/petcenter/registrations decoded the result of its Lua script with JSON.parse even when the default Upstash client (redis() with automatic deserialization; only redisRaw() has none) already returns it as an object. Every request therefore ended with the exception SyntaxError: "[object Object]" is not valid JSON and a 500 response. The exception happened after the script had run and before the result was mapped, so a newly stored registration (or a replay of the same operation) showed up as a 500 to the client, and a Lua refusal never reached it as 409 revision_conflict (operation_conflict, manifest_cas_conflict, task_changed_during_registration with error.details), 404 not_found or 400 validation. registerPetcenterDispatchScope now decodes the result with the helper decodeLuaJsonObject: JSON.parse only over a real string, and an object passes unchanged. A script reply that is not an object (valid JSON of another shape, or text that is not JSON) throws and the route answers 500, because the script may already have written the change and the outcome is uncertain; the client then asks for the operation result with GET /v1/outbound/dispatch-scopes/petcenter/registrations?operationId=.... An empty result still ends in registration_failed. The batch pause decodes its results with the same helper and its behavior and error message do not change. The contract does not change: request and response shapes, idempotency by operationId (replayed: true on a repeat), expectedManifestSha, the status codes and the providerActionStarted flag. The only client-visible difference is that the former 500 responses are now 200, 409, 404 or 400 according to the script result; 500 remains only for an unexpected shape of its reply.
  • 18 Oct 2026 (1.40.0): GET /v1/subscription and MCP get_subscription: new field recommendation, or null (no plan offer for the account, or less than 30 Prague days of credit history). It holds spendHal (spend over the last 30 Prague days on calls, the agent, numbers and SMS, minus SMS refunds), days (30), cheapestPath (per_second or plan), tier and tierTotalHal (the cheapest tier with top-ups and its cost at that spend), savingsHal, worthIt (a saving of at least 50 CZK and 5%, the same threshold as the portal) and options (every way to pay for the same spend: {path, tier, totalHal} for paying by the second and for each tier). For a subscriber MCP get_subscription also adds a sentence with advice under the same rule as the portal and the e-mail. Nothing else in the API changes.
  • 18 Oct 2026 (1.39.1): PUT /api/admin/call-quotas loads the agent (getAgent) and refuses the write when the agent does not exist or is deleted (404 agent_not_found), or when userId in the body is not the agent's owner (400 validation, the message does not reveal the real owner). A refused write stores nothing in call-quota:agent:{agentId}, in the index call-quota:index or in user:{userId}:admin-log. userId stays required in the body so the stored shape from GET can be sent back. The relay_lease_limit message when placing an agent call (POST /v1/calls, MCP make_call, outbound tasks) now reads This agent can have at most 3 running calls at once, and that many are already running on your account. Try again in a moment. (Czech: Tento agent může mít najednou nejvýš 3 běžící hovory a tolik jich teď na tvém účtu už běží. Zkus to za chvíli znovu.; the Czech noun and adjective agree with the count: 1 reads běžící hovor, 2 to 4 běžící hovory, 5 or more běžících hovorů). The number is the threshold of the calling agent from resolveAgentCallLimits (a stored quota, otherwise the default 2, after the pool clamp); the running calls come from the account-wide counter agentcallslot:{userId}, so a slot may be held by another agent of the same account. Before, the message said the maximum was per account although the agent decides the threshold, and the Czech text used the same plural form for every count. The code relay_lease_limit, the HTTP status 400, the counter, the threshold and the way outbound tasks wait on this code do not change. The history table heading on the customer detail page in the admin is now Admin action history (Historie admin akcí), the rows do not change.
  • 18 Oct 2026 (1.39.0): New admin endpoint GET/PUT/DELETE /api/admin/call-quotas (admin session, not an API key; writes check the Origin) stores an agent's quota in call-quota:agent:{agentId}: concurrent 1 to 30, perMinute 1 to 60, daily 1 to 20,000, a mandatory note, outboundTaskOnly and the optional taskPurposes (standard, coupon_reminder) and validUntil (milliseconds since the epoch). Every change is written to user:{userId}:admin-log as call_quota_set or call_quota_deleted. resolveAgentCallLimits in lib/service/call-quotas.ts applies it ahead of the PetCenter exception and the default { concurrent: 2, daily: 1000, perMinute: 10 }, only for the same account, an outbound task (when outboundTaskOnly is set), an allowed purpose and a time before validUntil. Concurrency is clamped to min(stored, max(2, number of distinct names in ODORIK_RELAY_NAMES - 2)), the per-minute and daily limits are not. Without a stored quota behaviour is unchanged. Placing a call on a relay name waits for its turn (one shared pointer in Redis, spacing RELAY_PLACEMENT_GAP_MS 3 s, at most RELAY_PLACEMENT_MAX_WAIT_MS 10 s; on a Redis outage the call is placed at once and relay placement spacing unavailable is logged): agent calls (POST /v1/calls, MCP, tasks) and trial calls on the engine and on ElevenLabs, the transfer bridge claim for at most 4 s; not the BYO relay lease (POST /v1/relay) and not callback calls without a relay name. POST /v1/calls and a trial call can therefore take up to 10 s longer during a burst of calls; maxDuration is 100 s for POST /v1/calls and 70 s for POST /v1/agents/{id}/test-call. The outbound task tick starts no further task after TICK_DISPATCH_BUDGET_MS (90 s), the rest waits for the next run. An engine rejection because of the concurrent-call cap carries Retry-After: 30, which volai already forwards (retryAfterSecs, the Retry-After header, items[].nextAttemptAt): once the engine with this cap is deployed, contacts wait 30 s instead of 5 minutes; an engine without the header still means 300 s.
  • 18 Oct 2026 (1.38.3): No change in API behaviour. The plan offer is on for every account (PAUSAL_MODE=on), so GET /v1/subscription returns available: true; pausal_unavailable (404) remains for when the offer is switched off. The documentation (/en/docs/credit, SKILL.md, llms.txt) no longer says the plan is limited to some accounts and describes renewals as hourly.
  • 18 Oct 2026 (1.38.2): agentCallLimits in lib/service/call-quotas.ts keeps returning { concurrent: 6, daily: 6000, perMinute: 15 } after CAMPAIGN_QUOTA_EXPIRES_AT (2026-10-31T23:00:00Z) when the quota context carries the new optional taskPurpose: "coupon_reminder" and petcenterReminderQuotaActive() holds, that is, the VOLAI_PETCENTER_CALL_QUOTA_ENABLED switch is on and the time is before PETCENTER_REMINDER_DISPATCH_END (2026-11-05T19:55:00+01:00, 18:55 UTC; the constant moved into call-quotas.ts and the dispatch tick reads it from there). makeAgentCall passes the purpose to the quota only after it has verified the link to an approved reminder. A call without a purpose gets the default { concurrent: 2, daily: 1000, perMinute: 10 } after 31 October. The other conditions (the exact account, agent and internal outbound-task context match and at least eight distinct ODORIK_RELAY_NAMES) apply to reminders as well; the main campaign still dials nothing after 31 October, petcenterCampaignQuotaActive and the tick logic are unchanged. API behaviour for other accounts is unchanged.
  • 18 Oct 2026 (1.38.1): GET /v1/balance and MCP get_balance: an eighth notice shape {kind:"subscription_runway",renewsAt,runsOutAt} (at the recent pace the balance runs out before the renewal; returned to subscribers instead of {kind:"runway"}, nothing while auto top-up is on). POST /v1/subscription/checkout and MCP create_subscription_link: consumerConsent is ignored for an account with a company ID, VAT ID or company name (Stripe metadata get 0); a consumer without a company ID still gets a confirmUrl. Nothing else in the API changes.
  • 17 Oct 2026 (1.38.0): New REST endpoints: GET /v1/subscription (response {subscription, tiers, topupBalanceHal, available}; subscription is null without a plan, tiers lists {id, priceHal, creditHal} in hellers excluding VAT, available says whether a plan can be started on the account), POST /v1/subscription/checkout (body {tier, exhaustionMode, consumerConsent?} where tier is "490", "990" or "1990" and exhaustionMode is topup or cap with no default; returns {checkoutUrl}, nothing is charged until a person pays in Checkout; an account without a company ID must send consumerConsent), PATCH /v1/subscription (body {tier?, cancelAtPeriodEnd?, exhaustionMode?}), POST /v1/subscription/pay (a Checkout link to pay a failed renewal by hand, only in status past_due, otherwise invalid_state) and POST /v1/subscription/card (a Checkout link in setup mode to replace the saved card, nothing is charged); the POST endpoints accept Idempotency-Key. PATCH applies a lower tier (from the next period), cancelAtPeriodEnd: true and exhaustionMode: "cap" at once and returns {subscription}; a higher tier, cancelAtPeriodEnd: false (resuming a plan set to end) and exhaustionMode: "topup" change nothing and return 409 subscription_confirmation_required with a confirmUrl (single use, valid for 24 hours) that a person must open and confirm in the portal. The subscription object carries tier, status (active, past_due or canceled), periodStart and periodEnd as ISO 8601 strings (unlike ts in the ledger, which is epoch milliseconds), monthlyCreditHal, monthlyRemainingHal, exhaustionMode, cancelAtPeriodEnd, nextTier and card (brand, last4). GET /v1/balance and the MCP tool get_balance now also carry subscription (null without a plan) and topupBalanceHal (top-up credit alone, negative when the account is in debt); balanceHal is still the total of both. The ledger (GET /v1/credit/ledger, MCP list_ledger) has two new type values, subscription_grant and subscription_expire; a ledger entry for a charge covered by the monthly credit also carries fromSubscriptionHal (the part the monthly credit paid), other entries do not have the field. Five new MCP tools: get_subscription, create_subscription_link, update_subscription, cancel_subscription and create_subscription_payment_link; replacing the card stays REST and portal only. New error codes: 402 subscription_cap_reached (returned instead of insufficient_credit by calls, test calls, gate rings, SMS and purchases of numbers, SMS numbers and relay leases when the plan runs with exhaustionMode: "cap", the monthly credit is used up and the remaining credit does not cover the action), 409 subscription_exists, 404 subscription_missing, 409 subscription_canceled, 409 subscription_confirmation_required, 400 consumer_consent_required, 404 pausal_unavailable (the offer is not enabled for the account), 400 invalid_tier and 409 subscription_cap_active (auto top-up cannot be turned on while the plan runs with the cap); the confirmation page in the portal (not REST) can also end in the state confirm_invalid, confirm_expired or confirm_used. Once the offer is on for an account, the portal shows a plan card on the Credit page and pages to start or change the plan and to confirm a confirmUrl link. Accounts without a plan see no change in existing fields, statuses or codes.
  • 16 Oct 2026 (1.37.5): The engine sends rationale and reason as null in every item of analysis.evaluation_criteria_results when they have no value. The post-call webhook schema rejected null and dropped the evaluation of all criteria, so goal in GET /v1/calls, GET /v1/calls/{id} and in the MCP tools list_calls and get_call was null for calls on the engine, the goal filter counted them as not_evaluated and the after-call e-mail had no goal line. The schema now treats null as a missing field for every optional field where null means nothing, and a malformed evaluation item drops only itself. Where null carries meaning (for example recording_url: null = a call without a recording), it stays. No field or endpoint changes. Calls from 16 September to 16 October 2026 do not have an evaluation yet.
  • 15 Oct 2026 (1.37.4): Three new agent fields turnDigitTailFloorMs, turnLongSpeechFloorMs (integer, 0 = off, otherwise 400 to 2300 ms; the gap 1 to 399 returns validation) and turnLongSpeechSecs (1 to 30, decimals allowed) on POST /v1/agents, PATCH /v1/agents/{id} (a number sets it, null removes the stored value, an omitted key leaves it unchanged), GET /v1/agents and GET /v1/agents/{id} (always present, a number or null when not set, the engine uses its defaults 0 / 0 / 5), in the draft snapshot (PUT/GET /v1/agents/{id}/draft; an absent key means unchanged, null removes it) and in the MCP tools create_agent/update_agent/save_agent_draft. They are sent to the engine in the turn block as digit_tail_floor_ms, long_speech_floor_ms and long_speech_secs on EVERY save of the agent (the engine does not carry the fields over from the previous version; a missing value goes as the engine default) and the read-back compares them (engine contract ch. 3.5af and 3.5ag). Stored for either provider, read only on the engine in smart_turn mode; ElevenLabs ignores them. Engine guidance: step 1 = 800 for Czech agents that take dictated numbers, step 2 = 1200, practical ceiling 1500; dates, postcodes and years get the floor too. The counters of applied floors stay in the engine (its dump and GET /v1/calls), they are not in volai webhooks. In the portal, the "End of reply" card in the Advanced tab.
  • 15 Oct 2026 (1.37.3): New agent field sttLanguageHintsStrict: boolean on POST /v1/agents, PATCH /v1/agents/{id} (true turns it on, false or null turns it off, an omitted key leaves it unchanged), GET /v1/agents and GET /v1/agents/{id} (always a boolean, false when not set), in the draft snapshot (PUT/GET /v1/agents/{id}/draft; an absent key means unchanged, null turns it off) and in the MCP tools create_agent/update_agent/save_agent_draft. It is sent to the engine as stt.language_hints_strict on EVERY save of the agent (the engine does not carry the field over from the previous version) and the read-back compares it. Stored for either provider, read only by the engine (Soniox); best effort, only for engine agents with language cs and outbound calls, never for sk. The call detail GET /v1/calls/{id}, MCP get_call and the call.completed webhook (and call.failed with endReason: "engine_error") carry a new engine: { protectedUtterances: [{ timeInCallSecs?, atSecs, message, words, reason }], protectedUtterancesCount } block - utterances of the person who answered that the engine dropped during the greeting window (metadata.engine.protected_utterances from the engine post-call, contract ch. 3.5ae): not in the transcript, the agent did not react to them; reason is first_message_protect, greeting_courtesy or greeting_identification (open list), at most 10 items, message up to 200 characters, the count covers them all. The block is present only on engine calls from the 15 Oct 2026 build on ([] and 0 when nothing was dropped); older calls, the GET /v1/calls list and agents on ElevenLabs do not have it. In the portal a switch on the Advanced tab and a "What the person said during the greeting" card in the call detail.
  • 15 Oct 2026 (1.37.2): cdr-sync: the second leg of an answered ring (same from/to, different active_call_id, starting shortly after the first leg, first leg answered) is matched to the same kind: "ring" record without the per-attempt fee; seconds are billed only when length > 0. The ring.rangSecs description in OpenAPI and the docs: the carrier's figure is usually 1 to 3 s above ringSecs. No field or endpoint changes.
  • 15 Oct 2026 (1.37.1): New optional agent field inboundVariables: Record<string, string> on POST /v1/agents, PATCH /v1/agents/{id}, GET /v1/agents and GET /v1/agents/{id}, in the draft snapshot (PUT /v1/agents/{id}/draft, GET .../draft) and in the MCP tools create_agent/update_agent/save_agent_draft: default values for {{variable}} placeholders on INBOUND calls. The initiation webhook merges them into dynamic_variables only for names the call does not supply itself (caller_number, called_number, attempt_id, volai_*, trial_* and system__* take precedence and validation rejects such names); outbound calls (POST /v1/calls, relay, tasks) do not use them. At most 10 keys matching [A-Za-z0-9_]{1,40}, values are trimmed strings up to 200 characters. On PATCH an object replaces the stored values entirely, null or {} removes them and an omitted key leaves them unchanged; the response omits the key when the agent has none. In a draft an absent key means unchanged. The prompt_variables_unavailable_inbound and first_message_empty warnings skip a variable that has a default. Works for either provider - the engine and ElevenLabs read the same webhook.
  • 15 Oct 2026 (1.37.0): New POST /v1/rings with body {to, from?, ringSecs?} (from = your active volai number, defaults to the first number of the account; ringSecs 3 to 30, default 10) replies right after the carrier accepts the order with {id, status: "initiated", kind: "ring", from, to, requestedSecs, priceHal}. The result arrives by webhook (call.no_answer for rang and ended_early, call.completed for answered) and in GET /v1/calls/{id} (also with ?waitSecs=) in the new ring: {requestedSecs, outcome, rangSecs} block; outcome is rang, ended_early, answered or unknown. kind has the new value ring; the body of every call webhook now carries kind and, for rings, the ring block. MCP tool ring_number takes the same fields. Limits: 30 rings per minute and 500 per day per account, 120 per hour per target; the manual do-not-call list applies, the automatic 30-day block is neither applied nor fed. Idempotency-Key is supported. New error code: ring_needs_number (account without an active number).
  • 13 Oct 2026 (1.36.2): PATCH /v1/numbers/{e164} and MCP set_number_routing return validation when routing.mode is sip, sipUri points at <credentialId>.sip.vapi.ai or <credentialId>.sip.eu.vapi.ai, and sipUsername with sipPassword are sent or stored from before. A Vapi BYO trunk recognises our calls by the IP in its gateways (IP 81.31.45.0, netmask 24) and does not connect authenticated routing. Vapi's native SIP numbers (sip:<name>@sip.vapi.ai) are not affected. A number that already has such routing stored is fixed by sending both fields as empty strings. The set_number_routing description and the /en/integrations/vapi, /en/docs/bring-your-own-agent and /en/docs/sip pages say so; for a failed call to a Vapi BYO trunk, the portal points at the login fields, the gateways and the region.
  • 13 Oct 2026 (1.36.1): An outbound agent call through the relay whose route never reached the carrier (the routing webhook did not answer within five seconds) still has status: "no_answer", but now endReason: "rejected" instead of "no_answer", and it does not count towards the automatic destination block (3 failures in 24 hours). In tasks such an attempt has countsAsAttempt: false and errorCode: "relay_not_routed", uses up neither maxAttempts nor the lorela_enterprise schedule, and the contact gets nextAttemptAt no sooner than 60 seconds later. After the third such attempt in a row the contact goes to review with reviewReason: "call:relay_not_routed".
  • 12 Oct 2026 (1.36.0): The new internal POST /v1/outbound/dispatch-scopes/petcenter/registrations accepts a durable operationId, manifest SHA-256 and ordered task IDs. The first manifest is pinned to the approved 19-task list; later manifests can only append. GET returns registration state and operation readback. The new /api/cron/outbound-tasks/petcenter cron uses a separately and fairly rotated queue; the general cron and atomic claim both enforce separation. Limits of 6 concurrent calls, 15 attempts per minute and 6,000 per day remain unchanged. GET /v1/tasks?ids=id1,id2 reads one to five selected tasks owned by the authenticated account, reports subset completeness and rejects responses over 4 MiB. POST /v1/outbound/dispatch-scopes/petcenter/pauses safely pauses up to five registered tasks with revision checks; GET returns durable outcomes and an input hash for safe reconciliation.
  • 11 Oct 2026 (1.35.0): POST/PATCH /v1/agents and the MCP create_agent/update_agent/save_agent_draft tools take two new fields: firstMessageProtectSecs: number | null (0 to 20 seconds, decimals allowed, outbound calls only; while the first line plays, a short reaction from the person who answered does not interrupt it: a reply without an interrupting word (for example stop, no, wait) is dropped in the protected window, so it does not interrupt the line, is not in the transcript and the agent does not react to it, while an interrupting word always interrupts it; the interrupting words follow the agent's language, so an English agent is interrupted by stop, no, wait or hold; null or 0 turns the protection off) and silencePromptText: string | null (your own silence reminder sentence, up to 80 characters, spoken word for word instead of the default reminder for the agent's language ("Are you still there?" in English); an empty string or null restores the default text). Unlike silencePromptSecs, WITHOUT a forced default: a missing field on POST is not stored, GET /v1/agents returns it as null for an older agent, and a PATCH without the key leaves the stored value alone, so nothing changes for existing agents. Both fields are accepted and stored for EITHER provider, but only heard on an agent running on volai's own engine. A value outside the bounds fails with the generic validation error (validation, 400), no new code. A transcript turn (transcript[] in GET /v1/calls/{id}, MCP get_call and the call.completed webhook) carries an optional interrupted: true on an agent line the caller interrupted, with message still the full planned text; it is absent on calls handled by ElevenLabs and on calls without an interruption.
  • 10 Oct 2026 (1.34.5): GET and POST /v1/sms-numbers and the MCP tools list_sms_numbers and buy_sms_number return dailySendLimit for each SMS number (20 SMS per 24-hour window during the number's first 30 days, 50 after that), dailySendRemaining (0 for a number being released) and dailySendResetsAt (Unix ms when the window ends, null when none is running). The window starts with the first SMS from any SMS number of the account, is shared by all of them and also counts attempts over the limit and SMS the carrier rejected. The message.sent webhook body has a new smsNumber field: the E.164 SMS number for a message sent from an SMS number, null for the shared sender SMSinfo. The internal_error and send_failed_operator messages for SMS now say "The error is on our side and we know about it", sms_number_out_of_stock no longer promises a restock and the rate_limited message for a used-up SMS number limit says how long until the window ends; error codes do not change. In the portal the /en/messages form shows the limit of the selected SMS number and the SMS messages card on the overview also counts received SMS.
  • 10 Oct 2026 (1.34.4): agentCallLimits in lib/service/call-quotas.ts returns { concurrent: 6, daily: 6000, perMinute: 15 } for the campaign scope; the condition of at least eight distinct ODORIK_RELAY_NAMES stays and guarantees two free names for other callers. The account default (2, 1000, 10), the enablement conditions and the shared account counters are unchanged; API behaviour for other accounts is unchanged.
  • 10 Oct 2026 (1.34.3): The action for send_unknown no longer says that unknown is always final: for an SMS sent from an SMS number it can still change on its own to sent with a deliveryStatus, or to failed with the credit refunded; for an SMS from the shared sender SMSinfo it stays final. The action for rate_limited no longer promises a Retry-After header in every case: the daily cap for sending from an SMS number (20 SMS a day per account during the first 30 days after buying the number, 50 after that) resets the next day, and a number purchase already running finishes within seconds. POST /v1/messages lists blocked_destination (400, premium-rate numbers) among its errors. Messages received on an SMS number have source: "inbound", the received-message list holds at most the 1,000 newest messages per account, and the message.received webhook is not sent above 300 received messages per hour on one number (the messages are still stored). In message.received, from is an E.164 number or a text sender name (at most 32 characters); a message that was not picked up at once is added by a periodic check within about 15 minutes and its event then arrives late. Neither the delivery report (deliveryStatus) nor a late failed triggers an event; read them from GET /v1/messages/{id}. Releasing an SMS number is not available over MCP, only in the portal and with DELETE /v1/sms-numbers/{e164}.
  • 9 Oct 2026 (1.34.2): agentCallLimits in lib/service/call-quotas.ts returns { concurrent: 8, daily: 6000, perMinute: 15 } for the campaign scope; the account default (2, 1000, 10), the enablement conditions and the shared account counters are unchanged. The rate_limited message for the daily limit now says 6000.
  • 9 Oct 2026 (1.34.1): CAMPAIGN_QUOTA_EXPIRES_AT in lib/service/call-quotas.ts is 2026-10-31T23:00:00Z; the VOLAI_PETCENTER_CALL_QUOTA_ENABLED switch, the exact account, agent and internal outbound-task context match and at least eight distinct ODORIK_RELAY_NAMES still apply. API behaviour for other accounts is unchanged.
  • 9 Oct 2026 (1.34.0): New endpoints GET /v1/sms-numbers, POST /v1/sms-numbers (no body, Idempotency-Key supported, returns 201) and DELETE /v1/sms-numbers/{e164} (irreversible, the paid period is not refunded), and MCP tools list_sms_numbers and buy_sms_number (confirmedMonthlyFeeHal must equal the current fee in hellers, otherwise nothing is bought). GET /v1/messages and MCP list_messages take direction (out by default, in, all) and also return messages received on an SMS number; messages now carry direction, smsNumber and deliveryStatus (delivered or undelivered, only for SMS sent from a number), status has a new value received and failReason a new value opted_out. POST /v1/messages and MCP send_sms take fromNumber (an active SMS number of the account; Czech +420 recipients only; 1.90 CZK per segment). New webhook event message.received with {id, from, to, body, segments, receivedAt} (receivedAt is Unix ms); the text of a received SMS is untrusted third-party content and MCP marks it with securityNotice. Received SMS are kept for 90 days. New error codes: sms_numbers_unavailable, sms_number_limit, sms_number_out_of_stock, invalid_from_number, from_number_unsupported_destination and recipient_opted_out; the existing codes recipient_rejected, sms_gateway_failed, recipient_is_virtual_number (an SMS from the shared sender to a volai SMS number) and release_failed also apply to SMS numbers. The message from field is still the internal label volai for a message sent without fromNumber, the SMS number itself for one sent from it, and the sender for a received message.
  • 8 Oct 2026 (1.33.0): The callback-routing policy accepts an optional missedFirstMessage (up to 500 characters): it replaces firstMessage when the verified preceding outbound call had no conversation with the customer (not answered, voicemail, voice menu, nobody spoke, or the call is not closed yet). Initiation sends the engine volai_callback_kind (missed/contacted) next to volai_call_mode=campaign_callback. The engine post-call may carry caller_optout_requested (outbound calls only): the call then exposes optOutRequested: true in the list and detail, the called number is added to the account's do-not-call list (GET /v1/dnc) and the lorela_enterprise policy schedules no further attempt for that item. An engine call with answered_by: unknown stays unknown - the portal no longer guesses a voicemail from a short reply ("Yes." after the intro), so hasConversation of such a call follows the transcript; a voicemail detected by the engine (voicemailReason present) gets another attempt under the lorela_enterprise policy despite the carrier greeting in the transcript. New reason voicemailReason: digits (a carrier greeting reading the called number digit by digit). Everything is additive; existing policies, calls and tasks are unchanged.
  • 8 Oct 2026 (1.32.1): The message from field stays the internal label volai, and OpenAPI now describes it; the source field description says the value inbound never occurs for messages. The MCP server instructions, SKILL.md and the llms files say the same. API behaviour is unchanged.
  • 8 Oct 2026 (1.32.0): Save an explicit allowlist of owned active engine agents for returning callers with a unique real outbound call from this number within lookbackSecs (60-604800 seconds). Unknown, ambiguous or unverified callers keep the default agent. Empty agentIds disables the policy. Optional firstMessage applies only to verified callbacks. engineSyncRequired: true means the default agent engine configuration must separately activate webhooks.inbound_route_url with readback; this request does not rewrite live engine configuration. Verified incoming calls expose callbackOf.callId and optional server-owned taskId and taskItemId in call details. New REST GET/PUT /v1/numbers/{e164}/callback-routing and MCP get_callback_routing / set_callback_routing. Signed incoming tool context carries direction=in and empty dispatch/task/item fields. Server-owned volai_call_mode=campaign_callback is set only for verified callbacks. Verified inbound human contact stops later scheduled retries of the same task item without creating an outbound attempt or charge. An already running call and its billing finish normally. The server-owned dispatch/task/item binding is retained for eight days to cover the callback window.
  • 8 Oct 2026 (1.31.0): POST /v1/tasks, PATCH /v1/tasks/{id}, create_task and update_task accept optional retryPolicy: "lorela_enterprise" and expiresAt (positive safe-integer Unix milliseconds); both fields are returned in the public task. Without a policy, maxAttempts remains 1-3 with a creation default of 1; with the policy it is 1-4 with a creation default of 4. PATCH without a limit preserves it. The policy can be enabled only before the first dispatch attempt. The second attempt is no earlier than eight minutes after the first real attempt starts, within 08:00-22:00 Europe/Prague; the third uses the next other 08:00-09:00 or 17:00-19:00 window; the fourth uses the opposite window on the following calendar day. A narrower callingWindow, including weekdays, still applies. Only no_answer, missed, busy or completed voicemail without human contact can retry; uncertain results and engine failures need review. The policy rejects manual resolve with action: "retry" and stops calling five days after the first real attempt. expiresAt also works without a policy and prevents any new dial at or after the deadline, including the first attempt; a call already in progress finishes normally. DNC and automatic blocking after three failures within 24 hours are not bypassed, so the fourth attempt is not guaranteed.
  • 5 Oct 2026 (1.30.2): A call for which the engine does not send caller_loop in the post-call (the caller first talked to the agent and only afterwards just a repeated message was left on the line) has endReason: "completed" and the regular price, like any other completed call. The fallback sync of a lost post-call (the engine's GET /v1/calls) now reads metrics.caller_loop_reported: the value 1 means the engine sent caller_loop in the post-call, and caller_loop is taken over as before; the value 0 means an ordinary call, which is closed and billed with endReason: "completed" regardless of metrics.caller_loop_released. For an older engine without this field, the existing rule with metrics.caller_loop_released applies (a positive value means an ordinary call). REST and MCP response shapes, the endReason values and the outcome filter do not change.
  • 4 Oct 2026 (1.30.1): endReason: "caller_loop" and priceHal: 0 are now given only to an inbound call with a positive durationSecs; an outbound call, or a call with zero duration, for which the engine sends termination_reason: "caller_loop" takes the regular path (endReason: "completed" and regular billing; a zero-duration call stays unclosed as before). The fallback sync of a lost post-call (the engine's GET /v1/calls) takes over caller_loop only when metrics.caller_loop_released is missing or 0; with a positive value (a person spoke up during the wait) the call is closed and billed like any other completed call with endReason: "completed", and call.completed carries the price, the same as when the post-call arrives on its own. A call with endReason: "caller_loop" is never listed in the portal among calls needing attention (Overview and the Calls filter), and the weekly e-mail summary does not count it as a handled call or a caller and does not list it among calls that need a reaction. REST and MCP response shapes, the endReason values and the outcome filter do not change.
  • 4 Oct 2026 (1.30.0): New endReason: "caller_loop" value (REST GET /v1/calls and GET /v1/calls/{id}, MCP list_calls and get_call, webhook call.completed): an inbound call whose caller was an automated system repeating the same message (a queue, a dialer), ended by the engine's guard. The source is metadata.engine.termination_reason: "caller_loop" in the engine's post-call (for a lost post-call, the same field from the engine's GET /v1/calls). The call has status: "completed", a positive durationSecs and priceHal: 0, and no credit is charged; the price of 0 applies up to five minutes of call duration - a longer call is billed at the regular rates and keeps endReason: "caller_loop". The call.completed webhook carries endReason: "caller_loop". A call where a person spoke up during the wait and the engine carried on with them does not get caller_loop. In the outcome filter (GET /v1/calls, list_calls) such a call counts as agent.
  • 4 Oct 2026 (1.29.6): PATCH /v1/agents/{id}, update_agent and draft publish: changing language from a language in which new agents start on ElevenLabs (today en, de, pl) to one in which they start on the engine (cs, sk) triggers, for an agent with provider: "elevenlabs", the same post-save engine switch attempt as turning on transferTo. On success the agent has provider: "engine" and the engine's default voice for the new language (milena, katarina); on failure it stays on ElevenLabs. A change between cs and sk moves nothing. voicemail_requires_engine has new wording: on creation it points to useForOutboundTasks: true, on an existing agent to support.
  • 4 Oct 2026 (1.29.5): POST /v1/agents and create_agent return a new code elevenlabs_by_explicit_choice ({code, message: {cs, en}}) in warnings when the request sent useForOutboundTasks: false, the deployment default would have picked the engine for the agent's language, and the agent really stayed on ElevenLabs (a transferTo handoff may have switched it to the engine). The agent is created as before and the code blocks nothing. PATCH /v1/agents/{id}, draft publish and rollback never return it.
  • 3 Oct 2026 (1.29.4): Documentation only, the API behavior does not change. maxAttempts (1-3) is the highest number of automatic dials of one contact, the first call included; 1 means no retries. A contact that you give resolve with action: "retry" after its attempts are used up gets one more dial. Every attempt where the call could have happened counts (unanswered, declined by the person called, or with an uncertain result). An attempt rejected before dialing does not count and has items[].attempts[].countsAsAttempt: false.
  • 3 Oct 2026 (1.29.3): For attempts recorded from this version on, items[].attempts[].countsAsAttempt is false for every code where the call provably never happened, so they do not count toward maxAttempts: agent_not_found, agent_no_number, insufficient_credit, invalid_number, unsupported_country, blocked_destination, on_dnc, destination_auto_blocked, cannot_call_own_number, cannot_call_volai_number, capacity_busy, call_rejected, validation, rate_limited, relay_lease_limit, invalid_workflow, engine_not_configured and destination_busy. Previously the permanent problems with the number (invalid_number, unsupported_country, blocked_destination, on_dnc, destination_auto_blocked, cannot_call_own_number, cannot_call_volai_number) were counted, so after lifting a block and another rejection a contact showed more attempts than allowed although nothing was dialed. Attempts written before this version are not rewritten retroactively (the exception is an attempt whose dial intent the accounting repair closes). Uncertain dial errors (for example engine_unavailable) still count, because the call may have happened. A permanent problem still sends the contact to review (you decide), a repairable code (missing credit, an agent without a number and the like) pauses the task; rate_limited and relay_lease_limit leave the task running and only wait. Nothing is dialed in a loop because of this. A contact you return via resolve with retry after its attempts are used up now stays pending after a repairable dial error without a call (for example insufficient_credit) and is dialed again once the cause is fixed; before, it stayed failed and the task could not be started (task_not_startable).
  • 3 Oct 2026 (1.29.2): destination_busy while dialing from a task (the call provably never happened): the contact keeps waiting (failed when it already had a counted attempt and has another free one, otherwise pending) with items[].lastError: "destination_busy" and items[].nextAttemptAt from the remaining time of the number lock (at least 30 s, at most 16 min, 90 s without a lock), the attempt has countsAsAttempt: false, the reservation in reservedBudgetHal is released and the other contacts keep running; the task's lastError is not set, only a stale waiting rate_limited or relay_lease_limit is cleared, because a busy result proves the limit passed. After the 6th busy result in a row (5 waits) the contact goes to review with reviewReason: "dial:destination_busy". The seven permanent codes (on_dnc, destination_auto_blocked, cannot_call_own_number, cannot_call_volai_number, invalid_number, unsupported_country, blocked_destination) send the contact to review with reviewReason: "dial:<code>", but the task stays running and moves to needs_attention only when no other work is left (previously immediately). Over the API and MCP a block is lifted with two calls: POST /v1/dnc/{e164}/unblock (unblock_destination), then resolve with action: "retry" (resolve_task_item); for your own number, a number of another volai account, an invalid number, a number outside Czechia and Slovakia and a premium-rate line only skip helps. A contact in review can now appear while the task is still running; resolve then returns 409 task_not_editable, so wait for needs_attention or pause the task. POST /v1/calls does not change.
  • 2 Oct 2026 (1.29.1): items[].providerCallId points only to the call of the latest attempt: a contact in failed that is waiting for another attempt does not carry it; the call of every attempt stays in items[].attempts[].providerCallId. Previously the item kept the call of the first attempt, the next dialed call was not recorded on the task, and the contact was dialed again without counting the attempt and without adding the price to spentHal. The errors on_dnc, destination_auto_blocked, cannot_call_own_number and cannot_call_volai_number while dialing from a task are provably no call: the attempt gets outcome: "failed", the reservation in reservedBudgetHal is released right away and the contact goes to review with reviewReason: "dial:<code>" (previously outcome: "unknown" and a held reservation). POST /v1/tasks/{id}/start no longer returns 409 task_needs_attention because of a reservation that no contact holds; POST /v1/tasks/{id}/reconcile settles such a reservation and also closes an older open dispatch intent left after an attempt that was never dialed.
  • 2 Oct 2026 (1.29.0): New endpoint POST /v1/numbers/orders/{id}/cancel (no body) and MCP tool cancel_number_order: a pending order moves to the new status cancelled (a new status value of the order in GET /v1/numbers/orders and list_number_orders); provisioning returns 409 in_progress, done and failed 409 invalid_transition, a foreign or unknown id 404 not_found; cancelling again returns the order unchanged. A cancelled order no longer counts toward the first top-up gate (one number per account without a top-up). callingWindow.end of tasks is inclusive of the whole minute (current <= end): a 00:00-23:59 window covers the whole day and window_closed no longer occurs in the end minute itself.
  • 30 Sep 2026 (1.28.1): PATCH /v1/numbers/{e164} (MCP set_number_routing) with mode: "forward" returns 402 insufficient_credit when the account has never topped up and the number is not forwarded yet. A number that is already in forward can be pointed at a different target without a top-up. POST /v1/numbers (MCP buy_number) and POST /v1/numbers/orders (MCP order_number_from_region) return 402 insufficient_credit when asked for an additional number while an account without a top-up already holds an active number or has an open order (pending, provisioning). Same code and cause (account) as for SMS, different message text - it says what to do (make the first credit top-up); nothing is charged. After the first credit top-up (card, auto top-up) the restriction is gone.
  • 25 Sep 2026 (1.28.0): New suspended: boolean field on the agent object (REST and MCP, GET/POST/PATCH /v1/agents). New error codes agent_suspended and account_suspended (403, cause: "account") - account_suspended on every REST call with an API key and every MCP tool (after the rate limit) except reading tax documents (GET /v1/billing/documents, /{id} and /{id}/pdf, the MCP tools list_billing_documents and get_billing_document), which stay available; agent_suspended on POST /v1/calls, POST /v1/agents/{id}/test-call and POST /v1/tasks/{id}/start. An inbound call blocked by a suspension of the agent or the account carries endReason: "suspended" (a new value next to credit_blocked, price 0). An account_suspended/agent_suspended response is never stored under an Idempotency-Key, so the same key succeeds once restored. Custom variable keys (variables on POST /v1/calls and make_call) can no longer start with the volai_ prefix - it is reserved for variables volai fills in itself (such as volai_block_reason), and such a request returns 400 validation; in tasks, such a key is only refused when the contact is dialed. Suspending and resuming is done only by the operator in the admin panel - there is no REST or MCP tool for it. The sentence a caller hears on a blocked line (debt or suspension) is now spoken in the agent's language (cs, sk, en, de, pl).
  • 25 Sep 2026 (1.27.3): No interface change: the same warnings code agent_misuse_suspected in the same REST and MCP responses, only broader recognition.
  • 24 Sep 2026 (1.27.2): Outbound tasks: relay_lease_limit from dialing (the quota of 2 concurrent agent calls per account) now behaves like rate_limited - the task stays running, sets lastError: "relay_lease_limit", the attempt does not count (countsAsAttempt: false) and waiting contacts get items[].nextAttemptAt one minute later. Previously the item went to review with reviewReason: "dial:relay_lease_limit" and the task to needs_attention. The engine sync (GET /v1/calls) reads the new attempt_id field of an outbound call and uses it to match an initiated record after an uncertain dial (no call_sid, also for an agent without its own number); once matched, call.completed is sent with the price and the relay line and quota are released. Requires an engine that lists attempt_id; an older listing behaves as before.
  • 24 Sep 2026 (1.27.1): POST /v1/calls with agentId on an agent on volai's own engine, a trial call with systemPrompt, MCP make_call and outbound tasks: when dialing on the engine ends with a timeout, a dropped connection, a 500/504 response or an unreadable 2xx, the response is still 502 engine_unavailable, but the call stays initiated (no priceHal), the relay line is not released and the same to stays locked for 15 minutes (destination_busy); the concurrent call quota is released right away. If the call happened, the post-call or the engine sync fills in the outcome and price (the post-call now finds it by the attempt identifier even without a call_sid, including agents without a number of their own) and call.completed is sent; if not, the watchdog closes it after 2 h as failed with priceHal: 0. The call.failed webhook is not sent for an uncertain dial. A certain failure (no connection to the engine at all or a timed-out connection attempt, 4xx, 502/503) behaves as before: failed, priceHal: 0, call.failed.
  • 24 Sep 2026 (1.27.0): New warnings code agent_misuse_suspected ({code, message: {cs, en}}). Appears in POST/PATCH /v1/agents, PUT /v1/agents/{id}/draft, POST /v1/agents/{id}/simulate, POST .../draft/publish, POST .../draft/rollback, POST /v1/calls (the trial call prompt or variables), POST/PATCH /v1/tasks, POST/PATCH /v1/tools and the matching MCP tools (create_agent, update_agent, save_agent_draft, simulate_agent_draft, publish_agent_draft, rollback_agent_draft, make_call, create_task, update_task, create_tool, update_tool). The warnings field is optional, absent when there is nothing to flag, and /openapi.json describes it on all of these responses.
  • 24 Sep 2026 (1.26.3): POST /v1/calls with from (bridge) and MCP make_call: when the connection order to the phone operator ends with a network error, a timeout or a 429/5xx response, the call is returned as a success with status: "initiated" instead of 502 callback_failed and stays initiated until cdr-sync pairs it with the CDR (and bills it), or the watchdog closes it after 24 h as failed with priceHal: 0. callback_failed now means only a provable rejection by the operator (an error response or 4xx). The call.failed webhook is not sent for an uncertain order; the same to number stays locked for about 10 minutes (destination_busy).
  • 24 Sep 2026 (1.26.2): The per-account cap on calls within 24 hours (shared by POST /v1/calls with an agent or a bridge, relay and trial calls, MCP make_call and outbound tasks) is now 1000 instead of 200. Exceeding it still returns 429 rate_limited with the daily-limit message; 10/min, concurrency and the engine budget are unchanged.
  • 24 Sep 2026 (1.26.1): Outbound tasks: a call record in failed with no conversationId and no priceHal (the engine refused or did not confirm the dial) now settles at 0 in reconcile - previously the item kept reviewReason: "billing_unknown" and the task stayed needs_attention forever. resolve with skip on a billing_unknown item moves a task with remaining work to paused (the original call's reservation keeps counting in reservedBudgetHal, and start accepts it); retry still waits for the price. A decision right after a dial error (reviewReason: "dial:...") no longer loses the link to the call or its reservation. rate_limited while dialing (engine limit, 10 calls per minute, 200 per day) keeps the task running with lastError: "rate_limited" and sets waiting items' nextAttemptAt to the end of the limit (from Retry-After, otherwise in 5 minutes, at most 24 hours) instead of paused; the attempt does not count. invalid_workflow and engine_not_configured while dialing are provably no call (the task becomes paused, the attempt does not count). Every call by an agent on volai's own engine that the engine never dialed (outbound tasks as well as POST /v1/calls, MCP make_call and the portal) has priceHal: 0 and durationSecs: 0 in GET /v1/calls instead of missing values; the call.failed webhook is unchanged.
  • 24 Sep 2026 (1.26.0): POST /v1/calls with agentId on an agent on volai's own engine (and MCP make_call): a rejection by the engine's outbound-minute limit (hourly and daily bucket per account) or by full engine concurrency is now 429 rate_limited instead of 502 engine_unavailable; the minute limit adds a Retry-After header (seconds until the end of the hourly window, or until midnight UTC for the daily one). Nothing was dialed or charged; the call stays in the history as failed and the call.failed webhook carries reason: "rate_limited". Outbound tasks treat rate_limited (including the 10 calls/min and 200/day limits) as provably no call: the item is failed without counting an attempt, and the task is paused instead of needs_attention. The POST /v1/calls error table now also lists 502 engine_unavailable - for an agent on volai's own engine it means only a real engine outage, not a limit.
  • 23 Sep 2026 (1.25.0): New optional event_id field in the webhook envelope ({event, data, ts, event_id}) for call.completed/call.failed/call.no_answer/call.missed - message.sent and the webhook.test test event are unchanged. A failed delivery of those four events no longer stops after 3 attempts (3s apart): it stays queued and retries over the following minutes, up to 5 rounds; a repeat delivery carries a byte-identical body. GET /v1/webhook/deliveries (and MCP list_webhook_deliveries) now also show rounds before the final one, attempts is the sum of attempts across all rounds, and there is a new optional eventId field.
  • 23 Sep 2026 (1.24.1): Two new warnings codes: prompt_variables_unavailable_inbound (an agent with numberE164 whose systemPrompt/firstMessage uses a {{variable}} outside the set an inbound call actually supplies) and first_message_empty (a firstMessage with no letter or digit left in it outside the variables once every {{...}} block is removed). Both REST (POST/PATCH /v1/agents, publish and rollback) and MCP (create_agent, update_agent, publish_agent_draft, rollback_agent_draft) read the same source as the portal's agent editor (agentWarnings).
  • 20 Sep 2026 (1.24.0): New optional busyCalendarIds field on the agent (POST/PATCH /v1/agents, MCP create_agent/update_agent, drafts) and on agent-less slot search and booking (POST /v1/integrations/{id}/availability, POST /v1/integrations/{id}/events, MCP find_free_slots, create_calendar_event). The calendars are read in parallel; if any of them fails, the whole lookup fails, so no time is offered over an event we simply could not see. At most four, without duplicates and without calendarId; otherwise 400 calendar_invalid_rules, an unknown calendar 400 calendar_invalid_calendar.
  • 20 Sep 2026 (1.23.4): The error tables of POST /v1/agents, PATCH /v1/agents/{id} and draft publish/rollback add the six codes validateCalendar returns: 404 calendar_integration_not_found and 400 calendar_invalid_calendar, calendar_invalid_timezone, calendar_invalid_windows, calendar_no_windows, calendar_invalid_rules. This flows into openapi.json, the /docs/api reference, SKILL.md and llms-full.txt.
  • 20 Sep 2026 (1.23.3): maybeQueueMissedCallSms now also fires for an outbound call with answeredBy: "voicemail" (previously only status: "no_answer" and inbound missed). A voice menu (ivr) or unknown does not trigger it. All other conditions (CZ/SK number only, DNC, blocked destinations, one SMS per number per 24 h, quiet hours, last task attempt) are unchanged; CallRecord.missedSms is written the same way.
  • 19 Sep 2026 (1.23.2): A timestamp with milliseconds was formatted with a time zone offset one minute short (+01:59 instead of +02:00) - this affected the now field in the agent tools and the start of a created event when a client sent start with fractional seconds. Alternatives returned with 409 calendar_slot_taken (POST /v1/integrations/{id}/events, MCP create_calendar_event) are now computed from the requested time, the same as find_free_slots with a time.
  • 19 Sep 2026 (1.23.1): The agent calendar field (POST/PATCH /v1/agents, MCP create_agent/update_agent and drafts) rejects a calendar whose accessRole is reader or freeBusyReader with 400 calendar_invalid_calendar, because the agent writes appointments into the same calendar. list_calendars returns the role as accessRole where the provider reports it; a calendar without a role is accepted as before. No other error codes change.
  • 19 Sep 2026 (1.23.0): New CallRecord.rating field (value: "good" | "bad", reason?, note?, at, source: "portal" | "email" | "api" | "mcp") and CallRecord.missedSms; PATCH /v1/calls/{id} and MCP annotate_call accept rating/ratingReason/ratingNote (patchCallAnnotation calls rateCall with source: "api"/"mcp"). New AgentRecord.missedCallSms { enabled, text? } field (variables {firma}, {cislo}, {agent}) on POST/PATCH /v1/agents, GET /v1/agents/{id} and MCP create_agent/update_agent/get_agent/save_agent_draft. GET/PATCH /v1/account and MCP get_account/update_account have companyName (max 80 chars, empty string clears it), and GET now returns notifications.weeklySummary. The test call in the agent editor shows the outcome based on the call goal (call.evaluation.goal) and the collected data.
  • 18 Sep 2026 (1.22.0): New endpoints POST /v1/integrations/{id}/availability (free slots without a saved agent - windows omitted means 24 hours every day) and POST /v1/integrations/{id}/events (create an appointment, requires confirm: true, optional idempotencyKey for safe retries; 409 calendar_slot_taken on a collision), MCP tools find_free_slots and create_calendar_event with the same shape. DELETE /v1/integrations/{id} now returns affectedAgents - agents whose calendar field was turned off by disconnecting this integration. New calendar field on POST/PATCH /v1/agents, GET /v1/agents/{id} and MCP create_agent/update_agent/get_agent: integrationId, calendarId, timezone, slotMinutes, minNoticeMinutes, horizonDays, bufferMinutes, windows (an array of {from,to} windows per weekday). Works only on volai's own engine (provider: "engine") - on an agent hosted on ElevenLabs the field is saved and waits for the calendar_pending_engine_switch warning until the agent switches. Eleven new error codes with cause/action: calendar_slot_taken, calendar_confirmation_required, calendar_invalid_range, calendar_integration_not_found, calendar_invalid_calendar, calendar_invalid_timezone, calendar_invalid_windows, calendar_no_windows, calendar_invalid_rules, calendar_too_many_events, calendar_unavailable.
  • 18 Sep 2026 (1.21.0): New ledger movement type setup_revision (GET /v1/credit/ledger, MCP) for a done-for-you setup order's revision round beyond the package, amount SETUP_EXTRA_REVISION_HAL (490 CZK excl. VAT). Tax documents (GET /v1/billing/documents, .../{id}, list_billing_documents, get_billing_document) now always carry a kind field ("invoice" - default, or "credit_note"), plus optional correctsNumber and correctionReason fields; a done-for-you setup refund's credit note is numbered in its own OD series and carries positive amounts (the minus sign is added by the PDF). credit() (lib/service/balance.ts) gained an internal notifyTelegram parameter - a done-for-you payment now sends just one Telegram alert ("Na klíč: zaplaceno"), not two. New public landing page at /receptionist-done-for-you (Czech canonical /recepcni-na-klic).
  • 18 Sep 2026 (1.20.0): New laughter field (auto/on/off) on POST/PATCH /v1/agents and MCP create_agent/update_agent: auto follows the engine's sensitive-topic detection (debt collection, healthcare, authorities, funeral services), on overrides that detection, off always suppresses it; an omitted key is stored and returned as auto, never absent. GET /v1/agents/{id} and the new MCP tool get_agent (previously missing parity for a single agent's detail) add laughterEffective ({active, reason, sensitiveCategory} | null) nested inside the returned agent object, computed fresh for the published configuration; null means it could not be determined right now (the engine did not respond within 3 seconds, was down, or returned a silent 404 on an older build) - never a guess. MCP update_agent returns the same object as a top-level field next to agent instead, since PATCH /v1/agents/{id} never returns it. The field is accepted and stored for an agent on ElevenLabs too, but has no audible effect there - only a Czech Cartesia voice on volai's own engine plays it.
  • 18 Sep 2026 (1.19.0): New REST API v1 and MCP area - source setup-orders, capability area setup (after credit). Seven endpoints (POST /v1/setup-orders, GET /v1/setup-orders, GET/POST /v1/setup-orders/{id}, .../messages, .../checkout, .../launch, .../cancel) and seven matching MCP tools (create_setup_order, list_setup_orders, get_setup_order, message_setup_order, checkout_setup_order, launch_setup_order, cancel_setup_order) over the same service layer, lib/service/setup-orders.ts. The quote is always computed by the catalog in code (lib/setup-catalog.ts); the model only picks items from the conversation. New error codes: setup_order_not_found, order_closed, invalid_transition, quote_pending_confirmation, checkout_open, turn_in_progress, advisor_no_quote, advisor_unavailable, setup_orders_disabled. Documentation at /docs/done-for-you (Czech /docs/na-klic).
  • 17 Sep 2026 (1.18.0): The agent draft (PUT/GET /v1/agents/{id}/draft, POST /v1/agents/{id}/draft/publish) and the MCP save_agent_draft tool now treat numberE164 as three-state: an absent key leaves the agent's number untouched, null disconnects it, and a string attaches that number - parity with the semantics PATCH /v1/agents/{id} already had. Reading a draft also reconciles it against the live agent: published.numberE164 always mirrors the live number, and draft.numberE164 does too whenever the draft made no explicit choice, so the editor's pre-publish check and outbound tasks see the true state even after a number was attached or moved outside the editor; "no explicit choice" also covers a string that matches the agent's current LIVE number - that value behaves the same as an absent key, re-checked on every draft read against whatever number is live at that moment; if the number later moves to a different agent outside this draft, the same stored value becomes an explicit choice again and the next publish or rollback reattaches it here - not silently: publish and rollback responses (REST and both MCP tools) now carry a new number_changed_by_publish warning with from/to (E.164, or null for no number) in that case, without blocking the operation either. One read-side compatibility note: draft.numberE164 can now come back as null (an explicit "no number" choice) where the key used to be simply absent - treat it the same as an absent key, meaning the agent has no number. The "tested" marker and the agent fingerprint pinned to a running outbound task are now computed WITHOUT the phone number too (behaviorFingerprint, not draftFingerprint), so attaching or moving a number outside the editor no longer requires a fresh test and no longer stops a running campaign; a draft with a number saved BEFORE this change has its marker computed the old way, including the number, so it asks to be re-earned once - one test or publish after the update restores it, and the new rule applies from then on.
  • 15 Sep 2026 (1.17.0): A new goal display state, GoalDisplayState (success/failure/unclear/no_conversation/not_evaluated), replaces the AgentGoalResult triple in the portal's display, in the /hovory filters and in the overview. REST and MCP gained answeredBy: "ivr", goal.reason ("no_caller_speech"/"evaluation_error"), and hasConversation (boolean | null). The goal parameter (GET /v1/calls, MCP list_calls) accepts five new values alongside the existing unknown, which stays backward compatible - it still covers records with no clear result (goal.result missing or unknown): always unclear and not_evaluated, and no_conversation only when its result is also unknown.
  • 13 Sep 2026 (1.16.0): A new endReason: "engine_error" value (status failed) appears when the engine sends metadata.engine.termination_reason as engine_stall or engine_error for a call that was actually handled - previously that field was discarded for such calls. priceHal is set to 0 only when the call has no price yet (otherwise it is left unchanged, with an ALERT log). The call.failed customer webhook gained four new optional fields: durationSecs, priceHal, transcript, summary - populated only for this technical branch, missing everywhere else as before. GET /v1/calls/{id} and MCP get_call return the same endReason value. Outbound tasks (POST /v1/outbound-tasks, MCP) treat engine_error as a retryable attempt (the same path as no_answer), not a reason to stop the campaign, and do not record it toward the automatic 30-day destination block.
  • 13 Sep 2026 (1.15.0): POST/PATCH /v1/agents and the MCP create_agent/update_agent/save_agent_draft tools take a new silencePromptSecs: number | null field (a whole number 3 to 25, null turns it off), bounds matching the engine (engine/types.py, U1). A missing field on POST/create_agent saves the default of 10 - unlike voicemail, the field is accepted and returned for EITHER provider (GET /v1/agents returns the stored value even for provider: "elevenlabs"). A value outside the bounds fails with the generic validation error (validation, 400), no new code. Existing agents on the engine get the default of 10 via a one-off re-sync script (scripts/resync-silence-prompt.mts) that changes only this one field.
  • 13 Sep 2026 (1.14.7): OpenAPI adds descriptions to every operation and request field, including nested variants. Agent, tool, SMS and call constraints use product limits shared with the service layer instead of permissive parser ceilings. Automated checks validate all request and response examples against their schemas. API behavior, error codes and provider settings are unchanged.
  • 13 Sep 2026 (1.14.6): POST /v1/messages and MCP send_sms return insufficient_credit (HTTP 402, cause account) until the account has a positive topup (card or auto top-up) or admin (manual owner adjustment) ledger entry. The previous cap of 3 SMS for accounts without an active number of their own is gone, and an active number no longer grants an exception. The first top-up is kept as a permanent account flag, so a long ledger history never blocks a customer.
  • 13 Sep 2026 (1.14.5): New workflow_node_tool_missing code in warnings on POST/PATCH /v1/agents, on draft publish and rollback, and on MCP create_agent, update_agent, publish_agent_draft and rollback_agent_draft. It applies to both providers, because a deleted tool does not reach the phase on volai's own engine either. workflow_node_tool_not_synced now only covers a tool that is on the account but not among the agent's own. The Reception template also recommends two sentences for the base prompt: do not guess operational details, and ask about one thing at a time.
  • 12 Sep 2026 (1.14.4): Setup distinguishes OAuth grant identifiers from API keys when restoring older saved choices. An unavailable status check is not treated as revoked access.
  • 12 Sep 2026 (1.14.3): Added the catalog files katty-studio.mp3 and katty-telefon.mp3 using the same generator and content as the other voices. The agent voice, provider and phone service settings are unchanged.
  • 12 Sep 2026 (1.14.2): Copy labels and next-step guidance match the selected connection method. Codex desktop with an API key points to config.toml. Closing the mobile menu preserves focus restoration.
  • 12 Sep 2026 (1.14.1): Sign-in preserves the assistant setup destination. The workspace preference is stored per account separately from actual MCP verification. Manual guides cover Claude Code, Codex CLI and desktop, with API keys as an alternative. Help and the names Voice agents, Phone numbers and Data & integrations are consistent.
  • 12 Sep 2026 (1.14.0): When useForOutboundTasks is omitted, selection depends on VOLAI_ENGINE_DEFAULT_FOR_NEW, engine availability and VOLAI_ENGINE_DEFAULT_FOR_NEW_LANGUAGES (unset means cs,sk). Language alone does not guarantee the engine. Explicit true requests the engine; false starts on ElevenLabs. Applies to the portal, POST /v1/agents and MCP create_agent. Read back provider and voiceId after creation; handoff may trigger a subsequent provider switch attempt.
  • 12 Sep 2026 (1.13.0): The workflow field is available in POST and PATCH /v1/agents, in the agent draft, and in the create_agent, update_agent and save_agent_draft MCP tools. A call that went through phases carries workflowPath in GET /v1/calls and GET /v1/calls/{id}. New workflow_*, workflow_not_synced_to_provider and workflow_node_tool_not_synced warnings flag phase configuration issues.
  • 12 Sep 2026 (1.12.5): voiceId for an ElevenLabs agent: katty (default, the template voice) or a raw ElevenLabs id; jana is gone from the catalog and from ElevenLabs (the two agents from the afternoon of 12 Sep were switched to Katty and the voice was removed from the workspace). GET /v1/voices?provider=elevenlabs and MCP list_voices with provider: elevenlabs return katty. The engine's ElevenLabs fallback for Milena, Tereza and Katarina is Katty as well.
  • 12 Sep 2026 (1.12.4): Polling no longer interrupts a slow status request. Successful MCP read evidence is found by active access even if writing the helper index failed. Verification still requires get_balance or list_agents through MCP.
  • 12 Sep 2026 (1.12.3): Fixed the English calendar privacy link and kept an active goal filter visible even without previous evaluations. Both languages have regression coverage for links and unavailable integrations.
  • 12 Sep 2026 (1.12.2): The MCP guide uses existing evidence of successful reads through an active API key or OAuth grant, with no simulated verification. The goal=unknown filter in GET /v1/calls and MCP list_calls also includes records without a goal evaluation. Technical completion does not mean a goal was met. REST and MCP still return individual records; the portal groups them into conversations.
  • 12 Sep 2026 (1.12.1): voiceId for an ElevenLabs agent: jana (default, the template voice) or a raw ElevenLabs id; anet passes only on an agent that already has it, otherwise a 400 validation with an explanation (previously a 502 eleven_labs_error from ElevenLabs voice_live_moderated_not_allowed). GET /v1/voices?provider=elevenlabs and MCP list_voices with provider: elevenlabs return jana. An ElevenLabs agent without voiceId gets Jana explicitly (the record carries her id). SIP registration: the carrier returned 403 INVALID_USER for lines bought through its API until the line's SIP protocol was toggled off and on once; fixed for all lines and done automatically when a new line is bought.
  • 12 Sep 2026 (1.12.0): OAuth authorization code + PKCE S256, DCR, resource-bound opaque tokens, refresh rotation/replay detection, OIDC discovery/JWKS/userinfo and revocation. Access tokens last 10 minutes, refresh tokens up to 30 days, grants up to 90 days. Password changes invalidate OAuth access. MCP annotations explicitly distinguish overwrites, paid actions, messages and external side effects.
  • 12 Sep 2026 (1.11.0): GET /v1/numbers/{e164}/sip and MCP get_sip_credentials: outboundTrunkAddress = sip.volai.cz (volai's own SIP proxy with digest auth, realm sip.volai.cz; measured: the platform refuses an INVITE larger than the UDP MTU, the same call passes over TCP), transport = tcp (schema is now enum [tcp, udp], UDP works too), port 5060 unchanged. The watchdog monitors the proxy healthz (SIP_PROXY_HEALTHZ_URL): ops e-mail when unreachable, when the auth data sync stalls or when the certificate has under 14 days left. The ElevenLabs post-call webhook has its HMAC secret in production and is enabled per agent (ELEVENLABS_POST_CALL_WEBHOOK_ID).
  • 12 Sep 2026 (1.10.0): GET /v1/numbers/{e164}/sip and MCP get_sip_credentials: outboundTrunkAddress is driven by its own configuration (it may equal server), field descriptions no longer mention a realm; inboundSignallingCidrs unchanged. The ElevenLabs post-call webhook matches inbound calls via metadata.phone_call.call_sid (it used to read the SIP Call-ID call_id, which never matched the call:sid key written by the initiation webhook) through findExistingCallByKeys shared with the conversations-sync cron (order call:conv -> call:attempt -> call:sid). Per-agent post-call webhook settings (platform_settings.workspace_overrides.webhooks) are migrated by the cron once ELEVENLABS_POST_CALL_WEBHOOK_ID is set; until then the cron keeps closing calls. The engine post-call accepts phone_call.external_number: null and caller_presentation; the uri_ caller prefix is stripped as in the initiation webhook. The call transfer target (transfer_to_number) is built from a separate VOLAI_SIP_TRANSFER_HOST, not from the public SIP domain. New internal source of auth data for the SIP proxy (GET /api/internal/sip-subscribers, outside v1, bearer + IP allowlist + rate limit).
  • 12 Sep 2026 (1.9.0): POST/PATCH /v1/agents and MCP create_agent/update_agent can now return a second warnings code: first_message_too_long, independent of first_message_no_ai_disclosure - and publishing an agent draft (POST /v1/agents/{id}/draft/publish, MCP publish_agent_draft) and rolling it back to an earlier revision (POST /v1/agents/{id}/draft/rollback, MCP rollback_agent_draft) now return the same warnings too, which they previously omitted entirely - both of them write the first line to the live agent. The estimate counts words, digits per character, and all-caps abbreviations up to four characters; a longer all-caps word counts as one word, so a company name written in capitals no longer inflates the estimate. The single threshold (an estimated duration over 7 seconds) is measured against what the caller actually hears - the greeting plus the call-recording notice, when enabled. An unchanged default greeting template never gets the warning, only a line the customer has edited.
  • 12 Sep 2026 (1.8.2): Documentation, integration guides and error actions point to AI assistant for access management. MCP makes clear that the voice engine is required to start an outbound task; a task can also be created with an ElevenLabs agent.
  • 12 Sep 2026 (1.8.1): OpenAPI now describes Idempotency-Key for 14 supported operations, response headers and the optional revision JSON body when deleting a task. Documentation corrections without changing paid-action behavior: useForOutboundTasks distinguishes true/false/omission, tasks support 1000 recipients and billing_unknown retains the original call and reservation until its price is known. Credit tax documents are available over REST and MCP; an API key can revoke only itself over REST; integration disconnect is REST/portal. Correction to 1.6.1: preview_task_csv is not an MCP tool; use POST /v1/tasks/csv-preview or the portal. Install commands share the onboarding generator, example tabs have unique anchors and Python preserves JSON values.
  • 11 Sep 2026 (1.8.0): The new REST POST /v1/dnc/{e164}/unblock and the corresponding MCP tool unblock_destination lift an automatic destination block; they also work for blocks created before this deployment. Older blocks may be absent from GET /v1/dnc and list_dnc because they predate the listing index, but direct unblock by phone number still works. Indexed blocks are returned in a blocked: [{e164, blockedAt, expiresAt}] array (times are Unix milliseconds) alongside the unchanged numbers. After a block is lifted, the failed-attempt counter starts over - three new failed attempts to the same number block it again, and lifting it again is not limited. groupCallsByConversation (the shared primitive behind /hovory, the CSV export, the Previous/Next navigation, and the stats) now sorts by representative.startedAt descending; it used to sort by key, i.e. alphabetically by conversation id. TestCallOutcome has a new no_answer value kept separate from failed, so the panel never claims a cause it doesn't know. A name written in ALL CAPS now gets an ALL CAPS vocative form (RADEK -> RADKU) in both the e-mail and the Overview header.
  • 11 Sep 2026 (1.7.1): agent_busy (HTTP 409, cause: "busy") was added to the shared error map PUBLIC_ERROR_HTTP/PUBLIC_ERROR_CAUSE (lib/types.ts). It is returned by switchAgentProvider (lib/service/engine-provider.ts) - the only portal admin action that switches an agent's provider; REST v1 and MCP have no such input (agents.switch_provider in the capability catalog, lib/capabilities.ts). The check uses a new GET /v1/calls/active client (lib/engine.ts listActiveCalls): the agent's call is matched PRIMARILY by the agent_id field, which the engine carries on an active call since the version that added it was deployed; the number stays a fallback for an older engine without it.
  • 11 Sep 2026 (1.7.0): POST/PATCH /v1/agents and the MCP create_agent/update_agent/save_agent_draft tools take a new voicemail: {enabled, action: "mark"|"hangup"|"message", message?} field - only for an agent with provider: "engine", otherwise voicemail_requires_engine; message is required when action: "message", up to 400 characters (invalid_voicemail_message). GET /v1/agents returns the configured value. The engine's post-call now carries answered_by/voicemail_reason/voicemail_message_left/voicemail_detected_at_secs; answered_by takes precedence over the previous transcript-based estimate (lib/answered-by.ts) only with human and voicemail - unknown is treated as "the engine didn't decide" and the transcript-based estimate is used instead. GET/list_calls/get_call for an outbound call handled by the engine also return voicemailReason (a fourth value, human_reply, for a short human reply), voicemailMessageLeft, and voicemailDetectedAtSecs.
  • 11 Sep 2026 (1.6.5): For an outbound call ended before answer the engine deletes the room and delivers a post-call webhook: empty transcript, call_duration_secs: 0 and the new additive field metadata.engine.termination_reason (no_answer or disconnected_before_answer). The call gets status: no_answer, endReason: no_answer and price 0 as before, only immediately. The GET /v1/calls reconciliation pairs engine outbound calls by call_sid and sends zero duration for calls that never connected. GET /openapi.json: answeredBy now carries a description about the outbound-only limitation.
  • 11 Sep 2026 (1.6.4): POST /v1/tasks and PATCH /v1/tasks/{id} (and create_task/update_task in MCP) accept up to 1000 recipients, POST /v1/tasks/csv-preview up to 1000 rows. A new task record size check (2 MB of serialized JSON) returns validation with field recipients.
  • 11 Sep 2026 (1.6.3): ElevenLabs initiation webhook: the payload's agent_id is now checked against the routed agent's elevenAgentId OR id - a foreign agent_id gets only a minimal response without conversation_config_override; the same check guards closing the conversation in the post-call webhook and the conversations-sync cron. CDR-sync cron: an unrecognized outbound CDR record from your own line (excluding the demo number), older than 600s and without an ambiguously matching existing record, is now billed as kind: "sip" at the outbound rate with no agent surcharge (it shows up in GET /v1/calls with kind: "sip"; the chargedSip counter is only in the cron's own response, not in the public API); a younger or ambiguously matching record is still just held for manual review. CallKind extended with "sip". The CDR shape of a real SIP client call has no production evidence yet (no registered softphone) - hence both safeguards.
  • 11 Sep 2026 (1.6.2): New endpoint POST /v1/tasks/{id}/items/{itemId}/resolve with body { action: "retry" | "skip", revision } and the MCP tool resolve_task_item; new error code item_not_resolvable (409, account), task_not_editable for a running or completed task. The engine call sync matches the account's own outbound leg by relay line and start time, closes an unanswered outbound call as no_answer and releases the tenant concurrency quota after closing. relay_lease_limit while dialing a task is a transient state that does not consume an attempt.
  • 11 Sep 2026 (1.6.1): POST /v1/tasks/csv-preview and the portal recognise the phone column regardless of case, surrounding spaces and a trailing colon and accept aliases (telefon, tel, mobile, phone number); the response always names the column phone. A single-column input without a header whose first value is a phone is treated as data. Without a phone column the preview returns a single phone error on the header instead of Phone is required on every row. The agent_not_ready contract is unchanged. Documentation correction, 12 Sep 2026: the original MCP-tool claim was incorrect; CSV preview is REST/portal-only.
  • 11 Sep 2026 (1.6.0): GET /v1/numbers/{e164}/sip and the MCP get_sip_credentials tool now also return outboundTrunkAddress, port, transport and inboundSignallingCidrs alongside server/username/password; MCP create_relay_lease and the get_sip_credentials description now explicitly distinguish server (registration) from outboundTrunkAddress (a platform's outbound trunk). The /en/docs/bring-your-own-agent guide, the ElevenLabs integration page and the blog post no longer put server into outbound_trunk_config.address - only outboundTrunkAddress.
  • 11 Sep 2026 (1.5.1): GET /v1/calls, GET /v1/calls/{id}, the call.completed webhook and MCP list_calls/get_call: answeredBy is present only when direction: "out" (older records included). POST /v1/messages and send_sms: an account without an active number and without a positive topup/refund/admin ledger entry gets insufficient_credit (HTTP 402, cause account) after three sent SMS.
  • 8 Sep 2026 (1.5.0): New REST endpoints: GET/PATCH /v1/account, PUT /v1/account/billing, GET /v1/api-keys, DELETE /v1/api-keys/{id} (self-revoke); PATCH /v1/calls/{id} and GET /v1/calls extended with from, to, agentId, flagged, goal, outcome query parameters; POST /v1/tools/test, POST /v1/tools/{id}/test, DELETE /v1/webhook, and GET /v1/tools/{id} now additionally returns agents; POST /v1/agents/{id}/draft/rollback; GET /v1/numbers/{e164}, GET/POST /v1/numbers/waitlist, DELETE /v1/numbers/waitlist/{offerId}, GET /v1/numbers/{e164}/sip/status; POST /v1/integrations, DELETE /v1/integrations/{id}, POST /v1/integrations/{id}/events/{eventId}/propose; GET /v1/changelog (no API key, x-volai-version on every v1 response including errors, 429 and /openapi.json). 16 matching new MCP tools: get_account, update_account, update_billing_details, list_api_keys, annotate_call, test_tool, remove_webhook, list_webhook_deliveries, rollback_agent_draft, reconcile_agent_draft_operation, test_call, get_number, join_number_waitlist, leave_number_waitlist, get_sip_status, get_changelog - revoking someone else's API key, creating an API key, and disconnecting an integration or card stay REST-only or portal-only (spec §3). The new capability catalog holds a capability field on every endpoint and tool; guard tests verify the error table and response example on /docs/api match the real error codes for every endpoint. Additive only - no existing status or code changed. The new content/changelog.json file is the single source of truth: /en/changelog, the changelog section on /docs/api, the Versioning section in SKILL.md, RSS (/en/feed/<area>), GET /v1/changelog and the MCP get_changelog tool are all generated views over it. Additive only - no existing content disappeared. New REST endpoints: GET/POST /v1/tasks, GET/PATCH/DELETE /v1/tasks/{id}, POST /v1/tasks/{id}/start, POST /v1/tasks/{id}/pause, POST /v1/tasks/{id}/reconcile, POST /v1/tasks/csv-preview. 7 matching new MCP tools: list_tasks, get_task, create_task, update_task, pause_task, reconcile_task, start_task (which requires repeating the real recipient count and budget, otherwise it returns an error with the real numbers) - deleting a task and previewing a CSV stay REST and portal only (spec §3). Portal: a Delete task button on the task detail page with type-to-confirm. Additive only - no existing status or code changed. New REST endpoints: GET /v1/credit/ledger, POST /v1/credit/topup, GET/PATCH /v1/credit/auto-topup, POST /v1/credit/auto-topup/setup, POST/DELETE /v1/credit/auto-topup/card, GET /v1/billing/documents, GET /v1/billing/documents/{id}, GET /v1/billing/documents/{id}/pdf; GET /v1/balance now additionally returns runway and notice. 6 matching new MCP tools: list_ledger, create_topup_link, get_auto_topup, disable_auto_topup, list_billing_documents, get_billing_document (get_balance extended with the same runway/notice) - get_billing_document does not return the PDF, which stays REST-only via GET /v1/billing/documents/{id}/pdf (binary output); turning auto top-up on and changing its amount or card stay behind a Stripe Checkout link only, MCP has neither (spec §2, §3). Additive only - no existing status or code changed. GET /v1/account now returns a new notifications.productUpdates field (on by default); there is a matching toggle in portal Settings. The daily email digest (cron 0 6 * * * UTC) only sends to accounts with a verified email and productUpdates !== false, at most one email per account per day. The List-Unsubscribe header and cookie-free one-click unsubscribe now also cover the reactivation email when UNSUBSCRIBE_SECRET is configured on the server - without it the email still sends, just without the unsubscribe link. Additive only - no existing status or code changed.
  • 8 Sep 2026 (1.4.3): Every input property of all 44 MCP tools carries its own description (clients see it in tools/list; the PATCH .../events/{eventId} and PUT /v1/agents/{id}/draft bodies expose it in openapi.json too). The invoice endpoints GET /v1/integrations/{id}/invoices[/{invoiceId}] list their error codes by real reachability in the docs and in OpenAPI - integration_storage_error was removed, it never came from the API - and their query validation returns the human-readable message like the rest of v1 (same for GET .../events). Additive only - no status or code changed.
  • 8 Sep 2026 (1.4.2): Fixed Apple event reads and confirmed updates: iCloud rejects UID searches, so event lists now return opaque CalDAV resource IDs. Pass externalId unchanged as eventId; reload any Apple event IDs saved from earlier versions. Invalid Apple IDs return 400 calendar_invalid_query. Google identifiers are unchanged.
  • 8 Sep 2026 (1.4.1): POST /v1/agents and create_agent accept useForOutboundTasks (choosing volai's own voice engine at creation, the same choice as the portal checkbox "Use for outbound tasks"; omitted = the deployment default, today ElevenLabs). Additive only - no status or code changed.
  • 8 Sep 2026 (1.4.0): Apple Calendar shares the same calendar flow over REST and MCP as Google. Fakturoid and ABRA Flexi added GET /v1/integrations/{id}/invoices[/{invoiceId}] plus the list_invoices and get_invoice tools (the interface only reads invoices). GET /v1/integrations and list_integrations also return providers with setup readiness and a browser connection URL. Provider credentials still require connection in the portal. Additive only - no status or code changed.
  • 7 Sep 2026 (1.3.0): Google Calendar entered the public interface - GET /v1/integrations, GET /v1/integrations/{id}/calendars, GET /v1/integrations/{id}/events, GET/PATCH /v1/integrations/{id}/events/{eventId} and six MCP tools (list_integrations, list_calendars, list_calendar_events, get_calendar_event, propose_calendar_update, confirm_calendar_update), which takes REST to 50 endpoints and MCP to 42 tools. Every error response also carries cause (request / account / busy / service - who fixes it) and action (one sentence on what to do). validation messages name the field, the actual value and the accepted maximum instead of the raw validator text; the input caps for an agent's name, instructions, goal and knowledge are ten times the product limits, so the limit is always reported by the product error with the exact number. MCP errors carry the same fields in structuredContent.error (including requestId) and a text prefixed by cause. Additive only, no status or code changed.
  • 6 Sep 2026 (1.2.0): The /v1/agents/{id}/draft* and /simulate endpoints lost the ok wrapper and plain-string errors - errors now share the same shape, {error:{code,message,requestId,docsUrl}}, as the rest of v1; revision in request bodies was renamed to expectedRevision; added hasMore/nextBefore pagination fields, X-Request-Id and RateLimit-* headers, POST /v1/webhook/test, GET /v1/webhook/deliveries, and GET /openapi.json. The draft endpoints were already public from 5 Sep 2026, but without a stable contract - they are therefore excluded from the versioning guarantee (rule 1 of the Versioning section) up to and including 1.2.0.

Täielik, pidevalt uuendatav loend asub lehel Muudatuste logi (saadaval ka RSS-voona).

Kokkulepped

Harjumused, mis kehtivad üle lõpp-punktide - mitte ainult ühe puhul.

Identifikaatorid

Iga id kannab prefiksit, mis nimetab kirje tüüpi, ja on muidu läbipaistmatu (ärge parsige seda edasi):

vk_ API-võti, ag_ agent, ad_ agendi mustand, ado_ mustandi toiming, c_ kõne, msg_ SMS-sõnum, tl_ tööriist, whd_ webhooki kohaletoimetamine, rl_ relay-rent, int_ ühendatud integratsioon, inv_ maksudokument (GET /v1/billing/documents), l_ saldo liikumise kirje, task_ väljamineva kõne ülesanne, item_ ülesande saaja, attempt_ kõnekatse ülesande kirjel, req_ päringu id (vt ülal Vea kuju).

Ajatemplid

Ajatemplid on peaaegu kõikjal unix-millisekundid (createdAt, startedAt, boughtAt, issuedAt, taxableAt) - ERAND on ühendatud kalendri JA ühendatud arvete väljad: start, end, fetchedAt (kalender) ja parameetrid timeMin/timeMax on RFC 3339 stringid (2026-09-08T10:00:00.000Z), mitte kunagi arv; GET /v1/integrations/{id}/invoices ja .../invoices/{externalId} on samuti stringid - fetchedAt on sama RFC 3339 kuju, dueDate on lihtne kuupäev (2026-09-08) otse Fakturoidist/ABRA Flexist või null, kui teenusepakkuja seda ei andnud. Kuupakett on teine erand: periodStart ja periodEnd (/v1/subscription, /v1/balance) on ISO 8601 stringid UTC-s, mitte millisekundid.

Lehitsemine - kolm skeemi ja loendid ilma selleta

GET /v1/messages, GET /v1/calls ja GET /v1/billing/documents võtavad limit + before (ms ajatempel, ekskluusiivne) ja vastavad väljadega hasMore/nextBefore - üksikasjad vt ülal Lehitsemine. Ühendatud kalendri sündmused (GET /v1/integrations/{id}/events) kasutavad selle asemel läbipaistmatut pageToken/nextPageToken - timeMin/timeMax/search peavad lehtede vahel jääma muutmata, pageToken üksi seda ei taga. GET /v1/credit/ledger võtab ainult limit (1-200, vaikimisi 50), kursorit üldse ei ole - see algab alati viimasest kirjest. GET /v1/tasks ilma ids-ita tagastab kuni 100 viimast ülesannet; ids loeb kuni viis määratud ülesannet päringu kohta, väitmata kogu rentniku inventari täielikkust. GET /v1/webhook/deliveries-il ei ole samuti kursorit ja see tagastab kuni 50 viimast kohaletoimetamist (õnnestunud, ebaõnnestunud ja testsündmused). Ühendatud arvete otsing on samuti vaikselt piiratud - esimesed 40 Fakturoidi või 50 ABRA Flexi rida, rohkema nägemiseks kursorit ei ole; kitsendage selle asemel otsingut. Kõik muu, mis tagastab loendi (agendid, numbrid, mobiilinumbrid, tööriistad, API-võtmed, helistamiskeeluloend, hääled), tagastab täieliku hulga ühe vastusena - lehitseda pole midagi.

Tundmatud ja tšehhikeelse nimega parameetrid

Tundmatu päringuparameeter ignoreeritakse peaaegu kõikjal vaikselt (et vanem klient ei läheks ühe lisaparameetri tõttu katki) - erand on ühendatud kalendri ja ühendatud arvete lõpp-punktid (/v1/integrations/{id}/...), mis lükkavad tundmatu parameetri tagasi veaga 400 validation, sest nad edastavad selle teenusepakkujale ning vaikselt maha jäetud filter näeks seal välja nagu puuduvad andmed, mitte nagu viga; ja, teisel põhjusel, GET /v1/credit/ledger ning GET /v1/billing/documents, mille päringuskeemid on meelega ranged, et kirjaviga väljas limit/before ebaõnnestuks valjusti, mitte ei ignoreeritaks vaikselt.

Mõned väljad säilitavad meelega tšehhikeelse nime: numbri aadressivoog (GET /v1/numbers/address-options, seejärel POST /v1/numbers/orders - tavaline POST /v1/numbers võtab ainult e164/region ja ignoreerib aadressi) edastab psc, obec, cobce, ulice (ainult kui aadressil on tänav) ja cp - need on RÚIAN-registri (operaatori enda aadressikoodide loend), kust number tellitakse, täpsed väljanimed, seega kahe vahel edasi-tagasi liikuvat väärtust ei tõlgita kunagi vaikselt valesti. GET /v1/calls/{id}/recording?stahnout=1 on ainus tšehhikeelse nimega parameeter väljaspool seda voogu (allalaadimine manusena, mitte sisseehitatuna). Kõik muu - identifikaatorid, väljad ja parameetrid - on inglise keeles.

Kvoodid ühes kohas

Iga kvooti mainitakse ka oma lõpp-punkti juures ülal - see on lihtsalt kokkuvõte:

  • 60 päringut/min API-võtme kohta (REST ja MCP jagavad seda, vt ülal Päringupiirangud)
  • SMS: 1 iga 2 s järel ja 100/päevas konto kohta, alles pärast esimest saldo täiendamist
  • Mobiilinumbrilt (fromNumber) saadetud SMS: lisaks 20 sõnumit päevas konto kohta esimese 30 päeva jooksul pärast numbri ostmist, pärast seda 50; kuni kaks mobiilinumbrit konto kohta
  • Väljaminevad kõned (agent, sild, prooviversioon): 10/min ja 1000/päevas konto kohta, korraga kuni 2 sisseehitatud agendi kõnet
  • Kutsungid (POST /v1/rings): 30/min ja 500/päevas konto kohta ning 120/tunnis ühele numbrile, sõltumatult kõnepiirangutest
  • Häälsõnumid (POST /v1/voice-messages): kuni 200 ööpäevas konto kohta, lisaks tavalistele kõnepiirangutele
  • Prooviversiooni kõne ilma oma numbrita (POST /v1/calls väljaga systemPrompt välja agentId/from asemel): lisaks 3/24 h konto kohta JA ühine piirang 30/tunnis KÕIGI kontode peale kokku - ühine piirang võib teid tabada ilma teie süüta.
  • POST /v1/agents/{id}/test-call: 3/päevas konto kohta
  • POST /v1/tools/test ja .../{id}/test: 10/min konto kohta
  • POST /v1/agents/{id}/simulate: 20/tunnis konto kohta
  • POST /v1/webhook/test: 10/tunnis konto kohta
  • GET /v1/changelog: 30/min IP kohta (API-võtit ei vajata)
  • Ülesanded: töötav ülesanne helistab ühe cron-tiksu kohta kuni ÜHELE saajale. Üldine järjekord jääb ajastusele */2 * * * * ja puudutab kõigi kontode peale kuni 20 ülesannet; registreeritud PetCenteri ülesanded kasutavad eraldi tiksu * * * * * ja järjekorda samade samaaegsuse ja kõnetempo piirangutega. Mõlemad järjekorrad pöörlevad õiglaselt, kui ootab üle 20 ülesande.

Webhooki kordused

Ebaõnnestunud kohaletoimetamine saab sama väljasaatmise sees kuni 3 katset, 3 sekundi vahega. Kõnesündmuste (call.completed, call.failed, call.no_answer, call.missed) ja sündmuse message.received puhul sellega asi ei lõpe: sündmus jääb järjekorda ja kohaletoimetamist korratakse järgmiste minutite jooksul veel mõned korrad, kokku kuni 5 vooru - deduplikeerige keha event_id järgi harvaesineval juhul, kui see saabub rohkem kui üks kord. message.sent ja testsündmusel webhook.test järjekorda ei ole: pärast ebaõnnestumist see lihtsalt logitakse ega saadeta uuesti. Edenemist, sh enne viimast vooru toimunud voorusid, näete päringuga GET /v1/webhook/deliveries (või list_webhook_deliveries) - attempts seal on katsete summa KÕIGI voorude peale.

Aegumine

v1 on seni ainult lisanud (vt ülal Versioonimine) - ainus erand oli versioon 1.5.1, mis lõpetas SISSETULEVATE kõnede puhul välja answeredBy tagastamise (sellel väljal ei olnud seal kunagi tähendusrikast väärtust; väljaminevate kõnede puhul on see muutmata). volai ei ole veel ühtegi välja täielikult kasutusest kõrvaldanud. Kui ta seda teeb, märgitakse väli GET /openapi.json-is deprecated: true ja vastus kannab päiseid Deprecation/Sunset vähemalt 90 päeva ette, ning MCP-vastus, mis seda puudutab, saab kirje väljale warnings (sama väli, mida täna juba kasutatakse tehisintellekti määruse avalikustamise hoiatuse jaoks) - eemaldamine ise tuleb ainult uue põhiversiooniga (v2), mitte kunagi vaikselt v1 sees.

Kõned vs. vestlused - vt enne arvude summeerimist allpool jaotises Kõned sama nimega lõiku.

Volitusandmed (parool, token, rakendusespetsiifiline parool) lähevad ainult sinna, kuhu kasutaja on need juba pannud kohta, mida te saate lugeda (keskkonnamuutuja või tema nimetatud fail) - ärge küsige neid kunagi vestluses ja ärge neid kordage; kehtib täna Apple'i kalendri ja ABRA Flexi kohta (vt allpool kalendri- ja arvete jaotisi).

Mida API ei suuda

Kogu telefonipoolt juhite API ja MCP kaudu - numbrid, kõned, SMS-id, agendid, webhookid, relay ja helistamiskeeluloend. Teie profiil, arveldusaadress ja ettevõtte andmed käivad samuti API kaudu (jaotis Konto ülal). Mõned asjad jäävad meelega ainult portaali:

MisKus see on ja miks
Saldo lisaminePortaal /kredit (nii ühekordsed täiendused kui automaatne täiendamine). Kaardiga maksmine on inimese samm - agent, kes täiendab ise oma saldot, et saaks edasi helistada, on täpselt see, mida me ei taha. Kui toiming jõuab veani insufficient_credit, öelge seda kasutajale ja saatke ta siia.
Uue API-võtme loominePortaal /api-a-mcp. Loend (GET /v1/api-keys) ja OMA võtme tühistamine (DELETE /v1/api-keys/{id}) käivad API kaudu - ainult uue võtme loomine mitte: võti, mis loob teise võtme, tähendaks, et üks lekkinud võti annab püsiva juurdepääsu, mida ei saa kunagi tühistada.
Parooli muutminePortaal /nastaveni. Nimi, konto keel ja arveldusaadress käivad läbi PATCH /v1/account ja PUT /v1/account/billing (jaotis Konto ülal) - parool mitte, see on puhtalt brauseripoolne toiming oma kinnitusega.
MaksuarvedPortaal /kredit, jaotis Arved - iga saldo täienduse kohta ootab seal allalaaditav PDF; sama PDF laaditakse alla päringuga GET /v1/billing/documents/{id}/pdf. API ei saa arvet välja anda: see on raamatupidamisdokument oma järjestikuse numeratsiooniga, mis ei muutu pärast väljaandmist kunagi ja mida ei tohi kunagi kaks korda luua.
SMS häälnumbritelMitte kusagil - volai häälnumbrid ei saa SMS-e vastu võtta. Mobiilinumbri lisand ja number kõnede ja SMS-ide jaoks võtavad SMS-e vastu, vt allpool jaotisi mobiilinumbrid ja Number kõnede ja SMS-ide jaokss.

Teises suunas puudub meelega rohkem kui üks asi: ostetud numbri (DELETE /v1/numbers/{e164}), mobiilinumbri (DELETE /v1/sms-numbers/{e164}) või number kõnede ja SMS-ide jaoks (DELETE /v1/voice-sms-numbers/{e164}) vabastamine on olemas nii REST API-s kui portaalis, kuid mitte MCP tööriistade seas - pöördumatu toiming on seal ühe valesti loetud lause kaugusel liiga riskantsest. Meelega puuduvad ka: salvestise allalaadimine (binaarne keha, GET /v1/calls/{id}/recording), üksiku sõnumi või tööriista detail (loendid list_messages/list_tools kannavad juba samu välju, lihtsalt mitte ühe ID kaupa) ja eraldi testkõne tööriist - make_call väljaga agentId valib sama kõne nagu POST /v1/agents/{id}/test-call, lihtsalt ilma selle rangema päevalimiidita 3 kõnet.

Konto

Profiil, hädaabiaadress, arveldusandmed ja API-võtmete ülevaade. Uute API-võtmete loomine (POST /v1/api-keys) ei ole selle liidese kaudu saadaval - võti, mis loob võtmeid, muudaks ühe võtme kaotamise püsivaks juurdepääsuks. Looge uus võti portaalis (jaotis Juurdepääs ja API). E-posti teavitused (callSummary, lowCredit, reactivation, productUpdates) on selle liidese kaudu ainult LUGEMISEKS - kirjutada saab ainult portaalis, sest lowCredit on ainus pidur saldo lõppemise ja märkamatu katkestuse vahel.

GET/v1/account

Profiil, hädaabiaadress, arveldusandmed ja e-posti teavituste olek (ainult lugemiseks).

Päring

bash
curl https://volai.cz/v1/account \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "account": {
    "id": "u_8f2a1c9d3b47",
    "email": "radek@example.com",
    "name": "Radek Klein",
    "locale": "cs",
    "emailVerified": true,
    "createdAt": 1755000000000,
    "companyName": "Ukázková s.r.o.",
    "address": { "street": "Na Zámku 636", "city": "Nehvizdy", "zip": "250 81" },
    "billing": null,
    "notifications": { "callSummary": true, "lowCredit": true, "reactivation": true, "productUpdates": true, "weeklySummary": true }
  },
  "testCalls": { "max": 3, "remaining": 2, "resetAt": 1755086400000 },
  "serviceStopped": null
}

Veaolekud

  • 404user_not_foundSelle API-võtme omanikku kontol ei leidu - ebatavaline olukord; võtke ühendust toega.

PATCH/v1/account

Uuendab nime ja konto keelt. locale määrab e-kirjade ja maksudokumentide keele, MITTE selle vastuse keele - REST ja MCP räägivad alati inglise keeles. Nõutav on vähemalt üks väli.

Päring

bash
curl -X PATCH https://volai.cz/v1/account \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"locale":"en"}'

Vastus

json
{
  "account": {
    "id": "u_8f2a1c9d3b47",
    "email": "radek@example.com",
    "name": "Radek Klein",
    "locale": "en",
    "emailVerified": true,
    "createdAt": 1755000000000,
    "companyName": "Ukázková s.r.o.",
    "address": { "street": "Na Zámku 636", "city": "Nehvizdy", "zip": "250 81" },
    "billing": null,
    "notifications": { "callSummary": true, "lowCredit": true, "reactivation": true, "productUpdates": true, "weeklySummary": true }
  }
}

Veaolekud

  • 400validationPäringu keha ei ole kehtiv JSON-objekt, ei sisalda uuendatavat välja, name on tühi string või pikem kui 200 tähemärki, või locale ei ole cs ega en.
  • 400invalid_nameNimi on pärast alguse ja lõpu tühikute eemaldamist tühi.
  • 404user_not_foundSelle API-võtme omanikku kontol ei leidu - ebatavaline olukord; võtke ühendust toega.

PUT/v1/account/billing

Salvestab hädaabiaadressi ja arveldusandmed. address sisaldab (kui see on olemas) tänavat, linna ja postiindeksit korraga - ühtegi neist ei saa üksi saata. company, ico ja dic ÜHENDATAKSE juba salvestatuga: puuduv väli jääb MUUTMATA, ainult selgesõnaline tühi string ("") kustutab selle (dic puhul kustub ka selle VIES-kinnitus). Välismaist EL-i käibemaksukohustuslase numbrit kontrollitakse VIES-registris; vastuses olev vies täidetakse ainult siis, kui tulemus sisaldab kinnitatud käibemaksunumbrit (värskelt või säilitatud varasemast kinnitusest). Kodumaist käibemaksunumbrit (CZ...) ei kontrollita - see ei mõjuta määra.

Päring

bash
curl -X PUT https://volai.cz/v1/account/billing \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"company":"Ukázková s.r.o.","dic":"SK9999999999","address":{"street":"Na Zámku 636","city":"Nehvizdy","zip":"250 81"}}'

Vastus

json
{
  "billing": {
    "company": "Ukázková s.r.o.",
    "ico": null,
    "dic": "SK9999999999",
    "dicCountry": "SK",
    "dicVerified": true,
    "dicName": "Ukázková s.r.o."
  },
  "address": { "street": "Na Zámku 636", "city": "Nehvizdy", "zip": "250 81" },
  "vies": { "dic": "SK9999999999", "country": "Slovakia", "name": "Ukázková s.r.o." }
}

Veaolekud

  • 400validationPäringu keha ei ole kehtiv JSON-objekt, sisaldab tundmatut välja (skeem on range), company/ico/dic on pikem kui 120/20/20 tähemärki, address sisaldab tundmatut välja, address.street või address.city on tühi või pikem kui 200 tähemärki, või address.zip on lühem kui 3 või pikem kui 10 tähemärki.
  • 400invalid_addressTänav või linn jääb pärast alguse ja lõpu tühikute eemaldamist tühjaks (näiteks ainult tühikutest koosnev väli) või postiindeks ei läbi normaliseerimist - see ei tundu postiindeksina.
  • 400invalid_icoEttevõtte ID (IČO) kontrollsumma ei klapi.
  • 400invalid_dicKäibemaksunumber ei ole kehtiva kujuga (kodumaine CZ pluss 8-10 numbrit või välisriigi kood pluss registrinumber).
  • 400foreign_vat_unsupportedKäibemaksunumbri riigikood ei kuulu EL-i liikmesriigile - pöördmaksustamine kehtib ainult EL-i sees.
  • 400vat_id_not_foundEuroopa käibemaksuregister (VIES) ei tunne seda käibemaksunumbrit. Ilma kinnituseta arvestatakse Tšehhi käibemaksu.
  • 503vat_registry_unavailableVIES-register on ajutiselt kättesaamatu - proovige hiljem uuesti; varasem kinnitus (kui see on olemas) jääb kehtima.
  • 404user_not_foundSelle API-võtme omanikku kontol ei leidu - ebatavaline olukord; võtke ühendust toega.

POST/v1/account/cancellation-request

Taotleb konto sulgemist, nagu vorm Sulge konto jaotises Seaded. reason on kohustuslik (too_expensive, callers_hang_up, missing_feature, not_needed või other), note on valikuline märkus kuni 500 tähemärki. Taotlus kontot EI muuda ega kustuta midagi: see registreeritakse, volai meeskonda teavitatakse põhjusest ja klient saab konto keeles kinnitusliku e-kirja; konto peatatakse seejärel käsitsi. Uuesti saatmine on kahjutu: tagastatakse algne taotlus väärtusega alreadyRequested: true ning uut e-kirja ei saadeta.

Päring

bash
curl -X POST https://volai.cz/v1/account/cancellation-request \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"reason":"callers_hang_up","note":"Volající zavěšují po první větě."}'

Vastus

json
{
  "cancellationRequest": {
    "reason": "callers_hang_up",
    "note": "Volající zavěšují po první větě.",
    "requestedAt": 1793520000000,
    "alreadyRequested": false
  }
}

Veaolekud

  • 400validationPäringu keha ei ole kehtiv JSON-objekt, sisaldab tundmatut välja (skeem on range), reason puudub või ei ole üks viiest väärtusest, või note on pikem kui 500 tähemärki.
  • 404user_not_foundSelle API-võtme omanikku kontol ei leidu - ebatavaline olukord; võtke ühendust toega.

GET/v1/api-keys

Konto API-võtmed. id on ainult võtme sõrmejälje esimesed 12 märki - täielikku sõrmejälge ei tagastata kunagi.

Päring

bash
curl https://volai.cz/v1/api-keys \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "apiKeys": [
    {
      "id": "3f9a2c8e1b04",
      "label": "Production integration",
      "prefix": "vk_8h2j4kx",
      "createdAt": 1750000000000,
      "lastUsedAt": 1757280000000
    }
  ]
}

DELETE/v1/api-keys/{id}

Enda tühistamine: API kaudu võib võti tühistada ainult ENNAST, mitte kunagi mõnda teist konto võtit - muidu lõikaks varastatud võti ära kõik teised integratsioonid ja jääks ise aktiivseks. Teiste võtmete tühistamine on võimalik ainult portaalis. Pärast tühistamist saadetakse konto omanikule e-kiri, olenemata sellest, kes tühistamist taotles.

Päring

bash
curl -X DELETE https://volai.cz/v1/api-keys/3f9a2c8e1b04 \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "revoked": true
}

Veaolekud

  • 404not_foundKontol ei ole selle id-ga võtit.
  • 403api_key_self_onlyTeel olev id kuulub teisele võtmele kui sellele, mis seda päringut autentib - API kaudu saate tühistada ainult iseennast.

Saldo

balanceHal ja kõik selle API määrad on ilma käibemaksuta - volai on käibemaksukohustuslane, kuid käibemaksu arvestatakse alles siis, kui täiendate saldot portaalis kaardiga (vt leht /cenik), API ise seda ei arvesta. Täielik läbivaatus voo näidetega asub aadressil /docs/kredit.

GET/v1/balance

Konto praegune saldo, pluss runway (hinnang, mitu päeva saldo praeguse kulutempo juures vastu peab) ja notice (sama teade, mida näidatakse portaali ülevaatelehel, null, kui teadet ei ole) - mõlemad LISANDUVAD, nii et klient, mis loeb ainult balanceHal/balanceCzk/currency, jätkab tööd. Samuti topupBalanceHal (täiendatud osa, negatiivne, kui konto on võlgu) ja subscription (kuupakett või null): balanceHal jääb kuupaketi saldo ja täiendatud saldo KOGUSUMMAKS.

Päring

bash
curl https://volai.cz/v1/balance \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "balanceHal": 8730,
  "balanceCzk": 87.30,
  "currency": "CZK",
  "runway": { "dailyAverageHal": 2910, "runwayDays": 3 },
  "notice": { "kind": "runway", "days": 3 },
  "topupBalanceHal": 8730,
  "subscription": null,
  "serviceStopped": null
}

Veaolekud

  • 503ledger_unavailableSaldot või liikumiste ajalugu ei õnnestunud praegu lugeda - proovige varsti uuesti.

GET/v1/credit/ledger

Saldo liikumiste ajalugu, uusimad eespool, ILMA kursorita (ainult limit, 1-200, vaikimisi 50). Iga kirje description on ingliskeelne kirjeldus, mis KOOSTATAKSE väljast type - salvestatud tšehhikeelne märkus ei lähe kunagi välja.

Päring

bash
curl "https://volai.cz/v1/credit/ledger?limit=3" \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "ledger": [
    { "id": "l_9f2a1c8e", "ts": 1757280000000, "type": "call_out", "amountHal": -420, "grossHal": null, "description": "Outbound call" },
    { "id": "l_7c1e9a2f", "ts": 1757193600000, "type": "number_fee", "amountHal": -9900, "grossHal": null, "description": "Monthly number fee for +420601234567" },
    { "id": "l_3b7e1c9a", "ts": 1757107200000, "type": "topup", "amountHal": 50000, "grossHal": 60500, "description": "Card top-up" }
  ]
}

Veaolekud

  • 400validationlimit on vahemikust 1-200 väljas või päring sisaldab lisatundmatut parameetrit.
  • 503ledger_unavailableSaldot või liikumiste ajalugu ei õnnestunud praegu lugeda - proovige varsti uuesti.

POST/v1/credit/topup

Loob Stripe Checkouti lingi kindla summa ühekordseks täienduseks CZK-des. Midagi ei maksta enne, kui INIMENE on makse brauseris lõpetanud. Toetab päist Idempotency-Key.

Päring

bash
curl -X POST https://volai.cz/v1/credit/topup \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: topup-2026-09-08-01" \
  -d '{"amountCzk": 500}'

Vastus

json
{
  "checkoutUrl": "https://checkout.stripe.com/c/pay/cs_test_a1b2c3d4"
}

Veaolekud

  • 400validationamountCzk puudub, ei ole positiivne täisarv või keha sisaldab tundmatut välja.
  • 400invalid_amountSumma ei ole üks pakutavatest fikseeritud väärtustest.
  • 400billing_address_requiredKonto arveldusaadress puudub või on poolik - ilma selleta ei saa kehtivat maksudokumenti välja anda. Lisage see päringuga PUT /v1/account/billing.
  • 404user_not_foundSelle API-võtme omanikku kontol ei leidu - ebatavaline olukord; võtke ühendust toega.
  • 503stripe_not_configuredMaksed on selle volai juurutuse jaoks välja lülitatud - see ei ole teie päringule omane.
  • 502stripe_errorStripe keeldus makseseansi loomisest - proovige varsti uuesti.

GET/v1/credit/auto-topup

Automaatse täiendamise olek: lubatud/keelatud, lävi, summa, salvestatud kaart (ainult kaubamärk ja neli viimast numbrit), kulu ja ülempiir selle kalendrikuu kohta.

Päring

bash
curl https://volai.cz/v1/credit/auto-topup \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "autoTopup": {
    "enabled": true,
    "thresholdHal": 10000,
    "amountHal": 50000,
    "card": { "brand": "visa", "last4": "4242" },
    "spentThisMonthHal": 50000,
    "monthlyCapHal": 1000000,
    "disabledReason": null
  }
}

PATCH/v1/credit/auto-topup

AINULT selle välja lülitamine ({"enabled": false}) ja/või läve muutmine ({"thresholdHal": ...}) - sisselülitamine või summa muutmine käib ainult läbi POST .../setup (Stripe Checkout), mitte kunagi otsekirjutusega, nii et lihtne enabled: true ei saa kunagi käivitada salvestatud kaardilt maksmist ilma inimeseta.

Päring

bash
curl -X PATCH https://volai.cz/v1/credit/auto-topup \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"thresholdHal": 20000}'

Vastus

json
{
  "autoTopup": {
    "enabled": true,
    "thresholdHal": 20000,
    "amountHal": 50000,
    "card": { "brand": "visa", "last4": "4242" },
    "spentThisMonthHal": 50000,
    "monthlyCapHal": 1000000,
    "disabledReason": null
  }
}

Veaolekud

  • 400validationKeha sisaldab enabled: true või amountHal (mõlemad kuuluvad ainult päringusse POST .../setup), thresholdHal on pakutavast vahemikust väljas või kehas ei ole ei enabled ega thresholdHal.
  • 400autotopup_not_configuredAutomaatne täiendamine ei ole kunagi läbinud POST .../setup - pole midagi välja lülitada, muuta ega kaarti asendada.
  • 400invalid_amountSumma ei ole üks pakutavatest fikseeritud väärtustest.

POST/v1/credit/auto-topup/setup

Loob Stripe Checkouti seansi, mille lõpetamine arveldab KOHE amountHal esimese täiendusena ja ainult see salvestab kaardi tulevasteks automaatseteks täiendusteks - töötab ka varem salvestatud kaardiga. Ainus viis automaatne täiendamine sisse lülitada või selle summat muuta; ainult läve muutmine ilma arveldamiseta on ülalolev PATCH. Arveldusaadress on kohustuslik. Keeldutakse veaga subscription_cap_active, kui kuupakett töötab kulutuste ülempiiriga. Toetab päist Idempotency-Key.

Päring

bash
curl -X POST https://volai.cz/v1/credit/auto-topup/setup \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: autotopup-setup-2026-09-08-01" \
  -d '{"thresholdHal": 10000, "amountHal": 50000}'

Vastus

json
{
  "checkoutUrl": "https://checkout.stripe.com/c/pay/cs_test_a1b2c3d4"
}

Veaolekud

  • 400validationthresholdHal või amountHal puudub, ei ole mittenegatiivne/positiivne täisarv või keha sisaldab tundmatut välja.
  • 400invalid_amountSumma ei ole üks pakutavatest fikseeritud väärtustest.
  • 400billing_address_requiredKonto arveldusaadress puudub või on poolik - ilma selleta ei saa kehtivat maksudokumenti välja anda. Lisage see päringuga PUT /v1/account/billing.
  • 409subscription_cap_activeAutomaatset täiendamist ei saa sisse lülitada, kui pakett töötab kulutuste ülempiiriga. Lülitage pakett kaardilt täiendustele (PATCH /v1/subscription tagastab kinnituslingi) või jätke ülempiir.
  • 404user_not_foundSelle API-võtme omanikku kontol ei leidu - ebatavaline olukord; võtke ühendust toega.
  • 503stripe_not_configuredMaksed on selle volai juurutuse jaoks välja lülitatud - see ei ole teie päringule omane.
  • 502stripe_errorStripe keeldus makseseansi loomisest - proovige varsti uuesti.

POST/v1/credit/auto-topup/card

Loob Stripe Checkouti seansi kaardi seadistamise režiimis automaatse täiendamise jaoks - midagi ei arveldata, salvestatakse ainult uus kaart.

Päring

bash
curl -X POST https://volai.cz/v1/credit/auto-topup/card \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "checkoutUrl": "https://checkout.stripe.com/c/pay/cs_test_a1b2c3d4"
}

Veaolekud

  • 400autotopup_not_configuredAutomaatne täiendamine ei ole kunagi läbinud POST .../setup - pole midagi välja lülitada, muuta ega kaarti asendada.
  • 404user_not_foundSelle API-võtme omanikku kontol ei leidu - ebatavaline olukord; võtke ühendust toega.
  • 503stripe_not_configuredMaksed on selle volai juurutuse jaoks välja lülitatud - see ei ole teie päringule omane.
  • 502stripe_errorStripe keeldus makseseansi loomisest - proovige varsti uuesti.

DELETE/v1/credit/auto-topup/card

Eraldab salvestatud kaardi KOHE - kustutatakse KOGU automaatse täiendamise seadistus (sh lävi ja summa), mitte ainult kaart. Uuesti sisselülitamine toimib ainult läbi POST .../setup, mis arveldab kohe esimese täienduse. Kui töötav kuupakett maksab sama kaardiga, lükatakse kõne tagasi veaga invalid_state: asendage kaart hoopis päringuga POST /v1/subscription/card.

Päring

bash
curl -X DELETE https://volai.cz/v1/credit/auto-topup/card \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "removed": true
}

Veaolekud

  • 400invalid_stateKaart on ka töötava kuupaketi kaart, seega selle eraldamine üksi põhjustaks järgmise pikendamise ebaõnnestumise. Asendage see päringuga POST /v1/subscription/card; eraldada saab selle iseseisvalt pärast paketi lõppemist.

GET/v1/account/spend-cap

Kuine kulutuste ülempiir: kas see on seatud, capHal, warnShare, inboundAboveCap ning selle kalendrikuu kulu kõnedele, SMS-idele ja häälagendile (monthSpendHal, kuu YYYY-MM Praha aja järgi), jääk ja kas ülempiir on reached. Kulu loetakse igal kontol, ka ilma ülempiirita; numbritasusid ja kuupaketti ei arvestata.

Päring

bash
curl https://volai.cz/v1/account/spend-cap \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "spendCap": {
    "enabled": true,
    "capHal": 500000,
    "warnShare": 0.8,
    "inboundAboveCap": false,
    "month": "2026-11",
    "monthSpendHal": 183400,
    "remainingHal": 316600,
    "reached": false,
    "updatedAt": 1793520000000
  }
}

Veaolekud

  • 503ledger_unavailableSaldot või liikumiste ajalugu ei õnnestunud praegu lugeda - proovige varsti uuesti.

PUT/v1/account/spend-cap

Seab või muudab kuist kulutuste ülempiiri: capHal täisarvuliste sadasosadena (50 kuni 1 000 000 CZK), valikuline warnShare (0,5 kuni 0,99, vaikimisi 0,8) hoiatuskirja jaoks ja valikuline inboundAboveCap (vaikimisi false). Kui kuu kulu ülempiiri saavutab, ebaõnnestuvad uued väljaminevad kõned, kutsungid, prooviversiooni kõned ja SMS-id veaga spend_cap_reached (HTTP 402), ning teie agentidele sissetulevad kõned lõppevad pärast ühte lauset, mis ütleb, et liin on ajutiselt kättesaamatu (endReason: spend_cap, hind 0), kui inboundAboveCap ei ole true. Juba käimasolevaid kõnesid ei katkestata, seega võib kulu ülempiiri nende maksumuse võrra ületada. Agendita edastamist ülempiir ei peata ja ülempiiri ületanud konto SIP-liinid lahkuvad SIP-proksist (peatuvad ka sissetulevad kõned teie enda keskjaama), kui inboundAboveCap ei ole true; väärtusega inboundAboveCap: true jääb liin proksisse, seega ülempiir ei peata ka väljaminevaid kõnesid teie keskjaamast ja need arveldatakse endiselt. Automaatne täiendamine jääb muutmata.

Päring

bash
curl -X PUT https://volai.cz/v1/account/spend-cap \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"capHal": 500000, "warnShare": 0.8, "inboundAboveCap": false}'

Vastus

json
{
  "spendCap": {
    "enabled": true,
    "capHal": 500000,
    "warnShare": 0.8,
    "inboundAboveCap": false,
    "month": "2026-11",
    "monthSpendHal": 183400,
    "remainingHal": 316600,
    "reached": false,
    "updatedAt": 1793520000000
  }
}

Veaolekud

  • 400validationcapHal puudub, ei ole täisarv sadasosades vahemikus 5000 kuni 100 000 000, warnShare on väljaspool vahemikku 0,5 kuni 0,99, inboundAboveCap ei ole tõeväärtus või keha sisaldab tundmatut välja.
  • 502ledger_failedÜlempiiri ei õnnestunud praegu kirjutada - midagi ei muudetud. Proovige varsti uuesti.
  • 503ledger_unavailableSaldot või liikumiste ajalugu ei õnnestunud praegu lugeda - proovige varsti uuesti.

DELETE/v1/account/spend-cap

Eemaldab kuise kulutuste ülempiiri; konto käitub nagu enne selle seadmist. Seadmata ülempiiri eemaldamine õnnestub samuti.

Päring

bash
curl -X DELETE https://volai.cz/v1/account/spend-cap \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "spendCap": {
    "enabled": false,
    "capHal": null,
    "warnShare": null,
    "inboundAboveCap": null,
    "month": "2026-11",
    "monthSpendHal": 183400,
    "remainingHal": null,
    "reached": false,
    "updatedAt": null
  }
}

Veaolekud

  • 502ledger_failedÜlempiiri ei õnnestunud praegu kirjutada - midagi ei muudetud. Proovige varsti uuesti.
  • 503ledger_unavailableSaldot või liikumiste ajalugu ei õnnestunud praegu lugeda - proovige varsti uuesti.

GET/v1/billing/documents

Väljaantud maksudokumentide (saldo täiendused, kuupaketi maksed, võtmed-kätte tellimused) ja kreeditarvete loend, uusimad eespool. before on kursor (Unix ms, ekskluusiivne) - saatke eelmise lehe nextBefore. Aluseks olev salvestus ei tagasta kunagi rohkem kui 100 kirjet kõne kohta, isegi kui limit küsib rohkem.

Päring

bash
curl "https://volai.cz/v1/billing/documents?limit=2" \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "documents": [
    {
      "id": "inv_4kX9mQ2pRtLz",
      "number": "VF2026000042",
      "issuedAt": 1757280000000,
      "taxableAt": 1757280000000,
      "netHal": 50000,
      "vatHal": 10500,
      "grossHal": 60500,
      "vatRatePercent": 21,
      "reverseCharge": false,
      "kind": "invoice",
      "description": "Prepaid credit for volai telecommunications services",
      "customer": { "name": "Radek Klein", "street": "Na Zámku 636", "city": "Nehvizdy", "zip": "250 81" },
      "paymentRef": "pi_3PQr7s2eZvKYlo2C1a2b3c4d",
      "pdfUrl": "https://volai.cz/v1/billing/documents/inv_4kX9mQ2pRtLz/pdf"
    }
  ],
  "hasMore": false,
  "nextBefore": null
}

Veaolekud

  • 400validationlimit või before on lubatud vahemikust väljas või päring sisaldab lisatundmatut parameetrit.

GET/v1/billing/documents/{id}

Ühe maksudokumendi andmed - summad, käibemaks, klient, maksetunnus ja link PDF-ile.

Päring

bash
curl https://volai.cz/v1/billing/documents/inv_4kX9mQ2pRtLz \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "document": {
    "id": "inv_4kX9mQ2pRtLz",
    "number": "VF2026000042",
    "issuedAt": 1757280000000,
    "taxableAt": 1757280000000,
    "netHal": 50000,
    "vatHal": 10500,
    "grossHal": 60500,
    "vatRatePercent": 21,
    "reverseCharge": false,
    "kind": "invoice",
    "description": "Prepaid credit for volai telecommunications services",
    "customer": { "name": "Radek Klein", "street": "Na Zámku 636", "city": "Nehvizdy", "zip": "250 81" },
    "paymentRef": "pi_3PQr7s2eZvKYlo2C1a2b3c4d",
    "pdfUrl": "https://volai.cz/v1/billing/documents/inv_4kX9mQ2pRtLz/pdf"
  }
}

Veaolekud

  • 404invoice_not_foundKontol ei ole selle id-ga dokumenti (võõras või puuduv id annab sama vea).

GET/v1/billing/documents/{id}/pdf

Laadib sama dokumendi alla kujul application/pdf - see renderdatakse igal allalaadimisel värskelt, mitte ei salvestata.

Päring

bash
curl https://volai.cz/v1/billing/documents/inv_4kX9mQ2pRtLz/pdf \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -o invoice.pdf

Veaolekud

  • 404invoice_not_foundKontol ei ole selle id-ga dokumenti (võõras või puuduv id annab sama vea).

Kuupakett

Kuupakett arveldab salvestatud kaardilt kord kuus ja lisab kuusaldo, mida kulutatakse enne täiendatud saldot ja mis aegub perioodi lõpus. Igal astmel on hind ja suurem kuusaldo, mõlemad ilma käibemaksuta (vt tiers päringus GET /v1/subscription). Raha liigub ainult siis, kui kaardi juures on inimene: see API ei alusta ega suurenda kunagi korduvaid arveldusi iseenesest. Paketi alustamine, ebaõnnestunud pikenduse tasumine ja kaardi asendamine tagastavad Stripe Checkouti lingi ning astme tõstmine, lõppevaks seatud paketi jätkamine või üleminek kaardilt täiendustele tagastavad confirmUrl-i, mille peab inimene portaalis kinnitama. Täielik läbivaatus asub aadressil /docs/kredit.

GET/v1/subscription

Konto kuupakett ja kõik, mis on selle pakkumiseks vajalik. subscription on null, kui kontol ei ole kunagi paketti olnud; lõppenud pakett tagastatakse ikkagi, väärtusega status: "canceled". tiers loetleb pakutavad astmed koos nende priceHal ja creditHal (sadasosades, ilma käibemaksuta). topupBalanceHal on täiendatud saldo; GET /v1/balance kannab samu kahte plokki kogusumma kõrval. available ütleb, kas see konto saab praegu alustada UUT paketti: pakkumine on kontol sisse lülitatud ja kontol ei ole töötavat paketti (active, past_due), sest teist ei saa alustada ja checkout tagastaks subscription_exists; kui pakett on lõppenud (canceled), on see taas true. Olemasolev pakett tagastatakse alati ja jätkab tööd ka siis, kui see on false. recommendation on odavaim viis maksta selle eest, mida konto viimase 30 päeva jooksul tegelikult kulutas (sama arvutus nagu veebilehe kalkulaatoris): spendHal, cheapestPath (per_second või plan), odavaim aste täiendustega tier ja selle maksumus tierTotalHal, kokkuhoid savingsHal, worthIt, kas kokkuhoid on piisavalt suur, steady, kas kulu on püsiv, mitte ühekordne tipp (viimase 14 päeva kasutus skaleeritud 30 päevale pluss kuised numbritasud jõuab vähemalt soovitatud astme hinnani; portaal pakub paketti ainult siis, kui worthIt ja steady on mõlemad tõesed) ja options, kõik viisid sama kulu eest maksta (sekundipõhine ja iga aste täiendustega; samad arvud, mida portaal paketi taseme muutmisel näitab). See on null, kui kontole paketti ei pakuta või saldo ajalugu ei ulatu 30 päeva tagasi (uus konto). previousPeriod võtab kokku praegusele eelnenud tasutud perioodi (subscription.periodStart) samade arvudega nagu pikendamise e-kiri: tier, periodStart ja periodEnd (ISO 8601), selle kuusaldo creditHal, kui palju sellest kasutati usedHal ja usedPercent (allapoole ümardatud), kuusaldot ületanud kulu overHal (täiendustega ilma võlata, mille järgmine saldo tasus, ülempiiri korral koos võlaga; null, kui saldo ajalugu seda tõendada ei suuda), mis aegus expiredHal, exhaustionMode ja exhaustedAt, millal kuusaldo otsa sai (null, kui ei saanud või kui saldo ajalugu ei näita millal). See tagastatakse ainult siis, kui pakett on aktiivne, olenemata sellest, mida available ütleb; see on null ilma paketita, olekuga past_due või canceled, esimesel perioodil, kui saldo ajalugu ei suutnud kasutust tõendada, ning 45 päeva pärast seda pikendamist, mis selle salvestas.

Päring

bash
curl https://volai.cz/v1/subscription \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "subscription": {
    "tier": "990",
    "status": "active",
    "periodStart": "2026-10-17T08:00:00.000Z",
    "periodEnd": "2026-11-17T09:00:00.000Z",
    "monthlyCreditHal": 130000,
    "monthlyRemainingHal": 98500,
    "exhaustionMode": "topup",
    "cancelAtPeriodEnd": false,
    "nextTier": null,
    "card": {
      "brand": "visa",
      "last4": "4242"
    }
  },
  "tiers": [
    {
      "id": "490",
      "priceHal": 49000,
      "creditHal": 60000
    },
    {
      "id": "990",
      "priceHal": 99000,
      "creditHal": 130000
    },
    {
      "id": "1990",
      "priceHal": 199000,
      "creditHal": 280000
    }
  ],
  "topupBalanceHal": 8500,
  "available": false,
  "recommendation": {
    "spendHal": 105500,
    "days": 30,
    "cheapestPath": "plan",
    "tier": "490",
    "tierTotalHal": 94500,
    "savingsHal": 11000,
    "worthIt": true,
    "steady": true,
    "options": [
      {
        "path": "per_second",
        "tier": null,
        "totalHal": 105500
      },
      {
        "path": "plan",
        "tier": "490",
        "totalHal": 94500
      },
      {
        "path": "plan",
        "tier": "990",
        "totalHal": 99000
      },
      {
        "path": "plan",
        "tier": "1990",
        "totalHal": 199000
      }
    ]
  },
  "previousPeriod": {
    "tier": "990",
    "periodStart": "2026-09-17T08:00:00.000Z",
    "periodEnd": "2026-10-17T08:00:00.000Z",
    "creditHal": 130000,
    "usedHal": 105500,
    "usedPercent": 81,
    "overHal": 0,
    "expiredHal": 24500,
    "exhaustionMode": "topup",
    "exhaustedAt": null
  }
}

Veaolekud

  • 503ledger_unavailableSaldot või liikumiste ajalugu ei õnnestunud praegu lugeda - proovige varsti uuesti.

POST/v1/subscription/checkout

Loob Stripe Checkouti lingi kuupaketi esimeseks perioodiks. Siit midagi ei arveldata: INIMENE maksab Stripe'i lehel, kaart salvestatakse kuiste pikenduste jaoks ja alles siis lisatakse kuusaldo. exhaustionMode-il vaikeväärtust ei ole ja see tuleb valida: topup ostab salvestatud kaardiga saldot, kui kuusaldo on ära kasutatud (nagu automaatne täiendamine), cap ei osta midagi ja piirab kuu paketi hinnaga. Tarbijakonto (ilma ettevõtte ID, käibemaksunumbri ja ettevõtte nimeta) Checkouti linki ei saa: kõne tagastab 409 subscription_confirmation_required koos confirmUrl-iga portaali vormile, kus isik taotleb selgesõnaliselt teenuse alustamist enne 14-päevase taganemisperioodi lõppu, valib käitumise pärast ammendumist ja maksab; consumerConsent ei ole enam saadetav. Arveldusaadress on kohustuslik. Toetab päist Idempotency-Key.

Päring

bash
curl -X POST https://volai.cz/v1/subscription/checkout \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: plan-2026-10-17-01" \
  -d '{"tier": "990", "exhaustionMode": "cap", "consumerConsent": true}'

Vastus

json
{
  "checkoutUrl": "https://checkout.stripe.com/c/pay/cs_test_a1b2c3d4"
}

Veaolekud

  • 400validationtier või exhaustionMode puudub või ei ole üks pakutavatest väärtustest, consumerConsent ei ole tõeväärtus või keha sisaldab tundmatut välja (tagasipöördumis-URL-i ei aktsepteerita kunagi).
  • 404pausal_unavailableKuupaketti sellele kontole veel ei pakuta (seda juurutatakse järk-järgult). Kordamine ei aita; available päringus GET /v1/subscription ütleb, millal see on saadaval.
  • 404user_not_foundSelle API-võtme omanikku kontol ei leidu - ebatavaline olukord; võtke ühendust toega.
  • 400billing_address_requiredKonto arveldusaadress puudub või on poolik - ilma selleta ei saa kehtivat maksudokumenti välja anda. Lisage see päringuga PUT /v1/account/billing.
  • 409subscription_existsKontol on juba töötav pakett. Muutke seda hoopis päringuga PATCH /v1/subscription; lõppenud pakett uut ei blokeeri.
  • 409subscription_confirmation_requiredTarbijakonto (ilma ettevõtte ID, käibemaksunumbri ja ettevõtte nimeta): API kaudu Checkouti ei looda, vea keha kannab confirmUrl-i portaali vormile, kus isik taotleb teenuse alustamist ja maksab. Midagi ei arveldatud.
  • 400consumer_consent_requiredAinult portaal: tarbija saatis vormi, märkimata teenuse alustamise taotlust. API kaudu saab tarbija selle asemel 409 subscription_confirmation_required. Midagi ei arveldatud.
  • 503stripe_not_configuredMaksed on selle volai juurutuse jaoks välja lülitatud - see ei ole teie päringule omane.
  • 502stripe_errorStripe keeldus makseseansi loomisest - proovige varsti uuesti.
  • 503ledger_unavailableSaldot või liikumiste ajalugu ei õnnestunud praegu lugeda - proovige varsti uuesti.

PATCH/v1/subscription

Muudab paketti ilma kaardilt arveldamata. Need rakenduvad kohe, sest nad ei suurenda kunagi seda, mida saab arveldada: tier langetamine (jõustub järgmisest perioodist, nextTier näitab seda), cancelAtPeriodEnd: true (rohkem ei arveldata, saldo jääb kasutatavaks kuni periodEnd) ja exhaustionMode: "cap" (lülitab ka automaatse täiendamise välja). tier tõstmine, cancelAtPeriodEnd: false lõppevaks seatud paketil (selle jätkamine) ja exhaustionMode: "topup" EI rakendu: kõne tagastab 409 subscription_confirmation_required ja midagi päringus ei muutu. Vea keha kannab confirmUrl-i, linki portaalilehele, kus kontole sisse logitud isik muudatuse kinnitab; link kehtib 24 tundi ja töötab ühe korra. Saatke kinnitust vajavad muudatused üks päringu kohta. Päring, mis midagi ei muuda (lõppevaks mitteseatud paketi jätkamine, topup, kui täiendused juba töötavad, aste, millele pakett juba üle läheb), õnnestub ilma kinnituse ja veata. Sama keha saab seega pärast katkestust ohutult uuesti saata: juba kehtiv jäetakse vahele ja tehakse ainult see, mis on järel. Ainus erand on tagasipöördumine praegusele astmele (see tühistab ajastatud muudatuse): kordusel ei ole enam midagi tühistada ja see lõpeb veaga invalid_tier, seega saatke ülejäänud väljad eraldi. Lõppevaks seatud paketil tagastab ainult tier muudatus invalid_state (võtke esmalt tühistamine tagasi); koos cancelAtPeriodEnd: true-ga saadetuna on see kordus ja loetakse tehtuks.

Päring

bash
curl -X PATCH https://volai.cz/v1/subscription \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"tier": "490"}'

Vastus

json
{
  "subscription": {
    "tier": "990",
    "status": "active",
    "periodStart": "2026-10-17T08:00:00.000Z",
    "periodEnd": "2026-11-17T09:00:00.000Z",
    "monthlyCreditHal": 130000,
    "monthlyRemainingHal": 98500,
    "exhaustionMode": "topup",
    "cancelAtPeriodEnd": false,
    "nextTier": "490",
    "card": {
      "brand": "visa",
      "last4": "4242"
    }
  }
}

Veaolekud

  • 400validationKeha on tühi, sisaldab tundmatut välja või väärtust väljaspool pakutavaid või nõuab ühes päringus rohkem kui ühte kinnitust vajavat muudatust. Midagi ei muudetud.
  • 400invalid_tierKonto on juba sellel astmel ja ühtegi teist astet ei ole ajastatud, seega pole midagi muuta. Aste, millele see juba järgmisest perioodist üle läheb, ei ole viga: see loetakse tehtuks.
  • 400invalid_statetier muudatus paketil, mis on seatud perioodi lõpus lõppema: järgmist perioodi ei alga, seega aste ei rakenduks kunagi. Võtke esmalt tühistamine tagasi (cancelAtPeriodEnd: false, mille inimene portaalis kinnitab). Keha, mis kannab ka cancelAtPeriodEnd: true, on kordus ja läheb läbi.
  • 404subscription_missingKontol ei ole kuupaketti - alustage seda päringuga POST /v1/subscription/checkout.
  • 409subscription_canceledPakett on juba lõppenud, seega seda ei saa enam muuta, jätkata ega tasuda. Alustage uut päringuga POST /v1/subscription/checkout.
  • 409subscription_confirmation_requiredMuudatus suurendab seda, mida kaardilt võib arveldada, seega saab selle kinnitada ainult inimene. Midagi ei muudetud; viga kannab confirmUrl-i.
  • 503ledger_unavailableSaldot või liikumiste ajalugu ei õnnestunud praegu lugeda - proovige varsti uuesti.

POST/v1/subscription/pay

Paketi jaoks, mille viimane pikendamine ebaõnnestus (status: "past_due"): loob Stripe Checkouti lingi, mis arveldab pikendamise summa ühe korra ja salvestab uue kaardi; uus periood algab maksest. Siit midagi ei arveldata, INIMENE maksab Stripe'i lehel. Pakett, mis ei ole maksega hilinenud, ei vaja tasumist ja tagastab invalid_state. Toetab päist Idempotency-Key.

Päring

bash
curl -X POST https://volai.cz/v1/subscription/pay \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Idempotency-Key: plan-pay-2026-11-18-01"

Vastus

json
{
  "checkoutUrl": "https://checkout.stripe.com/c/pay/cs_test_a1b2c3d4"
}

Veaolekud

  • 404subscription_missingKontol ei ole kuupaketti - alustage seda päringuga POST /v1/subscription/checkout.
  • 409subscription_canceledPakett on juba lõppenud, seega seda ei saa enam muuta, jätkata ega tasuda. Alustage uut päringuga POST /v1/subscription/checkout.
  • 400invalid_stateViimane pikendamine ei ebaõnnestunud (status ei ole past_due), seega pole midagi käsitsi tasuda.
  • 404user_not_foundSelle API-võtme omanikku kontol ei leidu - ebatavaline olukord; võtke ühendust toega.
  • 503stripe_not_configuredMaksed on selle volai juurutuse jaoks välja lülitatud - see ei ole teie päringule omane.
  • 502stripe_errorStripe keeldus makseseansi loomisest - proovige varsti uuesti.
  • 503ledger_unavailableSaldot või liikumiste ajalugu ei õnnestunud praegu lugeda - proovige varsti uuesti.

POST/v1/subscription/card

Loob Stripe Checkouti lingi kaardi seadistamise režiimis, et asendada kaart, millega pakett pikeneb. Siit midagi ei arveldata, INIMENE sisestab uue kaardi Stripe'i lehel; seda kasutatakse seejärel paketi ja kaardilt täienduste jaoks ning vana eraldatakse. Töötab igas paketi olekus peale canceled. Toetab päist Idempotency-Key.

Päring

bash
curl -X POST https://volai.cz/v1/subscription/card \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Idempotency-Key: plan-card-2026-11-18-01"

Vastus

json
{
  "checkoutUrl": "https://checkout.stripe.com/c/pay/cs_test_a1b2c3d4"
}

Veaolekud

  • 404subscription_missingKontol ei ole kuupaketti - alustage seda päringuga POST /v1/subscription/checkout.
  • 409subscription_canceledPakett on juba lõppenud, seega seda ei saa enam muuta, jätkata ega tasuda. Alustage uut päringuga POST /v1/subscription/checkout.
  • 404user_not_foundSelle API-võtme omanikku kontol ei leidu - ebatavaline olukord; võtke ühendust toega.
  • 503stripe_not_configuredMaksed on selle volai juurutuse jaoks välja lülitatud - see ei ole teie päringule omane.
  • 502stripe_errorStripe keeldus makseseansi loomisest - proovige varsti uuesti.
  • 503ledger_unavailableSaldot või liikumiste ajalugu ei õnnestunud praegu lugeda - proovige varsti uuesti.

Ülesanded

Ülesanne helistab saajate loendile ühe agendiga eelnevalt seatud reeglite järgi (eelarve, helistamisaken, katsete arv) - midagi ei valita, kuni te seda ise ei käivita (POST .../start). Täielik juhend CSV-impordi, olekute ja globaalse läbilaskevõimega asub aadressil /docs/ukoly. Agent, kellel on number kõnede ja SMS-ide jaoks, helistab kampaanias ainult Tšehhi numbritele (+420) ja numbrilt töötab korraga ainult üks kõne: mis tahes muu numbriga kontakt läheb ülevaatusele, kuni ülesanne jätkab teistele helistamist, ja hõivatud number paneb ülesande korraks ootama.

GET/v1/tasks

Ilma ids-ita loetleb kuni 100 viimast ülesannet. Parameetriga ids=id1,id2 loeb ühe kuni viis unikaalset konto omanduses olevat ülesannet ning tagastab requestedIdsComplete: true, requestedIds ja hasMore: false; tundmatud või võõrad ID-d tagastavad kõik sama 404. Valitud vastus on piiratud 4 MiB-ga; jagage ID-d pärast task_inventory_payload_limit väiksemateks rühmadeks. Kui üks ülesanne ületab piiri üksi, uurige seda päringuga GET /v1/tasks/{id} või võtke ühendust toega; ärge muutke selle muutumatut saajate loendit, et vastuse piirangust mööda minna.

Päring

bash
curl https://volai.cz/v1/tasks \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "tasks": [
    {
      "id": "task_9f3a2c1d",
      "name": "Payment reminder - September",
      "agentId": "ag_4e91a2f0",
      "taskType": "custom",
      "purpose": "standard",
      "source": "manual",
      "callingWindow": { "timezone": "Europe/Prague", "start": "09:00", "end": "18:00", "days": [1, 2, 3, 4, 5] },
      "maxAttempts": 2,
      "maxDurationSecs": 120,
      "budgetHal": 50000,
      "reservedBudgetHal": 0,
      "spentHal": 0,
      "status": "draft",
      "revision": 0,
      "createdAt": 1757280000000,
      "updatedAt": 1757280000000,
      "items": [
        { "id": "item_1a2b3c", "phone": "+420777123456", "variables": { "jmeno": "Jana Novakova" }, "paymentStatus": "not_applicable", "status": "pending", "attempts": [] }
      ]
    }
  ]
}

Veaolekud

  • 400validationParameeter ids peab sisaldama ühte kuni viit unikaalset kehtivat väljamineva kõne ülesande ID-d ja võib esineda ainult üks kord.
  • 404task_not_foundKontol ei ole selle id-ga ülesannet.
  • 413task_inventory_payload_limitValitud ülesannete kirjed ületavad 4 MiB. Jagage ID-d väiksemateks rühmadeks ja proovige uuesti; kui üks ülesanne ületab piiri üksi, uurige seda päringuga GET /v1/tasks/{id} või võtke ühendust toega. Ärge muutke selle muutumatut saajate loendit, et sellest piirangust mööda minna.

GET/v1/outbound/dispatch-scopes/petcenter/registrations

Ainult omaniku jaoks mõeldud operatiivne tagasilugemine PetCenteri väljamineva väljasaatmise ulatuse kohta. Ilma operationId-ta tagastab praeguse registreeritud manifesti kokkuvõtte; operationId-ga tagastab selle toimingu püsiva tulemuse pärast ebaselget POST-i. See lõpp-punkt ei saa ülesannete koosseisu muuta.

Päring

bash
curl https://volai.cz/v1/outbound/dispatch-scopes/petcenter/registrations \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{"registration":null,"operation":null}

Veaolekud

  • 400validationToimingu ID, manifesti kokkuvõte või ülesannete loend on vigane või on vastuolus registreeritud ainult lisatava manifestiga.

POST/v1/outbound/dispatch-scopes/petcenter/registrations

Ainult omaniku jaoks mõeldud operatiivne registreerimine PetCenteri ühe minuti väljasaatjale. Saatke stabiilne operationId, lähtemanifesti SHA-256 ja järjestatud taskIds. Server kontrollib konto ja agendi omandit; esimene manifest peab vastama kinnitatud 19 ülesande loendile ja hilisemad manifestid võivad ainult ülesandeid lisada. Ainult kokkuvõtte selgesõnaliseks värskendamiseks saatke ka expectedManifestSha praegusest GET-ist ja säilitage kogu järjestatud ülesannete loend. Compare-and-swap lükkab aegunud kokkuvõtte tagasi; see väli ei saa ülesandeid lisada, eemaldada ega ümber järjestada. Tingimus on muutumatu toimingu keha osa. Toimingu ID taaskasutamine sama kehaga on ohutu; keha muutmine põhjustab konflikti. See muudab ainult ajastaja koosseisu ega käivita ega jätka kunagi ülesannet.

Päring

bash
curl https://volai.cz/v1/outbound/dispatch-scopes/petcenter/registrations \
  -H "Authorization: Bearer vk_YOUR_KEY" -H "Content-Type: application/json" \
  --data-binary @petcenter-manifest-operation.json

Vastus

json
{"registration":{"manifestSha":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","taskCount":19,"updatedAt":1791802800000},"operation":{"operationId":"registration-2026-10-12","manifestSha":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","taskCount":19,"acceptedAt":1791802800000,"replayed":false}}

Veaolekud

  • 400validationToimingu ID, manifesti kokkuvõte või ülesannete loend on vigane või on vastuolus registreeritud ainult lisatava manifestiga.
  • 409revision_conflictToimingu ID on juba seotud teise kehaga, manifest muutus või ülesande revisjon on aegunud. Lugege toiming ja praegused ülesanded enne uue toimingu alustamist. Ainult registreerimiskonflikt väärtusega error.details.reason: task_changed_during_registration sisaldab ka providerActionStarted: false ja algset operationId-d: kontrollid peatati enne registri muutmist. Enne uut katset lugege registreering päringuga GET sama operationId-ga, veenduge, et operation: null, ja värskendage ülesanded. Ajalõpp või mõni muu konflikt seda ohutu kordamise tingimust ei tõenda.

GET/v1/outbound/dispatch-scopes/petcenter/pauses

Ainult omaniku jaoks mõeldud püsiv tagasilugemine PetCenteri partii peatamise kohta. Saatke selle operationId; vastus pakib toimingu väljale operation ja sisaldab täpset manifestSha, kanoonilist requestHash, järjestatud ülesannete ID-sid ja revisjone ning iga kinnitatud ülesande tulemust. requestHash on SHA-256 kompaktsest UTF-8 JSON-ist leksikograafiliselt sorteeritud objektivõtmetega väljale {manifestSha,tasks} (ülesannete massiivi järjekord säilitatakse); operationId on välja jäetud. Kasutage seda pärast iga ebaselget POST-i enne uue toimingu loomist.

Päring

bash
curl 'https://volai.cz/v1/outbound/dispatch-scopes/petcenter/pauses?operationId=pause-batch-2026-10-12-01' \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "operation": {
    "operationId": "pause-batch-2026-10-12-01",
    "manifestSha": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "requestHash": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
    "tasks": [{ "taskId": "task_abcdefgh", "revision": 12 }],
    "acceptedAt": 1791802800000,
    "complete": true,
    "outcomes": [{ "taskId": "task_abcdefgh", "outcome": "paused", "revision": 13 }]
  }
}

Veaolekud

  • 400validationToimingu ID, manifesti kokkuvõte või üks kuni viis unikaalset ülesande ID/revisjoni sisendit on vigased.

POST/v1/outbound/dispatch-scopes/petcenter/pauses

Ainult omaniku jaoks mõeldud peatamistoiming ühele kuni viiele praegu registreeritud PetCenteri ülesandele. Saatke stabiilne operationId, praegune manifesti SHA ja iga ülesande värskelt loetud revisjon. Vastus pakib toimingu väljale operation, sisaldades kanoonilist päringuräsi ja järjestatud ülesannete sisendeid. Ülesande revisjoni muutus ja ülesandekohane püsiv tulemus on aatomilised; sama toimingu taasesitamine on ohutu, keha muutmine põhjustab konflikti. Revisjonikonflikt teatatakse ülesande kaupa ega peata seda ülesannet.

Päring

bash
curl https://volai.cz/v1/outbound/dispatch-scopes/petcenter/pauses \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"operationId":"pause-batch-2026-10-12-01","manifestSha":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","tasks":[{"taskId":"task_abcdefgh","revision":12}]}'

Vastus

json
{
  "operation": {
    "operationId": "pause-batch-2026-10-12-01",
    "manifestSha": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "requestHash": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
    "tasks": [{ "taskId": "task_abcdefgh", "revision": 12 }],
    "acceptedAt": 1791802800000,
    "complete": true,
    "outcomes": [{ "taskId": "task_abcdefgh", "outcome": "paused", "revision": 13 }]
  }
}

Veaolekud

  • 400validationToimingu ID, manifesti kokkuvõte või üks kuni viis unikaalset ülesande ID/revisjoni sisendit on vigased.
  • 409revision_conflictToimingu ID on juba seotud teise kehaga, manifest muutus või ülesande revisjon on aegunud. Lugege toiming ja praegused ülesanded enne uue toimingu alustamist. Ainult registreerimiskonflikt väärtusega error.details.reason: task_changed_during_registration sisaldab ka providerActionStarted: false ja algset operationId-d: kontrollid peatati enne registri muutmist. Enne uut katset lugege registreering päringuga GET sama operationId-ga, veenduge, et operation: null, ja värskendage ülesanded. Ajalõpp või mõni muu konflikt seda ohutu kordamise tingimust ei tõenda.

POST/v1/tasks

Loob ülesande olekus draft - midagi ei valita. agentId võib olla mis tahes aktiivne agent, sh ElevenLabsi peal olev - mootori nõuet (provider: "engine", valitud loomisel väärtusega useForOutboundTasks: true) kontrollitakse alles päringul POST .../start, mis seejärel ebaõnnestub veaga engine_required. Kuni 1000 recipients. Ilma retryPolicy-ta on maxAttempts 1-3 ja vaikimisi 1; valikulise retryPolicy: "lorela_enterprise" korral on see 1-4 ja vaikimisi 4. Valikuline expiresAt (positiivne ohutu täisarv Unix-millisekundites) takistab uusi kõnesid kampaania tähtajal või pärast seda, sh esimest. Valikuline retryMaxAgeDays (täisarv 1-30, vaikimisi 5; ainult koos poliitikaga, samas päringus) seab kordamiste horisondi: N × 24 tundi iga saaja esimesest loetud katsest. Poliitika, horisont ja tähtaeg tagastatakse ülesande detailis. Toetab päist Idempotency-Key. Valikuline muutumatu purpose on vaikimisi standard. coupon_reminder nõuab source: manual, taskType: custom, selgesõnalist maxAttempts: 1 ja expiresAt. Enne helistamist kontrollib usaldatud serveri värav täpset meeldetuletust; kasutajamuutujad ei saa selle tervitust ega kupongi üle kirjutada. Ilma värava seadistuseta meeldetuletusele ei helistata.

Päring

bash
curl -X POST https://volai.cz/v1/tasks \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: task-2026-09-08-01" \
  -d '{
    "name": "Payment reminder - September",
    "agentId": "ag_4e91a2f0",
    "taskType": "custom",
    "purpose": "standard",
    "source": "manual",
    "maxAttempts": 2,
    "budgetHal": 50000,
    "recipients": [
      { "phone": "+420777123456", "variables": { "jmeno": "Jana Novakova" } }
    ]
  }'

Vastus

json
{
  "task": {
    "id": "task_9f3a2c1d",
    "name": "Payment reminder - September",
    "agentId": "ag_4e91a2f0",
    "taskType": "custom",
    "purpose": "standard",
    "source": "manual",
    "callingWindow": { "timezone": "Europe/Prague", "start": "09:00", "end": "18:00", "days": [1, 2, 3, 4, 5] },
    "maxAttempts": 2,
    "maxDurationSecs": 120,
    "budgetHal": 50000,
    "reservedBudgetHal": 0,
    "spentHal": 0,
    "status": "draft",
    "revision": 0,
    "createdAt": 1757280000000,
    "updatedAt": 1757280000000,
    "items": [
      { "id": "item_1a2b3c", "phone": "+420777123456", "variables": { "jmeno": "Jana Novakova" }, "paymentStatus": "not_applicable", "status": "pending", "attempts": [] }
    ]
  }
}

Veaolekud

  • 400validationKeha ei vasta skeemile (puuduv väli, vale tüüp, üle 1000 saaja või ülesanne suurem kui 2 MB, kehtetu telefoninumber ühel saajal, retryMaxAgeDays väljaspool 1-30 või saadetud ilma retryPolicy: "lorela_enterprise"...).
  • 404agent_not_foundKontol ei ole selle agentId-ga agenti või see ei ole aktiivne.
  • 400budget_too_lowbudgetHal ei kata isegi ühte katset maksimaalse kõne kestuse (maxDurationSecs) korral.

GET/v1/tasks/{id}

Ülesande detail, SH issues - kuivkäivitus selle kohta, mis ülesande käivitamist praegu blokeerib (arvutatakse värskelt, midagi ei salvestata). Meeldetuletuste integratsioonid saavad kasutada ka päringut GET /v1/tasks/{id}/items/{itemId}/reminder-call?callId=c_..., et lugeda täpset omanikuga seotud tegelikku katset ja puhastatud kvaliteeti väljal reminderCall. Puuduvad mõõdikud on observed: false ja null, mitte kunagi arv 0. Iga tõendatud dismissReminder.invoked: true summutab SMS-i.

Päring

bash
curl https://volai.cz/v1/tasks/task_9f3a2c1d \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "task": {
    "id": "task_9f3a2c1d",
    "name": "Payment reminder - September",
    "agentId": "ag_4e91a2f0",
    "taskType": "custom",
    "purpose": "standard",
    "source": "manual",
    "callingWindow": { "timezone": "Europe/Prague", "start": "09:00", "end": "18:00", "days": [1, 2, 3, 4, 5] },
    "maxAttempts": 2,
    "maxDurationSecs": 120,
    "budgetHal": 50000,
    "reservedBudgetHal": 0,
    "spentHal": 0,
    "status": "draft",
    "revision": 0,
    "createdAt": 1757280000000,
    "updatedAt": 1757280000000,
    "items": [
      { "id": "item_1a2b3c", "phone": "+420777123456", "variables": { "jmeno": "Jana Novakova" }, "paymentStatus": "not_applicable", "status": "pending", "attempts": [] }
    ],
    "issues": []
  }
}

Veaolekud

  • 404task_not_foundKontol ei ole selle id-ga ülesannet.

PATCH/v1/tasks/{id}

Uuendab muudetava ülesande reegleid (name, recipients, callingWindow, maxAttempts, retryPolicy, retryMaxAgeDays, expiresAt, maxDurationSecs, budgetHal) - agentId, taskType ja source ei saa pärast loomist muuta. revision on KOHUSTUSLIK (optimistlik samaaegsus). Poliitikat saab lubada ainult enne esimest katset; sama poliitikat saab hiljem uuesti saata. Väljajäetud maxAttempts, retryPolicy, retryMaxAgeDays ja expiresAt jäävad muutmata. maxAttempts: 4 nõuab poliitikat selles päringus või juba ülesandele salvestatuna. retryMaxAgeDays (1-30, vaikimisi 5; horisont lõpeb N × 24 tundi iga saaja esimesest loetud katsest) vajab samuti poliitikat ja võib erinevalt poliitikast muutuda ka pärast katsete algust: selle tõstmine tagastab saajad, kes jäid vahele ainult kordamise horisondi tõttu (reviewReason: "retry_age_expired"), tagasi olekusse failed (ootavad oma järgmist katset) uue nextAttemptAt-iga, kui neil on veel katse järel ja ajakava järgmine aken jääb uue horisondi sisse ja enne expiresAt-i; selle langetamine ei ava midagi uuesti. Saajaid avab uuesti ainult PATCH, mis tõstab horisonti, seega saatke retryMaxAgeDays koos pikendatud expiresAt-iga ühes päringus. running või completed ülesannet ei saa muuta, seega peatage töötav ülesanne esmalt.

Päring

bash
curl -X PATCH https://volai.cz/v1/tasks/task_9f3a2c1d \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"revision": 0, "budgetHal": 80000}'

Vastus

json
{
  "task": {
    "id": "task_9f3a2c1d",
    "name": "Payment reminder - September",
    "agentId": "ag_4e91a2f0",
    "taskType": "custom",
    "purpose": "standard",
    "source": "manual",
    "callingWindow": { "timezone": "Europe/Prague", "start": "09:00", "end": "18:00", "days": [1, 2, 3, 4, 5] },
    "maxAttempts": 2,
    "maxDurationSecs": 120,
    "budgetHal": 80000,
    "reservedBudgetHal": 0,
    "spentHal": 0,
    "status": "draft",
    "revision": 1,
    "createdAt": 1757280000000,
    "updatedAt": 1757280060000,
    "items": [
      { "id": "item_1a2b3c", "phone": "+420777123456", "variables": { "jmeno": "Jana Novakova" }, "paymentStatus": "not_applicable", "status": "pending", "attempts": [] }
    ]
  }
}

Veaolekud

  • 400validationKeha ei vasta skeemile (näiteks retryMaxAgeDays väljaspool 1-30 või ilma poliitikata lorela_enterprise) või sellel puudub revision.
  • 404task_not_foundKontol ei ole selle id-ga ülesannet.
  • 409revision_conflictÜlesanne muutus vahepeal - lugege see uuesti (GET) ja korrake praeguse revision-iga.
  • 409task_not_editableÜlesanne on running/completed või needs_attention ilma taastamisvõimaluseta - selle reegleid ei saa praegu muuta.
  • 409items_immutableSaajate loendit (recipients) ei saa asendada, kui on toimunud vähemalt üks valimiskatse või kirjel on auditeeritud vahelejätmise lahendus (pärast ostu või tellimusest loobumist).

POST/v1/tasks/{id}/start

Alustab (või pärast pausi jätkab) saajatele helistamist - IGA vastatud kõne arveldatakse kohe, eelarve broneeritakse enne iga valimist. Toetab päist Idempotency-Key.

Päring

bash
curl -X POST https://volai.cz/v1/tasks/task_9f3a2c1d/start \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: task-start-2026-09-08-01" \
  -d '{"revision": 1}'

Vastus

json
{
  "task": {
    "id": "task_9f3a2c1d",
    "name": "Payment reminder - September",
    "agentId": "ag_4e91a2f0",
    "taskType": "custom",
    "purpose": "standard",
    "source": "manual",
    "callingWindow": { "timezone": "Europe/Prague", "start": "09:00", "end": "18:00", "days": [1, 2, 3, 4, 5] },
    "maxAttempts": 2,
    "maxDurationSecs": 120,
    "budgetHal": 80000,
    "reservedBudgetHal": 0,
    "spentHal": 0,
    "status": "running",
    "revision": 2,
    "createdAt": 1757280000000,
    "updatedAt": 1757280120000,
    "items": [
      { "id": "item_1a2b3c", "phone": "+420777123456", "variables": { "jmeno": "Jana Novakova" }, "paymentStatus": "not_applicable", "status": "pending", "attempts": [] }
    ]
  }
}

Veaolekud

  • 400validationKeha ei vasta skeemile, sellel puudub revision või expiresAt on juba möödas.
  • 404task_not_foundKontol ei ole selle id-ga ülesannet.
  • 409revision_conflictÜlesanne muutus vahepeal - lugege see uuesti (GET) ja korrake praeguse revision-iga.
  • 409task_not_startableÜlesanne ei ole olekus draft/ready/paused või sel ei ole enam saajat, kellele helistada.
  • 409task_needs_attentionEnne järgmist käivitamist on vaja POST .../reconcile - ülesande töö ajal midagi muutus.
  • 404agent_not_foundKontol ei ole selle agentId-ga agenti või see ei ole aktiivne.
  • 403agent_suspendedvolai operaator on ülesande agendi käsitsi peatanud - ülesannet ei saa käivitada ega pärast pausi taaskäivitada enne peatamise tühistamist. Peatatud konto tagastab selle asemel account_suspended.
  • 409engine_requiredÜlesande agent ei ole volai mootoril - väljaminevad ülesanded nõuavad täna mootorit, mitte ElevenLabsi.
  • 409agent_not_readyAgendi mustand on kas avaldamata või avaldatud versiooni ei ole testitud - avaldage see (POST /v1/agents/{id}/draft/publish) ja simuleerige seejärel avaldatud versiooni (POST /v1/agents/{id}/simulate) enne käivitamist.
  • 503engine_contract_unavailableMootor ei teata praegu väljamineva ülesande muutujate ja piirangute toetust - proovige käivitada hiljem uuesti.
  • 409window_closedSeadistatud helistamisaknast (callingWindow) väljas - oodake selle taasavanemist või muutke seda päringuga PATCH.

POST/v1/tasks/{id}/pause

Peatab edasise helistamise ENNE järgmist katset; juba käimasolevat kõnet ei katkestata. Idempotency-Key puudub - kordamine sama revisjoniga on iseenesest ohutu.

Päring

bash
curl -X POST https://volai.cz/v1/tasks/task_9f3a2c1d/pause \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"revision": 2}'

Vastus

json
{
  "task": {
    "id": "task_9f3a2c1d",
    "status": "paused",
    "revision": 3,
    "budgetHal": 80000,
    "reservedBudgetHal": 0,
    "spentHal": 684,
    "name": "Payment reminder - September",
    "agentId": "ag_4e91a2f0",
    "taskType": "custom",
    "purpose": "standard",
    "source": "manual",
    "callingWindow": { "timezone": "Europe/Prague", "start": "09:00", "end": "18:00", "days": [1, 2, 3, 4, 5] },
    "maxAttempts": 2,
    "maxDurationSecs": 120,
    "createdAt": 1757280000000,
    "updatedAt": 1757280180000,
    "items": [
      { "id": "item_1a2b3c", "phone": "+420777123456", "variables": { "jmeno": "Jana Novakova" }, "paymentStatus": "not_applicable", "status": "completed", "attempts": [{ "id": "attempt_5d4c3b", "startedAt": 1757280100000, "finishedAt": 1757280160000, "providerCallId": "c_7a2b9c1d", "outcome": "completed", "costHal": 684 }], "actualCostHal": 684 }
    ]
  }
}

Veaolekud

  • 400validationKeha ei vasta skeemile või sellel puudub revision.
  • 404task_not_foundKontol ei ole selle id-ga ülesannet.
  • 409task_not_runningPeatamine toimib ainult töötaval (running) ülesandel.
  • 409revision_conflictÜlesanne muutus vahepeal - lugege see uuesti (GET) ja korrake praeguse revision-iga.

GET/v1/tasks/{id}/items/{itemId}/reminder-call

Loeb tõendeid ülesandest purpose: coupon_reminder pärit tegeliku loetud kõne kohta. Esitage nõutav päringuparameeter callId=c_... täpselt üks kord. Server kontrollib täpset konto, ülesande, kirje, kõne ja meeldetuletuse volituse seost. reminderCall sisaldab telefoni räsi, olekut, hinda ja puhastatud kvaliteeti; see ei tagasta telefoninumbreid, transkriptsioone ega tööriista argumente. Puuduvatel mõõdikutel on observed: false ja count: null, mitte kunagi arv 0. dismissReminder.invoked: true või optOutRequested: true summutab SMS-i isegi siis, kui tööriist ebaõnnestub või aegub. Ainult tõendatud suletud vastamata katse nullkestuse ja nullhinnaga, ilma vastuolulise vestlustõendita, saab tuvastada, et loobumine ja keeldumine on false; puuduvad vooru/tööriista mõõdikud jäävad teadmata. Kontrollige kõne olekut enne järgnevat tegevust. See lõpp-punkt ainult loeb tõendeid ega saada SMS-i.

Päring

bash
curl "https://volai.cz/v1/tasks/task_reminder_9f3a/items/item_1a2b3c/reminder-call?callId=c_reminder_7e2d" \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "reminderCall": {
    "callId": "c_reminder_7e2d",
    "tenantId": "u_4a8d2c",
    "agentId": "ag_4e91a2f0",
    "taskId": "task_reminder_9f3a",
    "taskItemId": "item_1a2b3c",
    "dispatchIntentId": "dispatch_8d2a4f",
    "purpose": "coupon_reminder",
    "phoneSha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
    "direction": "out",
    "status": "no_answer",
    "startedAt": 1791882000000,
    "durationSecs": 0,
    "priceHal": 0,
    "endReason": "no_answer",
    "optOutRequested": false,
    "hasConversation": false,
    "quality": {
      "turnFailures": { "observed": false, "count": null },
      "toolFailures": { "observed": false, "count": null },
      "dismissReminder": { "observed": true, "invoked": false }
    }
  }
}

Veaolekud

  • 400validationEsitage täpselt üks kehtiv päringuparameeter callId kujul c_..., ilma muude parameetriteta.
  • 404task_not_foundTäpset omanikuga seotud loetud meeldetuletuskõnet ei leitud; võõrad ID-d, teine eesmärk ja vigased seosed tagastavad sama vastuse.

POST/v1/tasks/{id}/items/{itemId}/resolve

Eraldi variant pärast kinnitatud ostu või pärast seda, kui klient tellimusest loobus, aktsepteerib action: skip, reason (customer_purchased = klient ostis, unsubscribed = klient loobus tellimusest), revision, operationId ja evidenceRef (läbipaistmatud identifikaatorid kuni 128 märki; evidenceRef osutab ostu- või loobumiskirjele ega kanna telefoninumbrit, e-posti ega nime), näiteks {"action":"skip","revision":12,"reason":"unsubscribed","operationId":"unsub-001","evidenceRef":"unsub-record-001"}. See jätab vahele ainult mitteaktiivse pending kirje draft ülesandes või pending/failed kirje paused ülesandes, millel pole lahendamata kõnesid ega broneeringuid. Ajalugu, kulud ja DNC säilivad: numbrit ei lisata helistamiskeeluloendisse, isegi mitte väärtuse unsubscribed korral. GET tagastab muutumatu items[].resolution kviitungi, mille reason on customer_purchased või unsubscribed. Taasesitage sama toimingut pärast ebaselget vastust ilma uue kirjutuseta; teine lahendus juba lahendatud kirjel (sh teine reason sama operationId-ga) tagastab 409 revision_conflict. Algne käitumine ilma reason-ita: otsustab ülevaatust ootava kontakti (items[].status: "review") üle: tavaliselt paneb retry selle tagasi järjekorda ilma uut katset kulutamata ja skip sulgeb selle vahelejäetuna. Poliitikaga retryPolicy: "lorela_enterprise" tagastab käsitsi retry validation; lubatud on ainult ajastatud automaatsed katsed. Kontakt olekus review võib ilmuda, kui ülesanne veel töötab, kuid resolve toimib ainult siis, kui ülesanne ei tööta - töötaval ülesandel tagastab see 409 task_not_editable, seega oodake needs_attention või peatage ülesanne (pause). Väärtuse reviewReason: "dial:destination_auto_blocked" korral eemaldage esmalt blokeering (POST /v1/dnc/{e164}/unblock) ja alles seejärel retry; väärtuste dial:cannot_call_own_number, dial:cannot_call_volai_number, dial:invalid_number, dial:unsupported_country ja dial:blocked_destination korral aitab ainult skip. reviewReason: "billing_unknown" on teistsugune: providerCallId ja broneeritud eelarve jäävad seotuks kuni POST .../reconcile; pärast retry ootab asendav katse algse kõne arveldamist ja pärast skip asendavat kõnet ei tehta, kuid algse kõne eest võidakse hiljem ikkagi arveldada (selle broneering loeb edasi eelarve vastu). Pärast retry jääb ülesanne seega olekusse needs_attention, kuni hind on arveldatud; pärast skip läheb see olekusse paused ja selle saab käivitada, kui tööd on järel, vastasel juhul ootab see olekus needs_attention ja lõpeb, kui hind on arveldatud. Kõne, mida ei valitud kunagi, arveldatakse kohe nulliga. Muude ülevaatuse põhjuste korral viib viimase kontakti lahendamine ülesande olekust needs_attention olekusse paused (start jätkab seda) või completed.

Päring

bash
curl -X POST https://volai.cz/v1/tasks/task_9f3a2c1d/items/item_1a2b3c/resolve \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"action": "retry", "revision": 5}'

Vastus

json
{
  "task": {
    "id": "task_9f3a2c1d",
    "name": "Payment reminder - September",
    "agentId": "ag_4e91a2f0",
    "taskType": "custom",
    "purpose": "standard",
    "source": "manual",
    "callingWindow": { "timezone": "Europe/Prague", "start": "09:00", "end": "18:00", "days": [1, 2, 3, 4, 5] },
    "maxAttempts": 2,
    "maxDurationSecs": 120,
    "budgetHal": 80000,
    "reservedBudgetHal": 2400,
    "spentHal": 0,
    "status": "needs_attention",
    "revision": 6,
    "createdAt": 1757280000000,
    "updatedAt": 1757280240000,
    "reviewReason": "billing_unknown",
    "items": [
      {
        "id": "item_1a2b3c",
        "phone": "+420777123456",
        "variables": { "jmeno": "Jana Novakova" },
        "paymentStatus": "not_applicable",
        "status": "pending",
        "attempts": [
          { "id": "attempt_7c2d", "startedAt": 1757280180000, "finishedAt": 1757280230000, "providerCallId": "c_late_price", "outcome": "completed" }
        ],
        "reviewReason": "billing_unknown",
        "providerCallId": "c_late_price",
        "estimatedCostHal": 2400,
        "reservedCostHal": 2400
      }
    ]
  }
}

Veaolekud

  • 400validationKeha ei vasta skeemile (action on retry või skip, revision mittenegatiivne täisarv, valikuline reason on customer_purchased või unsubscribed ja nõuab operationId ja evidenceRef) või itemId ei eksisteeri ülesandel või poliitika lorela_enterprise lükkab käsitsi retry tagasi.
  • 404task_not_foundKontol ei ole selle id-ga ülesannet.
  • 409task_not_editableÜlesanne ei ole lubatud olekus. Vahelejätmine pärast ostu või tellimusest loobumist nõuab olekut draft või paused; peatage töötav ülesanne ja arveldage aktiivsed kõned esmalt.
  • 409item_not_resolvableKirje ei sobi selle lahenduse jaoks. Algne variant nõuab ülevaatust; vahelejätmine väärtusega reason (customer_purchased või unsubscribed) nõuab mitteaktiivset ootel draft-kirjet või ootel/ebaõnnestunud paused-kirjet ilma lahendamata kõnedeta.
  • 409revision_conflictÜlesanne muutus vahepeal - lugege see uuesti (GET) ja korrake praeguse revision-iga.

POST/v1/tasks/{id}/reconcile

Ühitab ülesande oleku pärast katkestust tegelike kõnedega - ohutu igal ajal, isegi korduvalt kutsuda. ERINEVALT start/pause-st on revision VALIKULINE. See lahendab ülesande, mis on peatunud ühel neljast põhjusest: paus valimise keskel (dispatch_in_flight), aegunud claim (dispatch_claim_expired), kõne, mille hinda ei teatud veel (billing_unknown) või ebaselge valimine (dial:*), mille kõne leiti. Kui ükski kõne enam arveldamist ei oota, muutub selline ülesanne paused, kui mõni kontakt ootab veel katset (isegi kui teised on review-s), needs_attention, kui järel on ainult review-s kontaktid, ja completed, kui midagi ei jää. Eraldi vabastab see valimissoovi, mille töötaja suri enne kõne tegemist (kõnekirjet ega registreeritud katset ei ole), kui nii selle töö claim kui 5-minutiline varu on möödunud, seega kõige varem 15 minutit pärast valimise algust: kontakt läheb tagasi ootele (või muutub pärast kinnitatud tagasihelistust completed-iks) ja selle eelarvebroneering tagastatakse. Midagi muud ei muutu: running ülesanne jätkab tööd ja ülesanne, mis peatus muul põhjusel (variables_limit, ebaõnnestunud arve- või kalendrikontroll, ebaselge valimine, mille kõnet ei leita, või review-s kontaktid, mis selle varem peatasid), jääb olekusse needs_attention, kuni te nende kontaktide üle päringuga resolve otsustate.

Päring

bash
curl -X POST https://volai.cz/v1/tasks/task_9f3a2c1d/reconcile \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Vastus

json
{
  "task": {
    "id": "task_9f3a2c1d",
    "status": "completed",
    "revision": 3,
    "budgetHal": 80000,
    "reservedBudgetHal": 0,
    "spentHal": 684,
    "name": "Payment reminder - September",
    "agentId": "ag_4e91a2f0",
    "taskType": "custom",
    "purpose": "standard",
    "source": "manual",
    "callingWindow": { "timezone": "Europe/Prague", "start": "09:00", "end": "18:00", "days": [1, 2, 3, 4, 5] },
    "maxAttempts": 2,
    "maxDurationSecs": 120,
    "createdAt": 1757280000000,
    "updatedAt": 1757280240000,
    "items": [
      { "id": "item_1a2b3c", "phone": "+420777123456", "variables": { "jmeno": "Jana Novakova" }, "paymentStatus": "not_applicable", "status": "completed", "attempts": [{ "id": "attempt_5d4c3b", "startedAt": 1757280100000, "finishedAt": 1757280160000, "providerCallId": "c_7a2b9c1d", "outcome": "completed", "costHal": 684 }], "actualCostHal": 684 }
    ]
  }
}

Veaolekud

  • 400validationKeha ei vasta skeemile (revision, kui see on antud, peab olema mittenegatiivne täisarv).
  • 404task_not_foundKontol ei ole selle id-ga ülesannet.
  • 409revision_conflictÜlesanne muutus vahepeal - lugege see uuesti (GET) ja korrake praeguse revision-iga.

POST/v1/tasks/{id}/process

Ühitab tegelikud kõned ja proovib töödelda kuni ühe tähtajale jõudnud saaja juba töötavast ülesandest. Nõuab praegust revision-it; see ei käivita ega jätka kunagi ülesannet. See kasutab sama helistamisakent, summutamist, eelarve broneerimist, saldot, mahtu ja aatomilist claim'i nagu cron. Püsiv opt-in dispatchOrder: "first_attempts_first" seab tähtajale jõudnud saajad ilma loetud katseta esikohale; enne valimist tagasilükkamised (countsAsAttempt: false) säilitavad selle prioriteedi. Olemasolev kirjete järjekord jääb vaikimisi ja tulevikus olevaid nextAttemptAt väärtusi austatakse. Lugege pärast ebaselget tulemust praegune olek, selle asemel et päringut pimesi korrata. Iga uus loogiline tikse vajab uut Idempotency-Key, isegi kui revisjon ei ole muutunud.

Päring

bash
curl -X POST https://volai.cz/v1/tasks/task_9f3a2c1d/process \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: task-process-2026-10-08-tick-001" \
  -d '{"revision": 2}'

Vastus

json
{
  "status": "idle",
  "task": {
    "id": "task_9f3a2c1d",
    "name": "Payment reminder - September",
    "agentId": "ag_4e91a2f0",
    "taskType": "custom",
    "purpose": "standard",
    "source": "manual",
    "callingWindow": { "timezone": "Europe/Prague", "start": "09:00", "end": "18:00", "days": [1, 2, 3, 4, 5] },
    "maxAttempts": 2,
    "maxDurationSecs": 120,
    "budgetHal": 80000,
    "reservedBudgetHal": 0,
    "spentHal": 0,
    "status": "running",
    "revision": 2,
    "createdAt": 1757280000000,
    "updatedAt": 1757280120000,
    "items": [
      { "id": "item_1a2b3c", "phone": "+420777123456", "variables": { "jmeno": "Jana Novakova" }, "paymentStatus": "not_applicable", "status": "pending", "attempts": [], "nextAttemptAt": 1757280180000 }
    ]
  }
}

Veaolekud

  • 400validationKeha ei vasta skeemile või sellel puudub revision.
  • 404task_not_foundKontol ei ole selle id-ga ülesannet.
  • 409revision_conflictÜlesanne muutus vahepeal - lugege see uuesti (GET) ja korrake praeguse revision-iga.
  • 409task_not_runningÜlesanne ei tööta või peatati enne valimist. Lugege selle praegune olek; process ei jätka seda kunagi.
  • 409task_pausedÜlesanne ei tööta või peatati enne valimist. Lugege selle praegune olek; process ei jätka seda kunagi.
  • 409claim_lostVäljasaatmise tulemust ei saa ohutult kinnitada. Lugege või ühitage ülesanne ja uurige selle kõnet, selle asemel et päringut pimesi korrata.
  • 500dispatch_result_unpersistedVäljasaatmise tulemust ei saa ohutult kinnitada. Lugege või ühitage ülesanne ja uurige selle kõnet, selle asemel et päringut pimesi korrata.
  • 409agent_version_changedAvaldatud agendi versioon muutus. Vaadake see üle ja testige uuesti enne ülesande taaskäivitamist.
  • 403agent_suspendedvolai operaator on ülesande agendi käsitsi peatanud - ülesannet ei saa käivitada ega pärast pausi taaskäivitada enne peatamise tühistamist. Peatatud konto tagastab selle asemel account_suspended.
  • 503engine_contract_unavailableMootor ei teata praegu väljamineva ülesande muutujate ja piirangute toetust - proovige käivitada hiljem uuesti.
  • 409window_closedSeadistatud helistamisaknast (callingWindow) väljas - oodake selle taasavanemist või muutke seda päringuga PATCH.

DELETE/v1/tasks/{id}

Kustutab ülesande ja kõik selle kirjed - ainult olekus draft/ready/paused/completed/needs_attention, ILMA in_progress kirjeta. revision loetakse väärtusest ?revision= VÕI JSON-keha {"revision": ...} (päringuparameeter on ülimuslik).

Päring

bash
curl -X DELETE "https://volai.cz/v1/tasks/task_9f3a2c1d?revision=3" \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "deleted": true
}

Veaolekud

  • 400validationrevision puudub või ei ole mittenegatiivne täisarv (kas päringus või kehas).
  • 404task_not_foundKontol ei ole selle id-ga ülesannet.
  • 409revision_conflictÜlesanne muutus vahepeal - lugege see uuesti (GET) ja korrake praeguse revision-iga.
  • 409task_not_deletableÜlesandel on in_progress kirje või see on running - oodake selle lõppemist või peatage see esmalt.

POST/v1/tasks/csv-preview

Parsib ja valideerib saajate CSV-d ENNE ülesande loomist või uuendamist - midagi ei salvestata, ridade vead lähevad 200-vastuse massiivi errors, mitte HTTP-veana.

Päring

bash
curl -X POST https://volai.cz/v1/tasks/csv-preview \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"csv": "phone,jmeno\n+420777123456,Jana Novakova\nneplatne,Petr Svoboda\n"}'

Vastus

json
{
  "headers": ["phone", "jmeno"],
  "delimiter": ",",
  "rows": [
    { "line": 2, "phone": "+420777123456", "variables": { "jmeno": "Jana Novakova" }, "errors": [] },
    { "line": 3, "variables": { "jmeno": "Petr Svoboda" }, "errors": [{ "field": "phone", "message": "Invalid phone number", "row": 3 }] }
  ],
  "validRows": [
    { "phone": "+420777123456", "variables": { "jmeno": "Jana Novakova" } }
  ],
  "errors": [{ "field": "phone", "message": "Invalid phone number", "row": 3 }]
}

Veaolekud

  • 400validationKeha väli csv puudub, ei ole string või csv ületab 1 000 000 märki.

Numbrid

GET/v1/numbers/{e164}/callback-routing

Loeb omatud numbri valikulise tagasihelistamise poliitika. Numbri vaikimisi marsruutimine jääb muutmata.

Päring

bash
curl "https://volai.cz/v1/numbers/+420601234567/callback-routing" \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{"callbackRouting":{"agentIds":["ag_campaign"],"lookbackSecs":604800}}

Veaolekud

  • 400validatione164 URL-is ei ole kehtiv telefoninumber.
  • 404not_foundNumbrit ei ole olemas või see ei kuulu teie kontole.

PUT/v1/numbers/{e164}/callback-routing

Salvestab selgesõnalise lubatud loendi omatud aktiivsetest mootori agentidest tagasi helistavate helistajate jaoks, kellele on sellelt numbrilt lookbackSecs (60-604800 sekundit) jooksul tehtud unikaalne tegelik väljaminev kõne. Tundmatud, ebaselged või kinnitamata helistajad jäävad vaikeagendi juurde. Tühi agentIds keelab poliitika. Valikuline firstMessage kehtib ainult kinnitatud tagasihelistuste puhul. Valikuline missedFirstMessage (kuni 500 märki) asendab firstMessage helistaja puhul, kellele eelnenud väljamineval kõnel vestlust ei toimunud (ei vastatud, kõnepost, häälmenüü, keegi ei rääkinud) - see helistaja ei ole pakkumist veel kuulnud; ilma selleta kehtib firstMessage kõigile. Mootor saab kinnitatud tagasihelistuse puhul ka volai_callback_kind (missed või contacted). engineSyncRequired: true tähendab, et vaikeagendi mootori seadistus peab eraldi aktiveerima webhooks.inbound_route_url tagasilugemisega; see päring ei kirjuta ümber töötavat mootori seadistust. Kinnitatud sissetulevad kõned avaldavad kõne detailides callbackOf.callId ja valikulise serveri omandis taskId ning taskItemId.

Päring

bash
curl -X PUT "https://volai.cz/v1/numbers/+420601234567/callback-routing" \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"agentIds":["ag_campaign"],"lookbackSecs":604800}'

Vastus

json
{"callbackRouting":{"agentIds":["ag_campaign"],"lookbackSecs":604800},"engineSyncRequired":true}

Veaolekud

  • 400validatione164 URL-is ei ole kehtiv telefoninumber.
  • 404not_foundNumbrit ei ole olemas või see ei kuulu teie kontole.

GET/v1/numbers

Konto häälnumbrid, igaühel oma praegune marsruutimine. Mobiilinumbreid loetletakse eraldi päringus GET /v1/sms-numbers (MCP list_sms_numbers) ja number kõnede ja SMS-ide jaokss päringus GET /v1/voice-sms-numbers (MCP list_voice_sms_numbers).

Päring

bash
curl https://volai.cz/v1/numbers \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "numbers": [
    {
      "e164": "+420601234567",
      "routing": { "mode": "agent", "agentId": "ag_kx91fa2b", "hasSipPassword": false, "sipTarget": "engine" },
      "monthlyFeeHal": 2500,
      "boughtAt": 1756111640000,
      "region": "objednavka",
      "regionLabel": "Czech number",
      "billingMonths": 1
    }
  ]
}

GET/v1/numbers/{e164}

Ühe omatud numbri detail - sama kuju nagu GET /v1/numbers loendi kirjel. Mugav, kui teate ainult E.164 (tavaliselt agent MCP kaudu) ega taha kogu loendit lehitseda.

Päring

bash
curl "https://volai.cz/v1/numbers/+420601234567" \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "number": {
    "e164": "+420601234567",
    "routing": { "mode": "agent", "agentId": "ag_kx91fa2b", "hasSipPassword": false, "sipTarget": "engine" },
    "monthlyFeeHal": 2500,
    "boughtAt": 1756111640000,
    "region": "objednavka",
    "regionLabel": "Czech number",
    "billingMonths": 1
  }
}

Veaolekud

  • 400validatione164 URL-is ei ole kehtiv telefoninumber.
  • 404not_foundNumbrit ei ole olemas või see ei kuulu teie kontole.

POST/v1/numbers

Ostab numbri. Tühi keha {} määrab mis tahes vaba numbri praegusest nimekirjast või saatke konkreetne { "e164": "..." } päringust GET /v1/numbers/available. Valige piirkond väärtusega { "region": "brno" } - lubatud väärtused on praha, brno, internet, bratislava ja praegu müügil olevad piirkondlikud pakkumised (loetletud päringu GET /v1/numbers/available väljal regions); piirkonna number, mis ei ole müügil, tellitakse päringuga POST /v1/numbers/orders. See arveldab kuutasu 25.00 CZK (~EUR 1.04) (Slovaki numbri puhul, pakkumine bratislava, on see 75.00 CZK (~EUR 3.13) ette - billingMonths kuud ette makstud ja sama summa arveldatakse uuesti iga billingMonths kuu järel) ning marsruutimine algab väärtusega none - seadke see kohe päringuga PATCH.

Päring

bash
curl -X POST https://volai.cz/v1/numbers \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Vastus

json
{
  "number": {
    "e164": "+420266266647",
    "routing": { "mode": "none", "hasSipPassword": false },
    "monthlyFeeHal": 2500,
    "boughtAt": 1756111640000,
    "region": "praha",
    "regionLabel": "Prague",
    "billingMonths": 1
  }
}

Veaolekud

  • 400validationPäringu keha ei vasta skeemile (e164/region üle 32 märgi või vale tüüp) või region ei ole tuntud pakkumise id.
  • 402insufficient_creditTeie saldo ei kata kuutasu 25.00 CZK (~EUR 1.04). Slovaki numbri (pakkumine bratislava) puhul peab saldo katma ette monthlyFeeHal * billingMonths. Konto, mis ei ole kunagi saldot täiendanud, võib omada ühte numbrit tervitussaldost (ka avatud tellimus loeb); teise numbri saab osta alles pärast esimest täiendust. Midagi ei arveldata.
  • 402subscription_cap_reachedKontol on kulutuste ülempiiriga kuupakett, kuusaldo on ära kasutatud ja täiendatud saldo ei kata toimingut. See asendab sellise konto puhul vea insufficient_credit (sama HTTP-olek). Midagi ei arveldatud.
  • 404number_unavailableKeegi teine on selle konkreetse numbri juba ostnud - palun valige praegusest nimekirjast mõni teine (GET /v1/numbers/available).
  • 503pool_emptyPraeguses nimekirjas on numbrid otsas - tellige number mõnest teisest piirkonnast (POST /v1/numbers/orders) või liituge portaalis ootenimekirjaga.

GET/v1/numbers/waitlist

Ootenimekirja olek iga varupakkumise kohta (praha/brno/internet/bratislava ja müügil olevad piirkondlikud pakkumised, sama loend nagu regions päringus GET /v1/numbers/available) - joined ütleb, kas konto ootab selle järele, available kas see on praegu laos.

Päring

bash
curl https://volai.cz/v1/numbers/waitlist \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "offers": [
    { "offerId": "praha", "label": "Prague", "joined": false, "available": true },
    { "offerId": "brno", "label": "Brno", "joined": true, "available": false },
    { "offerId": "internet", "label": "Internet number", "joined": false, "available": true },
    { "offerId": "bratislava", "label": "Bratislava", "joined": false, "available": true }
  ]
}

Veaolekud

  • 404user_not_foundSelle API-võtme omanikku kontol ei leidu - ebatavaline olukord; võtke ühendust toega.

POST/v1/numbers/waitlist

Liitub välja müüdud pakkumise ootenimekirjaga (POST /v1/numbers ebaõnnestus veaga pool_empty) - see ei osta numbrit, vaid registreerib ainult huvi. Saate e-kirja, kui pakkumine uuesti laoseisu jõuab. Tühi keha {} kasutab vaikepakkumist (praha).

Päring

bash
curl -X POST https://volai.cz/v1/numbers/waitlist \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"offerId": "brno"}'

Vastus

json
{
  "joined": true
}

Veaolekud

  • 400validationofferId ei ole üks müügil olevatest pakkumistest (praha/brno/internet/bratislava ja piirkondlikud pakkumised väljal regions).
  • 404user_not_foundSelle API-võtme omanikku kontol ei leidu - ebatavaline olukord; võtke ühendust toega.

DELETE/v1/numbers/waitlist/{offerId}

Lahkub ÜHE pakkumise ootenimekirjast (offerId teel) - ei muuda teiste pakkumiste ootenimekirja.

Päring

bash
curl -X DELETE https://volai.cz/v1/numbers/waitlist/brno \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "left": true
}

Veaolekud

  • 400validationofferId teel ei ole üks pakkumise väärtustest.
  • 404user_not_foundSelle API-võtme omanikku kontol ei leidu - ebatavaline olukord; võtke ühendust toega.

GET/v1/numbers/available

Ostmiseks saadaolevate numbrite nimekiri (kuni 5 piirkonna kohta). numbers sisaldab valitud piirkonna numbreid (Praha, kui parameetri välja jätate), regions tagastab alati kogu nimekirja korraga - sh bratislava (Slovaki number teistsuguse tasuga, vt ülal POST /v1/numbers). Piirkondlikud pakkumised (jihocesky, karlovarsky, kralovehradecky, liberecky, moravskoslezsky, olomoucky, pardubicky, plzensky, stredocesky, ustecky, vysocina, zlinsky) ilmuvad väljale regions alles siis, kui piirkond on müügil (volail on seal hädaabiteenuste aadress); seni lükatakse selline region tundmatuna tagasi ja selle piirkonna number tellitakse päringuga POST /v1/numbers/orders.

Päring

bash
curl "https://volai.cz/v1/numbers/available?region=brno" \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "region": "brno",
  "numbers": ["+420510510129", "+420510510132"],
  "regions": [
    {
      "id": "praha",
      "label": "Prague",
      "description": "A landline with a Prague area code.",
      "numbers": ["+420266266643", "+420266266645"]
    },
    {
      "id": "brno",
      "label": "Brno",
      "description": "A landline with a Brno area code.",
      "numbers": ["+420510510129", "+420510510132"]
    },
    {
      "id": "internet",
      "label": "Internet number",
      "description": "Area code 910, not tied to any region - works from anywhere.",
      "numbers": ["+420910084099"]
    },
    {
      "id": "bratislava",
      "label": "Bratislava",
      "description": "A Slovak number with the Bratislava area code +421 2. Billed three months upfront.",
      "numbers": ["+421222205798"]
    }
  ]
}

Veaolekud

  • 400validationregion peab olema üks pakkumises olevatest id-dest (vt /cenik).

GET/v1/numbers/address-options

Aadressid numbri tellimiseks piirkonnast väljaspool nimekirja. See läbib operaatori kaskaadkataloogi: saatke psc ja saate omavalitsused, lisage obec ja saate linnaosad, cobce tagastab tänavad ning ulice tagastab majanumbrid. Kui cp on valitud, saabub loetav aadress väljal recap. Ärge mõelge koode välja - kehtivad on ainult siin tagastatud. Kiirem tee, mis kaskaadi vahele jätab, on query, vt allolevat märkust.

Päring

bash
curl "https://volai.cz/v1/numbers/address-options?psc=70200&obec=554821&cobce=413950" \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "obce": [{ "value": "554821", "label": "Ostrava" }],
  "casti": [{ "value": "413950", "label": "Moravská Ostrava" }],
  "ulice": [{ "value": "353710", "label": "28. října" }],
  "cp": [],
  "recap": null
}

Veaolekud

  • 400validationquery on pikem kui 200 märki, ei sisalda postiindeksit või operaatoril ei ole sobivat varianti tasemele, milleni see jõudis.
  • 502provisioning_failedAadresse ei õnnestunud operaatorilt üldse laadida.
  • 503orders_disabledTellimused on ajutiselt peatatud.

Kiirem tee: kogu aadress ühes päringus

Kaskaadi asemel saatke query kogu aadressiga (nt "Nadrazni 100, 702 00 Ostrava") - server juhib kaskaadi teie eest. Ainult postiindeks loetakse otse tekstist; kõik muu sobitatakse lihtsalt valikutega, mille operaator selle taseme jaoks tagastas - server ei mõtle kunagi koodi välja.

bash
curl -G https://volai.cz/v1/numbers/address-options \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  --data-urlencode "query=Nádražní 100, 702 00 Ostrava"
json
{
  "obce": [],
  "casti": [],
  "ulice": [],
  "cp": [],
  "recap": "28. října 102/1, Ostrava, 70200",
  "selection": {
    "psc": "70200",
    "obec": "554821",
    "cobce": "413950",
    "ulice": "353710",
    "cp": "3180026"
  }
}

Kui aadress on mitmetähenduslik, tagastatakse ainult tase, kus see selgub (ambiguousLevel: obec/cobce/ulice/cp), koos valikutega vastavas väljas, näiteks:

json
{
  "obce": [
    { "value": "554821", "label": "Ostrava" },
    { "value": "554813", "label": "Fulnek" }
  ],
  "casti": [],
  "ulice": [],
  "cp": [],
  "recap": null,
  "selection": { "psc": "70200", "obec": "", "cobce": "", "ulice": "", "cp": "" },
  "ambiguousLevel": "obec",
  "message": "The given address is ambiguous - choose the municipality (obec) from the options. Repeat the query WITHOUT query and with the step parameters: psc=70200, obec=<value from the options>."
}

selection kannab alati seda, mis on juba lahendatud - jätkake sama sammuparameetriga (psc/obec/cobce/ulice/cp), mida kasutaksite ilma query-ta. Kui aadressi ei saa üldse lahendada või ajaeelarve saab otsingu keskel otsa, saabub recap asemel loetav teade väljal message, koos seni lahendatud selection-iga - jätkake sealt sammuparameetritega.

query ja sammuparameetrid EI SEGUNE ühes päringus - saatke mõlemad koos ja lõpp-punkt tagastab validation. Seega pärast mitmetähenduslikku vastust ärge korrake sama query-t lisatud obec-iga (või muu tasemega) valikute hulgast - saatke järgmine päring ILMA query-ta, kasutades ainult sammuparameetreid. Täpne kuju (sh juba lahendatud väärtused) on kirjas otse selle mitmetähendusliku vastuse väljal message.

POST/v1/numbers/orders

Tellib numbri kliendi asukoha aadressil - kui ta soovib seda sinna registreerida või piirkond on välja müüdud või väljaspool nimekirja. Aadressikoodid peavad pärinema päringust GET /v1/numbers/address-options. Lõpp-punkt ootab, kuni me operaatori juures hädaabiteenuste aadressi seadistame ja numbri ostame - tavaliselt alla minuti; valmis number tuleb seejärel tagasi väljal e164 olekuga done. Kui esimesel katsel ei õnnestu, tagastab see tellimuse olekuga pending ja cron-ülesanne lõpetab selle. Tasu 25.00 CZK (~EUR 1.04) arveldatakse alles siis, kui number on valmis.

Päring

bash
curl -X POST https://volai.cz/v1/numbers/orders \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"psc":"70200","obec":"554821","cobce":"413950","ulice":"353710","cp":"3180026"}'

Vastus

json
{
  "order": {
    "id": "Xa3Kd9pQmR2v",
    "status": "pending",
    "address": "70200",
    "createdAt": 1756111640000,
    "updatedAt": 1756111640000
  }
}

Veaolekud

  • 400validationPäringu keha ei vasta skeemile - psc/obec/cobce/cp puudub või on tühi või väli ületab pikkusepiiri (ulice on valikuline).
  • 400incomplete_addresspsc, obec, cobce või cp puudub (ulice on valikuline - mitte igal aadressil ei ole seda).
  • 402insufficient_creditTeie saldo ei kata kuutasu 25.00 CZK (~EUR 1.04). Konto, mis ei ole kunagi saldot täiendanud, võib omada ühte numbrit tervitussaldost (ka avatud tellimus loeb); teise saab tellida alles pärast esimest täiendust. Midagi ei arveldata.
  • 402subscription_cap_reachedKontol on kulutuste ülempiiriga kuupakett, kuusaldo on ära kasutatud ja täiendatud saldo ei kata toimingut. See asendab sellise konto puhul vea insufficient_credit (sama HTTP-olek). Midagi ei arveldatud.
  • 503orders_disabledTellimused on ajutiselt peatatud.
  • 409idempotency_conflictSeda Idempotency-Key-d on juba kasutatud teise tellimuse aadressi jaoks.

GET/v1/numbers/orders

Tellimuse olek: pending (järjekorras), provisioning (seadistatakse praegu), done (number on väljal e164 ja kuulub kontole), failed (põhjus on väljal error, midagi ei arveldatud), cancelled (klient tühistas, kui see oli veel järjekorras - midagi ei arveldatud).

Päring

bash
curl https://volai.cz/v1/numbers/orders \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "orders": [
    {
      "id": "Xa3Kd9pQmR2v",
      "status": "done",
      "address": "28. října 102/1, Ostrava, 70200",
      "e164": "+420596123456",
      "createdAt": 1756111640000,
      "updatedAt": 1756118840000
    }
  ]
}

POST/v1/numbers/orders/{id}/cancel

Tühistab tellimuse, mis on veel järjekorras (pending) - ilma kehata, tagastab tellimuse olekuga cancelled. Midagi ei arveldata (tasu arvestatakse maha alles siis, kui number on valmis) ja konto, mis ei ole kunagi saldot täiendanud, saab uuesti tellida. Tellimust, mida praegu seadistatakse (provisioning), ei saa tühistada - see tagastab 409 in_progress, proovige mõne minuti pärast uuesti; samuti ei saa tühistada done ega failed tellimust (409 invalid_transition) - vabastage valmis number hoopis päringuga DELETE /v1/numbers/{e164}. Juba tühistatud tellimuse tühistamine on kahjutu (see tagastatakse muutmata kujul).

Päring

bash
curl -X POST https://volai.cz/v1/numbers/orders/Xa3Kd9pQmR2v/cancel \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "order": {
    "id": "Xa3Kd9pQmR2v",
    "status": "cancelled",
    "address": "28. října 102/1, Ostrava, 70200",
    "createdAt": 1756111640000,
    "updatedAt": 1756112240000
  }
}

Veaolekud

  • 404not_foundTellimust ei ole olemas või see ei kuulu teie kontole.
  • 409in_progressTellimust seadistatakse praegu (provisioning või cron-ülesanne alles võtab selle kätte) - seda saab hiljem vabastada ainult valmis numbrina. Proovige mõne minuti pärast uuesti.
  • 409invalid_transitionTellimus on lõpetatud (done - vabastage number päringuga DELETE /v1/numbers/{e164}) või on juba ebaõnnestunud (failed - pole midagi tühistada).

DELETE/v1/numbers/{e164}

Vabastab numbri tagasi varusse - katkestab marsruutimise ja agendi registreeringu. Juba makstud kuud ei hüvitata.

Päring

bash
curl -X DELETE "https://volai.cz/v1/numbers/+420601234567" \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "released": true
}

Veaolekud

  • 400validatione164 URL-is ei ole kehtiv telefoninumber.
  • 404not_foundNumbrit ei ole olemas või see ei kuulu teie kontole.
  • 502release_failedMarsruutimise katkestamist võrgus ei õnnestunud ohutult kinnitada, seega numbrit ei vabastatud tagasi varusse. Palun proovige varsti uuesti või võtke ühendust toega.

PATCH/v1/numbers/{e164}

Muudab numbri marsruutimist.

  • mode: "agent" + agentId - häälagent võtab kõned vastu.
  • mode: "forward" + forwardTo (E.164) - kõnede edastamine - maksate mõlema haru eest.
  • mode: "sip" + sipUri - marsruutib teie enda SIP-serverisse (vt SIP) - valikuliselt autentimisega väljadega sipUsername ja sipPassword, kui sihtkeskjaam seda nõuab. PATCH-i kehast täielikult välja jäetud väli säilitab oma salvestatud väärtuse - sama kehtib mõlema välja kohta, seega ainult sipUri muutmine ei nõua salvestatud kasutajanime ega parooli uuesti saatmist. Erand: kui sipUri muudatus muudab ka serverit (@-märgi järgne osa), peate parooli uuesti saatma - me ei saada kunagi salvestatud parooli teisele serverile kui sellele, mille jaoks te selle sisestasite. Autentimise kustutamine on ainult selgesõnaline - saatke nii sipUsername kui sipPassword tühjade stringidena. Vastus kannab alati ka hasSipPassword (valikuline, ainult lugemiseks) - true tähendab, et numbril on salvestatud SIP-parool; sipPassword ise ei tagastata API kaudu kunagi.
  • mode: "none" - numbrile tulevaid kõnesid ei marsruudita kuhugi ja võrk lükkab need tagasi.

sipTarget väljal routing on valikuline informatiivne väli, mille seab volai - te ei saada seda kunagi ise. Väärtus "engine" tähendab, et numbri agent töötab volai enda mootoril. Mis tahes muu väärtus või puuduv väli tähendab, et ei tööta (tavaliselt agent ElevenLabsi peal) - ärge käsitlege ainult puuduvat välja kindla tõendina ElevenLabsi kohta; "engine" on ainus usaldusväärne signaal.

Päring

bash
curl -X PATCH "https://volai.cz/v1/numbers/+420601234567" \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"routing": {"mode": "agent", "agentId": "ag_kx91fa2b"}}'

Vastus

json
{
  "number": {
    "e164": "+420601234567",
    "routing": { "mode": "agent", "agentId": "ag_kx91fa2b", "hasSipPassword": false, "sipTarget": "engine" },
    "monthlyFeeHal": 2500,
    "boughtAt": 1756111640000,
    "region": "objednavka",
    "regionLabel": "Czech number",
    "billingMonths": 1
  }
}

Veaolekud

  • 400validationrouting.mode nõuab vastavat välja (agentId / forwardTo / sipUri). Väärtuse routing.mode: "sip" korral kehtivad ka sipUsername ja sipPassword: täitke mõlemad või ei kumbagi, ilma koolonita, @-märgita, tühikuta, jutumärgita ja kaldkriipsuta tagurpidi, kumbki kuni 64 märki. Kui mõlemad volitusandmed on täidetud, ei tohi sipUri-s kutsutav number (enne @-märki) sisaldada koolonit ning sipUri server (pärast @-märki) ei tohi sisaldada porti - seda ei toetata veel koos volitusandmetega. Selle koodi saate ka siis, kui muudate sipUri serverit numbril, millel on salvestatud parool, saatmata sipPassword uuesti, või kui sipUri osutab Vapi BYO SIP-trunk'ile (<credentialId>.sip.vapi.ai või .sip.eu.vapi.ai), samal ajal kui volitusandmed saadetakse või on salvestatud - mõlemad väljad peavad seal jääma tühjaks, sest Vapi tunneb meie kõned ära lüüside IP järgi.
  • 400invalid_sip_urisipUri ei ole kujul sip:user@server (valikuliselt pordiga) - kehtib ainult väärtuse routing.mode: "sip" korral. Sama koodi saate alati, kui operaator keeldub lõplikult AUTENTITUD marsruudi salvestamisest (mõlemad sipUsername ja sipPassword täidetud) või loeb tagasi teise sihtmärgi kui see, mille me saatsime - kordamine muutmata kujul ei aita. Volitusandmeteta marsruutimise puhul teatatakse sama olukorrast kui routing_failed.
  • 402insufficient_creditKonto ei ole kunagi saldot täiendanud ja number ei ole veel edastatud - kõnede edastamist (routing.mode: "forward") saab sisse lülitada alles pärast esimest täiendust, sest see arveldatakse hiljem operaatori kirjete põhjal ilma pidurita kõne ajal. Agent, SIP ja sissetulevad kõned jätkavad tööd. Numbri, mis on juba edastatud, saab suunata teisele sihtmärgile ilma täienduseta. Midagi ei arveldata.
  • 404not_foundNumbrit ei ole olemas või see ei kuulu teie kontole.
  • 502routing_failedSoovitud marsruutimist ei kinnitatud just praegu (edastamine, SIP, selle katkestamine või marsruudi kinnitamine mootorisse) - ajutine võrgukatkestus, proovige varsti uuesti.
  • 502engine_unavailableVäärtusega routing.mode: "agent" volai enda mootoril oleva agendi puhul: mootor ei vasta praegu, numbri määramine ebaõnnestus. Palun proovige varsti uuesti või võtke ühendust toega. Sama koodi tagastatakse kirjutamise puhul, mille mootori ooterežiimi sõlm tagasi lükkas (mootor töötab praegu ooterežiimi sõlmel, mis seadistust vastu ei võta): teade ütleb seda, muudatust ei salvestatud ja sama päringut saab mõne minuti pärast korrata.
  • 502engine_readback_mismatchVäärtusega routing.mode: "agent" volai enda mootoril oleva agendi puhul: mootor vastas, kuid tagasilugemine näitas teistsugust vastendust kui see, mille me saatsime. Proovige uuesti.

GET/v1/numbers/{e164}/sip

Numbri SIP-andmed - teie enda softphone'i/keskjaama ja häälplatvormi väljamineva trunk'i jaoks (ElevenLabs, Vapi...). Samm-sammuline seadistus asub lehel SIP.

VäliTähendus
serverRegistreerimise domeen teie enda softphone'i või keskjaama jaoks (SIP REGISTER). Mitte platvormi väljamineva trunk'i jaoks - vt outboundTrunkAddress.
outboundTrunkAddressAadress teie platvormi väljamineva SIP-trunk'i jaoks (ElevenLabs outbound_trunk_config.address). Kasutage täpselt seda väärtust olenemata sellest, kas see ühtib server-iga - teistsugune aadress tähendab, et kõnet võrgus ei marsruudita ja platvorm teatab ajalõpust.
username / passwordLiini sisselogimisandmed - samad REGISTER-i ja digest-autentimisega trunk'i jaoks.
port / transportSIP-signalisatsiooni port ja soovitatav transport - TCP (suur INVITE koos SDP-ga ei pruugi UDP MTU-sse mahtuda ja platvorm keeldub siis selle saatmisest üldse); UDP töötab samuti.
inboundSignallingCidrsKust meie SIP-signalisatsioon teie keskjaama või platvormi poole tuleb - lubatud loend teie sissetuleva trunk'i jaoks (nt ElevenLabs allowed_addresses, Vapi lüüsid).

server ja outboundTrunkAddress ei ole vahetatavad: server on REGISTER-i jaoks softphone'ist või keskjaamast, outboundTrunkAddress on platvormi väljamineva trunk'i jaoks - trunk võtab alati väärtuse väljalt outboundTrunkAddress, olenemata sellest, kas see ühtib väärtusega server; teistsugune aadress tähendab, et kõnet võrgus ei marsruudita ja platvorm teatab ajalõpust (üksikasjad SIP-lehel ja kohandatud agendi juhendis).

Päring

bash
curl "https://volai.cz/v1/numbers/+420601234567/sip" \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "server": "sip.volai.cz",
  "username": "123456",
  "password": "a1b2c3d4e5f6",
  "outboundTrunkAddress": "sip.volai.cz",
  "port": 5060,
  "transport": "tcp",
  "inboundSignallingCidrs": ["81.31.45.0/24"]
}

Veaolekud

  • 400validatione164 URL-is ei ole kehtiv telefoninumber.
  • 404not_foundNumbrit ei ole olemas või see ei kuulu teie kontole.
  • 502sip_credentials_unavailableSIP-liini parooli ei leitud. Palun proovige hetke pärast uuesti või võtke ühendust toega.

GET/v1/numbers/{e164}/sip/status

Numbri tegelik SIP-registreerimise olek, mis on marsruutitud teie enda keskjaama ja selle viimane sissetulev kõne - erinevalt väljast routing.mode on see TÕESTI kontrollitud olek, mitte seadetest tuletatud. registration on null, kui number osutab VÕÕRALE keskjaamale (sipa: sihtmärk ilma väljakutseta) - seal on tähendusrikas ainult lastInbound.

Päring

bash
curl "https://volai.cz/v1/numbers/+420601234567/sip/status" \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "target": { "kind": "own_line", "host": null },
  "registration": { "registered": true },
  "lastInbound": {
    "at": 1756118900000,
    "status": "completed",
    "from": "+420777123456",
    "recent": true
  },
  "serviceStopped": null
}

Veaolekud

  • 400validatione164 URL-is ei ole kehtiv telefoninumber.
  • 404not_foundNumbrit ei ole olemas või see ei kuulu teie kontole.
  • 400not_sip_modeNumber ei ole marsruutitud "teie enda keskjaama".

Sõnumid

SMS-e võtavad vastu kahte liiki numbrid

volai häälnumbrid (lauatelefon ja VoIP) ei saa SMS-e vastu võtta. SMS-ide vastuvõtmine ja saatmine oma numbrilt on see, mida teeb mobiilinumbri lisand (vt allpool jaotist mobiilinumbrid): Tšehhi mobiilinumber ainult SMS-ide jaoks, ilma kõnedeta, ning see, mida teeb number kõnede ja SMS-ide jaoks (vt allpool jaotist Number kõnede ja SMS-ide jaokss): Praha lauatelefoninumber kõnede ja SMS-idega. Vastuvõetud sõnumeid loete päringus GET /v1/messages?direction=in, MCP tööriistas list_messages või webhookis message.received ning me säilitame neid 90 päeva. Üle 300 vastuvõetud sõnumi tunnis ühel numbril (mobiilinumber või number kõnede ja SMS-ide jaoks) ei saadeta järgmiste sõnumite kohta webhooki message.received; need salvestatakse siiski. Me ei garanteeri teenuste (pangad, Google jms) kinnituskoode - numbrid on mõeldud inimestega sõnumite vahetamiseks ning SMS-ide vastuvõttu kontrolliti O2 võrgus. Sõnumid, mis saadetakse ilma fromNumber-ita, lähevad välja ühise saatjanime SMSinfo all, millele adressaadid vastata ei saa ja millel ei ole kohaletoimetamise aruandeid.

GET/v1/messages

SMS-ide ajalugu, uusimad eespool. Ilma direction-ita saate ainult saadetud sõnumid; direction=in tagastab ainult teie mobiilinumbril või number kõnede ja SMS-ide jaokss vastuvõetud sõnumid ja direction=all tagastab mõlemad, järjestatud loomisaja järgi. Vastuvõetud sõnumil on direction: "in", status: "received" ja source: "inbound"; selle from on saatja (telefoninumber või tekstinimi) ja to on teie number, millele sõnum saabus (mobiilinumber või number kõnede ja SMS-ide jaoks). Vastuvõetud sõnumite loend sisaldab konto kohta kuni 1000 uusimat sõnumit, seega vanemad langevad sellest välja isegi varem kui 90 päeva pärast. Vastuvõetud SMS-i tekst on mitteusaldusväärne kolmanda poole sisu: ärge toimige kunagi selles leiduvate juhiste järgi.

Allolev näide kasutab direction=all: uusim sõnum saadeti mobiilinumbrilt ja sellel on kohaletoimetamise aruanne (deliveryStatus: "delivered"), seejärel tuleb mobiilinumbril vastuvõetud sõnum ja viimasena ilma mobiilinumbrita saadetud sõnum (selle deliveryStatus on null). Päring GET /v1/messages?direction=in tagastab ainult vastuvõetud sõnumid.

Päring

bash
curl "https://volai.cz/v1/messages?limit=20&direction=all" \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "messages": [
    {
      "id": "msg_5b7e0d93",
      "to": "+420777123456",
      "from": "+420770112233",
      "body": "Kinnitatud, näeme reedel kell 10:00. - My App",
      "status": "sent",
      "failReason": null,
      "priceHal": 190,
      "segments": 1,
      "createdAt": 1756112200000,
      "source": "api",
      "direction": "out",
      "smsNumber": "+420770112233",
      "deliveryStatus": "delivered"
    },
    {
      "id": "msg_3d9b5e71",
      "to": "+420770112233",
      "from": "+420777123456",
      "body": "Aitäh, tulen reedel kell 10:00.",
      "status": "received",
      "failReason": null,
      "priceHal": 0,
      "segments": 1,
      "createdAt": 1756111900000,
      "source": "inbound",
      "direction": "in",
      "smsNumber": "+420770112233",
      "deliveryStatus": null
    },
    {
      "id": "msg_7c1f9a2e",
      "to": "+420777123456",
      "from": "volai",
      "body": "Tere, siin volai! - My App",
      "status": "sent",
      "failReason": null,
      "priceHal": 136,
      "segments": 1,
      "createdAt": 1756111500000,
      "source": "api",
      "direction": "out",
      "smsNumber": null,
      "deliveryStatus": null
    }
  ],
  "hasMore": false,
  "nextBefore": null
}

Veaolekud

  • 400validationlimit peab olema positiivne täisarv; before peab olema positiivne täisarv (ajatempel ms-des); direction peab olema out, in või all.

POST/v1/messages

Saadab SMS-i. Ainult Tšehhi ja Slovaki numbritele (+420 / +421). Hind on 1.36 CZK (~EUR 0.06) segmendi kohta - pikemad sõnumid (või sõnumid, milles on märke väljaspool GSM-7 tähestikku, tavaliselt tšehhi diakriitikud) jagunevad mitmeks segmendiks, igaüks arveldatakse eraldi - vt vastuses segments. Nõuab esimest saldo täiendust - tervitussaldo SMS-e ei ava.

Ilma fromNumber-ita lähevad sõnumid välja ühise saatjanime SMSinfo all - operaatorid lubavad Tšehhi võrkudes ainult kinnitatud saatjanimesid, seega ühise saatjaga oma saatjanime kasutada ei saa ja adressaadid ei saa SMSinfo-le vastata. Vastuse väli from on siis ainult sisemine silt volai; adressaadid ei näe seda kunagi. Mobiilinumbrilt saadetud sõnumi puhul on from see number. Pange oma identiteet hoopis otse sõnumi teksti, nagu allolevas näites.

Oma mobiilinumbrilt saatmiseks seadke fromNumber (number päringust GET /v1/sms-numbers). Adressaat näeb siis SMSinfo asemel teie numbrit. Numbrilt saatmine toimib ainult Tšehhi numbritele (+420), maksab 1.90 CZK (~EUR 0.08) segmendi kohta (ilma käibemaksuta) ja sellel on päevane limiit konto kohta: 20 sõnumit esimese 30 päeva jooksul pärast numbri ostmist, pärast seda 50. Päringu väli from ignoreeritakse endiselt.

fromNumber aktsepteerib ka number kõnede ja SMS-ide jaoks (number päringust GET /v1/voice-sms-numbers). Sellelt saadetud SMS maksab 2.50 CZK (~EUR 0.10) segmendi kohta (ilma käibemaksuta), läheb ainult Tšehhi numbritele (+420), sellel ei ole kohaletoimetamise aruandeid (deliveryStatus jääb null) ja päevane saatmislimiit jagatakse mobiilinumbritega: 20 sõnumit esimese 30 päeva jooksul pärast numbri tellimist, pärast seda 50. Vastus STOP sellel numbril midagi ei blokeeri (recipient_opted_out tagastatakse ainult mobiilinumbrite puhul), seega jälgige oma adressaatide loobumisi oma rakenduses.

  • Ilma diakriitikuta (GSM-7 tähestik) mahub ühte segmenti 160 märki; pikem tekst jaguneb 153-märgilisteks tükkideks.
  • Diakriitikute või mis tahes märgiga väljaspool GSM-7 (UCS-2) on piir 70 märki segmendi kohta; pikem tekst jaguneb 67-märgilisteks tükkideks.
  • Näpunäide: ühte segmenti mahtumiseks kirjutage ilma diakriitikuta - Prilis zlutoucky kun asemel Příliš žluťoučký kůň.

Päring

bash
curl -X POST "https://volai.cz/v1/messages" \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: REPLACE_WITH_UNIQUE_POST_V1_MESSAGES_ID" \
  -d '{"to":"+420777123456","body":"Tere, siin volai! - My App"}'

Enne käivitamist asendage REPLACE_WITH_UNIQUE… selle toimingu unikaalse ID-ga, näiteks UUID-ga, ja salvestage see. Sama päringu kordamisel pärast ajalõppu kasutage sama ID-d. Teise toimingu või muudetud sisu korral kasutage uut ID-d, isegi kui kutsute teist lõpp-punkti.

Vastus

json
{
  "id": "msg_7c1f9a2e",
  "status": "sent",
  "priceHal": 136,
  "segments": 1
}

Veaolekud

  • 400validationPäringu keha ei vasta skeemile (to või body puudub, body on üle 2000 märgi, fromNumber ei ole kuni 32 märgi pikkune string) või to on sama number mis fromNumber (number ei saa endale SMS-i saata). Selle eest me ei arvelda.
  • 400invalid_numberSee ei ole kehtiv Tšehhi ega Slovaki telefoninumber.
  • 400invalid_bodySõnumi tekst peab olema 1 kuni 765 märki.
  • 400unsupported_countryNumber väljaspool CZ/SK - me ei saada sinna SMS-e.
  • 400blocked_destinationSihtkoht on lisatasuga number (prefiksid +420 900, +420 906, +420 908, +420 909, +420 976 ja +421 900). Me ei saada neile SMS-e, et te ei saaks kogemata arvet kasvatada. Selle eest me ei arvelda.
  • 400recipient_cannot_receive_smsLauatelefoni number - SMS ei jõuaks kohale. Selle eest me ei arvelda.
  • 400unsupported_charactersTekst sisaldab emojit või muud märki, mida telefonivõrk ei suuda kohale toimetada. Selle eest me ei arvelda.
  • 400recipient_is_virtual_numberAdressaat on volai number. SMS ei jõua kunagi volai häälnumbrini (sh teie enda omani) - need käsitlevad ainult kõnesid. SMS ühiselt nimelt SMSinfo ei jõua volai mobiilinumbrini ega number kõnede ja SMS-ide jaoks-ni: saatke see oma mobiilinumbrilt või number kõnede ja SMS-ide jaoks-lt väljaga fromNumber. Selle eest me ei arvelda.
  • 400recipient_rejectedTelefonivõrk ei võta seda numbrit vastu - tavaliselt on see virtuaalne või olematu number. Selle eest me ei arvelda.
  • 400invalid_from_numberfromNumber ei ole ei teie konto aktiivne mobiilinumber ega aktiivne number kõnede ja SMS-ide jaoks (tundmatu number või number teisest kontost annab sama vea). Kontrollige seda päringutes GET /v1/sms-numbers ja GET /v1/voice-sms-numbers; numbrit, mille olek ei ole active (näiteks releasing või awaiting_registration), ei saa kasutada. Midagi ei arveldata.
  • 400from_number_unsupported_destinationMobiilinumbrilt saatmine toimib ainult Tšehhi numbritele (+420). Saatke Slovaki numbrile ilma fromNumber-ita, ühise nime SMSinfo all. Midagi ei arveldata.
  • 400destination_not_allowednumber kõnede ja SMS-ide jaoks-lt saatmine toimib ainult Tšehhi numbritele (+420). Saatke Slovaki numbrile ilma fromNumber-ita, ühise nime SMSinfo all. Midagi ei arveldata.
  • 402insufficient_creditSaldo ei kata kõiki sõnumi segmente või konto ei ole kunagi saldot täiendanud - ühiselt saatjalt SMSinfo saadetavad SMS-id nõuavad esimest täiendust ja tervitussaldo ei kata neid isegi oma numbriga. Selle eest me ei arvelda.
  • 402subscription_cap_reachedKontol on kulutuste ülempiiriga kuupakett, kuusaldo on ära kasutatud ja täiendatud saldo ei kata toimingut. See asendab sellise konto puhul vea insufficient_credit (sama HTTP-olek). Midagi ei arveldatud.
  • 402spend_cap_reachedTeie seatud kuine kulutuste ülempiir on saavutatud. Midagi ei tehtud ega saadetud ning midagi ei arvestatud. Tõstke või eemaldage ülempiir päringuga PUT või DELETE /v1/account/spend-cap või oodake järgmist kalendrikuud.
  • 403sms_numbers_unavailableMobiilinumbrilt saatmine ei ole sellel kontol praegu saadaval. Midagi ei arveldata; ilma fromNumber-ita saab sõnumi siiski SMSinfo all välja saata.
  • 403voice_sms_numbers_unavailablenumber kõnede ja SMS-ide jaoks-lt saatmine ei ole sellel kontol praegu saadaval. Midagi ei arveldata; ilma fromNumber-ita saab sõnumi siiski SMSinfo all välja saata.
  • 409recipient_opted_outAdressaat vastas teie mobiilinumbrile STOP ega võta sellelt rohkem sõnumeid vastu, kuni ta saadab START. Kordamine ei aita ja midagi ei arveldata.
  • 429rate_limitedÜle 1 SMS iga 2 sekundi järel või üle 100 SMS kontol 24 tunni jooksul alates esimesest (teade ütleb, kui kaua kulub piirangu lähtestumiseni). Mobiilinumbrilt või number kõnede ja SMS-ide jaoks-lt (fromNumber) saatmisel on lisaks päevane limiit konto kohta, mida jagavad mõlemad liigid: 20 sõnumit esimese 30 päeva jooksul pärast numbri ostmist, pärast seda 50.
  • 502send_failedTelefonivõrk lükkas päringu tagasi. Me ei arveldanud teie saldot - palun proovige uuesti.
  • 502send_failed_operatorViga meie poolel (saatja või operaatori saldo). Me ei arveldanud teie saldot - palun proovige varsti uuesti.
  • 502sms_gateway_failedOperaatori lüüs ebaõnnestus ajutiselt. Me ei arveldanud teie saldot - proovige mõne minuti pärast uuesti.
  • 502send_unknownMe ei suutnud saatmise tulemust usaldusväärselt kinnitada; sõnum võis siiski minna - see arveldatakse ikkagi, seega palun ärge saatke seda pimesi uuesti.
  • 503ledger_unavailableSaldot ei õnnestunud praegu lugeda, proovige varsti uuesti. Midagi ei arveldata.

Sõnumi status: pending (salvestatud, veel saadetakse), sent (operaator võttis sõnumi saatmiseks vastu, sh järjekorras sõnumid; see ei ole kohaletoimetamise kviitung), failed (operaator lükkas tagasi, mobiilinumbrilt saadetud sõnumi puhul võib see juhtuda alles hiljem - ei arveldata, juba arveldatud saldo hüvitatakse, priceHal 0), received (teie mobiilinumbril või number kõnede ja SMS-ide jaoks-l vastuvõetud sõnum, alati koos direction: "in" ja priceHal 0) ja unknown (operaator ei kinnitanud vastuvõttu, tavaliselt sellepärast, et selle vastus aegus) - see arveldatakse siiski täishinnaga, sest sõnum võis kohale jõuda. Mobiilinumbrilt saadetud sõnumi puhul võib unknown ise veel muutuda: olekuks sent koos deliveryStatus-iga, kui operaator sõnumi kinnitab, või olekuks failed koos saldo hüvitamisega, kui ta selle tagasi lükkab. Kui saate unknown, siis palun ärge saatke seda pimesi uuesti - võtke ühendust toega ja me hüvitame võimaliku topeltarvelduse.

Väärtuse status: "failed" korral saate ka failReason: unsupported_characters (emoji või märk, mida võrk ei suuda kohale toimetada), unsupported_recipient (võrk ei võta numbrit vastu), forbidden_sender ja low_balance (viga meie poolel), gateway_failed (operaatori lüüs), network_rejected (mõni muu tagasilükkamine), opted_out (adressaat vastas teie mobiilinumbrile STOP). Muude olekute korral on see null.

deliveryStatus (delivered või undelivered) on operaatori kohaletoimetamise aruanne ja eksisteerib ainult teie mobiilinumbrilt saadetud sõnumite puhul. See on null ühise nime SMSinfo all saadetud sõnumite puhul, millel kohaletoimetamise aruandeid ei ole, number kõnede ja SMS-ide jaoks-lt saadetud sõnumite puhul, millel neid samuti ei ole, ning vastuvõetud sõnumite puhul. sent tähendab endiselt ainult seda, et operaator võttis sõnumi vastu, ega tõenda kohaletoimetamist. Sõnum väärtusega undelivered arveldatakse siiski, sest operaator võttis selle vastu. Kui operaator teatab hiljem tõrkest, muutub sõnumi status väärtuseks failed, priceHal langeb 0-ni ja selle eest hüvitatakse saldo. Kohaletoimetamise aruanne saabub niipea, kui operaator selle teatab; kui olekuteade ei saabu, täidab selle korrapärane kontroll iga 15 minuti järel. Kui operaator ei teata seda kunagi, jääb see null.

Näide: saatmine oma mobiilinumbrilt

Vastuvõetud SMS-ile vastamiseks saatke samalt numbrilt: seadke fromNumber oma mobiilinumbriks päringust GET /v1/sms-numbers ja adressaat näeb teie numbrit. Kohaletoimetamise aruanne saabub hiljem: sõnumi deliveryStatus algab väärtusega null ja delivered või undelivered loete päringust GET /v1/messages/{id}.

bash
curl -X POST https://volai.cz/v1/messages \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to": "+420777123456", "fromNumber": "+420770112233", "body": "Kinnitatud, näeme reedel kell 10:00. - My App"}'
json
{
  "id": "msg_5b7e0d93",
  "status": "sent",
  "priceHal": 190,
  "segments": 1
}

Näide: diakriitikuga sõnum üle 70 märgi tähendab rohkem segmente

See sõnum on 112 märki pikk ja sisaldab diakriitikuid, seega loetakse see UCS-2-ks (mitmeosaliste sõnumite puhul piir 67 märki segmendi kohta) - see teeb 2 segmenti, seega 2.72 CZK (~EUR 0.11), mitte 1.36 CZK (~EUR 0.06):

bash
curl -X POST https://volai.cz/v1/messages \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to": "+420777123456", "body": "Příliš žluťoučký kůň úpěl ďábelské ódy - a tahle věta má přes sedmdesát znaků, takže spadne do druhého segmentu."}'
json
{
  "id": "msg_9a3f1c7d",
  "status": "sent",
  "priceHal": 272,
  "segments": 2
}

GET/v1/messages/{id}

Ühe sõnumi detail.

Päring

bash
curl https://volai.cz/v1/messages/msg_7c1f9a2e \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "message": {
    "id": "msg_7c1f9a2e",
    "to": "+420777123456",
    "from": "volai",
    "body": "Tere, siin volai! - My App",
    "status": "sent",
    "failReason": null,
    "priceHal": 136,
    "segments": 1,
    "createdAt": 1756111500000,
    "source": "api",
    "direction": "out",
    "smsNumber": null,
    "deliveryStatus": null
  }
}

Veaolekud

  • 404not_foundSõnumit ei ole olemas, see ei kuulu teie kontole või on see vanem kui 90 päeva vastuvõetud sõnum.

Mobiilinumbrid

GET/v1/sms-numbers

Konto mobiilinumbrid (mobiilinumbri lisand): Tšehhi mobiilinumbrid, mis võtavad SMS-e vastu ja saadavad neid teie enda numbrilt. Igaühel on status (active või releasing, kui vabastamine käib või ootab kordust), tasu monthlyFeeHal 30-päevase perioodi kohta ja nextChargeAt, millal on järgmine tasu. Saatmislimiit on väljal dailySendLimit (20 SMS-i 24-tunnise akna kohta numbri esimese 30 päeva jooksul, seejärel 50), dailySendRemaining (mitu on järel, 0 vabastatava numbri puhul) ja dailySendResetsAt (millal aken lõpeb, null, kui ükski ei käi); aken on ühine kõigile konto mobiilinumbritele, algab esimese saadetud SMS-iga ning loeb ka limiiti ületavaid katseid ja SMS-e, mille operaator tagasi lükkas. Loendamine toimib isegi siis, kui uued ostud ei ole saadaval.

Päring

bash
curl https://volai.cz/v1/sms-numbers \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "smsNumbers": [
    {
      "number": "+420770112233",
      "status": "active",
      "createdAt": 1756111640000,
      "monthlyFeeHal": 29000,
      "nextChargeAt": 1758703640000,
      "dailySendLimit": 20,
      "dailySendRemaining": 17,
      "dailySendResetsAt": 1756198040000
    }
  ]
}

POST/v1/sms-numbers

Ostab kontole Tšehhi mobiilse mobiilinumbri. Ärge saatke keha; number valime meie. Number võtab SMS-e vastu (lugege neid päringuga GET /v1/messages?direction=in või webhooki sündmusega message.received) ja saadate sellelt väljaga fromNumber päringus POST /v1/messages. See ei tee ega võta kõnesid vastu. 290.00 CZK (~EUR 12.08) ilma käibemaksuta arveldatakse saldolt kohe esimese 30-päevase perioodi eest ja uuesti iga 30 päeva järel; makstud perioodi ei hüvitata, kui numbri vabastate. Kontol võib olla kuni kaks mobiilinumbrit ja ostmine nõuab esimest saldo täiendust. Kui pärast ostu operaatori juures midagi ebaõnnestub, vabastatakse number uuesti ja midagi ei arveldata. Kuni konto teine ost veel käib, saate 429 rate_limited; oodake mõni sekund ja korrake. Toetab päist Idempotency-Key: pärast ajalõppu saatke sama väärtus, et kordus ei saaks teist numbrit osta. Sõnumite kohaletoimetamine igalt saatjalt, sh kinnituskoodid, ei ole garanteeritud.

Päring

bash
curl -X POST "https://volai.cz/v1/sms-numbers" \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Idempotency-Key: REPLACE_WITH_UNIQUE_POST_V1_SMS_NUMBERS_ID"

Enne käivitamist asendage REPLACE_WITH_UNIQUE… selle toimingu unikaalse ID-ga, näiteks UUID-ga, ja salvestage see. Sama päringu kordamisel pärast ajalõppu kasutage sama ID-d. Teise toimingu või muudetud sisu korral kasutage uut ID-d, isegi kui kutsute teist lõpp-punkti.

201 Created

json
{
  "smsNumber": {
    "number": "+420770112233",
    "status": "active",
    "createdAt": 1756111640000,
    "monthlyFeeHal": 29000,
    "nextChargeAt": 1758703640000,
    "dailySendLimit": 20,
    "dailySendRemaining": 20,
    "dailySendResetsAt": null
  }
}

Veaolekud

  • 402insufficient_creditTeie saldo ei kata esimese perioodi tasu 290.00 CZK (~EUR 12.08) või konto ei ole kunagi saldot täiendanud - mobiilinumbri saab osta alles pärast esimest täiendust ja tervitussaldo seda ei ava. Midagi ei arveldata.
  • 402subscription_cap_reachedKontol on kulutuste ülempiiriga kuupakett, kuusaldo on ära kasutatud ja täiendatud saldo ei kata toimingut. See asendab sellise konto puhul vea insufficient_credit (sama HTTP-olek). Midagi ei arveldatud.
  • 403sms_numbers_unavailableMobiilinumbri lisand ei ole sellel kontol praegu saadaval. Midagi ei arveldata; kui ootasite juurdepääsu, kirjutage volai toele.
  • 409sms_number_limitKontol on juba mobiilinumbrite maksimaalne arv (kaks). Vabastage üks päringuga DELETE /v1/sms-numbers/{e164} ja ostke uuesti. Midagi ei arveldata.
  • 429rate_limitedMõni teine numbriost sellel kontol (hääl või SMS) veel käib. Oodake mõni sekund ja korrake sama päringut. Midagi ei arveldata.
  • 503sms_number_out_of_stockOperaatoril ei ole praegu vaba Tšehhi mobiilinumbrit. Midagi ei arveldata; proovige hiljem uuesti.
  • 503ledger_unavailableSaldot ei õnnestunud praegu lugeda, proovige varsti uuesti. Midagi ei arveldata.

DELETE/v1/sms-numbers/{e164}

Vabastab mobiilinumbri: see läheb tagasi operaatorile ja seda ei saa taastada ning sellele hiljem saadetud sõnumid teieni enam ei jõua. Juba vastuvõetud sõnumid jäävad loendisse kuni nende 90 päeva möödumiseni. Käimasoleva 30-päevase perioodi tasu ei hüvitata. Kui vabastamine operaatori juures ebaõnnestub, jääb number olekusse status: "releasing"; saatke sama päring uuesti, et see vabastada.

Päring

bash
curl -X DELETE "https://volai.cz/v1/sms-numbers/+420770112233" \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "released": true
}

Veaolekud

  • 400validatione164 URL-is ei ole kehtiv telefoninumber (kirjutage plussmärk otse või kujul %2B).
  • 404not_foundMobiilinumbrit ei ole olemas või see ei kuulu teie kontole.
  • 502release_failedVabastamist ei õnnestunud operaatori juures just praegu lõpule viia. Number jääb teie omaks olekus status: "releasing"; saatke sama päring varsti uuesti. Juba makstud perioodi ei hüvitata.

Number kõnede ja SMS-ide jaokss

Number kõnede ja SMS-ide jaoks on häälnumbrite ja mobiilinumbrite kõrval kolmas numbriliik: Praha lauatelefoninumber (+420 2xx), mis võtab vastu kõnesid ja SMS-e ning millelt teie agent teeb kõnesid ja saadab SMS-e. Häälnumber ei saa SMS-e vastu võtta ja mobiilinumbril ei ole kõnesid. Number registreeritakse operaatori juures volai teenusepakkuja nimel ja teie kasutate seda; pärast tellimist on see tavaliselt aktiivne 1 tööpäeva jooksul ja hiljemalt 48 tunni jooksul ning tasu arveldatakse alles pärast aktiveerimist. Sissetulevatele kõnedele vastab agent, mis töötab volai enda hääl mootoril, ja number käsitleb korraga kuni kahte kõnet. SMS-ide vastuvõttu kontrolliti O2 võrgus ja me ei garanteeri teenuste kinnituskoode. Tellimuse kehas oleva country-ga saate Praha numbri asemel number teises riigis: lauatelefoni number teises riigis, mis võtab vastu kõnesid (neile vastab agent), kuid millel ei ole SMS-e (see ei võta neid vastu ega saada) ja mis helistab välja ainult numbri riiki ja Tšehhi. Hind sõltub riigist (lugege see riigi monthlyFeeHal-ist päringus GET /v1/voice-sms-numbers/countries) ja muud reeglid on samad mis Praha numbril; number registreeritakse operaatori juures selle riigi aadressiga teenusepakkuja nimel ja see on aktiivne tavaliselt 1 tööpäeva jooksul ja hiljemalt 3 tööpäeva jooksul (tunni jooksul riikides, kus registreerimist ei ole). Riigid, kus saate tellida, muutuvad, seega lugege need päringust GET /v1/voice-sms-numbers/countries (MCP list_voice_sms_countries) ja ärge loetlege kunagi ühtegi mälu järgi. Tellite selle ise portaalis, REST-i kaudu (POST /v1/voice-sms-numbers) või MCP kaudu (order_voice_sms_number) pärast esimest saldo täiendust. Kui tellimused on ajutiselt peatatud, tagastab tellimus voice_sms_numbers_unavailable ja midagi ei arveldata; proovige hiljem uuesti või kirjutage volai toele.

GET/v1/voice-sms-numbers

Konto number kõnede ja SMS-ide jaokss ja number teises riigiss: Praha lauatelefonid, mis võtavad vastu kõnesid ja SMS-e ning millelt te helistate ja saadate SMS-e, ning muude riikide lauatelefonid, mis võtavad vastu kõnesid ja millelt agent helistab, ilma SMS-ideta. Igaühel on country (ISO-kood), capabilities (calls, sms ja outboundTo: riigid, kuhu agent numbrilt helistab) ja status (awaiting_registration, active, rejected või releasing), routing (kuhu sissetulevad kõned heliseevad), tasu monthlyFeeHal 30-päevase perioodi kohta, numbrilt saadetud ühe SMS-segmendi hind smsFromNumberHal (null numbri puhul, millel SMS-e ei ole), nextChargeAt (millal on järgmine tasu, null, kuni number on aktiivne), smsInboundReady (tõene, kui number on aktiivne ja SMS-ide vastuvõtt on seadistatud) ning ajad createdAt ja activatedAt. pendingOrders loetleb tellimused, mis võeti vastu, kuid millele ei ole numbrit määratud (pärast ajutist probleemi operaatori juures); igaüks kannab ainult createdAt. Selline tellimus lõpeb ise ja number ilmub siis numbrite sekka ning seni loeb see piirangute hulka, seega ärge tellige uuesti. Iga kirje kannab tellimuse country-t. Kui tellimus ebaõnnestub, kaob see pendingOrders-ist ilma numbrita, midagi ei arveldata ja konto saab e-kirja; seejärel saate uuesti tellida. Loendamine toimib isegi siis, kui uued tellimused ei ole saadaval.

Päring

bash
curl https://volai.cz/v1/voice-sms-numbers \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "voiceSmsNumbers": [
    {
      "number": "+420292000001",
      "country": "CZ",
      "capabilities": { "calls": true, "sms": true, "outboundTo": ["CZ"] },
      "status": "active",
      "routing": { "mode": "agent", "agentId": "ag_9f3a2b7c4d1e", "sipTarget": "engine", "hasSipPassword": false },
      "monthlyFeeHal": 4900,
      "smsFromNumberHal": 250,
      "nextChargeAt": 1758703640000,
      "smsInboundReady": true,
      "createdAt": 1756101640000,
      "activatedAt": 1756111640000
    }
  ],
  "pendingOrders": [{ "createdAt": 1758790000000, "country": "CZ" }]
}

GET/v1/voice-sms-numbers/countries

Riigid, kus saate praegu numbrit tellida, pakkumise järjekorras (Tšehhi esimesena). Igaüks kannab country (ISO-kood, mille edastate country-na päringule POST /v1/voice-sms-numbers), name, prefix, numberKind, sms (tõene ainult Tšehhi numbri puhul, väljaspool Tšehhit olev number käsitleb ainult kõnesid), outboundTo (riigid, kuhu agent võib numbrilt helistada), activation (within_hour või within_business_days) ja monthlyFeeHal (numbri hind selles riigis 30 päeva kohta hellerites, ilma käibemaksuta; see sõltub riigist, seega näidake kasutajale see summa enne tellimist). Pakkumine sõltub kontost ja muutub aja jooksul, seega lugege seda, selle asemel et riiki eeldada. Ainult lugemiseks, midagi ei arveldata.

Päring

bash
curl https://volai.cz/v1/voice-sms-numbers/countries \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "countries": [
    {
      "country": "CZ",
      "name": "Czechia",
      "prefix": "+420",
      "numberKind": "landline, Prague (+420 2)",
      "sms": true,
      "outboundTo": ["CZ"],
      "activation": "within_business_days",
      "monthlyFeeHal": 4900
    },
    {
      "country": "GB",
      "name": "United Kingdom",
      "prefix": "+44",
      "numberKind": "landline, London (+44 20)",
      "sms": false,
      "outboundTo": ["CZ"],
      "activation": "within_hour",
      "monthlyFeeHal": 2900
    }
  ],
  "waitlisted": ["NL"]
}

POST/v1/voice-sms-numbers/countries/{country}/waitlist

Lisab konto riigi ootenimekirja, kus numbreid veel ei müüda (portaali kaardil olev riik, mida GET /v1/voice-sms-numbers/countries ei tagasta). Midagi ei arvestata. Korduv kutse sama riigi jaoks tagastab alreadyJoined: true. Riik, mis on juba pakkumises, tagastab validation. Kliente ei teavitata veel automaatselt; kirjutatud riigid tagastab väli waitlisted riikide loendis.

Päring

bash
curl -X POST https://volai.cz/v1/voice-sms-numbers/countries/NL/waitlist \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "country": "NL",
  "joined": true,
  "alreadyJoined": false
}

Veaolekud

  • 400validationcountry ei ole kaardil oleva riigi ISO-kood, või see on Tšehhi, või riik on konto pakkumises praegu olemas ja selle saab kohe tellida.
  • 404user_not_foundSelle API-võtme omanikku kontol ei leidu - ebatavaline olukord; võtke ühendust toega.

POST/v1/voice-sms-numbers

Tellib kontole Praha number kõnede ja SMS-ide jaoks, või väljaga country number teises riigis. Keha on valikuline: ilma kehata (või väärtusega {"country": "CZ"}) saate Praha numbri, {"country": "<ISO-kood>"} tellib number teises riigis. Valige riik alati päringust GET /v1/voice-sms-numbers/countries; pakkumisest väljas olev riik tagastab 400 country_not_offered ja midagi ei arveldata. number teises riigis on mõeldud ainult kõnedeks, ilma SMS-ideta: see ei võta neid vastu ega saada, helistab välja ainult numbri riiki ja Tšehhi ning on aktiivne hiljemalt 3 tööpäeva pärast tellimust (tunni jooksul riikides, kus registreerimist ei ole). Numbri tüüpi „number teises riigis“ hind sõltub riigist: see on selle riigi monthlyFeeHal päringust GET /v1/voice-sms-numbers/countries, tasu arvestatakse alles pärast aktiveerimist ja muud reeglid on samad mis Praha numbril. Number määratakse automaatselt ja seda ei saa valida. Praha number muutub aktiivseks pärast registreerimist operaatori juures, tavaliselt ühe tööpäeva jooksul (kuni 48 tundi): seni on selle status awaiting_registration, see ei helise ega võta SMS-e vastu ning midagi ei arveldata. Tasu 49.00 CZK (~EUR 2.04) ilma käibemaksuta 30 päeva kohta (Praha numbri puhul; numbri tüüpi „number teises riigis“ puhul oma riigi hind) arveldatakse saldolt alles siis, kui number muutub aktiivseks, ja uuesti iga 30 päeva järel; makstud perioodi ei hüvitata, kui numbri vabastate. Sellelt helistate agendiga (POST /v1/calls koos agentId-ga) ja Praha numbrilt saadate SMS-e (fromNumber päringus POST /v1/messages, 2.50 CZK (~EUR 0.10) segmendi kohta, ainult Tšehhi numbritele ja ilma kohaletoimetamise aruanneteta); sissetulevaid kõnesid marsruutite päringuga PATCH /v1/voice-sms-numbers/{e164}. Kontol võib olla ühes riigis kuni kaks sellist numbrit ja kokku kuni neli (ka tellimus, mis ootab veel registreerimist või numbri määramist, loeb), ning tellimine nõuab esimest saldo täiendust. Vastus on 202; voiceSmsNumber on null, kui ajutine probleem operaatori juures jättis tellimuse ilma määratud numbrita: tellimus jätkub taustal, on nähtav päringu GET /v1/voice-sms-numbers väljal pendingOrders, kuni number määratakse, ja ilmub seejärel seal numbrite sekka, seega ärge tellige uuesti. Kui tellimus ebaõnnestub, kaob see pendingOrders-ist ilma numbrita, midagi ei arveldata ja konto saab e-kirja; seejärel saate uuesti tellida. Toetab päist Idempotency-Key: pärast ajalõppu saatke sama väärtus, et kordus ei saaks luua teist tellimust. Praha numbri puhul kontrolliti SMS-ide vastuvõttu ainult O2 võrgus ja sõnumite kohaletoimetamine igalt saatjalt, sh kinnituskoodid, ei ole garanteeritud.

bash
# Example: a number in another country (choose the country from GET /v1/voice-sms-numbers/countries)
curl -X POST https://volai.cz/v1/voice-sms-numbers \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"country":"GB"}'
json
{
  "voiceSmsNumber": {
    "number": "+442000000001",
    "country": "GB",
    "capabilities": { "calls": true, "sms": false, "outboundTo": ["CZ"] },
    "status": "awaiting_registration",
    "routing": { "mode": "none", "hasSipPassword": false },
    "monthlyFeeHal": 2900,
    "smsFromNumberHal": null,
    "nextChargeAt": null,
    "smsInboundReady": false,
    "createdAt": 1756101640000,
    "activatedAt": null
  }
}

Päring

bash
curl -X POST "https://volai.cz/v1/voice-sms-numbers" \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Idempotency-Key: REPLACE_WITH_UNIQUE_POST_V1_VOICE_SMS_NUMBERS_ID"

Enne käivitamist asendage REPLACE_WITH_UNIQUE… selle toimingu unikaalse ID-ga, näiteks UUID-ga, ja salvestage see. Sama päringu kordamisel pärast ajalõppu kasutage sama ID-d. Teise toimingu või muudetud sisu korral kasutage uut ID-d, isegi kui kutsute teist lõpp-punkti.

202 Accepted

json
{
  "voiceSmsNumber": {
    "number": "+420292000001",
    "country": "CZ",
    "capabilities": { "calls": true, "sms": true, "outboundTo": ["CZ"] },
    "status": "awaiting_registration",
    "routing": { "mode": "none", "hasSipPassword": false },
    "monthlyFeeHal": 4900,
    "smsFromNumberHal": 250,
    "nextChargeAt": null,
    "smsInboundReady": false,
    "createdAt": 1756101640000,
    "activatedAt": null
  }
}

Veaolekud

  • 400validationKeha ei ole kehtiv JSON-objekt või country ei ole kahetäheline suurtäheline ISO-kood (näiteks PL). Midagi ei arveldata.
  • 400country_not_offeredSee konto ei saa praegu nõutud country-s tellida, sest see ei ole pakkumises. GET /v1/voice-sms-numbers/countries tagastab praeguse pakkumise. Midagi ei arveldata.
  • 402insufficient_creditTeie saldo ei kata esimese perioodi tasu (49.00 CZK (~EUR 2.04) Praha numbri puhul, alates 29.00 CZK (~EUR 1.21) sõltuvalt riigist teises riigis oleva numbri puhul) või konto ei ole kunagi saldot täiendanud - number kõnede ja SMS-ide jaoks saab tellida alles pärast esimest täiendust ja tervitussaldo seda ei ava. Midagi ei arveldata.
  • 402subscription_cap_reachedKontol on kulutuste ülempiiriga kuupakett, kuusaldo on ära kasutatud ja täiendatud saldo ei kata toimingut. See asendab sellise konto puhul vea insufficient_credit (sama HTTP-olek). Midagi ei arveldatud.
  • 403voice_sms_numbers_unavailableNumber kõnede ja SMS-ide jaokss ei ole sellel kontol praegu saadaval: funktsioon on selle jaoks välja lülitatud või uued tellimused on pärast registreerimisprobleemi peatatud. Kordamine ei aita; midagi ei arveldata, kirjutage volai toele.
  • 409voice_sms_number_limitKontol on juba number kõnede ja SMS-ide jaokss maksimaalne arv (kaks ühes riigis, kokku neli kontol); ka tellimus, mis ootab veel registreerimist või millele ei ole numbrit määratud (pendingOrders loendis), loeb. Vabastage üks (DELETE /v1/voice-sms-numbers/{e164}) või tühistage registreerimist ootav tellimus (POST /v1/voice-sms-numbers/{e164}/cancel) ja tellige uuesti; tellimus ilma määratud numbrita lõpeb ise ja seda ei saa tühistada. Midagi ei arveldata.
  • 409idempotency_conflictSeda Idempotency-Key-d on juba kasutatud teise tellimuse jaoks.
  • 429rate_limitedSellel kontol käib juba mõni teine numbritellimus (hääl, SMS või kõned ja SMS). Oodake mõni sekund ja korrake sama päringut. Midagi ei arveldata.
  • 429voice_sms_order_limitViimase 30 päeva jooksul tühistas konto kaks number kõnede ja SMS-ide jaoks tellimust, seega praegu ei saa uut esitada; piirang peatab tellimise ja tühistamise tsüklid. Oodake, kuni 30-päevane aken on möödas, või kirjutage volai toele. Midagi ei arveldata.
  • 503voice_sms_number_out_of_stockOperaatoril ei ole praegu nõutud riigis vaba numbrit (Praha number, kui country on välja jäetud). Midagi ei arveldata; proovige hiljem uuesti.
  • 503order_failedNumbrit ei õnnestunud operaatori juures seadistada (ajutine probleem või tagasi lükatud registreerimine), seega ei saanud tellimust lõpule viia. Midagi ei arveldata; proovige hiljem uuesti või kirjutage volai toele.
  • 503ledger_unavailableSaldot ei õnnestunud praegu lugeda, proovige varsti uuesti. Midagi ei arveldata.

GET/v1/voice-sms-numbers/{e164}

Ühe number kõnede ja SMS-ide jaoks detail, sama kuju nagu loendi kirje. Teise konto number ja olematu number tagastavad sama 404.

Päring

bash
curl "https://volai.cz/v1/voice-sms-numbers/+420292000001" \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "voiceSmsNumber": {
    "number": "+420292000001",
    "country": "CZ",
    "capabilities": { "calls": true, "sms": true, "outboundTo": ["CZ"] },
    "status": "active",
    "routing": { "mode": "none", "hasSipPassword": false },
    "monthlyFeeHal": 4900,
    "smsFromNumberHal": 250,
    "nextChargeAt": 1758703640000,
    "smsInboundReady": true,
    "createdAt": 1756101640000,
    "activatedAt": 1756111640000
  }
}

Veaolekud

  • 400validatione164 URL-is ei ole kehtiv telefoninumber (kirjutage plussmärk otse või kujul %2B).
  • 404not_foundNumber kõnede ja SMS-ide jaoks ei ole olemas või see ei kuulu teie kontole.

PATCH/v1/voice-sms-numbers/{e164}

Määrab, kuhu number kõnede ja SMS-ide jaoks sissetulevad kõned heliseevad: routing on {"mode": "agent", "agentId": "ag_..."} (vastab volai enda hääl mootoril töötav agent) või {"mode": "none"} (kõnedele ei vastata ja agent eraldatakse). Teisele numbrile edastamine (forward) ja kohandatud SIP-server (sip) ei ole seda tüüpi numbri puhul toetatud ja tagastavad unsupported_for_number_type, nagu ka agent, mis ei tööta ettevõttesisesel mootoril. Agendi saab siduda ainult aktiivse numbriga (invalid_transition); marsruutimise väljalülitamine (none) toimib igas olekus. Sellele numbrile seotud agendil võib olla ainult Tšehhi (+420) edastusnumber, vastasel juhul tagastatakse destination_not_allowed. Kui numbrit töötleb praegu mõni teine toiming (aktiveerimine, arveldus või vabastamine), saate 409 in_progress: midagi ei muudetud ja päringut saab minuti pärast korrata. Teenuseni jõuavad ainult mode ja agentId; muud keha väljad jäetakse kõrvale.

Päring

bash
curl -X PATCH "https://volai.cz/v1/voice-sms-numbers/+420292000001" \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"routing":{"mode":"agent","agentId":"ag_9f3a2b7c4d1e"}}'

Vastus

json
{
  "voiceSmsNumber": {
    "number": "+420292000001",
    "country": "CZ",
    "capabilities": { "calls": true, "sms": true, "outboundTo": ["CZ"] },
    "status": "active",
    "routing": { "mode": "agent", "agentId": "ag_9f3a2b7c4d1e", "sipTarget": "engine", "hasSipPassword": false },
    "monthlyFeeHal": 4900,
    "smsFromNumberHal": 250,
    "nextChargeAt": 1758703640000,
    "smsInboundReady": true,
    "createdAt": 1756101640000,
    "activatedAt": 1756111640000
  }
}

Veaolekud

  • 400validationKeha ei ole kehtiv JSON-objekt väljaga routing, mode ei ole ei agent ega none, väärtuse agent korral puudub agentId või on see pikem kui 64 märki või e164 URL-is ei ole kehtiv telefoninumber.
  • 400unsupported_for_number_typeRežiim forward või sip või agent, mis ei tööta volai enda hääl mootoril. Valige mootoril olev agent või none. Midagi ei muudetud.
  • 400destination_not_allowedAgendil on edastusnumber väljaspool +420, kuhu number kõnede ja SMS-ide jaoks edastada ei saa. Muutke agendi edastusnumber Tšehhi omaks või eemaldage see ja seejärel siduge number. number teises riigis puhul peab edastusnumber olema numbri riigis (kui sellele helistamine on sisse lülitatud) või Tšehhis. Midagi ei muudetud.
  • 404not_foundNumbrit ei ole olemas või see ei kuulu teie kontole või agentId ei ole teie konto aktiivne agent.
  • 409invalid_transitionNumber ei ole aktiivne: see ootab registreerimist, selle registreerimine lükati tagasi või seda vabastatakse. Agendi saab siduda ainult aktiivse numbriga (none toimib alati). Olek on päringus GET /v1/voice-sms-numbers/{e164}.
  • 409in_progressNumbrit töötleb mõni teine toiming (aktiveerimine, arveldus või vabastamine). Midagi ei muudetud; korrake sama päringut minuti pärast.
  • 502routing_failedAgendi eraldamine ettevõttesiseses hääl mootoris ebaõnnestus; number jääb marsruutituks nagu enne. Korrake päringut varsti.
  • 502engine_unavailableEttevõttesisene hääl mootor ei vasta praegu, agenti ei seotud numbriga. Palun proovige varsti uuesti või võtke ühendust toega. Sama koodi tagastatakse kirjutamise puhul, mille mootori ooterežiimi sõlm tagasi lükkas (mootor töötab praegu ooterežiimi sõlmel, mis seadistust vastu ei võta): teade ütleb seda, muudatust ei salvestatud ja sama päringut saab mõne minuti pärast korrata.
  • 502engine_readback_mismatchMootor vastas, kuid tagasilugemine näitas teistsugust vastendust kui see, mille me saatsime. Proovige uuesti.

POST/v1/voice-sms-numbers/{e164}/cancel

Tühistab number kõnede ja SMS-ide jaoks, mis ootab veel registreerimist operaatori juures (awaiting_registration): number tühistatakse ja te ei maksa midagi, sest tasu arveldatakse alles pärast aktiveerimist. Aktiivset numbrit ei saa tühistada (409 invalid_transition); vabastage see päringuga DELETE /v1/voice-sms-numbers/{e164}. Tühistamine loeb 30 päeva jooksul kahe tühistatud tellimuse piiri hulka; kui see on saavutatud, tagastab POST /v1/voice-sms-numbers voice_sms_order_limit. Ilma kehata.

Päring

bash
curl -X POST "https://volai.cz/v1/voice-sms-numbers/+420292000001/cancel" \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "cancelled": true
}

Veaolekud

  • 400validatione164 URL-is ei ole kehtiv telefoninumber (kirjutage plussmärk otse või kujul %2B).
  • 404not_foundNumber kõnede ja SMS-ide jaoks ei ole olemas või see ei kuulu teie kontole.
  • 409invalid_transitionNumber on juba aktiivne (makstud; vabastage see päringuga DELETE), tagasi lükatud (pole midagi tühistada) või seda vabastatakse.
  • 409in_progressNumbrit aktiveeritakse praegu või mõni teine toiming töötleb selle tellimust. Proovige mõne minuti pärast uuesti; kui see on aktiivne, saate selle vabastada.
  • 500internal_errorTühistamist ei õnnestunud operaatori juures just praegu kinnitada. Tellimus jääb ootele ja midagi ei arveldata; korrake päringut varsti.

DELETE/v1/voice-sms-numbers/{e164}

Vabastab aktiivse number kõnede ja SMS-ide jaoks: see eraldab agendi, läheb tagasi operaatorile ja seda ei saa taastada. Käimasoleva 30-päevase perioodi tasu ei hüvitata. Registreerimist ootavat numbrit ei vabastata, vaid tühistatakse (POST /v1/voice-sms-numbers/{e164}/cancel). Kui vabastamine ebaõnnestub (agendi eraldamine mootoris või tühistamine operaatori juures), tagastatakse 502 release_failed: number jääb active või läheb olekusse releasing, milles see enam ei helise ning ei saa helistada ega saata, ja sama päringu uuesti saatmine lõpetab vabastamise.

Päring

bash
curl -X DELETE "https://volai.cz/v1/voice-sms-numbers/+420292000001" \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "released": true
}

Veaolekud

  • 400validatione164 URL-is ei ole kehtiv telefoninumber (kirjutage plussmärk otse või kujul %2B).
  • 404not_foundNumber kõnede ja SMS-ide jaoks ei ole olemas või see ei kuulu teie kontole.
  • 409invalid_transitionNumber ootab registreerimist (tühistage see päringuga POST /v1/voice-sms-numbers/{e164}/cancel, te ei maksa midagi) või operaator lükkas registreerimise tagasi ja number on juba tühistatud.
  • 409in_progressNumbrit töötleb mõni teine toiming (aktiveerimine, tühistamine või teine vabastamine). Proovige mõne minuti pärast uuesti.
  • 502release_failedVabastamist ei õnnestunud just praegu lõpule viia. Number jääb active või releasing (seda ei saa enam kasutada); saatke sama päring varsti uuesti. Juba makstud perioodi ei hüvitata.

Kõned

GET/v1/calls

Kõneajalugu, uusimad eespool. direction (in või out) piirab loendi ühe suunaga. Filtrid from/to (Unix ms, startedAt vahemikus, from <= to), agentId, flagged (true/false), goal (success/failure/unclear/no_conversation/not_evaluated või tagasiühilduv unknown - kirjed, millel pole selget tulemust: goal.result puudub või on unknown (alati tõene väärtuste unclear ja not_evaluated puhul ning no_conversation puhul ainult siis, kui selle tulemus on unknown) - vt kõne välja goal), outcome (agent/transferred/no_answer/other, vt allolevas kind tabelis veergu Arveldus; värava kutsung, kind: "ring", on alati other, isegi kui selle olek on no_answer). Tundmatuid parameetreid ignoreeritakse. Kõned vs. vestlused: GET /v1/calls tagastab üksikud kõne KIRJED - iga telefoniharu on oma rida. Portaali tabel /hovory rühmitab seotud harud (sissetulev agendi haru pluss väljaminev edastusharu) üheks VESTLUSEKS - edukalt edastatud kõne näitab portaalis seega ühte rida, kuid API/MCP kaudu kuni kahte kirjet (edastuse teinud haru väärtus on outcome: "transferred"; vastuvõttev haru säilitab oma outcome). Summeerige kõnede arve API-st sellega arvestades.

Päring

bash
curl "https://volai.cz/v1/calls?limit=20" \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "calls": [
    {
      "id": "c_8f2ac1d4",
      "direction": "in",
      "from": "+420777123456",
      "to": "+420601234567",
      "status": "completed",
      "startedAt": 1756111400000,
      "durationSecs": 47,
      "priceHal": 236,
      "agentId": "ag_kx91fa2b",
      "note": null,
      "flag": null,
      "handledAt": null,
      "rating": null,
      "goal": null,
      "hasConversation": true,
      "source": "inbound",
      "kind": "inbound",
      "endReason": "completed",
      "hasRecording": true,
      "data": {
        "name": "Mari Tamm",
        "coffee_count": 2,
        "urgency": "normal"
      }
    }
  ],
  "hasMore": false,
  "nextBefore": null
}

Veaolekud

  • 400validationlimit/before peab olema positiivne täisarv, direction peab olema "in" või "out"; from peab olema väiksem või võrdne to-ga, kui mõlemad on saadetud; agentId ei tohi ületada 64 märki; flagged/goal/outcome väljaspool lubatud väärtusi.

POST/v1/calls

Alustab väljaminevat kõnet numbrile to. Saatke täpselt ÜKS järgmistest: agentId (teie häälagent viib kõne läbi oma systemPrompt järgi), from (otseühendus kahe numbri vahel, ilma agendita - sild, vt allpool) või systemPrompt (prooviversiooni kõne ilma oma numbrita - ostu ega agendi seadistust ei vajata, vt allpool). Mitte kunagi rohkem kui üks, mitte kunagi ühtegi. Variandiga agentId saate saata ka variables (kohandatud väärtused promptile) ja ringingTimeoutSecs (kui kaua lasta heliseda, vt allolevat märkust).

Päring

bash
curl -X POST "https://volai.cz/v1/calls" \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: REPLACE_WITH_UNIQUE_POST_V1_CALLS_ID" \
  -d '{"to":"+420777123456","agentId":"ag_kx91fa2b","variables":{"jmeno_zakaznika":"Jana","cislo_objednavky":"A-42"},"ringingTimeoutSecs":30}'

Enne käivitamist asendage REPLACE_WITH_UNIQUE… selle toimingu unikaalse ID-ga, näiteks UUID-ga, ja salvestage see. Sama päringu kordamisel pärast ajalõppu kasutage sama ID-d. Teise toimingu või muudetud sisu korral kasutage uut ID-d, isegi kui kutsute teist lõpp-punkti.

Vastus

json
{
  "id": "c_9d4e2b7f",
  "status": "initiated"
}

Veaolekud

  • 400invalid_numberto ei ole kehtiv telefoninumber.
  • 400validationagentId/from/systemPrompt puudub või neid on rohkem kui üks; väärtusega agentId on variables piiridest väljas (kuni 20 võtit, 64-märgilised võtmed, 512-märgilised väärtused) või ringingTimeoutSecs on väljaspool vahemikku 5-60; väärtusega systemPrompt puudub see/on üle 1200 märgi, firstMessage on üle 300 märgi või ringingTimeoutSecs on väljaspool vahemikku 5-30.
  • 400on_dncSee number on teie helistamiskeeluloendis (/v1/dnc).
  • 400destination_auto_blockedSihtkoht blokeeriti automaatselt 30 päevaks korduvate ebaõnnestumiste järel - tühistage see portaalis (Seaded) või päringuga POST /v1/dnc/{e164}/unblock.
  • 400cannot_call_own_numberSilmuse kaitse - te ei saa helistada oma volai numbrile.
  • 400cannot_call_volai_numberSilmuse kaitse - sihtkoht on teise konto volai number.
  • 400destination_not_allowedNumber kõnede ja SMS-ide jaoks saab helistada ainult Tšehhi numbritele (+420); number teises riigis saab helistada ainult numbri riiki (kui sellele helistamine on sisse lülitatud, vt numbri capabilities.outboundTo) ja Tšehhi. to on mõni teine number. Edastage lubatud to või helistage agendilt, mis kasutab häälnumbrit. Midagi ei arveldata.
  • 400unsupported_for_number_typeVariant from (lihtne kõne kahe numbri vahel ilma agendita) ei ole number kõnede ja SMS-ide jaoks-lt saadaval: from on teie enda number kõnede ja SMS-ide jaoks ja sellelt helistab ainult agent. Edastage from-ina oma telefon (Tšehhi või Slovaki number) või saatke agentId. Midagi ei arveldata.
  • 404bridge_needs_numberSild (from) vajab kontol vähemalt ühte teie enda häälnumbrit. Number kõnede ja SMS-ide jaoks ei loe: sellelt helistab ainult agent. Ostke häälnumber päringuga POST /v1/numbers.
  • 409destination_busyTeil juba käib teine kõne samale numbrile.
  • 404agent_not_foundagentId ei ole olemas või ei kuulu teie kontole.
  • 404agent_no_numberAgendile ei ole telefoninumbrit määratud.
  • 403agent_suspendedvolai operaator on selle agendi käsitsi peatanud - selle kaudu ei saa praegu kõnet teha. Peatatud konto tagastab selle asemel account_suspended.
  • 402insufficient_creditTeie saldo ei kata kõne alustamiseks vajalikku miinimumi.
  • 402subscription_cap_reachedKontol on kulutuste ülempiiriga kuupakett, kuusaldo on ära kasutatud ja täiendatud saldo ei kata toimingut. See asendab sellise konto puhul vea insufficient_credit (sama HTTP-olek). Midagi ei arveldatud.
  • 402spend_cap_reachedTeie seatud kuine kulutuste ülempiir on saavutatud. Midagi ei tehtud ega saadetud ning midagi ei arvestatud. Tõstke või eemaldage ülempiir päringuga PUT või DELETE /v1/account/spend-cap või oodake järgmist kalendrikuud.
  • 503capacity_busyKõik väljaminevad liinid on praegu hõivatud, proovige minuti pärast uuesti. Number kõnede ja SMS-ide jaoks lubab korraga ainult ühte väljaminevat kõnet: kui sellelt juba üks käib, kannab vastus päist Retry-After sekunditega, mille pärast saate uuesti proovida.
  • 503trial_calls_disabledVäärtusega systemPrompt: prooviversiooni kõned on operatiivse lüliti poolt ajutiselt keelatud - helistage hoopis oma agendi kaudu (agentId).
  • 403trial_email_unverifiedVäärtusega systemPrompt: ainult kontodele kinnitatud e-posti aadressiga.
  • 500trial_not_configuredVäärtusega systemPrompt: ühine volai demoagent ei ole õigesti seadistatud - ajutine viga meie poolel.
  • 502call_rejectedVäärtusega systemPrompt: häälplatvorm lükkas ühenduse otse tagasi, midagi ei arveldatud.
  • 429rate_limitedKõnepiirang, midagi ei arveldata. Väärtusega agentId: kuni 10 kõnet minutis ja 1000 päevas konto kohta või ettevõttesisese häälmootori väljamineva minuti limiit on ammendatud - vastus kannab siis päist Retry-After (sekundid, mille pärast on mõistlik uuesti proovida). Väärtusega systemPrompt: konto 3 prooviversiooni kõne päevalimiit on ammendatud või kõigi kontode ühine piirang on ajutiselt täis.
  • 502callback_failedSildiga (from): telefonioperaator lükkas ühendustaotluse otse tagasi, kõnet ei seatud kunagi üles. Saldot ei arveldatud.
  • 502engine_unavailableVäärtusega agentId volai enda häälmootoril oleva agendi puhul: mootor ei vasta praegu (rike, mitte piirang) - proovige varsti uuesti ja kui see jätkub, võtke ühendust toega vea requestId-ga. Kui mootor võttis päringu vastu, kuid vastus ei saabunud õigel ajal, võis kõne siiski toimuda: see jääb ajalukku olekuga initiated, me täidame selle tegeliku tulemuse ja hinna ning sama number jääb umbes 15 minutiks lukku (destination_busy), et te ei helistaks sellele kaks korda. Ammendunud väljamineva kõne piirang on selle asemel 429 rate_limited.

Kohandatud muutujad ja helisemisaeg

variables on string-stringile objekt, mille agent saab dünaamiliste väärtustena - viidake neile promptis kujul {{jmeno_zakaznika}}. Piirangud: kuni 20 võtit, võtmed kuni 64 märki, väärtused kuni 512 märki. Võti võib sisaldada ainult tähti, numbreid ja alakriipse, ei tohi alata numbriga ega prefiksiga system__ või volai_ (mõlemad on reserveeritud ja sellise võtmega päring lükatakse tagasi). Nimed attempt_id, caller_number, called_number, trial_prompt ja trial_first_message on reserveeritud - need täidame ise ja kõik nende nimede all saadetud väärtused jäetakse kõrvale.

ringingTimeoutSecs on 5 kuni 60 sekundit, vaikimisi 25. Kui see möödub, lõpeb vastamata kõne ja selle detail saab endReason: "no_answer". Pikem helisemine tähendab paremat võimalust, et klient vastab, kuid ka pikemat väljamineva pesa hõivatust.

Ilma agendita: kahe numbri otseühendus

Saatke agentId asemel from - teie enda number või mõni teine kliendile kuuluv number. volai helistab esmalt from-ile ja kui keegi vastab, valib to. Mõlemad harud arveldatakse eraldi hinnaga 0.92 CZK/min (~EUR 0.04). Kui operaator tellimusele ei vasta (võrgukatkestus), tagastame kõne alustatuna (initiated): see võis läbi minna ja selle tegeliku tulemuse ning hinna täidab sünkroonimine operaatoriga. Ärge korrake seda kohe - sama number jääb umbes 10 minutiks lukku.

bash
curl -X POST https://volai.cz/v1/calls \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to": "+420777123456", "from": "+420601234567"}'

Prooviversiooni kõne ilma oma numbrita

agentId/from asemel saatke systemPrompt (juhised agendile ainult selle ühe kõne jaoks, kuni 1200 märki) ja valikuliselt firstMessage (avalause, kuni 300 märki). Kõne läheb välja volai ühiselt demonumbrilt, mitte teie enda omalt - seega kannab vastus ka trial: true ja from (demonumber). Selle variandi puhul ei saa saata voiceId-d, see töötab vaikehäälega. ringingTimeoutSecs on madalama ülempiiriga 5 kuni 30 (vaikimisi 25) - see hoiab ühise varu pesa.

bash
curl -X POST https://volai.cz/v1/calls \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+420777123456",
    "systemPrompt": "Te olete kohvik Nula vastuvõtt. Võtate vastu kaasavõtutellimusi ning olete lühike ja sõbralik.",
    "firstMessage": "Tere, siin volai prooviagent, kuidas saan aidata?"
  }'
json
{
  "id": "c_2f7a91mn",
  "status": "initiated",
  "trial": true,
  "from": "+420266266641"
}

Ainult kontodele kinnitatud e-posti aadressiga, kuni 3 kõnet konto kohta 24 tunni jooksul (pluss ühine piirang kõigi kontode peale, et tõus ei ülekoormaks demonumbrit). Arveldatakse täpselt nagu tavaline kõne, sh agendi lisatasu - ilma allahindluseta. Kes vajab rohkem, ostab oma numbri (POST /v1/numbers) ja loob agendi (POST /v1/agents) - seal see piirang ei kehti.

Kui prooviversiooni kõned on ajutiselt välja lülitatud (operatiivne lüliti), tagastab systemPrompt kõne tegemise asemel loetava vea (trial_calls_disabled); kasutage vahepeal oma agenti (agentId).

POST/v1/voice-messages

Helistab numbrile to, loeb text sõna-sõnalt ette (1 kuni 500 märki, repeat 1 kuni 3 korda, vaikimisi 1) ja katkestab. Ilma tehisintellekti agendita ja ilma oma numbrita: vastaja näeb ühist volai numbrit ning sellele tagasi helistamine jõuab volai demoliinile. Arveldatakse ainult väljamineva minutina, sekundi täpsusega (0.92 CZK/min ilma käibemaksuta); tekst kõneks on hinnas ja agendi lisatasu ei kehti. Kõne, millele keegi ei vasta, maksab 0. Vastus tuleb kohe pärast kõne tegemist; lugege tulemus päringust GET /v1/calls/{id} (kind: "voice_message", plokk voiceMessage) või webhookist.

Päring

bash
curl -X POST "https://volai.cz/v1/voice-messages" \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: REPLACE_WITH_UNIQUE_POST_V1_VOICE_MESSAGES_ID" \
  -d '{"to":"+420777123456","text":"Hoiatus: server api-1 ei ole viis minutit vastanud. Palun kontrollige selle olekut.","repeat":2}'

Enne käivitamist asendage REPLACE_WITH_UNIQUE… selle toimingu unikaalse ID-ga, näiteks UUID-ga, ja salvestage see. Sama päringu kordamisel pärast ajalõppu kasutage sama ID-d. Teise toimingu või muudetud sisu korral kasutage uut ID-d, isegi kui kutsute teist lõpp-punkti.

Vastus

json
{
  "id": "c_k4m8p2q7r1s5",
  "status": "ringing",
  "from": "+420266266641"
}

Veaolekud

  • 400validationto või text puudub, text on tühi või pikem kui 500 märki, repeat ei ole täisarv 1 kuni 3, keha sisaldab tundmatut välja (näiteks ringingTimeoutSecs, mida häälsõnumil ei ole) või keha ei ole kehtiv JSON.
  • 400invalid_numberto ei ole kehtiv telefoninumber.
  • 400unsupported_countryto ei ole Tšehhi (+420) ega Slovaki (+421) number.
  • 400blocked_destinationto on lisatasuga liin, seega on kõned sellele blokeeritud ja te ei saa tahtmatult suurt arvet.
  • 400on_dncSee number on teie helistamiskeeluloendis (/v1/dnc) või automaatse 30-päevase blokeeringu all pärast korduvaid vastamata kõnesid (destination_auto_blocked).
  • 400destination_auto_blockedSee number on teie helistamiskeeluloendis (/v1/dnc) või automaatse 30-päevase blokeeringu all pärast korduvaid vastamata kõnesid (destination_auto_blocked).
  • 400cannot_call_own_numberSilmuse kaitse - to on üks teie enda volai numbritest.
  • 400cannot_call_volai_numberSilmuse kaitse - to on teise konto volai number või volai demoliin.
  • 402insufficient_creditTeie saldo ei kata kõne alustamiseks vajalikku miinimumi või konto ei ole veel esimest saldo täiendust teinud (tervitussaldo ei kata häälsõnumeid). Täiendage ja proovige uuesti. Midagi ei arveldata.
  • 402subscription_cap_reachedKontol on kulutuste ülempiiriga kuupakett, kuusaldo on ära kasutatud ja täiendatud saldo ei kata toimingut. See asendab sellise konto puhul vea insufficient_credit (sama HTTP-olek). Midagi ei arveldatud.
  • 402spend_cap_reachedTeie seatud kuine kulutuste ülempiir on saavutatud. Midagi ei tehtud ega saadetud ning midagi ei arvestatud. Tõstke või eemaldage ülempiir päringuga PUT või DELETE /v1/account/spend-cap või oodake järgmist kalendrikuud.
  • 403email_unverifiedHäälsõnumi saavad saata ainult kontod kinnitatud e-posti aadressiga. Kinnitage oma e-post ja proovige uuesti. Midagi ei arveldata.
  • 409destination_busyMõni teine kõne või häälsõnum samale numbrile käib veel. Number jääb lukku kõne kestuse ajaks, seega proovige varsti uuesti.
  • 429rate_limitedKõnepiirang või 200 häälsõnumi päevalimiit konto kohta on ammendatud, midagi ei arveldata. Proovige hiljem uuesti või kirjutage volai toele ja me tõstame piirangut.
  • 502engine_unavailablevolai häälmootor ei võtnud kõnet praegu vastu. Midagi ei arveldata, proovige varsti uuesti. Ärge korrake pimesi ilma Idempotency-Key-ta.
  • 503capacity_busyKõik väljaminevad liinid on praegu hõivatud. Midagi ei arveldata, proovige minuti pärast uuesti.
  • 503ledger_unavailableSaldot ei õnnestunud praegu lugeda, proovige varsti uuesti. Midagi ei arveldata.
  • 503voice_messages_disabledHäälsõnumid ei ole veel sisse lülitatud. Midagi ei arveldata, proovige hiljem uuesti.
  • 503voice_message_unavailableHäälmootor ei saa praegu häälsõnumeid vastu võtta. Kõnet ei tehtud ja midagi ei arveldata, proovige varsti uuesti.

Häälsõnum: helistage, lugege tekst ette, katkestage

Hoiatuste ja teadete jaoks, millele keegi ei vasta: intsident valveinseneri jaoks, tähtaja meeldetuletus, kohaletoimetamise teade. POST /v1/voice-messages helistab, loeb text sõna-sõnalt ette (tšehhi keeles, ilma täidetud {{...}} muutujateta), jätab ettelugemiste vahele lühikese pausi ja katkestab. Te ei vaja ei agenti ega oma numbrit. Vestluse jaoks, kus vastaja peaks vastama, kasutage päringut POST /v1/calls koos agendiga.

Hind on ainult väljaminev minut, arveldatakse sekundi täpsusega (0.92 CZK/min ilma käibemaksuta); tekst kõneks on hinnas ja agendi lisatasu ei kehti, seega maksab lühike sõnum kümneid sadasosasid. Kõne, millele keegi ei vasta, maksab 0. Kui vastaja kõnepost vastab, salvestatakse sõnum sinna ja kõne arveldatakse nagu iga ühendatud kõne.

Vastaja näeb ühist volai numbrit, mitte teie oma. Igaüks, kes sellele tagasi helistab, jõuab volai demoliinile. Konto vajab kinnitatud e-posti aadressi ja vähemalt ühte saldo täiendust ning kehtib 200 häälsõnumi päevalimiit konto kohta.

Lugege tulemus päringust GET /v1/calls/{id}: kind on voice_message ja plokk voiceMessage kannab repeatPlayed (mitu korda sõnumit kuuldi) ja completed (true, kui see loeti lõpuni ette ja volai katkestas, false, kui vastaja katkestas varem). Samad väljad saabuvad webhookis call.completed (call.no_answer, kui keegi ei vastanud). E-posti kõnekokkuvõtet häälsõnumi kohta ei saadeta. Statistikas on kohale toimetatud sõnum kategooria other, vastamata jääb no_answer.

json
{
  "call": {
    "id": "c_k4m8p2q7r1s5",
    "direction": "out",
    "from": "+420266266641",
    "to": "+420777123456",
    "status": "completed",
    "kind": "voice_message",
    "durationSecs": 17.4,
    "voiceMessage": {
      "text": "...",
      "repeat": 2,
      "repeatPlayed": 2,
      "completed": true
    }
  }
}

Ärge kasutage seda soovimatuks turundamiseks. Automatiseeritud kõned ilma vastaja nõusolekuta on ebaseaduslikud. Häälsõnum on mõeldud operatiivseteks teadeteks inimestele, kes neid soovivad.

POST/v1/rings

Kutsub numbrit to ühelt teie enda häälnumbrilt (from) ega ühenda kõnet kunagi: helisemine lõpeb umbes ringSecs sekundi pärast (täisarv 3 kuni 30, vaikimisi 10) või varem, kui sihtkoht selle tagasi lükkab; operaator lõpetab helisemise kuni 3 sekundi viivitusega, seega on kirjes olev helisemisaeg (ring.rangSecs) veidi pikem. See on mõeldud GSM-väravatele, lukkudele ja kastidele, mis avanevad, kui nad helistaja numbri ära tunnevad. Sihtkoht näeb helistajana täpselt from (ilma from-ita kasutatakse teie esimest aktiivset numbrit), seega peab värav selle oma lubatud numbrite loendis olema. Vastus tuleb KOHE pärast seda, kui operaator tellimuse vastu võttis, umbes sekundi jooksul ja enne helisemise lõppu: status on initiated ja tulemust veel ei ole. Tulemus saabub webhooki kaudu (call.no_answer väärtuste rang ja ended_early puhul, call.completed väärtuse answered puhul) ning on päringus GET /v1/calls/{id} kujul ring.outcome (väärtusega ?waitSecs= ootab server, kuni katse on lõppenud). ring.outcome väärtus on rang, ended_early, answered või unknown (viimane, kuni tulemust veel operaatori kirjete põhjal lahendatakse). Üks katse maksab 0.25 CZK ilma käibemaksuta, arveldatakse kohe, kui operaator tellimuse vastu võttis; kui sihtkoht vastab, katkestab volai kohe ja ühendatud sekundid arveldatakse lisaks väljamineva kõnena. Kutsungid ei loe automaatse sihtkoha blokeeringu hulka, kuid teie helistamiskeeluloend kehtib. Piirangud konto kohta, sõltumatud kõnepiirangutest: 30 kutsungit minutis, 500 päevas ja 120 tunnis ühele numbrile. Toetab päist Idempotency-Key.

Päring

bash
curl -X POST "https://volai.cz/v1/rings" \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: REPLACE_WITH_UNIQUE_POST_V1_RINGS_ID" \
  -d '{"to":"+420777123456","from":"+420601234567","ringSecs":10}'

Enne käivitamist asendage REPLACE_WITH_UNIQUE… selle toimingu unikaalse ID-ga, näiteks UUID-ga, ja salvestage see. Sama päringu kordamisel pärast ajalõppu kasutage sama ID-d. Teise toimingu või muudetud sisu korral kasutage uut ID-d, isegi kui kutsute teist lõpp-punkti.

Vastus

json
{
  "id": "c_x7f2k9a1b3c4",
  "status": "initiated",
  "kind": "ring",
  "from": "+420601234567",
  "to": "+420777123456",
  "requestedSecs": 10,
  "priceHal": 25
}

Veaolekud

  • 400validationto puudub, ringSecs ei ole täisarv vahemikus 3 kuni 30 (vahemikust väljas väärtus lükatakse tagasi, mitte ei kärbita) või keha ei ole kehtiv JSON.
  • 400invalid_numberto ei ole kehtiv telefoninumber.
  • 400unsupported_countryto ei ole Tšehhi (+420) ega Slovaki (+421) number.
  • 400blocked_destinationto on lisatasuga liin, seega on kutsungid sellele blokeeritud ja te ei saa tahtmatult suurt arvet.
  • 400on_dncSee number on teie helistamiskeeluloendis (/v1/dnc). Automaatne 30-päevane blokeering kutsungitele ei kehti, käsitsi loend kehtib.
  • 400cannot_call_own_numberSilmuse kaitse - to on üks teie enda volai numbritest.
  • 400cannot_call_volai_numberSilmuse kaitse - to on teise konto volai number.
  • 400unsupported_for_number_typefrom on teie enda number kõnede ja SMS-ide jaoks ja sellelt helistab ainult agent, seega see ei saa kutsuda. Jätke from välja (kasutatakse teie esimest aktiivset häälnumbrit) või kasutage häälnumbrit. Midagi ei arveldata.
  • 402insufficient_creditTeie saldo ei kata kõne alustamiseks vajalikku miinimumi. Midagi ei arveldata.
  • 402subscription_cap_reachedKontol on kulutuste ülempiiriga kuupakett, kuusaldo on ära kasutatud ja täiendatud saldo ei kata toimingut. See asendab sellise konto puhul vea insufficient_credit (sama HTTP-olek). Midagi ei arveldatud.
  • 402spend_cap_reachedTeie seatud kuine kulutuste ülempiir on saavutatud. Midagi ei tehtud ega saadetud ning midagi ei arvestatud. Tõstke või eemaldage ülempiir päringuga PUT või DELETE /v1/account/spend-cap või oodake järgmist kalendrikuud.
  • 404from_number_not_ownedfrom ei ole teie konto aktiivne häälnumber. Loend on päringus GET /v1/numbers.
  • 404ring_needs_numberKontol ei ole aktiivset häälnumbrit, millelt kutsuda. Number kõnede ja SMS-ide jaoks ei loe: sellelt helistab ainult agent. Ostke häälnumber päringuga POST /v1/numbers.
  • 409destination_busyMõni teine kutsung või kõne samale numbrile käib veel. Number jääb lukku helisemisaja pluss umbes 30 sekundiks, seega proovige pärast seda uuesti.
  • 429rate_limitedKutsungipiirang saavutatud, midagi ei arveldata: kuni 30 minutis ja 500 päevas konto kohta ning 120 tunnis ühele numbrile. Sõltumatu kõnepiirangutest.
  • 502callback_failedOperaator lükkas kutsungi tellimuse kohe tagasi, seega midagi ei valitud. Teie saldot ei arveldatud.
  • 503ledger_unavailableSaldot ei õnnestunud praegu lugeda, proovige varsti uuesti. Midagi ei arveldata.

Värava kutsumine: avage see ühe päringuga

GSM-väravil, lukul või kastil on oma telefoninumber: kui selle lubatud loendis olev number sellele helistab, lükkab see kõne tagasi ja avaneb. POST /v1/rings teeb seda ühe päringuga - see helistab väravale teie häälnumbrilt from ja lõpetab helisemise umbes ringSecs sekundi pärast või varem, kui värav selle tagasi lükkab. Lisage from värava lubatud numbrite loendisse: see on number, mida see näeb.

Vastus (status: "initiated") tuleb kohe pärast tellimust. Kuidas katse lõppes, on väljal ring.outcome, webhooki sündmuses ja päringus GET /v1/calls/{id}: rang (see helises, kuni soovitud aeg sai otsa), ended_early (kõne lõppes varem, näiteks sellepärast, et värav lükkas selle tagasi), answered (sihtkoht vastas, volai katkestab kohe ja ühendatud sekundid arveldatakse lisaks väljamineva kõnena) või unknown (tulemust ei saanud kohe kindlaks teha; see täidetakse operaatori kirjetest mõne minuti jooksul).

json
{
  "call": {
    "id": "c_x7f2k9a1b3c4",
    "direction": "out",
    "from": "+420601234567",
    "to": "+420777123456",
    "status": "no_answer",
    "startedAt": 1756111640000,
    "durationSecs": 0,
    "priceHal": 25,
    "source": "api",
    "kind": "ring",
    "ring": { "requestedSecs": 10, "outcome": "ended_early", "rangSecs": 2 },
    "note": null,
    "flag": null,
    "handledAt": null,
    "rating": null,
    "goal": null,
    "hasConversation": false,
    "endReason": "no_answer"
  }
}

Vastamata kutsung (rang, ended_early) jõuab teie integratsioonini sündmusena call.no_answer, nagu iga muu vastamata väljaminev kõne; answered saabub kui call.completed. Üks erand: kui operaator kinnitab vastamise alles oma kõnekirjes (CDR), pärast seda, kui volai on kutsungi juba vastamata kõnena sulgenud, saabub ainult call.no_answer ja kirje päringus GET /v1/calls/{id} muutub hiljem väärtuseks completed koos ring.outcome: "answered" ja arveldatud vastatud sekunditega; teist sündmust ei saadeta. Sündmuse keha kannab kind: "ring" ja ring plokki (requestedSecs, outcome, rangSecs), seega kind ütleb teile, et värav lükkas kõne tagasi, mitte et keegi ei vastanud. Iga kõnesündmus kannab kind-i; ring plokk on ainult kutsungitel. Tulemus unknown jääb olekusse initiated ilma sündmuseta, kuni operaatori kirjed selle täidavad; kui operaator katset kunagi ei teata, suletakse see 24 tunni pärast kui failed.

Kutsungid ei loe automaatse sihtkoha blokeeringu hulka (kehtib ainult teie käsitsi helistamiskeeluloend) ja neil on oma piirangud, sõltumatud kõnepiirangutest: 30 minutis ja 500 päevas konto kohta ning 120 tunnis ühele numbrile. Number jääb lukku, kuni see heliseb, pluss umbes 30 sekundit: teine kutsung või kõne sellele tagastab sel ajal destination_busy. Võrguvea järel korrates saatke päis Idempotency-Key, et teist katset ei telliks ega arveldataks.

GET/v1/calls/active

Loeb ühe omatud agentId jaoks iga seadistatud natiivse mootori sõlme. See on elav hetktõmmis, erinevalt kõneajaloost. complete tähendab, et kõik mootori vastused olid kehtivad ja omandi metaandmed täielikud. outboundCount sisaldab lahendamata kõnesid; inboundCount loeb tagasihelistused eraldi. Igal väljamineval real on läbipaistmatu nativeRef, startedAt (Unix ms) ja resolved. Ainult kinnitatud ülesandekõned sisaldavad callId, taskId, itemId ja phoneSha256. Puuduv vastendus jääb nähtavaks väärtusega resolved: false. checkedAt on hetktõmmise valmimise ISO-aeg ja enginesChecked sõlmede arv. Tõendage väljaminevate kõnede puudumist ainult siis, kui complete: true, outboundCount: 0 ja unresolvedOutboundCount: 0; vead või mittetäielik hetktõmmis ei tõenda kunagi nulli. See lõpp-punkt hõlmab ainult natiivseid telefonikõnesid, mitte veebiseansse ega muid teenusepakkujaid. Kasutab olemasolevat ühist API-võtme päringupiirangut.

Päring

bash
curl 'https://volai.cz/v1/calls/active?agentId=ag_example' -H 'Authorization: Bearer vk_YOUR_KEY'

Vastus

json
{
  "data": {
    "agentId": "ag_example",
    "complete": true,
    "checkedAt": "2026-10-09T17:59:00.000Z",
    "enginesChecked": 2,
    "outboundCount": 0,
    "inboundCount": 0,
    "unresolvedOutboundCount": 0,
    "outbound": []
  }
}

Veaolekud

  • 400validationOodatud seosed või agendi päring puuduvad, on vigased või ei vasta enam kõnele.
  • 404agent_not_foundAgenti ei ole olemas või see kuulub teisele kontole.
  • 502engine_unavailableNatiivset olekut ei õnnestunud kontrollida; ärge eeldage, et kõned on lõppenud.
  • 503engine_not_configuredNatiivse mootori ühendus ei ole seadistatud.

POST/v1/calls/{id}/hangup

Lõpetab ühe omatud natiivse väljamineva ülesandekõne. Saatke kõik neli oodatud seost: expectedAgentId, expectedTaskId, expectedItemId ja expectedPhoneSha256 (täpse E.164 sihtkoha väiketähtedega SHA-256). Server kontrollib ülesande ajalugu, väljasaatmise konteksti, natiivset ruumi, rentnikku, agenti, suunda ja algusaega enne ühe natiivse hangup'i saatmist. Püsiv kõnekohane claim takistab teenusepakkuja päringute dubleerimist, sh samaaegsed päringud ja ajalõpud; Idempotency-Key ei ole vajalik. Vastus sisaldab callId, outcome ja endConfirmed: hung_up tähendab, et natiivne mootor kinnitas täpse kõne, already_ended nõuab lõplikku salvestatud kõnet ja puudumist kõigil sõlmedel ning unknown ei tähenda kunagi edu. Pärast tundmatut tulemust uurige elavat tegevust ja salvestatud kõne olekut; selle lõpp-punkti kordamine ainult loeb tagasi ega saada kunagi uut hangup'i. Kontrollige aktiivseid kõnesid pärast lõpetamist uuesti. Sissetulevad kõned, teised rentnikud, iseseisvad kõned ja teised teenusepakkujad lükatakse tagasi. Kampaania ulatus, helistamisaknad ja tähtajad kuuluvad helistamiskontrollerile; see lõpp-punkt ei muuda arveldust ega ülesande olekut.

Päring

bash
curl -X POST https://volai.cz/v1/calls/c_example/hangup -H 'Authorization: Bearer vk_YOUR_KEY' -H 'Content-Type: application/json' -d '{"expectedAgentId":"ag_example","expectedTaskId":"task_example","expectedItemId":"item_example","expectedPhoneSha256":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}'

Vastus

json
{
  "data": {
    "callId": "c_example",
    "outcome": "hung_up",
    "endConfirmed": true
  }
}

Veaolekud

  • 400validationOodatud seosed või agendi päring puuduvad, on vigased või ei vasta enam kõnele.
  • 404call_not_foundKõnet ei ole olemas või see ei kuulu teie kontole.
  • 502engine_unavailableNatiivset olekut ei õnnestunud kontrollida; ärge eeldage, et kõned on lõppenud.
  • 503engine_not_configuredNatiivse mootori ühendus ei ole seadistatud.

GET/v1/calls/{id}

Kõne detail. Valikuliselt paneb waitSecs (vt allolevat märkust) serveri tulemust ootama, et te ei peaks küsitlema. Agendiga kõnede puhul sisaldab see ka transcript (vooruhaaval transkriptsioon, igal voorul valikuline väli timeInCallSecs - sekundid kõne algusest, puudub, kui teenusepakkuja seda voorgu ajatemplit ei andnud; agendi voor, mille helistaja katkestas, kannab lisaks interrupted: true ja selle message on endiselt täielik planeeritud tekst, ainult volai enda mootor) ja summary (lühikokkuvõte) - vt Webhookid sama kuju kohta, mis toimetatakse automaatselt kohale pärast kõne lõppu. Nii loend kui detail kannavad ka answeredBy (ainult VÄLJAMINEVATE kõnede puhul: human, voicemail, ivr (vastas automaatne häälmenüü; mootor katkestab kohe) või unknown, kui mootor ei jõudnud otsuseni või transkriptsioon puudub; sissetulevad kõned jätavad välja ära, sest helistaja lühike vastus ei ole kõnepost). Mootor otsustab väärtustega human, voicemail ja ivr; unknown tähendab, et mootor ei jõudnud otsuseni enne tuvastusakna sulgumist, ja alates 1.33.0 jääb see unknown (varem asendas selle transkriptsioonipõhine hinnang, mis käsitles lühikest vastust nagu "Jah." pärast tutvustust kõneposti omana). Transkriptsioonipõhine hinnang (human või voicemail, unknown tühja transkriptsiooni puhul; see ei tuvasta kunagi häälmenüüd) kehtib ainult kõnede puhul, millel mootori väärtust ei ole. Väljaminev kõne, mida käsitleb volai enda häälmootor, kannab ka voicemailReason (phrase, long_monologue, beep, human_reply, ivr_phrase või digits - human_reply tähendab, et inimene vastas nii lühikese vastusega, et detektor märkis selle (mitte et see oli kõnepost), ivr_phrase on häälmenüü fraas, digits operaatori tervitus, mis loeb valitud numbri number-numbrilt ette), voicemailMessageLeft (mootor luges seadistatud sõnumi kõneposti) ja voicemailDetectedAtSecs (sekundid vastamisest, kuni mootori detektor jõudis otsuseni - isegi kõnel, millele inimene vastas) - kõik kolm välja tulevad ainult mootorist; ElevenLabsi transkriptsioonipõhine klassifikatsioon (answeredBy ilma selgesõnalise väärtuseta) ei tunne põhjust ega ajastust. Sissetulev või väljaminev kõne mootoril kannab ka optOutRequested: true, kui kaugosaline palus selgesõnaliselt, et talle enam ei helistataks (näiteks "ärge mulle helistage", isegi viimastel sekunditel pärast hüvastijätmist) - number on siis automaatselt konto helistamiskeeluloendis (GET /v1/dnc) ja ülesande kordamispoliitika ei ajasta rohkem katseid; kõnel ilma sellise vastuseta sellist võtit ei ole. See kannab ka endReason (completed, no_answer, busy, rejected, capacity, blocked, loop_guard, credit_blocked, suspended, engine_error, caller_loop, failed) ja kind (agent, bridge, relay, inbound, transfer, sip, ring, voice_message) - vt allolevat tabelit. Häälsõnum (kind: "voice_message") kannab ka plokki voiceMessage (text, repeat ning pärast kõne lõppu repeatPlayed ja completed) - vt POST /v1/voice-messages. Kutsung (kind: "ring") kannab ka plokki ring (requestedSecs, outcome, rangSecs) - vt POST /v1/rings. Tööriistade ja salvestiste laine lisas veel kaks välja: data (mida agent kõnest oma dataFields järgi jäädvustas; väärtus null tähendab, et seda ei mainitud) ja hasRecording (kõnel on allalaadimiseks salvestis saadaval, vt allolevat lõpp-punkti). Vanematel kõnedel neid välju ei ole ja need puuduvad vastusest. durationSecs on sekundites; volai enda mootoriga käsitletud kõnede puhul võib see olla kümnendarv (ümardatud kahe kümnendkohani). Vastus kannab konto omaniku enda annotatsioone, alati olemas, null, kui seadmata: note (string), flag ({reason, flaggedAt} | null), handledAt (Unix ms või null) ja goal ({result: "success"|"failure"|"unknown", rationale, reason} | null, täidetakse alles pärast agendi eesmärgi hindamist; reason on "no_caller_speech"|"evaluation_error"|null ja ütleb, miks tulemus tuli "unknown" - null tõeliselt ebaselge tulemuse puhul) - vt allpool PATCH /v1/calls/{id}. Vastus kannab alati ka hasConversation (boolean | null) - kas kõnel tegelikult toimus vestlus helistajaga; false kõne puhul, mis ei ühendunud, kõneposti või häälmenüü puhul, null vanema kirje puhul, millel ei ole otsustamiseks piisavalt signaali. Faasidega agendi (töövoo sõlmede plaan) kõne, mida käsitleb volai enda häälmootor (provider: "engine"), kannab ka workflowPath - vt ülal agentide all jaotist Kõne faasid (töövoog); ElevenLabsis majutatud agendi kõne ei kanna seda välja kunagi, isegi kui see läbis faasid, sest seda kirjutab ainult mootori kõnejärgne kirjutus. Kõne, mida käsitleb 15. okt 2026 mootori järk, kannab detailis (mitte loendis) ka engine plokki väljadega protectedUtterances ja protectedUtterancesCount: vastanud isiku repliigid, mille mootor tervitusakna ajal kõrvale jättis - mida ta ütles, kui agent rääkis oma esimest rida ("Halloo?", tema nimi või midagi firstMessageProtectSecs sees) ja mida mootor meelega vastu ei võtnud, seega seda EI ole transkriptsioonis ja agent sellele ei reageerinud; ainult agendi transkriptsioon koos mittetühja loendiga tähendab seega, et inimene vastas ja rääkis. Igal kirjel on timeInCallSecs (kõne algus salvestises, puudub, kui mootor seda ei tea), atSecs (millal mootor selle kuulmise lõpetas, sekundid kõne algusest, alati), message (kuni 200 märki), words ja reason (first_message_protect, greeting_courtesy või greeting_identification; avatud loend). Kuni 10 kirjet, protectedUtterancesCount loeb need kõik; kõne, millel midagi kõrvale ei jäetud, kannab [] ja 0; vanemad kõned, ElevenLabsis majutatud agendid ja mootori taaskäivitusega katkestatud kõned (endReason: engine_error, webhook reason: unfinished; mootor ei mõõtnud nende tervitusakent) ei kanna plokki engine üldse. Sama plokk on webhookis call.*.

Päring

bash
curl https://volai.cz/v1/calls/c_8f2ac1d4 \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "call": {
    "id": "c_8f2ac1d4",
    "direction": "in",
    "from": "+420777123456",
    "to": "+420601234567",
    "status": "completed",
    "startedAt": 1756111400000,
    "durationSecs": 47,
    "priceHal": 236,
    "agentId": "ag_kx91fa2b",
    "note": null,
    "flag": null,
    "handledAt": null,
    "rating": null,
    "goal": null,
    "hasConversation": true,
    "source": "inbound",
    "kind": "inbound",
    "endReason": "completed",
    "hasRecording": true,
    "data": {
      "name": "Mari Tamm",
      "coffee_count": 2,
      "urgency": "normal"
    },
    "transcript": [
      { "role": "agent", "message": "Tere, siin kohvik Nula, kuidas saan aidata?", "timeInCallSecs": 0 },
      { "role": "caller", "message": "Tahaksin tellida kaks latet kaasa.", "timeInCallSecs": 4 },
      { "role": "agent", "message": "Kindlasti, kaks latet kaasa, need on valmis viieteistkümne minuti pärast.", "timeInCallSecs": 9 }
    ],
    "summary": "Helistaja tellis kaks latet kaasa, äravõtmine 15 minuti pärast."
  }
}

Veaolekud

  • 404call_not_foundKõnet ei ole olemas või see ei kuulu teie kontole.
  • 400validationwaitSecs ei ole täisarv vahemikus 0 kuni 45.

Oodake tulemust küsitlemise asemel (waitSecs)

Kohe pärast POST /v1/calls kutsuge GET /v1/calls/{id} koos waitSecs (0 kuni 45, vaikimisi 0) - server vastab, kui kõne jõuab lõppolekusse (completed/failed/missed/no_answer), tagastades kohe transcript ja summary, või kui waitSecs möödub, olenevalt sellest, kumb juhtub esimesena.

bash
curl -X GET "https://volai.cz/v1/calls/c_9d4e2b7f?waitSecs=30" \
  -H "Authorization: Bearer vk_YOUR_KEY"
json
{
  "call": {
    "id": "c_9d4e2b7f",
    "direction": "out",
    "from": "+420601234567",
    "to": "+420777123456",
    "status": "completed",
    "startedAt": 1756111400000,
    "durationSecs": 47,
    "priceHal": 269,
    "agentId": "ag_kx91fa2b",
    "note": null,
    "flag": null,
    "handledAt": null,
    "rating": null,
    "goal": null,
    "hasConversation": true,
    "source": "api",
    "kind": "agent",
    "endReason": "completed",
    "hasRecording": true,
    "answeredBy": "human",
    "engine": {
      "protectedUtterances": [
        { "timeInCallSecs": 1.2, "atSecs": 2.4, "message": "Haló?", "words": 1, "reason": "greeting_courtesy" }
      ],
      "protectedUtterancesCount": 1
    }
  }
}

Kui aeg saab otsa enne kõne lõppu, on stillRunning true ja väljad kannavad praegust (mitte lõplikku) olekut - see ei anna kunagi viga. Proovige GET (või MCP get_call) uuesti, soovi korral suurema waitSecs-iga.

json
{
  "call": {
    "id": "c_9d4e2b7f",
    "direction": "out",
    "from": "+420601234567",
    "to": "+420777123456",
    "status": "ringing",
    "startedAt": 1756111400000,
    "agentId": "ag_kx91fa2b",
    "note": null,
    "flag": null,
    "handledAt": null,
    "rating": null,
    "goal": null,
    "hasConversation": null,
    "source": "api"
  },
  "stillRunning": true
}

GET/v1/calls/{id}/recording

Kõne salvestis. Erinevalt ülejäänud API-st ei ole see vastus JSON - keha vorming järgib tegeliku vastuse content-type-i (laiend päises content-disposition ühtib sellega): audio/mpeg (MP3, 128 kbps, 16 kHz mono) ElevenLabsi agendi puhul, audio/ogg täna volai enda mootori agendi puhul. Vormingut ei teisendata kunagi - lähtuge sellest päisest, mitte eeldatud tüübist. Me ei säilita salvestisest ise koopiat: voog liigub häälplatvormilt otse meie kaudu ja me kontrollime ainult, et kõne kuulub teie kontole.

?stahnout=1 lülitab content-disposition väärtusele attachment (brauser salvestab faili esitamise asemel) - selles olev faililaiend (.mp3 / .ogg, muidu .bin) ühtib alati ülaltoodud tegeliku content-type-iga. See marsruut ei paku vahemikke (Range) - see on mõeldud masinintegratsioonidele, mis laadivad alla kogu faili. Salvestatakse ainult kõned, mida käsitles agent, kelle recordCalls on sisse lülitatud, ja me säilitame neid 90 päeva pärast kõnet.

Päring

bash
curl https://volai.cz/v1/calls/c_8f2ac1d4/recording \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -OJ

Veaolekud

  • 404call_not_foundKõnet ei ole olemas või see ei kuulu teie kontole.
  • 404no_recordingKõnel ei ole salvestist - seda ei käsitlenud agent või salvestamine oli välja lülitatud.
  • 410recording_expiredSalvestis oli, kuid 90 päeva on möödunud ja see on kustutatud. Transkriptsioon jääb.

PATCH/v1/calls/{id}

Konto omaniku enda annotatsioon kõnel - märkus, agendi märgistamine põhjusega ja käsitsi "käsitletud". Vähemalt üks kolmest väljast peab olema olemas. note (string või null, kuni 2000 märki) - null kustutab märkuse. flag ({reason} kuni 500 märki või null) - märgise seadmine KUSTUTAB handledAt (märgistatud kõne ei ole enam "käsitletud"); flag: null kustutab märgise, muutmata handled. handled (boolean) - true seab handledAt praegusele hetkele, false lähtestab selle väärtuseks null. flag (mitte null) ja handled: true ei saa mõlemad olla seatud SAMAS päringus (400 validation) - märgistamine ja kinnitatud käsitlemine välistavad üksteist; saatke need kahe kõnena.

Päring

bash
curl -X PATCH https://volai.cz/v1/calls/c_8f2ac1d4 \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"note": "Volal kvůli reklamaci, přeposlat na podporu.", "flag": {"reason": "Agent nerozuměl dotazu na fakturu."}}'

Vastus

json
{
  "call": {
    "id": "c_8f2ac1d4",
    "direction": "in",
    "from": "+420777123456",
    "to": "+420601234567",
    "status": "completed",
    "startedAt": 1756111400000,
    "durationSecs": 47,
    "priceHal": 236,
    "agentId": "ag_kx91fa2b",
    "source": "inbound",
    "kind": "inbound",
    "endReason": "completed",
    "hasRecording": true,
    "data": { "name": "Mari Tamm" },
    "note": "Volal kvůli reklamaci, přeposlat na podporu.",
    "flag": { "reason": "Agent nerozuměl dotazu na fakturu.", "flaggedAt": 1756111460000 },
    "handledAt": null,
    "rating": null,
    "goal": { "result": "failure", "rationale": "Helistaja tellis kaks latet kaasa, äravõtmine 15 minuti pärast.", "reason": null },
    "hasConversation": true
  }
}

Veaolekud

  • 400validationKehas ei ole ühtegi väljadest note/flag/handled, note on üle 2000 märgi, flag.reason puudub või on üle 500 märgi või keha seab flag (mitte null) koos handled: true-ga.
  • 404call_not_foundKõnet ei ole olemas või see ei kuulu teie kontole.

Kõne olek: väli status

status on ainus väli, mis kõnel aja jooksul muutub. See võib veel liikuda esimese viie minuti jooksul pärast kõne algust; pärast seda on see lõplik - neli neist olekutest on lõplikud.

statusTähendus
initiatedKõne on tehtud, kuid ei ole veel helisema hakanud.
ringingSee heliseb vastajal.
in_progressKõne on käimas.
completedLõplik. Ühendatud kõne, mis lõppes normaalselt - valdaval enamikul on oodata durationSecs > 0 (erand: kõne, millel on allpool endReason: credit_blocked, suspended või spend_cap, kus nii kestus kui hind on 0). Kõne, millel on endReason: caller_loop (automatiseeritud helistaja teisel poolel, kuni viis minutit), on samuti hinnaga 0, kuid sellel on kestus.
no_answerLõplik. Väljaminev kõne helises ja vastaja ei vastanud. Kutsungi (kind: "ring") puhul on see normaalne tulemus: värav lükkas kõne tagasi või helisemine kestis soovitud aja lõpuni (ring.outcome eristab neid).
missedLõplik. Sissetulevale kõnele ei vastatud (sh see, mis lükati tagasi, sest kõik liinid olid hõivatud - endReason ütleb, milline).
failedLõplik. Tavaliselt ei ühendunud kõne üldse - platvorm lükkas selle tagasi või võrk ebaõnnestus. Erand (kaart K6, audit R02): endReason: engine_error tähendab, et kõne ÜHENDUS, kuid lõppes tehnilise vea tõttu meie poolel või katkestati häälmootori taaskäivitusega - see kannab transcript-i ja tavaliselt salvestist (kui mootor jõudis selle salvestada; pärast mootori taaskäivitust ainult osaline või tühi transkriptsioon ja salvestist ei ole) ning seda ei arveldata kunagi. endReason annab alati konkreetse põhjuse.

Kõne tüüp: väli kind

kind ütleb, kuidas kõne tekkis - ja seega ka kuidas see arveldatakse. See on ainus väli, mis lubab arvel eristada tuua-oma-agent (BYO) kõnet sisseehitatud agendi kõnest, sest relay-harud ei kanna agendi lisatasu.

kindMis see onArveldus
agentVäljaminev kõne sisseehitatud häälagendilt.0.92 CZK/min + 2.50 CZK/min
bridgeOtseühendus kahe numbri vahel, ilma agendita.0.92 CZK/min (~EUR 0.04) kummagi kahe haru eest
relayVäljaminev kõne teie enda agendilt kaudu POST /v1/relay.0.92 CZK/min (~EUR 0.04), ilma agendi lisatasuta
inboundSissetulev kõne teie numbrile.0.50 CZK/min (+ agent, kui see kõnet käsitles)
transferTeine haru, mis tekib sissetuleva kõne edastamisel inimesele. Agent lahkub kõnest pärast edastamist, seega arveldatakse see haru tavalise väljamineva kõnena.0.92 CZK/min, ilma agendi lisatasuta
sipKõne, mis valiti otse SIP-kliendist (softphone, teie enda keskjaam), mis on registreeritud teie liinile, väljaspool meie API-d - arveldatakse tagantjärele võrgu kõnekirjete põhjal.0.92 CZK/min, ilma agendi lisatasuta
voice_messageHäälsõnum: helistab, loeb teksti ette ja katkestab (POST /v1/voice-messages). Tulemus on plokis voiceMessage.ainult väljaminev minut (0.92 CZK/min), sekundi täpsusega, ilma agendi lisatasuta; vastamata kõne on 0
ringVärava avamise kutsung: lühike helin, mida ei ühendata kunagi (POST /v1/rings). Tulemus on plokis ring.0.25 CZK katse kohta, pluss sekundid, kui vastati

Miks kõne lõppes: väli endReason

Lisame igale suletud kõnele endReason. Tähelepanu: tasumata võla tõttu või käsitsi peatamise tõttu blokeeritud kõne olek on completed, kuid endReason on vastavalt credit_blocked või suspended ja hind on 0 (sama kehtib kuise kulutuste ülempiiri tõttu tagasi lükatud kõne kohta: spend_cap) - ainult status ei eralda seda kõnest, mis tegelikult läbi läks. Sama kehtib kõne kohta, mille teisel poolel on automatiseeritud helistaja, kes kordab sama sõnumit (caller_loop): selle olek on completed, kuid kui see kestis kuni viis minutit, on selle hind 0. Kolm "vastamata" varianti on meelega eraldi, mitte üks ühine olek.

endReasonTähendus
completedKõne läks läbi ja lõppes normaalselt.
no_answerSee helises ja vastaja ei vastanud.
busyKinnisignaal - see EI ole sama mis vastamata jätmine.
rejectedPlatvorm lükkas ühenduse otse tagasi.
capacityVäljaminevad liinid (relay-varu) olid täis. Sissetuleva kõne puhul: liinid olid täis ja häälmootor lükkas kõne tagasi, seega helistaja läbi ei pääsenud; kõne olek on missed, kestus 0 ja hind 0 ning selle kohta saadetakse webhook call.missed.
blockedSihtkoht on helistamiskeeluloendis või automaatses 30-päevases blokeeringus (vt allpool Helistamiskeeluloend).
loop_guardKaitse oma või teise konto volai numbrile helistamise vastu.
credit_blockedSissetulev kõne agendile, mille omanik on võlapiirist üle - agent katkestab kohe pärast oma avalauset, hind 0.
suspendedSissetulev kõne agendile, mille volai operaator on käsitsi peatanud (või mille kogu konto on peatatud) - agent katkestab kohe pärast oma avalauset, hind 0.
spend_capSissetulev kõne sellise konto agendile, mis jõudis oma omaniku seatud kuise kulutuste ülempiirini (GET /v1/account/spend-cap) ja ei valinud inboundAboveCap - agent katkestab kohe pärast oma avalauset, hind 0.
failedKõne ei ühendunud üldse (platvorm või võrk).
engine_errorKõne ühendus, kuid lõppes tehnilise vea tõttu meie häälmootoris - mitte vastaja süü. Ei arveldata kunagi. See hõlmab ka kõnet, mille mootori taaskäivitus või peatamine vestluse keskel katkestas (näiteks juurutuse ajal): sellel on ainult osaline või tühi transcript ja salvestist ei ole, summary sisaldab seda selgitavat lühikest teksti, plokki engine ei ole ning selle webhooki call.failed reason on unfinished.
caller_loopSissetulev kõne, kus helistaja oli automatiseeritud süsteem, mis kordas pidevalt sama sõnumit (järjekord, automaatvalija) - volai lõpetab selle pärast lühikest inimese ootamist. Kõne olek on completed ja kestus positiivne, kuid see on tasuta, kui kestab kuni viis minutit (hind 0); pikem kõne arveldatakse nagu iga muu.

Agendid

GET/v1/agents

Konto häälagendid.

Päring

bash
curl https://volai.cz/v1/agents \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "agents": [
    {
      "id": "ag_pw7q2vnd",
      "name": "Vastuvõtt",
      "language": "et",
      "systemPrompt": "Te olete kohvik Nula vastuvõtt. Võtate vastu kaasavõtutellimusi...",
      "firstMessage": "Tere, siin kohvik Nula, kuidas saan aidata?",
      "voiceId": "7JbZPqJGWUfXXBim0T8U",
      "provider": "elevenlabs",
      "createdAt": 1756111000000,
      "status": "active",
      "toolIds": ["tl_5c2a91f4"],
      "dataFields": [
        {
          "key": "name",
          "type": "string",
          "description": "Helistaja nimi, nii nagu ta selle ütles."
        }
      ],
      "recordCalls": true,
      "recordingNotice": false,
      "goal": null,
      "knowledge": null,
      "notifyEmail": true,
      "silencePromptSecs": 10,
      "laughter": "auto",
      "firstMessageProtectSecs": null,
      "silencePromptText": null,
      "sttLanguageHintsStrict": false,
      "turnDigitTailFloorMs": null,
      "turnLongSpeechFloorMs": null,
      "turnLongSpeechSecs": null,
      "missedCallSms": { "enabled": false },
      "suspended": false
    },
    {
      "id": "ag_kx91fa2b",
      "name": "Vastuvõtt",
      "language": "et",
      "systemPrompt": "Te olete kohvik Nula vastuvõtt. Võtate vastu kaasavõtutellimusi...",
      "firstMessage": "Tere, siin kohvik Nula, kuidas saan aidata?",
      "voiceId": "milena",
      "provider": "engine",
      "numberE164": "+420601234567",
      "createdAt": 1756111000000,
      "status": "active",
      "toolIds": ["tl_5c2a91f4"],
      "transferTo": "+420777123456",
      "transferCondition": "Helistaja palub selgesõnaliselt, et teda ühendataks inimesega.",
      "dataFields": [
        {
          "key": "name",
          "type": "string",
          "description": "Helistaja nimi, nii nagu ta selle ütles."
        },
        {
          "key": "urgency",
          "type": "string",
          "description": "Kui kiireloomuline päring oli.",
          "enumValues": ["low","normal","high"]
        }
      ],
      "recordCalls": true,
      "recordingNotice": false,
      "goal": null,
      "knowledge": null,
      "notifyEmail": true,
      "silencePromptSecs": 10,
      "laughter": "auto",
      "firstMessageProtectSecs": null,
      "silencePromptText": null,
      "sttLanguageHintsStrict": false,
      "turnDigitTailFloorMs": null,
      "turnLongSpeechFloorMs": null,
      "turnLongSpeechSecs": null,
      "missedCallSms": { "enabled": false },
      "suspended": false
    }
  ]
}

POST/v1/agents

Loob uue häälagendi. Kohustuslikud on ainult name ja systemPrompt - hea prompti kirjutamist käsitletakse lehel Häälagent . Kui saadate numberE164, seotakse agent sellesse numbrisse kohe. POST tagastab ainult id; tegeliku provider lugemiseks kasutage järgnevat GET /v1/agents/{id}. transferTo käivitab pärast salvestamist katse viia ElevenLabsi agent mootorile, kuid peatatud katse, kättesaamatu mootor või tõrge võib selle jätta ElevenLabsi, kus edastamine ei tööta. voiceId valib hääle: selgesõnaline useForOutboundTasks: true asendab tuntud kataloogihääle, mis ei ole mootoril saadaval (sh katty), mootori vaikehäälega. Väljaspool seda varuvarianti aktsepteerib mootor kataloogihääli, välja arvatud ElevenLabsi hääled (katty, vanem anet); töötlemata ElevenLabsi ID või muu ühildumatu hääl tagastab 400. Väärtusega false peab algne hääl olema ElevenLabsile kehtiv (katty või töötlemata ElevenLabsi ID; ElevenLabs ei määra enam uutele agentidele anet-i ja volai lükkab selle tagasi veaga 400); hilisem edukas üleminek väärtuse transferTo jaoks võib selle vastendada mootori vaikehääleks. Ilma voiceId-ta kasutab mootor Milenat ja ElevenLabs malli häält (Katty). Valikulised väljad (toolIds, transferTo, transferCondition, dataFields, recordCalls, recordingNotice, goal, knowledge, notifyEmail, useForOutboundTasks, voicemail) on kirjeldatud allpool.

Päring

bash
curl -X POST "https://volai.cz/v1/agents" \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: REPLACE_WITH_UNIQUE_POST_V1_AGENTS_ID" \
  -d '{"name":"Vastuvõtt","systemPrompt":"Te olete kohvik Nula vastuvõtt. Võtate vastu kaasavõtutellimusi ja vastate küsimustele lahtiolekuaegade kohta. Ärge kunagi mõelge välja hindu, mida te ei tea. Lõpetage kõne tellimuse kokkuvõttega.","firstMessage":"Tere, siin kohvik Nula, kuidas saan aidata?","language":"et","numberE164":"+420601234567","toolIds":["tl_5c2a91f4"],"transferTo":"+420777123456","transferCondition":"Helistaja soovib rääkida töötajaga või tal on kaebus.","dataFields":[{"key":"name","type":"string","description":"Helistaja nimi, nii nagu ta selle ütles."},{"key":"coffee_count","type":"number","description":"Mitu kohvi helistaja tellis."}],"recordCalls":true}'

Enne käivitamist asendage REPLACE_WITH_UNIQUE… selle toimingu unikaalse ID-ga, näiteks UUID-ga, ja salvestage see. Sama päringu kordamisel pärast ajalõppu kasutage sama ID-d. Teise toimingu või muudetud sisu korral kasutage uut ID-d, isegi kui kutsute teist lõpp-punkti.

Vastus

json
{
  "id": "ag_kx91fa2b"
}

Veaolekud

  • 400invalid_nameAgendi nimi peab olema 1 kuni 60 märki.
  • 400invalid_system_promptAgendi juhised peavad olema 10 kuni 6000 märki.
  • 400invalid_languagelanguage peab olema cs, sk, en, de või pl.
  • 400agent_limitKontol on juba agentide maksimaalne arv (10).
  • 400tool_limittoolIds sisaldab rohkem kui 10 tööriista.
  • 400invalid_data_fieldsdataFields sisaldab vigast võtit, tüüpi, kirjeldust või rohkem kui 10 kirjet.
  • 400invalid_goalgoal on liiga pikk - see mahutab 300 märki.
  • 400invalid_knowledgeknowledge on liiga pikk - see mahutab 20000 märki.
  • 400transfer_looptransferTo osutab sama konto volai numbrile - kõne läheks ise endale tagasi.
  • 400blocked_destinationtransferTo on lisatasuga liin erihinnaga.
  • 400destination_not_allowedAgent on mõeldud kasutama number kõnede ja SMS-ide jaoks-i ja transferTo ei ole Tšehhi (+420) number: sellelt numbrilt edastatud kõned võivad minna ainult Tšehhi numbritele. Edastage Tšehhi transferTo või ärge siduge seda numbrit agendiga. number teises riigis puhul peab edastusnumber olema numbri riigis (kui sellele helistamine on sisse lülitatud) või Tšehhis. Midagi ei muudetud.
  • 400unsupported_for_number_typeAgent on mõeldud kasutama number kõnede ja SMS-ide jaoks-i, kuid seda ei loodaks volai enda häälmootoril: seda liiki numbrile vastab ainult mootori agent (useForOutboundTasks: true või jätke väli välja, kui mootor on agendi keele vaikimisi). Agenti ei loodud ja midagi ei muudetud.
  • 400invalid_numbertransferTo ei ole kehtiv telefoninumber.
  • 400invalid_voicemail_messagevoicemail.message puudub või on liiga pikk - nõutav, kui action on "message", mahutab 400 märki.
  • 400voicemail_requires_enginevoicemail nõuab algse teenusepakkuja valikuna mootorit: useForOutboundTasks: true või väljajätmine, kui mootor on vaikimisi. false ebaõnnestub isegi koos transferTo-ga, sest valideerimine eelneb üleminekukatsele.
  • 400invalid_workflowVigane töövoo graaf (kättesaamatu sõlm, puuduv sisendsõlm, reserveeritud tööriista nimi...); midagi ei salvestata, konkreetne põhjus on alati väljal message.
  • 404calendar_integration_not_foundcalendar.integrationId ei osuta teie konto kalendriühendusele - valige see uuesti päringust GET /v1/integrations.
  • 400calendar_invalid_calendarcalendar.calendarId ei ole selle ühenduse kalendrite seas või on see ainult lugemiseks (accessRole reader või freeBusyReader), seega agent ei saaks sinna kohtumist kirjutada. Valige kirjutatav kalender päringust list_calendars.
  • 400calendar_invalid_timezonecalendar.timezone ei ole kehtiv IANA tsoon, näiteks "Europe/Prague".
  • 400calendar_invalid_windowscalendar.windows aknad ei kasuta kuju HH:MM, kattuvad või neid on ühel päeval rohkem kui neli.
  • 400calendar_no_windowsKalender on sees, kuid ühelgi nädalapäeval ei ole akent - agendil poleks midagi pakkuda.
  • 400calendar_invalid_rulesKalendri numbrilised reeglid on vahemikust väljas või minimaalne etteteatamine on pikem kui otsinguhorisont.
  • 404tool_not_foundTööriist väljalt toolIds ei ole olemas või ei kuulu teie kontole.
  • 404not_foundnumberE164 ei ole olemas või ei kuulu teie kontole.
  • 400validationSisendi kuju ei sobi - tavaliselt voiceId ei vasta ühelegi kirjele päringust GET /v1/voices ja ei näe välja nagu töötlemata ElevenLabsi ID (vea teade loetleb kehtivad väärtused) või silencePromptSecs väljaspool 3 kuni 25, firstMessageProtectSecs väljaspool 0 kuni 20 või silencePromptText pikem kui 80 märki või inboundVariables rohkem kui 10 võtmega, reserveeritud või vigase võtmenimega või väärtusega pikem kui 200 märki või sttLanguageHintsStrict, mis ei ole true, false ega null, või turnDigitTailFloorMs või turnLongSpeechFloorMs väljaspool 0 ja 400 kuni 2300 või turnLongSpeechSecs väljaspool 1 kuni 30.
  • 409invalid_transitionNumber kõnede ja SMS-ide jaoks, mida te agendiga seote, ei ole aktiivne (see ootab registreerimist, lükati tagasi või seda vabastatakse). Agendi saab siduda ainult aktiivse numbriga. Agenti ei loodud ja midagi ei muudetud.
  • 409in_progressMõni teine toiming (aktiveerimine, arveldus või vabastamine) töötleb number kõnede ja SMS-ide jaoks-i, mida te agendiga seote. Agenti ei loodud ja midagi ei muutunud; korrake päringut minuti pärast.
  • 500agent_template_missingAgendi loomise mall puudub või on meie poolel rikutud - ajutine viga meie poolel, palun võtke ühendust toega.
  • 502engine_unavailableNumber kõnede ja SMS-ide jaoks-i sidumisel ei vastanud volai enda häälmootor. Agenti ei loodud ja midagi ei muudetud; korrake päringut varsti. Sama koodi tagastatakse kirjutamise puhul, mille mootori ooterežiimi sõlm tagasi lükkas (mootor töötab praegu ooterežiimi sõlmel, mis seadistust vastu ei võta): teade ütleb seda ja päringut saab mõne minuti pärast korrata.
  • 502engine_readback_mismatchNumber kõnede ja SMS-ide jaoks-i sidumisel mootor vastas, kuid tagasilugemine näitas teistsugust vastendust kui see, mille me saatsime. Agenti ei loodud ja midagi ei muudetud; korrake päringut.
  • 503engine_not_configuredTe küsisite volai enda häälmootorit (useForOutboundTasks: true), kuid mootor või sellel väljaminev liiklus ei ole praegu seadistatud. Kontrollige seadistust või jätke väli välja - agent luuakse ElevenLabsis.
  • 503engine_setup_incompleteAgent loodi, kuid väljamineva ülesande seadistamine volai enda mootoril ei lõppenud. ÄRGE korrake loomist, mis looks duplikaadi. Leidke see päringust GET /v1/agents nime järgi, kontrollige provider-it ja lõpetage see seejärel portaali jaotises Agendid või toe abil; PATCH /v1/agents/{id} üksi ei saa teenusepakkujat valida.

GET/v1/agents/{id}

Ühe agendi detail. Kustutatud agent tagastab 404 agent_not_found. Loomisel valib useForOutboundTasks algse platvormi: true valib volai mootori, false ElevenLabsi ja väljajätmine kasutab juurutuse vaikeväärtust. Kuna POST tagastab ainult id, kontrollige tulemust selles järgnevas GET-is ja selle väljal provider. transferTo lubamine ElevenLabsi agendil käivitab mootorile ülemineku katse, kuid see võib olla peatatud, kättesaamatu või ebaõnnestuda; edastamine ei tööta, kuni provider jääb elevenlabs. Edukas üleminek võib hääle muuta. language muutmine päringuga PATCH keelest, milles uued agendid algavad ElevenLabsis (täna en, de, pl), keelde, milles nad algavad mootoril (cs, sk), käivitab sama katse: õnnestumisel saab agent uue keele vaikimisi mootori hääle (Milena, Katarina), ebaõnnestumisel jääb ta ElevenLabsi. Muutus cs ja sk vahel ei liiguta midagi. Muud teenusepakkuja üleminekud käsitleb tugi. ElevenLabs aktsepteerib kataloogist ainult anet või töötlemata ElevenLabsi hääle id-d; muud kataloogihääled nõuavad mootorit. Vastus kannab alati ka välja laughterEffective ({active, reason, sensitiveCategory} | null) - elav naermispoliitika tulemus agendi AVALDATUD seadistuse jaoks, arvutatud värskelt väljaspool mis tahes kõnet. ElevenLabsi agendi puhul on see alati {active: false, reason: "not_engine", sensitiveCategory: null} mootori poole pöördumata; mootori agendi puhul on reason üks mitmest väärtusest (ok, agent_off, sensitive_prompt, voice_not_listed ja rohkem) ja mootor võib aja jooksul uusi lisada - käsitlege tundmatut väärtust väljalülitatuna, mitte veana. Kui mootor ei vasta 3 sekundi jooksul, on maas või ei tunne agenti (vaikne 404 vanemal järgul), on laughterEffective otse null - mitte kunagi oletus.

Kui mootor ei vasta 3 sekundi jooksul, on maas või ei tunne agenti, näeb vastus välja nii: "laughterEffective": null - mitte objekt oletatud väärtustega.

Päring

bash
curl https://volai.cz/v1/agents/ag_kx91fa2b \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "agent": {
    "id": "ag_kx91fa2b",
    "name": "Vastuvõtt",
    "language": "et",
    "systemPrompt": "Te olete kohvik Nula vastuvõtt. Võtate vastu kaasavõtutellimusi...",
    "firstMessage": "Tere, siin kohvik Nula, kuidas saan aidata?",
    "voiceId": "milena",
    "provider": "engine",
    "numberE164": "+420601234567",
    "createdAt": 1756111000000,
    "status": "active",
    "toolIds": ["tl_5c2a91f4"],
    "transferTo": "+420777123456",
    "transferCondition": "Helistaja palub selgesõnaliselt, et teda ühendataks inimesega.",
    "dataFields": [
      {
        "key": "name",
        "type": "string",
        "description": "Helistaja nimi, nii nagu ta selle ütles."
      },
      {
        "key": "urgency",
        "type": "string",
        "description": "Kui kiireloomuline päring oli.",
        "enumValues": ["low","normal","high"]
      }
    ],
    "recordCalls": true,
    "recordingNotice": false,
    "goal": null,
    "knowledge": null,
    "notifyEmail": true,
    "silencePromptSecs": 10,
    "laughter": "auto",
    "firstMessageProtectSecs": null,
    "silencePromptText": null,
    "sttLanguageHintsStrict": false,
    "turnDigitTailFloorMs": null,
    "turnLongSpeechFloorMs": null,
    "turnLongSpeechSecs": null,
    "missedCallSms": { "enabled": false },
    "suspended": false,
    "laughterEffective": {
      "active": true,
      "reason": "ok",
      "sensitiveCategory": null
    }
  }
}

Veaolekud

  • 404agent_not_foundAgenti ei ole olemas, see on kustutatud või ei kuulu teie kontole.

GET/v1/agents/{id}/call-hold

Loeb omaniku püsiva agendi kõnepeatuse. Töötlemata vastus on {agentId, held, hold}; enne peatamist held:false, hold:null. See ei kirjelda administraatori peatamist ega muid kõnele lubamise väravaid.

Päring

bash
curl https://volai.cz/v1/agents/ag_example/call-hold -H 'Authorization: Bearer vk_YOUR_KEY'

Vastus

json
{
  "agentId": "ag_example",
  "held": false,
  "hold": null
}

Veaolekud

  • 404agent_not_foundAgenti ei ole olemas, see on kustutatud või ei kuulu teie kontole.

POST/v1/agents/{id}/call-hold

Peatab püsivalt uued väljaminevad kõned ja kinnitatud kampaania tagasihelistused omatud mootori agendile. Esitage täpselt reason:budget_limit ja operationId (1-128 tähte, numbrit, punkti, alakriipsu, koolonit või sidekriipsu, algusega tähe või numbriga). Aegumist ega jätkamise toimingut ei ole. Identne ID ja sisu taasesitavad algse auditi; teine toiming tagastab 409 revision_conflict. Pärast ebaselget vastust lugege GET. hold sisaldab agentId, reason, operationId, fingerprint ja createdAt. Administraatori peatamised, demo ja aktiivsed kõned jäävad muutmata. Sõltumatud tagasihelistuse lahendaja tõrked säilitavad numbri vaikeagendi. Idempotency-Key ei ole siin idempotentsuse mehhanism.

Päring

bash
curl https://volai.cz/v1/agents/ag_example/call-hold -X POST -H 'Authorization: Bearer vk_YOUR_KEY' -H 'Content-Type: application/json' -d '{"reason":"budget_limit","operationId":"budget-stop-001"}'

Vastus

json
{
  "agentId": "ag_example",
  "held": true,
  "hold": {
    "agentId": "ag_example",
    "reason": "budget_limit",
    "operationId": "budget-stop-001",
    "fingerprint": "14e5bfb3f57897b30d172ef4ba861b2a27e7beb1de278a94b47bc0f14c614f4c",
    "createdAt": "2026-10-08T12:00:00.000Z"
  }
}

Veaolekud

  • 404agent_not_foundAgenti ei ole olemas, see on kustutatud või ei kuulu teie kontole.
  • 400validationVigane keha või mittetoetatud agent. Valige omatud mootori agent väljaspool ühist demot.
  • 409revision_conflictOlemas on teine püsiv peatus. Algne audit säilib; lugege selle olekut päringuga GET.

PATCH/v1/agents/{id}

Uuendab olemasolevat agenti - samad väljad nagu loomisel, kõik valikulised. Saatke ainult see, mida on vaja muuta. Kaks neist saadetakse siiski alati TÄIELIKULT, sest need asendavad olemasoleva loendi: toolIds ja dataFields. Tühi massiiv lülitab funktsiooni seega välja ("toolIds": [] eemaldab kõik agendi tööriistad), samas kui puuduv võti tähendab "jäta nii, nagu on". Edastamine lülitatakse välja tühja stringiga: "transferTo": "".

Päring

bash
curl -X PATCH https://volai.cz/v1/agents/ag_kx91fa2b \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"firstMessage": "Tere, kohvik Nula, mida soovite?"}'

Vastus

json
{
  "agent": {
    "id": "ag_kx91fa2b",
    "name": "Vastuvõtt",
    "language": "et",
    "systemPrompt": "Te olete kohvik Nula vastuvõtt. Võtate vastu kaasavõtutellimusi...",
    "firstMessage": "Tere, kohvik Nula, mida soovite?",
    "voiceId": "milena",
    "provider": "engine",
    "numberE164": "+420601234567",
    "createdAt": 1756111000000,
    "status": "active",
    "toolIds": ["tl_5c2a91f4"],
    "transferTo": "+420777123456",
    "transferCondition": "Helistaja palub selgesõnaliselt, et teda ühendataks inimesega.",
    "recordCalls": true,
    "recordingNotice": false,
    "goal": null,
    "knowledge": null,
    "notifyEmail": true,
    "silencePromptSecs": 10,
    "laughter": "auto",
    "firstMessageProtectSecs": null,
    "silencePromptText": null,
    "sttLanguageHintsStrict": false,
    "turnDigitTailFloorMs": null,
    "turnLongSpeechFloorMs": null,
    "turnLongSpeechSecs": null,
    "missedCallSms": { "enabled": false },
    "suspended": false
  }
}

Veaolekud

  • 400invalid_nameAgendi nimi peab olema 1 kuni 60 märki.
  • 400invalid_system_promptAgendi juhised peavad olema 10 kuni 6000 märki.
  • 400invalid_languagelanguage peab olema cs, sk, en, de või pl.
  • 400tool_limittoolIds sisaldab rohkem kui 10 tööriista.
  • 400invalid_data_fieldsdataFields sisaldab vigast võtit, tüüpi, kirjeldust või rohkem kui 10 kirjet.
  • 400invalid_goalgoal on liiga pikk - see mahutab 300 märki.
  • 400invalid_knowledgeknowledge on liiga pikk - see mahutab 20000 märki.
  • 400transfer_looptransferTo osutab sama konto volai numbrile.
  • 400blocked_destinationtransferTo on lisatasuga liin erihinnaga.
  • 400destination_not_allowedAgendil on number kõnede ja SMS-ide jaoks (või te seote sellist praegu) ja transferTo ei ole Tšehhi (+420) number: sellelt numbrilt edastatud kõned võivad minna ainult Tšehhi numbritele. Edastage Tšehhi transferTo või ärge siduge seda numbrit agendiga. number teises riigis puhul peab edastusnumber olema numbri riigis (kui sellele helistamine on sisse lülitatud) või Tšehhis. Midagi ei muudetud.
  • 400unsupported_for_number_typeTe määrate (või vahetate sisse) number kõnede ja SMS-ide jaoks-i, kuid agent ei tööta volai enda häälmootoril: seda liiki numbrile vastab ainult mootori agent. Midagi ei muudetud.
  • 400invalid_voicemail_messagevoicemail.message puudub või on liiga pikk - nõutav, kui action on "message", mahutab 400 märki.
  • 400voicemail_requires_enginevoicemail on ainult agendile, mille provider on "engine". Tugi viib ElevenLabsi agendi mootorile; seni jätke väli välja.
  • 400invalid_workflowVigane töövoo graaf (kättesaamatu sõlm, puuduv sisendsõlm, reserveeritud tööriista nimi...); midagi ei salvestata, konkreetne põhjus on alati väljal message.
  • 404calendar_integration_not_foundcalendar.integrationId ei osuta teie konto kalendriühendusele - valige see uuesti päringust GET /v1/integrations.
  • 400calendar_invalid_calendarcalendar.calendarId ei ole selle ühenduse kalendrite seas või on see ainult lugemiseks (accessRole reader või freeBusyReader), seega agent ei saaks sinna kohtumist kirjutada. Valige kirjutatav kalender päringust list_calendars.
  • 400calendar_invalid_timezonecalendar.timezone ei ole kehtiv IANA tsoon, näiteks "Europe/Prague".
  • 400calendar_invalid_windowscalendar.windows aknad ei kasuta kuju HH:MM, kattuvad või neid on ühel päeval rohkem kui neli.
  • 400calendar_no_windowsKalender on sees, kuid ühelgi nädalapäeval ei ole akent - agendil poleks midagi pakkuda.
  • 400calendar_invalid_rulesKalendri numbrilised reeglid on vahemikust väljas või minimaalne etteteatamine on pikem kui otsinguhorisont.
  • 404tool_not_foundTööriist väljalt toolIds ei ole olemas või ei kuulu teie kontole.
  • 404agent_not_foundAgenti ei ole olemas või see ei kuulu teie kontole.
  • 400validationSisendi kuju ei sobi - tavaliselt voiceId ei vasta ühelegi kirjele päringust GET /v1/voices ja ei näe välja nagu töötlemata ElevenLabsi ID (vea teade loetleb kehtivad väärtused) või silencePromptSecs väljaspool 3 kuni 25, firstMessageProtectSecs väljaspool 0 kuni 20 või silencePromptText pikem kui 80 märki või inboundVariables rohkem kui 10 võtmega, reserveeritud või vigase võtmenimega või väärtusega pikem kui 200 märki või sttLanguageHintsStrict, mis ei ole true, false ega null, või turnDigitTailFloorMs või turnLongSpeechFloorMs väljaspool 0 ja 400 kuni 2300 või turnLongSpeechSecs väljaspool 1 kuni 30.
  • 409invalid_transitionNumber kõnede ja SMS-ide jaoks, mida te agendile määrate, ei ole aktiivne (see ootab registreerimist, lükati tagasi või seda vabastatakse). Agendi saab siduda ainult aktiivse numbriga. Midagi ei muudetud.
  • 409in_progressKas selle agendiga käib juba mõni teine muudatus (mustand või avaldamine) või eelmine muudatus läks läbi, kuid seda ei õnnestunud ohutult kinnitada - enne selle PATCH-i kordamist lugege GET /v1/agents/{id}/draft/operation ja otsustage operation põhjal. Sama koodi tagastatakse, kui number kõnede ja SMS-ide jaoks-i, mida te agendiga seote või sisse vahetate, töötleb mõni teine toiming (aktiveerimine, arveldus või vabastamine): see on ajutine, kuid numbrite vahetamisel võib algne number olla juba eraldatud, seega lugege esmalt agent (GET /v1/agents/{id}) ja korrake PATCH-i minuti pärast.
  • 502engine_unavailableJuba volai enda mootoril töötava agendi puhul: mootor ei vasta praegu, muudatust ei salvestatud. Palun proovige varsti uuesti. Sama koodi tagastatakse kirjutamise puhul, mille mootori ooterežiimi sõlm tagasi lükkas (mootor töötab praegu ooterežiimi sõlmel, mis seadistust vastu ei võta, tavaliselt pärast failover'it): teade ütleb seda, muudatust kindlasti ei salvestatud, agent ei ole ebaselgena lukustatud ja sama päringut saab mõne minuti pärast korrata.
  • 503engine_not_configuredJuba volai enda mootoril töötava agendi puhul: mootor ei ole meie poolel praegu seadistatud, muudatust ei salvestatud. Palun võtke ühendust toega.
  • 502engine_readback_mismatchJuba volai enda mootoril töötava agendi puhul: mootor salvestas teistsuguse seadistuse kui see, mille me saatsime, muudatust ei salvestatud. Proovige uuesti.

DELETE/v1/agents/{id}

Kustutab agendi nii volaist kui ElevenLabsist. Number, mis oli sellega seotud, jääb teie omaks - andke sellele lihtsalt uus marsruutimine: häälnumbrile päringuga PATCH /v1/numbers/{e164}, number kõnede ja SMS-ide jaoks-ile päringuga PATCH /v1/voice-sms-numbers/{e164} (MCP set_voice_sms_number_routing). Numbri agendist eraldamine on kustutamise osa: kui see ebaõnnestub (number kõnede ja SMS-ide jaoks-i puhul 409 in_progress, 502 routing_failed), siis agenti ei kustutata ja number jääb nagu enne - korrake päringut varsti.

Päring

bash
curl -X DELETE https://volai.cz/v1/agents/ag_kx91fa2b \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "deleted": true
}

Veaolekud

  • 404agent_not_foundAgenti ei ole olemas või see ei kuulu teie kontole.
  • 409in_progressAgendi numbrit töötleb mõni teine toiming (number kõnede ja SMS-ide jaoks-i puhul: aktiveerimine, arveldus või vabastamine). Agenti ei kustutatud ja number jääb nagu enne; korrake päringut minuti pärast.
  • 502routing_failedNumbri agendist eraldamine ebaõnnestus (number kõnede ja SMS-ide jaoks-i puhul: ettevõttesiseses häälmootoris). Agenti ei kustutatud ja number jääb marsruutituks nagu enne; korrake päringut varsti.

Vastused päringutele POST /v1/agents, PATCH /v1/agents/{id}, POST /v1/agents/{id}/draft/publish ja POST /v1/agents/{id}/draft/rollback võivad kanda valikulist välja warnings. Mitu koodi puudutab esimest rida: first_message_no_ai_disclosure, kui agendi salvestatud esimene rida ei avalda, et tegu on digitaalse assistendiga (EL tehisintellekti määrus, artikkel 50), ja first_message_too_long, kui selle hinnanguline kõneaeg, mida helistaja tegelikult kuuleb (esimene rida pluss salvestamise teate lause, kui see on sees: recordingNotice koos recordCalls), on üle 7 sekundi (umbes 2,53 sõna sekundis; numbrid alati ja kuni nelja märgi pikkused suurtähelised lühendid loetakse märkide kaupa). Muutmata vaikimisi esimene rida ei käivita seda koodi kunagi, ainult see, mida klient on muutnud. Helistajad, kes agendi katkestavad, teevad seda kõige sagedamini ühe sekundi jooksul kuuldavast kõnest. Faasidega agent (väli workflow, vt allpool jaotist Kõne faasid (töövoog)) lisab samale väljale veel kümme koodi - dead_end, empty_node, entry_phrase_never_spoken, missing_enter_phrase, short_condition, condition_about_agent, base_prompt_long, workflow_not_synced_to_provider, workflow_node_tool_not_synced ja workflow_node_tool_missing (sõlm viitab tööriistale, mida kontol enam ei ole - see kustutati; faas tuleb ilma selleta salvestada) - ja kannab neid tavaliselt isegi siis, kui esimene rida on korras (mall Vastuvõtt tagastab kolm). Hoiatus, mis kuulub ühele konkreetsele faasile või üleminekule, kannab ka nodeId või edgeId. Ükski kood ei blokeeri salvestamist - need ainult märgivad. Väli puudub vastusest ainult siis, kui märgitavat ei ole. Mustandi tagasipööramine varasemale revisjonile (draft/rollback) tagastab warnings nagu avaldamine, sest see kirjutab esimese rea ka elavale agendile. Ainult avaldamine ja tagasipööramine (mitte POST/PATCH /v1/agents) võivad samale väljale tagastada ka number_changed_by_publish väärtustega from/to (E.164 või null, kui numbrit ei ole), kui uuesti avaldamine tegelikult muudab elava agendi telefoninumbrit - see ei blokeeri avaldamist samuti. Eraldi kood calendar_pending_engine_switch ilmub siis, kui agendil on seadistatud calendar (kalendripõhised kohtumised), kuid ta töötab ElevenLabsis - seaded salvestatakse ja hakkavad toimima, kui agent liigub volai enda mootorile, mille kalendri sisselülitamine ise käivitab. Agent, millel on telefoninumber (numberE164) ja kelle juhised (systemPrompt või firstMessage) kasutavad {{variable}}-it väljaspool hulka, mida sissetulev kõne tegelikult annab (caller_number, called_number, attempt_id, volai_blocked, volai_block_reason, trial_prompt, trial_first_message ja seitse system__* muutujat), saab prompt_variables_unavailable_inbound - sissetulevas kõnes asendatakse see muutuja tühja tekstiga. Kui kõigi {{...}} plokkide eemaldamine mittetühjast esimesest reast ei jäta sinna väljaspool muutujaid ühtki tähte ega numbrit, saab see first_message_empty. Eraldi kood agent_misuse_suspected ilmub, kui agendi seadistus (ülaltoodud vastuste puhul) sisaldab sõnastust, mis võib jätta mulje, et esinetakse võimuorgani või muu asutusena, või delikaatse teabe küsimisena - vt volai tingimusi, jaotis 10. Sama kood samas kujus tuleb tagasi ka valikulisel väljal warnings päringutes PUT /v1/agents/{id}/draft ja POST /v1/agents/{id}/simulate (mustand), POST /v1/calls (prooviversiooni kõne prompt või variables), POST /v1/tasks ja PATCH /v1/tasks/{id} (ülesande nimi ja saajate muutujad) ning POST /v1/tools ja PATCH /v1/tools/{id} (tööriista kirjeldus ja selle parameetrid). See ei blokeeri kunagi salvestamist ega saatmist - see on ainult hoiatus. Ainult POST /v1/agents võib tagastada ka elevenlabs_by_explicit_choice, kui päring saatis useForOutboundTasks: false keele jaoks, mille juurutus muidu alustaks volai enda häälmootoril (täna cs ja sk), mistõttu agent jäi ElevenLabsi - ilma mootori häälteta ja ilma funktsioonideta, mis töötavad ainult mootoril. Agent luuakse siiski, hoiatus ainult märgib seda; kui soovisite agenti ainult sissetulevate kõnede jaoks, jätke väli välja.

json
{
  "id": "ag_kx91fa2b",
  "warnings": [
    {
      "code": "first_message_no_ai_disclosure",
      "message": {
        "cs": "Podle evropského AI Act (čl. 50) musí první věta prozradit, že mluví digitální asistentka. Stačí: „Dobrý den, tady digitální asistentka firmy Novák.“ Bez toho za sdělení odpovídáš ty.",
        "en": "Under the EU AI Act (Article 50), the first line must reveal that a digital assistant is speaking. For example: \"Hello, this is the digital assistant for Novak Inc.\" Without it, you are responsible for the disclosure."
      }
    }
  ]
}

Agendi uued väljad

Lisaks nimele, promptile, häälele ja numbrile võtavad POST /v1/agents ja PATCH /v1/agents/{id} ka neid välju. Kõik on loomisel valikulised. toolIds, transferTo, transferCondition, dataFields ja recordCalls puuduvad vanema agendi vastusest, kuni keegi neid seab. goal ja knowledge tagastatakse selle asemel alati - seadmata väärtusena null, mitte puuduva võtmena - ja notifyEmail on alati tõeväärtus (puudumine tähendab sees). recordingNotice on samuti alati tõeväärtus - false, kuni keegi selle sisse lülitab. Vastus kannab alati ka provider (engine või elevenlabs) - see ütleb, millisel platvormil agent tegelikult töötab, mõlemad väärtused esinevad toodangus. Samamoodi kannab see alati suspended (tõeväärtus) - true, kui volai operaator on agendi käsitsi peatanud; selline agent ei saa kõnesid vastu võtta ega teha (agent_suspended) ja välja ei saa seada API ega MCP kaudu. useForOutboundTasks on erand - seda võtab ainult POST /v1/agents, see ei ole PATCH-is (olemasolevat agenti liigutab teenusepakkujate vahel volai, mitte klient; ise teeb ta seda pärast transferTo või calendar sisselülitamist või pärast language muutmist keelde, milles uued agendid algavad mootoril - vt ülal agendi detaili). voicemail on saadaval ainult agendile, mille provider: "engine" - teiste puhul ebaõnnestub selle väljaga POST/PATCH. silencePromptSecs (vaikuse meeldetuletus) seevastu aktsepteeritakse ja tagastatakse mõlema teenusepakkuja puhul - ElevenLabsi agendi puhul väärtus ainult salvestatakse, seda kuuleb kohe, kui agent liigub volai enda häälmootorile. firstMessageProtectSecs (kaitseb esimest rida katkestamise eest, 0 kuni 20 sekundit) ja silencePromptText (teie enda vaikuse meeldetuletuse lause, kuni 80 märki) aktsepteeritakse ja tagastatakse samuti MÕLEMA teenusepakkuja puhul, kuid erinevalt silencePromptSecs-ist ILMA sunnitud vaikeväärtuseta: puuduvat välja POST-il ei salvestata ja vastus näitab null (kaitse väljas, vaiketekst) ning PATCH ilma võtmeta jätab salvestatud väärtuse rahule. workflow (kõne faasid) on saadaval mõlemal teenusepakkujal, kuid mitte võrdselt täielikult - vt allpool jaotist Kõne faasid (töövoog). laughter (agendi naer) on samuti alati olemas, nagu ülalolevad goal/knowledge/notifyEmail - vanema agendi puhul, millel väärtust ei ole seatud, on see auto, mitte kunagi puuduv võti; aktsepteeritakse ja salvestatakse MÕLEMA teenusepakkuja puhul, kuid kuuleb ainult mootoril oleva agendi puhul tšehhi Cartesia häälega. inboundVariables (vaikeväärtused {{variable}} kohatäitjatele SISSETULEVATE kõnede puhul) on valikuline nagu toolIds - agendil, millel neid ei ole, ei ole vastuses sellist võtit; aktsepteeritakse ja tagastatakse MÕLEMA teenusepakkuja puhul, sest mootor ja ElevenLabs loevad sama initsieerimise webhooki, ning väljaminevatel kõnedel ei kasutata. sttLanguageHintsStrict (range keelelukk kõnetuvastusele) on alati olemas tõeväärtusena - false, kui agendil on see seadmata; aktsepteeritakse ja salvestatakse MÕLEMA teenusepakkuja puhul, kuid loeb ainult volai enda mootor, ElevenLabs ignoreerib seda. turnDigitTailFloorMs, turnLongSpeechFloorMs ja turnLongSpeechSecs (vaikuse alampiirid helistaja vastuse lõpus) on alati olemas arvudena või null, nagu firstMessageProtectSecs - ILMA sunnitud vaikeväärtuseta: puuduvat välja POST-il ei salvestata ja vastus näitab null (mootor kasutab oma vaikeväärtusi 0 / 0 / 5), PATCH ilma võtmeta jätab salvestatud väärtuse rahule ja null eemaldab selle; aktsepteeritakse ja salvestatakse MÕLEMA teenusepakkuja puhul, loeb ainult volai enda mootor.

VäliMida see teeb
toolIdsMassiiv id-dest webhooki tööriistadest päringust GET /v1/tools, mida agent võib kõne ajal kutsuda. Kuni 10. Tööriist kuulub kontole, seega võib selle sisse lülitada rohkem kui ühel agendil.
transferToNumber kujul E.164, millele agent helistaja edastab, kui see palub inimest. Tühi string lülitab edastamise välja. Konto enda volai numbrit siin kasutada ei saa (transfer_loop).
transferConditionMillal edastada, kirjutatud juhisena mudelile (kuni 500 märki). Kui te seda ei saada, asendame vaikelausega.
dataFieldsMida agent peaks kõnest jäädvustama: massiiv objektidest {key, type, description, enumValues}, kuni 10. key on väiketähed, numbrid ja alakriipsud; type on string, number või boolean; enumValues saab seada ainult tekstiväljale. Täidetud väärtused saabuvad seejärel kõne väljal data.
recordCallsKas selle agendi kõnesid salvestada. Vaikimisi sees; kui false, siis kõnede kohta, mis algasid pärast muudatuse salvestamist, salvestist ei tehta ja GET /v1/calls/{id}/recording tagastab neile no_recording (kõne, mis juba heliseb või on käimas, järgib seadet alates selle algusest). Salvestamine üksi ei ütle helistajale midagi - recordingNotice lülitab sisse teate lause. Tagamine, et avalikustamine vastab teie olukorras seadusele, on teie vastutus.
recordingNoticeKas agent lõpetab oma esimese rea, öeldes helistajale, et kõnet salvestatakse - lühike lause agendi keeles (inglise keeles „Please note this call is recorded.”). Vaikimisi väljas: välja jätmine ei salvesta POST-il midagi ja PATCH ilma võtmeta jätab selle muutmata. Mängitakse ainult siis, kui recordCalls on sees; vastus kannab seda alati tõeväärtusena. Alates 22. okt 2026 volai seda enam ise ei lisa.
goalKõne eesmärk ühes lauses - LLM-kohtunik kasutab seda pärast kõnet, et otsustada, kas agent saavutas selle, mida helistaja soovis (hinnatakse ainult volai enda mootoril oleva agendi puhul, vt jaotist Eesmärk ja hindamine häälagendi dokumentatsioonis). Kuni 300 märki. PATCH väärtusega null või tühja stringiga kustutab eesmärgi.
knowledgeTekst, mida agent teab lisaks oma juhistele - hinnakiri, lahtiolekuajad, korduma kippuvad küsimused. Lisatakse prompti lõppu. Kuni 20000 märki. PATCH väärtusega null või tühja stringiga kustutab teadmised.
notifyEmailKas saata konto omanikule e-kirjaga kokkuvõte pärast iga selle agendi vastuvõetud kõnet - täna läheb e-kiri välja ainult volai enda mootoril oleva agendi puhul (provider: "engine"); ElevenLabsi agendi puhul väärtus salvestatakse, kuid e-kirja veel ei saadeta. Vaikimisi sees.
useForOutboundTaskstrue valib loomisel volai mootori, false alustab ElevenLabsis ja väljajätmine kasutab juurutuse vaikeväärtust, mis sõltub mootori saadavusest, lubamisest ja seadistatud keeltest. Ainult cs või sk valimine ei taga mootorit; kui mootori vaikeväärtus on keelatud, algab loomine ElevenLabsis. POST tagastab ainult id, seega lugege provider järgneva päringuga GET /v1/agents/{id}. Väli on ainult loomiseks; muud üleminekud käsitleb tugi. transferTo käivitab samuti katse viia ElevenLabsist mootorile, mille tulemus tuleb kontrollida.
voicemailKõneposti tuvastus VÄLJAMINEVATE kõnede puhul. message on kohustuslik väärtuse action: "message" korral, kuni 400 märki. PATCH aktsepteerib seda ainult väärtusega provider: "engine". POST-il peab algne valik olema mootor: selgesõnaline useForOutboundTasks: true või väljajätmine, kui mootor on vaikimisi. false ebaõnnestub veaga voicemail_requires_engine isegi koos transferTo-ga, sest valideerimine eelneb üleminekukatsele. PATCH väärtusega null kustutab selle.
silencePromptSecsMitu sekundit helistaja vaikust käivitab ühe meeldetuletuse ("Kas te olete seal?"), täisarv 3 kuni 25. null lülitab selle välja. Puudumine POST-il salvestab vaikeväärtuse 10. Aktsepteeritakse ja salvestatakse MÕLEMA teenusepakkuja puhul - standardplatvormi ElevenLabsi agendi puhul (provider: "elevenlabs") väärtus ainult salvestatakse, seda kuuleb kohe, kui agent liigub volai enda häälmootorile, mis on ainus, mis seda esitada oskab. Väärtus väljaspool 3 kuni 25 ebaõnnestub üldise valideerimisveaga (validation, 400) - eraldi koodi ei ole.
firstMessageProtectSecsMitu sekundit esimesest reast kaitsta vastanud isiku lühikese reaktsiooni eest ("Halloo?", "Jah?"), arv 0 kuni 20 (kümnendkohad lubatud), ainult VÄLJAMINEVAD kõned. Vastanud isiku vastus ilma katkestava sõnata (näiteks stopp, ei, oodake) jäetakse kaitstud aknas kõrvale: see ei katkesta rida, ei ole transkriptsioonis ja agent sellele ei reageeri. Katkestav sõna või selgesõnaline helistamiskeelu nõue katkestab selle endiselt. Katkestavad sõnad järgivad agendi keelt: inglise keele agenti katkestavad stop, no, wait või hold. null (või 0) lülitab kaitse välja. Vaikeväärtust ei rakendata: puuduv väli POST-il ei salvesta midagi ja vastus näitab null; PATCH ilma võtmeta jätab salvestatud väärtuse rahule. Aktsepteeritakse ja salvestatakse MÕLEMA teenusepakkuja puhul - standardplatvormi ElevenLabsi agendi puhul (provider: "elevenlabs") väärtus ainult salvestatakse, seda kuuleb kohe, kui agent liigub volai enda häälmootorile. Väärtus väljaspool 0 kuni 20 ebaõnnestub üldise valideerimisveaga (validation, 400) - eraldi koodi ei ole.
silencePromptTextTeie enda lause vaikuse meeldetuletuseks, kuni 80 märki, öeldakse sõna-sõnalt (ilma muutujate asendamiseta) agendi keele vaikemeeldetuletuse asemel (inglise keeles "Are you still there?"). Kõige parem lõpetada küsimärgiga, et lühike "Jah" pärast seda säiliks vastusena. Ümbritsevad tühikud eemaldatakse; tühi string või null taastab agendi keele vaiketeksti. Vaikeväärtust ei rakendata: puuduv väli POST-il ei salvesta midagi ja vastus näitab null; PATCH ilma võtmeta jätab salvestatud teksti rahule. Aktsepteeritakse ja salvestatakse MÕLEMA teenusepakkuja puhul, kuid kuuleb ainult volai enda mootoril ja ainult siis, kui vaikuse meeldetuletus on sees (silencePromptSecs ei ole null). Tekst pikem kui 80 märki ebaõnnestub üldise valideerimisveaga (validation, 400).
inboundVariablesVaikeväärtused {{variable}} kohatäitjatele SISSETULEVATE kõnede puhul, objekt {"name": "value"} - näiteks {"uvod": "Kuidas saan aidata?"} esimese rea "... seda kõnet salvestatakse. {{uvod}}" jaoks. Väljamineval kõnel edastate muutujad helistamisel (variables päringus POST /v1/calls); sissetulevas kõnes ei anna neid keegi ja mootor täidaks tühja teksti, seega liidetakse need väärtused sissetulevate kõnede puhul kõne muutujatega - ainult nimede puhul, mida kõne ise ei anna (caller_number, called_number, attempt_id, volai_*, trial_* ja system__* on alati ülimuslikud ja valideerimine lükkab sellised nimed tagasi). Väljaminevatel kõnedel ei kasutata. Kuni 10 võtit tähtedest, numbritest ja alakriipsudest (1 kuni 40 märki), väärtused on tekst kuni 200 märki (ümbritsevad tühikud eemaldatakse). PATCH-il objekt ASENDAB salvestatud väärtused täielikult (võtmepõhist liitmist ei ole), null või {} eemaldab need, väljajäetud võti jätab need rahule; POST-il väljajäetud väli ei salvesta midagi. Vastus jätab võtme välja, kui agendil vaikeväärtusi ei ole. Töötab MÕLEMA teenusepakkuja puhul - mootor ja ElevenLabs loevad sama webhooki. Vaikeväärtusega muutujast ei teata enam hoiatusega prompt_variables_unavailable_inbound. Nendest piiridest väljas kuju ebaõnnestub üldise valideerimisveaga (validation, 400).
sttLanguageHintsStrictRange keelelukk kõnetuvastusele (Soniox language_hints_strict): transkribeerimismudel eelistab tugevalt agendi keelt, nii et lühikest vastust nagu "Ano" väljamineval kõnel ei kirjutata võõra sõnana ega teises kirjas. Parim pingutus, mitte garantii. Ainult volai enda mootoril olevatele agentidele keelega cs ja väljaminevatele kõnedele; ÄRGE lülitage seda sisse keelele sk - Tšehhi helistajad saaksid Slovaki õigekirja. Agendi keelt ei sunnita peale. true lülitab sisse, false või null lülitab välja; puuduv väli POST-il ei salvesta midagi ja vastus näitab false; PATCH ilma võtmeta jätab salvestatud väärtuse rahule. Vastus kannab välja alati tõeväärtusena. Aktsepteeritakse ja salvestatakse MÕLEMA teenusepakkuja puhul, loeb ainult mootor - ElevenLabs ignoreerib seda. See saadetakse mootorile iga agendi salvestamisel, seega portaalis salvestamine ei lülita sisselülitatud luku välja.
turnDigitTailFloorMsVaikuse alampiir millisekundites vastuse puhul, mis lõpeb 3 kuni 8 numbri rühmaga (helistaja, kes dikteerib numbrit rühmade kaupa, võtab rühmade vahel hinge): pärast helistaja lõpetamist ootab mootor vähemalt nii kaua, enne kui vastuse sulgeb, et agent ei hüppaks numbri sisse. 0 lülitab välja; muidu 400 kuni 2300 (1 kuni 399 lükatakse tagasi). Soovitatav esimene samm Tšehhi agentidele, kes võtavad vastu dikteeritud numbreid, on 800, teine samm 1200, praktiline ülempiir 1500. Kuupäevad, postiindeksid ja aastaarvud saavad samuti alampiiri (aktsepteeritud hind). Puuduv väli POST-il ei salvesta midagi ja vastus näitab null (mootor kasutab oma vaikeväärtust 0); PATCH väärtusega null eemaldab salvestatud väärtuse, ilma võtmeta jätab selle rahule. Aktsepteeritakse ja salvestatakse MÕLEMA teenusepakkuja puhul, loeb ainult volai enda mootor - ElevenLabs ignoreerib seda. See saadetakse mootorile iga agendi salvestamisel, seega portaalis salvestamine ei lülita sisselülitatud alampiiri välja.
turnLongSpeechFloorMsVaikuse alampiir millisekundites pärast seda, kui helistaja rääkis kauem kui turnLongSpeechSecs: pärast pikka kõneperioodi võtavad helistajad hinge ja jätkavad, alampiir annab neile aega. 0 lülitab välja; muidu 400 kuni 2300, soovitatav 800. Samad salvestamisreeglid nagu turnDigitTailFloorMs: puuduv väli POST-il ei salvesta midagi ja vastus näitab null (mootori vaikeväärtus 0), PATCH väärtusega null eemaldab väärtuse. Ainult mootor.
turnLongSpeechSecsKõne pikkus sekundites väärtuse turnLongSpeechFloorMs jaoks, 1 kuni 30 (kümnendkohad sobivad). Mõõdetakse vastuse esimesest kinnitatud kõnest viimase kõne lõpuni, pausid kaasa arvatud; alampiir kehtib kõnele, mis on RANGELT pikem kui see. Ei mõju, kuni turnLongSpeechFloorMs on null. Puuduv väli POST-il ei salvesta midagi ja vastus näitab null (mootori vaikeväärtus 5), PATCH väärtusega null eemaldab väärtuse.
workflowJagab kõne faasideks (sõlmedeks) - kuju, piirangud ja näite vt allpool jaotisest Kõne faasid (töövoog). PATCH väärtusega null kustutab faasid ja viib agendi tagasi ühe faasi juurde nagu varem.
laughterKas agent võib kõne ajal naerda, kui helistaja naerab või teeb nalja: auto jätab otsuse delikaatsete teemade tuvastusele (võlgade sissenõudmine, tervishoid, ametiasutused, matuseteenused), on tühistab selle tuvastuse, off summutab alati; laughterEffective näitab tegelikku tulemust antud seadistuse jaoks. Väljajäetud võti salvestatakse POST-il kui auto ja vastus kannab alati laughter-it, mitte kunagi puuduvat võtit. Aktsepteeritakse ja salvestatakse MÕLEMA teenusepakkuja puhul, kuid kuuleb ainult mootoril oleva agendi puhul tšehhi Cartesia häälega - ElevenLabsis mõju ei ole. Muudatus jõustub järgmisest kõnest.

Edastamine: mida API tegelikult teeb

volai mootoril on edastamine sillatud: agent valib sihtkoha teise osalejana ja jääb pärast vastamist vait. Standardplatvormil edastamine ei tööta. transferTo käivitab mootorile ülemineku katse, kuid peatatud katse, kättesaamatu mootor või tõrge võib jätta agendi ElevenLabsi; kontrollige provider-it. Me ei saa kõne kokkuvõtet kaasa anda kummalgi platvormil, seega "soojast edastamist" ei ole.

Teine haru on tavaline väljaminev kõne ja see arveldatakse sellena: 0.92 CZK/min (~EUR 0.04) ilma agendi lisatasuta. Kõneloendis tunnete selle ära väljalt kind: "transfer".

Kõne faasid (töövoog)

Valikuline väli workflow jagab kõne faasideks (nodes). Sõlm on KÄSITLUSALA, mitte stsenaarium: see lisab ainult prompti, teadmiste ja tööriistade täienduse, mis kehtivad, kuni kõne on selles, pluss valikulise rea, mida agent ütleb kohe sisenemisel. Mudel ise otsustab, millal sõlmede vahel liikuda, kutsudes tööriista - te ei skriptita seda kunagi fikseeritud järjestusena. Agendi põhi-systemPrompt peaks sisaldama ainult seda, mis kehtib IGAS faasis (identiteet, toon, kuidas sõnum üles kirjutatakse); ühe faasi juhised kuuluvad selle enda sõlme, vastasel juhul sõlmel mõju ei ole. Põhiprompt peaks sisaldama ka kahte lauset, ilma milleta vastab agent kõige sagedamini sellele, mida ta ei tea: "Ärge väitke ega oletage tegevusandmeid, mida teil juhistes ei ole (lahtiolekuajad, tähtajad, hinnad, kes on saadaval) - öelge, et kolleeg kinnitab selle." ja "Küsige alati ainult ühe asja kohta korraga."

entry on sõlme id, millega kõne algab. edges on üleminekud: condition (5 kuni 200 märki) kirjeldab, MILLAL liikuda, ja see peab olema kirjutatud sellest, mida HELISTAJA ütles (mitte kunagi sellest, mida agent või tööriist tegi) - see läheb sõna-sõnalt selle tööriista kirjeldusse, mida mudel liikumiseks kutsub. Piirangud: 2 kuni 8 sõlme, 1 kuni 24 üleminekut, kuni 5 üleminekut ühest sõlmest väljas, ainult üks üleminek mis tahes kahe sõlme vahel (kummaski suunas, duplicate_pair); sõlme prompt on kuni 2000 märki, knowledge kuni 4000, prompt pluss knowledge kokku piiratud 4000-ga sõlme kohta ja toolIds kuni 10 tööriista sõlme kohta.

enterPhrase on rida, mida öeldakse üks kord sõlme sisenemisel (kuni 160 märki). enterBehavior: "wait" käsib mudelil sama vooru jooksul pärast seda midagi muud mitte öelda ja selle asemel helistajat oodata - tavaliselt delikaatse faasi puhul, nagu surmateate edastamine; see nõuab enterPhrase-i, vastasel juhul wait_without_phrase. Sõlm ilma oma enterPhrase-ita saab sisenemisel lühikese vaikerea (inglise keeles „I see.”) ainult volai enda mootoril (provider: "engine"); ElevenLabsis majutatud agendil sisenemisel midagi ei mängita - faasipõhine rida kõlab loomulikumalt ja on ainus, mis mängib mõlemal, mistõttu redaktor soovitab seda hoiatusega missing_enter_phrase pidevalt.

Lõppsõlme ei ole - faasid ei lõpeta kõnet kunagi ise. Kõne lõpeb endiselt ainult sisseehitatud lõpetamiskäitumise kaudu, täpselt nagu varem.

enterBehavior: "wait" kandub üle ka ElevenLabsi agentidele, mitte ainult volai enda häälmootorile (provider: "engine"); sisenemisrida öeldakse mootoril sõna-sõnalt, ElevenLabsis läheb see aga faasi prompti juhisena see öelda - mudel ütleb tavaliselt midagi sellele lähedast, kuid mitte tingimata täpseid sõnu. Sõlm ILMA oma enterPhrase-ita ei ütle ElevenLabsis sisenemisel üldse midagi: lühikese vaikerea (inglise keeles „I see.”) lisab ainult volai enda mootor. Kaks erinevust on suuremad. Tööriist, mis on määratud AINULT sõlmele (node.toolIds), ei kandu ElevenLabsi agendile veel üle - faas töötab seal ilma selleta ja vastus märgib seda koodiga workflow_node_tool_not_synced; kui soovite seda seal, lisage see ka agendi tööriistade hulka (väli toolIds, portaali vahekaart Täpsemalt). volai enda mootoril kandub sõlme tööriist üle muutmata kujul. Ja kõne workflowPath kirjutab ainult mootori kõnejärgne kirjutus, seega ElevenLabsis majutatud agendi kõne ei kanna seda kunagi, isegi kui kõne läbis faase.

Vigane graaf (kättesaamatu sõlm, puuduv sisendsõlm, reserveeritud tööriista nimi...) tagastab invalid_workflow ja midagi ei salvestata; konkreetne põhjus on alati väljal message.

Näide - matusebüroo vastuvõtt

json
{
  "workflow": {
    "version": 1,
    "entry": "triage",
    "nodes": [
      {
        "id": "triage",
        "label": "Triage",
        "prompt": "Find out in one question why the caller is calling. You help callers report a death, arrange a grave dig or urn interment, and request headstone work."
      },
      {
        "id": "bereavement",
        "label": "Bereavement",
        "prompt": "Find out the deceased's name, where the death occurred, whether the body is at a hospital or at home, a contact and a good time to call back. Promise a funeral home staff member will call within 15 minutes. Do not handle questions about a headstone or its price here - just say a colleague will go over that with the family, explain nothing, and return to the bereavement. Never bring up a headstone yourself.",
        "enterPhrase": "My condolences.",
        "enterBehavior": "wait"
      },
      {
        "id": "burial",
        "label": "Burial and interment",
        "prompt": "The caller needs a grave dug, an urn interred, or a tomb opened. Find out the date, cemetery and grave number, a contact, and whether a clergy member needs to be arranged."
      },
      {
        "id": "inquiry",
        "label": "Work inquiry",
        "prompt": "The caller wants new headstone work - an inscription, a repair or a grave restoration. Find out the cemetery, grave number, scope of work and a callback contact for a price."
      }
    ],
    "edges": [
      {
        "id": "triage_bereavement",
        "from": "triage",
        "to": "bereavement",
        "condition": "The caller is reporting the death of a loved one or needs funeral services."
      },
      {
        "id": "triage_burial",
        "from": "triage",
        "to": "burial",
        "condition": "The caller needs a grave dug, an urn interred, or a tomb opened."
      },
      {
        "id": "triage_inquiry",
        "from": "triage",
        "to": "inquiry",
        "condition": "The caller wants new work: a headstone, an inscription, a repair or a grave restoration."
      },
      {
        "id": "burial_bereavement",
        "from": "burial",
        "to": "bereavement",
        "condition": "The caller reports the death of a loved one during the call."
      },
      {
        "id": "inquiry_bereavement",
        "from": "inquiry",
        "to": "bereavement",
        "condition": "The caller reports the death of a loved one during the call."
      }
    ]
  }
}

Kõne, mis läbis faase volai enda häälmootoril (provider: "engine"), kannab päringus GET /v1/calls/{id} (ja loendis GET /v1/calls) ka workflowPath: massiiv sammudest {node, label, viaEdge, turnIndex, at, enterPhraseSpoken}, at unix ms-des. Sisenemissammu väärtus on viaEdge: null. ElevenLabsis majutatud agendi kõne ei kanna välja kunagi, isegi kui see läbis faase - seda kirjutab ainult mootori kõnejärgne kirjutus. Faasideta kõne jätab välja täielikult ära.

Agendi mustandid

Mustand on agendi eraldi pooleli töö hetktõmmis - salvestate muudatuse sinna, vaatate selle üle, soovi korral proovite (simulatsioon allpool) ja alles siis juurutate elavale agendile ühe päringuga. PUT /v1/agents/{id}/draft EI puuduta KUNAGI häälteenusepakkujat (ElevenLabs või volai enda mootor) ega telefoni marsruutimist - see salvestab ainult mustandi. POST /v1/agents/{id}/draft/publish seda teeb - see on ainus mustandi samm, mis elavat agenti tegelikult muudab.

Seevastu PATCH /v1/agents/{id} (vt ülal jaotist Agendid) puudutab teenusepakkujat ENNAST, KOHE, ilma mustandita ja ilma vaheastmeta.

Avaldamine võib tagastada mis tahes päringu PATCH /v1/agents/{id} vea - see on sama kirjutus teenusepakkujale.

Mustand või PATCH?

PATCH - te olete agendi ainus redigeerija ja muudatus peaks kohe käiku minema. Mustand - agenti redigeerib samaaegselt ka inimene volai portaalis (portaali redaktor töötab AINULT mustandite kaudu, mitte kunagi PATCH-iga), te soovite muudatust enne väljastamist üle vaadata või proovida (simulatsioon) või vajate optimistlikku samaaegsust (expectedRevision kaitseb kellegi teise pooleliolevate muudatuste ülekirjutamise eest).

Mis juhtub, kui mustandist mööda minna

Agendi lukk on JAGATUD päringu PATCH /v1/agents/{id} ja POST .../draft/publish vahel - PATCH käimasoleva avaldamise ajal tagastab 409 in_progress. Kuid PATCH väljaspool käimasolevat avaldamist läheb läbi: see suurendab revision-it 1 võrra, kirjutab published üle uue elava väärtusega, kustutab märke tested (varasem simulatsioon ei kehti enam uuele seadistusele) ja jätab draft-i puutumata. Pooleliolev mustand (tavaliselt inimene portaalis) saab siis oma järgmisel salvestamisel 409 revision_conflict - see on MEELEGA nii, mitte viga: vastuolus olevat PATCH-i ei tohi kunagi vaikselt kaotada.

Agendi redaktor portaalis (/agent/{id}) töötab AINULT mustandite kaudu - isegi ühe välja muutmine kutsub sisemiselt save_agent_draft + publish_agent_draft.

Mustandi hetktõmmise väljad

draft ja published jagavad IGAS vastuses SAMA kuju - AgentDraftSnapshot, seadistuse täielik hetktõmmis. PUT/publish keha on .strict() - erinevalt PATCH /v1/agents-ist, mis tundmatu võtme vaikselt kõrvale jätab, tagastab siin tundmatu võti 400 validation. Välja workflow JSON-kuju kontrollitakse mustandi salvestamisel ainult - graafi reegleid (kättesaadavad faasid, tuntud tööriistad, faasipõhised piirangud) kontrollitakse avaldamisel ja päringul PATCH /v1/agents/{id}, seega mustand salvestub ka graafiga, mille avaldamine lükkab tagasi veaga invalid_workflow. Mõned väljad on erandid reeglist "iga kord täielik hetktõmmis": hetktõmmises puuduv silencePromptSecs tähendab muutmata, mitte välja lülitatud ja mitte vaikimisi 10 - ElevenLabsi agendil kannab see salvestatud väärtust, mida kuuleb alles siis, kui agent liigub volai mootorile. Puuduv firstMessageProtectSecs ja silencePromptText tähendavad samuti muutmata, mitte välja lülitatud ja mitte vaiketekst (null lülitab esimese rea kaitse välja või taastab vaikimisi meeldetuletuse teksti). Puuduv inboundVariables (vaikeväärtused muutujatele sissetulevate kõnede puhul) tähendab samuti muutmata - null või {} eemaldab salvestatud väärtused, objekt asendab need täielikult. Puuduv recordingNotice (salvestamise teade esimese rea lõpus) tähendab samuti muutmata, mitte väljas - true/false seab selle. Puuduv sttLanguageHintsStrict (range keelelukk kõnetuvastusele) tähendab samuti muutmata - null lülitab luku välja (eemaldab salvestatud võtme), true/false seab selle. Puuduvad turnDigitTailFloorMs, turnLongSpeechFloorMs ja turnLongSpeechSecs (vaikuse alampiirid helistaja vastuse lõpus) tähendavad samuti muutmata - null eemaldab salvestatud väärtuse (mootor naaseb oma vaikeväärtuse 0 / 0 / 5 juurde), arv seab selle. Sama kehtib puuduva numberE164 kohta - see tähendab samuti muutmata, seega avaldamine jätab elava agendi numbri nagu on; ainult null eraldab selle ja string seob selle numbri, sama kolmepoolne tähendus, mis päringul PATCH /v1/agents/{id} juba on. String, mis ühtib agendi praeguse ELAVA numbriga sel hetkel (mitte salvestatud published hetktõmmisega), loetakse samuti muutmata - see käitub sama nagu puuduv võti. See kontroll hinnatakse uuesti iga mustandi lugemisel selle vastu, mis number on siis elav, seega ei ole see püsiv otsus: kui number liigub hiljem väljaspool seda mustandit teisele agendile, muutub sama salvestatud väärtus uuesti selgesõnaliseks valikuks ja järgmine avaldamine või tagasipööramine seob selle siia uuesti - mitte vaikselt, vaid märgituna hoiatusega number_changed_by_publish väljal warnings.

VäliMärkus
name, language, systemPrompt, providername, language, systemPrompt ja provider on KOHUSTUSLIKUD - mustand on täielik hetktõmmis, mitte osaline plaaster.
providerprovider ("engine" või "elevenlabs") peab täpselt ühtima agendi praeguse provider-iga, vastasel juhul saate invalid_draft - päringutel POST/PATCH /v1/agents seda üldse ei saadeta (server tuletab selle ise). See on ainus väli, mida mustand kannab tavalise agendi peal.
toolIds, dataFieldstoolIds ja dataFields on piiratud 10 kirjega - sama piirang nagu POST /v1/agents ja PATCH /v1/agents/{id} (vt ülal tabelit Agendi uued väljad).

Ülejäänud väljadel (firstMessage, voiceId, transferTo, transferCondition, recordCalls, recordingNotice, goal, knowledge, notifyEmail) on sama tähendus ja piirangud nagu POST/PATCH /v1/agents - vt ülal tabelit Agendi uued väljad.

operation: mis agenti praegu blokeerib

operation (nii GET .../draft kui GET .../draft/operation puhul) on null, kui midagi agenti ei blokeeri, muidu objekt { id, kind, status, expectedRevision, createdAt, updatedAt }. Väärtused kind ja status on kitsendatud selleni, mida vajate, et otsustada, mida teha - sisemised üksikasjad (täpselt, kes toimingu käivitas, teenusepakkuja täpne veatekst) ei lahku serverist kunagi.

kindMärkus
updateElav muudatus päringuga PATCH /v1/agents/{id} (väljaspool mustandit).
publishSalvestatud mustandi avaldamine (POST .../draft/publish).
rollbackTagasipööramine varasemale avaldatud revisjonile ajaloost (POST .../draft/rollback) - nagu publish, puudutab see teenusepakkujat ja telefoniühendust.
outbound_taskVäljaminevate kõnede partiitöö (väljaminev kampaania) - mõni teine partiitöö kasutab seda agenti praegu; publish/PATCH ootab selle lõppemist.
statusMärkus
runningToiming töötab praegu teenusepakkuja juures.
uncertainTeenusepakkuja võis muudatuse rakendada või mitte - kontrollige elavat agenti ja ÄRGE korrake toimingut pimesi (vt allpool POST .../draft/operation).
driftTeenusepakkuja elav seadistus erineb sellest, mida me arvame saatnud olevat - nõuab käsitsi otsust.
failedToiming ebaõnnestus kindlasti - mustand on muutmata, proovige julgelt uuesti.
doneToiming lõppes edukalt (avaldamine, kinnitatud tagasipööramine või ohutult lahendatud ebaselgus).

tested (nii GET .../draft kui vastuse POST .../simulate puhul) on { revision, testedAt } | null - millal seda TÄPSET mustandi revisjoni viimati simulatsiooniga kontrolliti. Iga edasine mustandi muudatus (PUT) kustutab märke; simulatsioon EI ole avaldamise nõue, see on ainult valikuline sõnastuse kontroll enne juurutamist.

history on loend { revision, publishedAt } viimaste avalduste kohta (ilma salvestatud seadistuse hetktõmmisteta) - ainult portaal säilitab täieliku ajaloo sisuga.

GET/v1/agents/{id}/draft

Loeb mustandi, viimase avaldatud seadistuse, revisjoni (väärtuse expectedRevision jaoks järgnevatel kõnedel), viimase simulatsiooni tulemuse (tested) ja selle, kas midagi agenti praegu blokeerib (operation).

Päring

bash
curl https://volai.cz/v1/agents/ag_kx91fa2b/draft \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "draft": {
    "name": "Vastuvõtt",
    "language": "et",
    "systemPrompt": "Te olete kohvik Nula vastuvõtt. Võtate vastu kaasavõtutellimusi...",
    "firstMessage": "Tere, kohvik Nula, mida soovite?",
    "voiceId": "milena",
    "numberE164": "+420601234567",
    "provider": "engine"
  },
  "published": {
    "name": "Vastuvõtt",
    "language": "et",
    "systemPrompt": "Te olete kohvik Nula vastuvõtt. Võtate vastu kaasavõtutellimusi...",
    "firstMessage": "Tere, siin kohvik Nula, kuidas saan aidata?",
    "voiceId": "milena",
    "numberE164": "+420601234567",
    "provider": "engine"
  },
  "revision": 4,
  "tested": {
    "revision": 4,
    "testedAt": 1756118920000
  },
  "history": [
    {
      "revision": 3,
      "publishedAt": 1756118840000
    },
    {
      "revision": 2,
      "publishedAt": 1756112640000
    }
  ],
  "operation": null
}

Veaolekud

  • 403forbiddenÜhine volai demoagent on ainult lugemiseks.
  • 404agent_not_foundAgenti ei ole olemas, see on kustutatud või ei kuulu teie kontole.
  • 500storage_failedMustandi salvestamine või lugemine ebaõnnestus meie poolel - palun proovige uuesti.

PUT/v1/agents/{id}/draft

Salvestab mustandi väärtuse expectedRevision vastu. Saatke keha TÄPSELT sama objektina, mille lugesite päringuga GET, ühe rakendatud muudatusega - keha on .strict(), seega isegi väike tundmatu võti tagastab 400. Salvestamine EI muuda kunagi töötavat agenti. Ülaltoodud GET .../draft näide näitab olekut PÄRAST seda PUT-i (revisjon 3 -> 4): sellepärast saadab see PUT expectedRevision: 3 (revisjon, millel muudatus põhines) ja ülaltoodud GET tagastab juba revision: 4 (uus revisjon pärast salvestamist).

Päring

bash
curl -X PUT "https://volai.cz/v1/agents/ag_kx91fa2b/draft" \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"expectedRevision":3,"draft":{"name":"Vastuvõtt","language":"et","systemPrompt":"Te olete kohvik Nula vastuvõtt. Võtate vastu kaasavõtutellimusi...","firstMessage":"Tere, kohvik Nula, mida soovite?","voiceId":"milena","numberE164":"+420601234567","provider":"engine"}}'

Vastus

json
{
  "draft": {
    "name": "Vastuvõtt",
    "language": "et",
    "systemPrompt": "Te olete kohvik Nula vastuvõtt. Võtate vastu kaasavõtutellimusi...",
    "firstMessage": "Tere, kohvik Nula, mida soovite?",
    "voiceId": "milena",
    "numberE164": "+420601234567",
    "provider": "engine"
  },
  "revision": 4
}

Veaolekud

  • 400validationVigase kujuga keha - vt konkreetse välja piiranguid.
  • 400invalid_draftMustandi provider ei ühti agendi provider-iga - mustandit saab redigeerida ainult sama teenusepakkuja piires.
  • 403forbiddenÜhine volai demoagent on ainult lugemiseks.
  • 404agent_not_foundAgenti ei ole olemas, see on kustutatud või ei kuulu teie kontole.
  • 409revision_conflictKeegi teine on mustandit vahepeal redigeerinud (või PATCH-iga mööda läinud). Viga kannab currentRevision-it - laadige praegune olek päringuga GET .../draft ja vaadake erinevus üle enne salvestamise kordamist.
  • 409publish_in_progressSellel agendil töötab praegu mõni teine avaldamine või partiitöö - proovige varsti uuesti.
  • 409operation_uncertainEelmise katse ebaselge toiming blokeerib seda agenti - kontrollige elavat agenti ja lahendage see päringuga GET/POST .../draft/operation enne uuesti proovimist.
  • 500storage_failedMustandi salvestamine või lugemine ebaõnnestus meie poolel - palun proovige uuesti.

POST/v1/agents/{id}/draft/publish

Juurutab salvestatud mustandi elavale agendile - ainus mustandi samm, mis puudutab teenusepakkujat (ElevenLabs või volai mootor) ja telefoni marsruutimist. Aktsepteerib päist Idempotency-Key (vt ülal Idempotentsus) - teine kõne sama võtmega 24 tunni jooksul tagastab täpselt sama salvestatud vastuse, olenemata sellest, kas see õnnestus või tuli tagasi operation_uncertain.

Juurutamise vead (deploy) edastatakse MUUTMATA kujul - avaldamine pärib KOGU ülalolevat PATCH /v1/agents/{id} vigade tabeli (in_progress, engine_unavailable, engine_not_configured, engine_readback_mismatch ja valideerimiskoodid), lisaks oma ülalolevale mustandi vigade tabelile.

Päring

bash
curl -X POST "https://volai.cz/v1/agents/ag_kx91fa2b/draft/publish" \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: REPLACE_WITH_UNIQUE_POST_V1_AGENTS_AG_KX91FA2B_DRAFT_PUBLISH_ID" \
  -d '{"expectedRevision":4}'

Enne käivitamist asendage REPLACE_WITH_UNIQUE… selle toimingu unikaalse ID-ga, näiteks UUID-ga, ja salvestage see. Sama päringu kordamisel pärast ajalõppu kasutage sama ID-d. Teise toimingu või muudetud sisu korral kasutage uut ID-d, isegi kui kutsute teist lõpp-punkti.

Vastus

json
{
  "revision": 5,
  "published": {
    "name": "Vastuvõtt",
    "language": "et",
    "systemPrompt": "Te olete kohvik Nula vastuvõtt. Võtate vastu kaasavõtutellimusi...",
    "firstMessage": "Tere, kohvik Nula, mida soovite?",
    "voiceId": "milena",
    "numberE164": "+420601234567",
    "provider": "engine"
  }
}

Veaolekud

  • 400validationVigase kujuga keha - vt konkreetse välja piiranguid.
  • 400invalid_draftMustandi provider ei ühti agendi provider-iga - mustandit saab redigeerida ainult sama teenusepakkuja piires.
  • 403forbiddenÜhine volai demoagent on ainult lugemiseks.
  • 404agent_not_foundAgenti ei ole olemas, see on kustutatud või ei kuulu teie kontole.
  • 409revision_conflictKeegi teine on mustandit vahepeal redigeerinud (või PATCH-iga mööda läinud). Viga kannab currentRevision-it - laadige praegune olek päringuga GET .../draft ja vaadake erinevus üle enne salvestamise kordamist.
  • 409publish_in_progressSellel agendil töötab praegu mõni teine avaldamine või partiitöö - proovige varsti uuesti.
  • 409operation_uncertainEelmise katse ebaselge toiming blokeerib seda agenti - kontrollige elavat agenti ja lahendage see päringuga GET/POST .../draft/operation enne uuesti proovimist.
  • 409idempotency_in_progressSamaaegne kõne sama Idempotency-Key-ga töötab veel - palun proovige varsti uuesti.
  • 500storage_failedMustandi salvestamine või lugemine ebaõnnestus meie poolel - palun proovige uuesti.
  • 503engine_not_configuredvolai enda mootoril oleva agendi puhul: mootor ei ole meie poolel praegu seadistatud, avaldamist ei salvestatud. Palun võtke ühendust toega.
  • 502engine_unavailablevolai enda mootoril oleva agendi puhul: mootor ei vasta praegu, avaldamist ei salvestatud. Palun proovige varsti uuesti. Sama koodi tagastatakse kirjutamise puhul, mille mootori ooterežiimi sõlm tagasi lükkas (mootor töötab praegu ooterežiimi sõlmel, mis seadistust vastu ei võta): teade ütleb seda, avaldamist kindlasti ei salvestatud, ei mustand ega agent ei ole ebaselgena lukustatud ja avaldamist saab mõne minuti pärast korrata.
  • 502engine_readback_mismatchvolai enda mootoril oleva agendi puhul: mootor salvestas teistsuguse seadistuse kui see, mille me saatsime, avaldamist ei salvestatud. Proovige uuesti.
  • 409in_progressKas agendil töötab praegu mõni teine muudatus (elav PATCH või teine avaldamine) või eelmine muudatus läks läbi, kuid seda ei õnnestunud ohutult kinnitada - enne avaldamise kordamist lugege GET /v1/agents/{id}/draft/operation ja otsustage operation põhjal.

POST/v1/agents/{id}/draft/rollback

Pöörab agendi tagasi varasemale AVALDATUD revisjonile ajaloost (targetRevision, vt välja history päringul GET .../draft) ja juurutab selle teenusepakkujale kohe - see on avaldamine, mitte lihtsalt üle kirjutatud mustand. expectedRevision kaitseb samaaegse muudatuse eest samamoodi nagu PUT .../draft. Erinevalt .../draft/publish-ist ILMA Idempotency-Key-ta - sama keha kordamine on iseenesest ohutu.

Jagab täpselt samu kahte vigade allikat nagu ülalolev avaldamine: oma mustandi vigade tabelit (validation, invalid_draft, forbidden, agent_not_found, revision_conflict, publish_in_progress, operation_uncertain, storage_failed) ja KOGU PATCH /v1/agents/{id} vigade tabelit (juurutamine puudutab teenusepakkujat samamoodi nagu PATCH/publish).

Päring

bash
curl -X POST "https://volai.cz/v1/agents/ag_kx91fa2b/draft/rollback" \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"expectedRevision":4,"targetRevision":2}'

Vastus

json
{
  "revision": 5,
  "published": {
    "name": "Vastuvõtt",
    "language": "et",
    "systemPrompt": "Te olete kohvik Nula vastuvõtt. Võtate vastu kaasavõtutellimusi...",
    "firstMessage": "Tere, kohvik Nula, mida soovite?",
    "voiceId": "milena",
    "numberE164": "+420601234567",
    "provider": "engine"
  }
}

Veaolekud

  • 400validationVigase kujuga keha - vt konkreetse välja piiranguid.
  • 400invalid_drafttargetRevision ei ole enam säilitatud ajalooliste revisjonide seas (history päringul GET .../draft seda ei kanna).
  • 403forbiddenÜhine volai demoagent on ainult lugemiseks.
  • 404agent_not_foundAgenti ei ole olemas, see on kustutatud või ei kuulu teie kontole.
  • 409revision_conflictKeegi teine on mustandit vahepeal redigeerinud (või PATCH-iga mööda läinud). Viga kannab currentRevision-it - laadige praegune olek päringuga GET .../draft ja vaadake erinevus üle enne salvestamise kordamist.
  • 409publish_in_progressSellel agendil töötab praegu mõni teine avaldamine või partiitöö - proovige varsti uuesti.
  • 409operation_uncertainEelmise katse ebaselge toiming blokeerib seda agenti - kontrollige elavat agenti ja lahendage see päringuga GET/POST .../draft/operation enne uuesti proovimist.
  • 500storage_failedMustandi salvestamine või lugemine ebaõnnestus meie poolel - palun proovige uuesti.
  • 503engine_not_configuredvolai enda mootoril oleva agendi puhul: mootor ei ole meie poolel praegu seadistatud, avaldamist ei salvestatud. Palun võtke ühendust toega.
  • 502engine_unavailablevolai enda mootoril oleva agendi puhul: mootor ei vasta praegu, avaldamist ei salvestatud. Palun proovige varsti uuesti. Sama koodi tagastatakse kirjutamise puhul, mille mootori ooterežiimi sõlm tagasi lükkas (mootor töötab praegu ooterežiimi sõlmel, mis seadistust vastu ei võta): teade ütleb seda, avaldamist kindlasti ei salvestatud, ei mustand ega agent ei ole ebaselgena lukustatud ja avaldamist saab mõne minuti pärast korrata.
  • 502engine_readback_mismatchvolai enda mootoril oleva agendi puhul: mootor salvestas teistsuguse seadistuse kui see, mille me saatsime, avaldamist ei salvestatud. Proovige uuesti.
  • 409in_progressKas agendil töötab praegu mõni teine muudatus (elav PATCH või teine avaldamine) või eelmine muudatus läks läbi, kuid seda ei õnnestunud ohutult kinnitada - enne avaldamise kordamist lugege GET /v1/agents/{id}/draft/operation ja otsustage operation põhjal.

GET/v1/agents/{id}/draft/operation

Loeb blokeeriva toimingu praeguse oleku (null, kui midagi agenti ei blokeeri) - sama kuju nagu operation päringul GET .../draft.

Päring

bash
curl https://volai.cz/v1/agents/ag_kx91fa2b/draft/operation \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "operation": {
    "id": "ado_4f2a91cd",
    "kind": "publish",
    "status": "uncertain",
    "expectedRevision": 4,
    "createdAt": 1756118900000,
    "updatedAt": 1756118905000
  }
}

Veaolekud

  • 403forbiddenÜhine volai demoagent on ainult lugemiseks.
  • 404agent_not_foundAgenti ei ole olemas, see on kustutatud või ei kuulu teie kontole.
  • 500storage_failedMustandi salvestamine või lugemine ebaõnnestus meie poolel - palun proovige uuesti.

POST/v1/agents/{id}/draft/operation

Pärast elava agendi käsitsi kontrollimist sulgeb ohutult uncertain toimingu - te kinnitate, et vaatasite oleku üle, ning server kontrollib teenusepakkujat (tagasilugemine) ja sulgeb toimingu.

Päring

bash
curl -X POST https://volai.cz/v1/agents/ag_kx91fa2b/draft/operation \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"operationId":"ado_4f2a91cd","decision":"acknowledge_live_state"}'

Vastus

json
{
  "reconciled": true,
  "revision": 5
}

Veaolekud

  • 400validationoperationId puudub või decision ei ole "acknowledge_live_state".
  • 403forbiddenÜhine volai demoagent on ainult lugemiseks.
  • 404agent_not_foundAgenti ei ole olemas, see on kustutatud või ei kuulu teie kontole.
  • 409revision_conflictKeegi teine on mustandit vahepeal redigeerinud (või PATCH-iga mööda läinud). Viga kannab currentRevision-it - laadige praegune olek päringuga GET .../draft ja vaadake erinevus üle enne salvestamise kordamist.
  • 409operation_uncertainEelmise katse ebaselge toiming blokeerib seda agenti - kontrollige elavat agenti ja lahendage see päringuga GET/POST .../draft/operation enne uuesti proovimist.
  • 500storage_failedMustandi salvestamine või lugemine ebaõnnestus meie poolel - palun proovige uuesti.

POST/v1/agents/{id}/simulate

Saadab tekstisõnumi SALVESTATUD mustandile (mitte elavale agendile) ja seab märke tested. Tasuta (0 CZK, maksab volai), EI ole avaldamise nõue, piiratud 20-ga tunnis konto kohta, töötab fikseeritud Anthropicu mudelil (nime ei avaldata kunagi), ILMA tööriistadeta ja ILMA häälata (ASR/TTS) - see on prompti sõnastuse kontroll, mitte tegeliku kõne test.

messages (valikuline) on varasemad vestluse voorud ILMA praeguse sõnumita - { role: "user" | "assistant", content }. Piirangud: message 1 kuni 4000 märki, kuni 8 ajaloosõnumit, 2000 märki ajaloosõnumi kohta, ajalugu kokku 8000 märki.

Päring

bash
curl -X POST https://volai.cz/v1/agents/ag_kx91fa2b/simulate \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"expectedRevision":4,"message":"Dobry den"}'

Vastus

json
{
  "revision": 4,
  "text": "Tere, kohvik Nula, mida soovite?",
  "usage": {
    "inputTokens": 412,
    "outputTokens": 58
  },
  "tested": {
    "revision": 4,
    "testedAt": 1756118920000
  }
}

Veaolekud

  • 400validationVigase kujuga keha - vt konkreetse välja piiranguid.
  • 403forbiddenÜhine volai demoagent on ainult lugemiseks.
  • 404agent_not_foundAgenti ei ole olemas, see on kustutatud või ei kuulu teie kontole.
  • 409revision_conflictKeegi teine on mustandit vahepeal redigeerinud (või PATCH-iga mööda läinud). Viga kannab currentRevision-it - laadige praegune olek päringuga GET .../draft ja vaadake erinevus üle enne salvestamise kordamist.
  • 429rate_limitedOlete kasutanud ära 20 simulatsiooni tunnis konto kohta piirangu.
  • 502simulation_failedAnthropicu mudel tagastas vea või vigase vastuse - palun proovige uuesti.
  • 503simulation_not_configuredSimulatsioon ei ole meie poolel ajutiselt seadistatud - palun võtke ühendust toega.
  • 503simulation_unavailableSimulatsiooni kvooti ei õnnestunud kontrollida (ajutine Redise katkestus) - palun proovige uuesti.
  • 409publish_in_progressSimulatsioon ise õnnestus, kuid märke tested kirjutamine sattus käimasolevale mustandi avaldamisele - proovige varsti uuesti.
  • 409operation_uncertainSimulatsioon ise õnnestus, kuid märke tested kirjutamine sattus eelmise katse ebaselgele toimingule - lahendage see päringuga GET/POST .../draft/operation enne uuesti proovimist.
  • 500storage_failedSimulatsioon ise õnnestus, kuid märke tested kirjutamine ebaõnnestus meie poolel - palun proovige uuesti.

POST/v1/agents/{id}/draft/knowledge-import

Loeb agendi teadmised avalikult veebiaadressilt (url) või .txt/.md faili tekstist kuni 1 MB (text + filename) ja kirjutab need MUSTANDISSE (knowledge pluss loend knowledgeSources). Aadress peab olema avalik http/https (privaatsed ja sisemised aadressid, sh nendele suunamised, lükatakse tagasi), leht kuni 2 MB ja vastama 10 s jooksul, kuni 3 suunamisega. Kõik, mis ei mahu teadmiste välja vabasse ruumi (kokku 20 000 märki), võtab kokku Anthropicu mudel; kui see ei ole saadaval, lõigatakse tekst ausalt (method: truncated). preview: true ei kirjuta midagi. See ei muuda kunagi elavat agenti, avaldamine jääb selgesõnaliseks. Piiratud 10 impordiga tunnis konto kohta.

Päring

bash
curl -X POST https://volai.cz/v1/agents/ag_kx91fa2b/draft/knowledge-import \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/pricing","mode":"append","expectedRevision":4}'

Vastus

json
{
  "saved": true,
  "revision": 5,
  "mode": "append",
  "text": "### example.com/pricing\n\nHaircut 25 EUR\nColouring from 60 EUR\nOpen Mon-Fri 9:00-18:00",
  "chars": 85,
  "originalChars": 412,
  "method": "verbatim",
  "inputTrimmed": false,
  "title": "Pricing",
  "source": {
    "url": "https://example.com/pricing",
    "importedAt": 1793000000000,
    "chars": 85
  },
  "knowledgeChars": 85
}

Veaolekud

  • 400validationVigase kujuga keha - vt konkreetse välja piiranguid.
  • 400invalid_draftMustandi provider ei ühti agendi provider-iga - mustandit saab redigeerida ainult sama teenusepakkuja piires.
  • 400invalid_import_urlAadress ei ole kehtiv http/https aadress, sisaldab volitusandmeid või kasutab mittestandardset porti.
  • 400private_addressAadress (või suunamise sihtkoht) osutab sisevõrku, loopback'i või pilve metaandmetele.
  • 400invalid_knowledgeTeadmiste väljas on peaaegu ruumi järel (kokku 20 000 märki) - lühendage olemasolevat teksti või saatke mode: replace.
  • 403forbiddenÜhine volai demoagent on ainult lugemiseks.
  • 404agent_not_foundAgenti ei ole olemas, see on kustutatud või ei kuulu teie kontole.
  • 409revision_conflictKeegi teine on mustandit vahepeal redigeerinud (või PATCH-iga mööda läinud). Viga kannab currentRevision-it - laadige praegune olek päringuga GET .../draft ja vaadake erinevus üle enne salvestamise kordamist.
  • 409publish_in_progressSellel agendil töötab praegu mõni teine avaldamine või partiitöö - proovige varsti uuesti.
  • 409operation_uncertainEelmise katse ebaselge toiming blokeerib seda agenti - kontrollige elavat agenti ja lahendage see päringuga GET/POST .../draft/operation enne uuesti proovimist.
  • 413import_too_largeLeht on suurem kui 2 MB või fail on suurem kui 1 MB.
  • 415import_unsupported_typeAadress ei ole ei HTML ega tekstifail (PDF-i ei toetata veel) või fail ei lõpe laiendiga .txt/.md.
  • 422import_fetch_failedLehte ei õnnestunud lugeda: DNS, ühendus, mitte-2xx olek, 10 s ajalõpp või rohkem kui 3 suunamist.
  • 422import_emptyAllikas ei sisalda kasutatavat teksti.
  • 429rate_limitedKuni 10 importi tunnis konto kohta.
  • 500storage_failedMustandi salvestamine või lugemine ebaõnnestus meie poolel - palun proovige uuesti.

Hääled

Häälte kataloog väärtuse voiceId jaoks päringutel POST/PATCH /v1/agents. provider ütleb, kus agent töötab; useForOutboundTasks teeb algse valiku. Olemasoleval mootori agendil aktsepteerib PATCH kõiki kataloogihääli PEALE ElevenLabsi häälte (katty, vanem anet); katty ja töötlemata ElevenLabsi ID-d kehtivad ainult ElevenLabsis (anet jääb sinna ainult agentidele, kellel see juba on). POST-il on üks erand: selgesõnaline true asendab tuntud hääle, mis ei ole mootoril saadaval (sh katty), mootori vaikehäälega. Kui väljajätmine valib mootori juurutuse vaikeväärtuse kaudu, tagastab sama väärtus 400; töötlemata ElevenLabsi ID lükatakse mootori puhul alati tagasi. ?provider=engine tagastab mootori hääled ja ?provider=elevenlabs ElevenLabsi hääled. Tundmatu väärtus tagastab 400 validation ja loetleb kehtivad väärtused. Sama kataloog koos iga hääle kirjeldusega on lehel Häälagent.

GET/v1/voices

Agendi voiceId jaoks saadaolevate häälte kataloog.

Päring

bash
curl https://volai.cz/v1/voices \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "voices": [
    {
      "id": "milena",
      "name": "Milena",
      "gender": "female",
      "provider": "cartesia",
      "tone": "calm, warm",
      "description": "The default volai voice - calm and natural, a good fit for most agents.",
      "languages": [
        "cs"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/milena-studio.mp3",
        "phone": "https://volai.cz/hlasy/milena-telefon.mp3"
      },
      "default": true
    },
    {
      "id": "jan",
      "name": "Jan",
      "gender": "male",
      "provider": "cartesia",
      "tone": "calm, matter-of-fact",
      "description": "The male counterpart to Milena - matter-of-fact, easy-to-follow delivery.",
      "languages": [
        "cs"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/jan-studio.mp3",
        "phone": "https://volai.cz/hlasy/jan-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "tereza",
      "name": "Tereza",
      "gender": "female",
      "provider": "cartesia",
      "tone": "professional, structured",
      "description": "The second female voice - professional, well-structured delivery.",
      "languages": [
        "cs"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/tereza-studio.mp3",
        "phone": "https://volai.cz/hlasy/tereza-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "marek",
      "name": "Marek",
      "gender": "male",
      "provider": "cartesia",
      "tone": "calm, resonant",
      "description": "The second male voice - calm, resonant delivery for longer calls.",
      "languages": [
        "cs"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/marek-studio.mp3",
        "phone": "https://volai.cz/hlasy/marek-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "katarina",
      "name": "Katarina",
      "gender": "female",
      "provider": "cartesia",
      "tone": "calm, natural",
      "description": "Slovak female voice - calm, natural delivery.",
      "languages": [
        "sk"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/katarina-studio.mp3",
        "phone": "https://volai.cz/hlasy/katarina-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "peter",
      "name": "Peter",
      "gender": "male",
      "provider": "cartesia",
      "tone": "matter-of-fact, clear",
      "description": "Slovak male voice - matter-of-fact, easy-to-follow delivery.",
      "languages": [
        "sk"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/peter-studio.mp3",
        "phone": "https://volai.cz/hlasy/peter-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "skylar",
      "name": "Skylar",
      "gender": "female",
      "provider": "cartesia",
      "tone": "calm, friendly",
      "description": "English female voice - calm, friendly delivery.",
      "languages": [
        "en"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/skylar-studio.mp3",
        "phone": "https://volai.cz/hlasy/skylar-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "daniel",
      "name": "Daniel",
      "gender": "male",
      "provider": "cartesia",
      "tone": "matter-of-fact, confident",
      "description": "English male voice - matter-of-fact, confident delivery.",
      "languages": [
        "en"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/daniel-studio.mp3",
        "phone": "https://volai.cz/hlasy/daniel-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "alina",
      "name": "Alina",
      "gender": "female",
      "provider": "cartesia",
      "tone": "calm, warm",
      "description": "German female voice - calm, warm delivery.",
      "languages": [
        "de"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/alina-studio.mp3",
        "phone": "https://volai.cz/hlasy/alina-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "lukas",
      "name": "Lukas",
      "gender": "male",
      "provider": "cartesia",
      "tone": "matter-of-fact, clear",
      "description": "German male voice - matter-of-fact, easy-to-follow delivery.",
      "languages": [
        "de"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/lukas-studio.mp3",
        "phone": "https://volai.cz/hlasy/lukas-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "ewa",
      "name": "Ewa",
      "gender": "female",
      "provider": "cartesia",
      "tone": "calm, natural",
      "description": "Polish female voice - calm, natural delivery.",
      "languages": [
        "pl"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/ewa-studio.mp3",
        "phone": "https://volai.cz/hlasy/ewa-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "kacper",
      "name": "Kacper",
      "gender": "male",
      "provider": "cartesia",
      "tone": "matter-of-fact, confident",
      "description": "Polish male voice - matter-of-fact, confident delivery.",
      "languages": [
        "pl"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/kacper-studio.mp3",
        "phone": "https://volai.cz/hlasy/kacper-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "ariel",
      "name": "Ariel",
      "gender": "female",
      "provider": "elevenlabs",
      "tone": "natural, conversational",
      "description": "Dutch female voice - natural conversational delivery.",
      "languages": [
        "nl"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/ariel-studio.mp3",
        "phone": "https://volai.cz/hlasy/ariel-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "alexander",
      "name": "Alexander",
      "gender": "male",
      "provider": "elevenlabs",
      "tone": "warm, natural",
      "description": "Dutch male voice - warm, natural delivery.",
      "languages": [
        "nl"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/alexander-studio.mp3",
        "phone": "https://volai.cz/hlasy/alexander-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "christine",
      "name": "Christine",
      "gender": "female",
      "provider": "elevenlabs",
      "tone": "conversational, relaxed",
      "description": "Portuguese female voice - relaxed conversational delivery.",
      "languages": [
        "pt"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/christine-studio.mp3",
        "phone": "https://volai.cz/hlasy/christine-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "filipe",
      "name": "Filipe",
      "gender": "male",
      "provider": "elevenlabs",
      "tone": "natural, expressive",
      "description": "Portuguese male voice - natural, expressive delivery.",
      "languages": [
        "pt"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/filipe-studio.mp3",
        "phone": "https://volai.cz/hlasy/filipe-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "mikidutza",
      "name": "Mikidutza",
      "gender": "female",
      "provider": "elevenlabs",
      "tone": "clear, friendly",
      "description": "Romanian female voice - clear, friendly delivery.",
      "languages": [
        "ro"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/mikidutza-studio.mp3",
        "phone": "https://volai.cz/hlasy/mikidutza-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "oliver",
      "name": "Oliver",
      "gender": "male",
      "provider": "elevenlabs",
      "tone": "matter-of-fact, clear",
      "description": "Romanian male voice - matter-of-fact, clear delivery.",
      "languages": [
        "ro"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/oliver-studio.mp3",
        "phone": "https://volai.cz/hlasy/oliver-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "isabella",
      "name": "Isabella",
      "gender": "female",
      "provider": "elevenlabs",
      "tone": "warm, calm",
      "description": "Danish female voice - warm, calm delivery.",
      "languages": [
        "da"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/isabella-studio.mp3",
        "phone": "https://volai.cz/hlasy/isabella-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "soren",
      "name": "Søren",
      "gender": "male",
      "provider": "elevenlabs",
      "tone": "clear, confident",
      "description": "Danish male voice - clear, confident delivery.",
      "languages": [
        "da"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/soren-studio.mp3",
        "phone": "https://volai.cz/hlasy/soren-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "yoana",
      "name": "Yoana",
      "gender": "female",
      "provider": "elevenlabs",
      "tone": "fresh, engaging",
      "description": "Bulgarian female voice - fresh, engaging delivery.",
      "languages": [
        "bg"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/yoana-studio.mp3",
        "phone": "https://volai.cz/hlasy/yoana-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "peterk",
      "name": "Peter K",
      "gender": "male",
      "provider": "elevenlabs",
      "tone": "warm, smooth",
      "description": "Bulgarian male voice - warm, smooth delivery.",
      "languages": [
        "bg"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/peterk-studio.mp3",
        "phone": "https://volai.cz/hlasy/peterk-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "soili",
      "name": "Soili",
      "gender": "female",
      "provider": "elevenlabs",
      "tone": "neutral, light",
      "description": "Finnish female voice - neutral, light delivery.",
      "languages": [
        "fi"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/soili-studio.mp3",
        "phone": "https://volai.cz/hlasy/soili-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "jussi",
      "name": "Jussi",
      "gender": "male",
      "provider": "elevenlabs",
      "tone": "strong, lively",
      "description": "Finnish male voice - strong, lively delivery.",
      "languages": [
        "fi"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/jussi-studio.mp3",
        "phone": "https://volai.cz/hlasy/jussi-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "crhysa",
      "name": "Crhysa",
      "gender": "female",
      "provider": "elevenlabs",
      "tone": "professional, lively",
      "description": "Greek female voice - professional, lively delivery.",
      "languages": [
        "el"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/crhysa-studio.mp3",
        "phone": "https://volai.cz/hlasy/crhysa-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "iordanis",
      "name": "Iordanis",
      "gender": "male",
      "provider": "elevenlabs",
      "tone": "natural, conversational",
      "description": "Greek male voice - natural conversational delivery.",
      "languages": [
        "el"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/iordanis-studio.mp3",
        "phone": "https://volai.cz/hlasy/iordanis-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "natasha",
      "name": "Natasha",
      "gender": "female",
      "provider": "elevenlabs",
      "tone": "soft, conversational",
      "description": "French female voice - soft, conversational delivery.",
      "languages": [
        "fr"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/natasha-studio.mp3",
        "phone": "https://volai.cz/hlasy/natasha-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "max",
      "name": "Max",
      "gender": "male",
      "provider": "elevenlabs",
      "tone": "charismatic, friendly",
      "description": "French male voice - charismatic, friendly delivery.",
      "languages": [
        "fr"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/max-studio.mp3",
        "phone": "https://volai.cz/hlasy/max-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "rossana",
      "name": "Rossana",
      "gender": "female",
      "provider": "elevenlabs",
      "tone": "warm, conversational",
      "description": "Italian female voice - warm conversational delivery.",
      "languages": [
        "it"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/rossana-studio.mp3",
        "phone": "https://volai.cz/hlasy/rossana-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "marco",
      "name": "Marco",
      "gender": "male",
      "provider": "elevenlabs",
      "tone": "charismatic, friendly",
      "description": "Italian male voice - charismatic, friendly delivery.",
      "languages": [
        "it"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/marco-studio.mp3",
        "phone": "https://volai.cz/hlasy/marco-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "zsofia",
      "name": "Zsófia",
      "gender": "female",
      "provider": "elevenlabs",
      "tone": "soft, inviting",
      "description": "Hungarian female voice - soft, inviting delivery.",
      "languages": [
        "hu"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/zsofia-studio.mp3",
        "phone": "https://volai.cz/hlasy/zsofia-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "gabor",
      "name": "Gábor",
      "gender": "male",
      "provider": "elevenlabs",
      "tone": "warm, confident",
      "description": "Hungarian male voice - warm, natural, confident delivery.",
      "languages": [
        "hu"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/gabor-studio.mp3",
        "phone": "https://volai.cz/hlasy/gabor-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "sanna",
      "name": "Sanna",
      "gender": "female",
      "provider": "elevenlabs",
      "tone": "direct, natural",
      "description": "Swedish female voice - direct, natural delivery.",
      "languages": [
        "sv"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/sanna-studio.mp3",
        "phone": "https://volai.cz/hlasy/sanna-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "filip",
      "name": "Filip",
      "gender": "male",
      "provider": "elevenlabs",
      "tone": "energetic, expressive",
      "description": "Swedish male voice - energetic, expressive delivery.",
      "languages": [
        "sv"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/filip-studio.mp3",
        "phone": "https://volai.cz/hlasy/filip-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "sarah-sl",
      "name": "Sarah",
      "gender": "female",
      "provider": "elevenlabs",
      "tone": "calm, confident",
      "description": "Slovenian female voice - calm, confident delivery (multilingual voice, the model drives the pronunciation).",
      "languages": [
        "sl"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/sarah-sl-studio.mp3",
        "phone": "https://volai.cz/hlasy/sarah-sl-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "daniel-sl",
      "name": "Daniel",
      "gender": "male",
      "provider": "elevenlabs",
      "tone": "steady, clear",
      "description": "Slovenian male voice - steady, broadcaster-style delivery (multilingual voice, the model drives the pronunciation).",
      "languages": [
        "sl"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/daniel-sl-studio.mp3",
        "phone": "https://volai.cz/hlasy/daniel-sl-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "alice-et",
      "name": "Alice",
      "gender": "female",
      "provider": "elevenlabs",
      "tone": "clear, engaging",
      "description": "Estonian female voice - clear, engaging delivery (multilingual voice, the model drives the pronunciation).",
      "languages": [
        "et"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/alice-et-studio.mp3",
        "phone": "https://volai.cz/hlasy/alice-et-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "chris-et",
      "name": "Chris",
      "gender": "male",
      "provider": "elevenlabs",
      "tone": "down-to-earth, charming",
      "description": "Estonian male voice - down-to-earth, charming delivery (multilingual voice, the model drives the pronunciation).",
      "languages": [
        "et"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/chris-et-studio.mp3",
        "phone": "https://volai.cz/hlasy/chris-et-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "matilda-lv",
      "name": "Matilda",
      "gender": "female",
      "provider": "elevenlabs",
      "tone": "professional, matter-of-fact",
      "description": "Latvian female voice - knowledgeable, professional delivery (multilingual voice, the model drives the pronunciation).",
      "languages": [
        "lv"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/matilda-lv-studio.mp3",
        "phone": "https://volai.cz/hlasy/matilda-lv-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "george-lv",
      "name": "George",
      "gender": "male",
      "provider": "elevenlabs",
      "tone": "warm, captivating",
      "description": "Latvian male voice - warm, captivating delivery (multilingual voice, the model drives the pronunciation).",
      "languages": [
        "lv"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/george-lv-studio.mp3",
        "phone": "https://volai.cz/hlasy/george-lv-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "sarah-lt",
      "name": "Sarah",
      "gender": "female",
      "provider": "elevenlabs",
      "tone": "calm, confident",
      "description": "Lithuanian female voice - calm, confident delivery (multilingual voice, the model drives the pronunciation).",
      "languages": [
        "lt"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/sarah-lt-studio.mp3",
        "phone": "https://volai.cz/hlasy/sarah-lt-telefon.mp3"
      },
      "default": false
    },
    {
      "id": "daniel-lt",
      "name": "Daniel",
      "gender": "male",
      "provider": "elevenlabs",
      "tone": "steady, clear",
      "description": "Lithuanian male voice - steady, broadcaster-style delivery (multilingual voice, the model drives the pronunciation).",
      "languages": [
        "lt"
      ],
      "preview": {
        "studio": "https://volai.cz/hlasy/daniel-lt-studio.mp3",
        "phone": "https://volai.cz/hlasy/daniel-lt-telefon.mp3"
      },
      "default": false
    }
  ]
}

Veaolekud

  • 400validationprovider ei ole üks järgmistest: elevenlabs, engine.

Väli tone kirjeldab hääle olemust (rahulik, asjalik); languages sisaldab keelekoode, milles hääl räägib - cs: Milena, Jan, Tereza, Marek; sk: Katarina, Peter; en: Skylar, Daniel; de: Alina, Lukas; pl: Ewa, Kacper; nl: Ariel, Alexander; pt: Christine, Filipe; sl: Sarah, Daniel; ro: Mikidutza, Oliver; da: Isabella, Søren; et: Alice, Chris; lv: Matilda, George; bg: Yoana, Peter K; fi: Soili, Jussi; el: Crhysa, Iordanis; fr: Natasha, Max; it: Rossana, Marco; hu: Zsófia, Gábor; lt: Sarah, Daniel; sv: Sanna, Filip; preview annab stuudio- ja telefoni-eelkuulamise näidiste URL-id; default märgib kataloogi soovitatud kirje - portaalis kannab see kaardil ainult märget „Vaikimisi” ega vali ise midagi ette. Uus agent, mis on loodud ilma voiceId-ta, selle peale ei lülitu - see pärib oma teenusepakkuja vaikehääle (Milena mootoril, malli hääl ElevenLabsis; vt ülal jaotist Agendid).

Agendi tööriistad

Tööriist on teie API aadress, mida agent kõne keskel kutsub (kontrollida tellimust, logida broneeringut) ja kasutab vastust kõnes. Tööriist kuulub kontole ja määratakse agendile väljaga toolIds - tööriista loomine üksi ei muuda ühtegi agenti.

Piirangud: kuni 10 tööriista konto kohta, 10 parameetrit ja 5 päist tööriista kohta, timeoutSecs 5 kuni 30 (vaikimisi 20). Aadress peab olema https ja avalik - me lükkame tagasi sisevõrgud ja loopback'i (private_address), sest muidu võiks meie serverit kasutada kellegi teise taristu sondeerimiseks.

Kinnitusvärav (requireConfirmation, vaikimisi false): tööriista puhul, mis midagi saadab või loob (SMS, päring), saatke päringus POST /v1/tools või PATCH /v1/tools/{id} requireConfirmation: true. volai häälmootor käivitab siis tööriista ainult siis, kui helistaja viimane vastus ütleb selgelt jah; muidu tööriista ei käivitata, agendile öeldakse, et ta küsiks uuesti, ja katse kõne samas voorus lõpetada peetakse kinni. See kehtib ainult volai mootoril oleva agendi puhul, mille keel on cs või sk (mootor tunneb nõusolekusõnu ainult tšehhi ja slovaki keeles; keelte en, de ja pl puhul blokeeriks see isegi selge „Jah”); iga teise agendi puhul ignoreeritakse välja, kuid tööriista salvestamisest ei keelduta kunagi keele tõttu, sest tööriista jagavad mitu agenti. ElevenLabs välja ei kasuta. Värav loeb ainult helistaja viimast vastust ega tea agendi küsimust: see püüab kinni ebaselge nõusoleku („Halloo?”, „Jah?”, „Jah, aga hiljem”), mitte iga „Jah”, mis öeldi teisele küsimusele. Muudatus ei jõustu kohe mootoril juba töötava agendi puhul: tööriist kirjutatakse seal ümber alles siis, kui see agent järgmine kord salvestatakse või avaldatakse (POST /v1/agents/{id}/draft/publish, Avalda portaalis või PATCH /v1/agents/{id}) - tööriista muutmine ei kirjuta agente kunagi ise ümber. Töötava kampaania puhul loeb viis: testitud mustandi uuesti avaldamine muutmata kujul säilitab testitud märke, seega ülesanne jätkab tööd, nüüd väravaga, mida test ei katnud; otsene PATCH /v1/agents/{id} kustutab testitud märke ja peatab ülesande veaga agent_version_changed. Planeerige värava sisselülitamine väljaspool töötavat kampaaniat ja testige kampaaniat pärast uuesti.

GET/v1/tools

Konto webhooki tööriistad. Päiste väärtused on alati maskeeritud.

Päring

bash
curl https://volai.cz/v1/tools \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "tools": [
    {
      "id": "tl_5c2a91f4",
      "name": "verify_order",
      "label": "Kontrolli tellimust",
      "description": "Otsib tellimuse olekut numbri järgi. Kasutage siis, kui helistaja küsib, kus tema tellimus on.",
      "url": "https://api.yourapp.com/orders",
      "method": "POST",
      "headers": { "Authorization": "Bear***" },
      "params": [
        {
          "name": "order_number",
          "type": "string",
          "source": "llm",
          "description": "Tellimuse number, mille helistaja dikteeris.",
          "required": true
        },
        { "name": "phone", "type": "string", "source": "caller_number" },
        { "name": "source", "type": "string", "source": "constant", "constantValue": "phone" }
      ],
      "timeoutSecs": 20,
      "requireConfirmation": false,
      "createdAt": 1756111000000,
      "updatedAt": 1756111000000
    }
  ]
}

POST/v1/tools

Loob tööriista. label on loetav nimi; mudelile nähtav nimi tuletatakse sellest automaatselt (Verify order -> verify_order) ja tagastatakse väljal name. description on ainus, mille põhjal mudel otsustab, MILLAL tööriista kasutada - kirjutage see juhisena ("Kasutage, kui helistaja küsib, kus tema tellimus on."), 10 kuni 1000 märki.

Päring

bash
curl -X POST https://volai.cz/v1/tools \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "Kontrolli tellimust",
    "description": "Otsib tellimuse olekut numbri järgi. Kasutage siis, kui helistaja küsib, kus tema tellimus on.",
    "url": "https://api.yourapp.com/orders",
    "method": "POST",
    "headers": { "Authorization": "Bearer your_key" },
    "params": [
      {
        "name": "order_number",
        "type": "string",
        "source": "llm",
        "description": "Tellimuse number, mille helistaja dikteeris.",
        "required": true
      },
      { "name": "phone", "type": "string", "source": "caller_number" },
      { "name": "source", "type": "string", "source": "constant", "constantValue": "phone" }
    ],
    "timeoutSecs": 20
  }'

Vastus

json
{
  "tool": {
    "id": "tl_5c2a91f4",
    "name": "verify_order",
    "label": "Kontrolli tellimust",
    "description": "Otsib tellimuse olekut numbri järgi. Kasutage siis, kui helistaja küsib, kus tema tellimus on.",
    "url": "https://api.yourapp.com/orders",
    "method": "POST",
    "headers": { "Authorization": "Bear***" },
    "params": [
      {
        "name": "order_number",
        "type": "string",
        "source": "llm",
        "description": "Tellimuse number, mille helistaja dikteeris.",
        "required": true
      },
      { "name": "phone", "type": "string", "source": "caller_number" },
      { "name": "source", "type": "string", "source": "constant", "constantValue": "phone" }
    ],
    "timeoutSecs": 20,
    "requireConfirmation": false,
    "createdAt": 1756111000000,
    "updatedAt": 1756111000000
  }
}

Veaolekud

  • 400tool_limitKontol on juba 10 tööriista.
  • 400invalid_tool_namelabel peab olema 1 kuni 60 märki või sellest tuletatud nimi oleks reserveeritud (end_call, transfer_to_human, switch_to_*).
  • 400invalid_tool_urlurl ei ole kehtiv aadress või ei ole https.
  • 400private_addressurl osutab sisevõrku või loopback'i.
  • 400invalid_tool_paramsParameetril on vigane nimi, tüüp, allikas või neid on rohkem kui 10.
  • 400invalid_tool_headersPäis on keelatud (host, content-length, x-conversation-id, x-caller-id), dubleeritud, tühi või neid on rohkem kui 5.
  • 400validationdescription on väljaspool 10 kuni 1000 märki, timeoutSecs on väljaspool 5 kuni 30, requireConfirmation ei ole tõeväärtus või method on midagi muud kui GET/POST.
  • 502eleven_labs_errorTööriista ei õnnestunud häälplatvormiga luua - me ei salvestanud lokaalselt midagi, palun proovige uuesti.

GET/v1/tools/{id}

Ühe tööriista detail - samad väljad nagu loendis, pluss agents: agendid, kellel see on väljaga toolIds sisse lülitatud (ainult id ja name; täieliku agendi saate päringuga GET /v1/agents/{id}).

Päring

bash
curl https://volai.cz/v1/tools/tl_5c2a91f4 \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "tool": {
    "id": "tl_5c2a91f4",
    "name": "verify_order",
    "label": "Kontrolli tellimust",
    "description": "Otsib tellimuse olekut numbri järgi. Kasutage siis, kui helistaja küsib, kus tema tellimus on.",
    "url": "https://api.yourapp.com/orders",
    "method": "POST",
    "headers": { "Authorization": "Bear***" },
    "params": [
      {
        "name": "order_number",
        "type": "string",
        "source": "llm",
        "description": "Tellimuse number, mille helistaja dikteeris.",
        "required": true
      },
      { "name": "phone", "type": "string", "source": "caller_number" },
      { "name": "source", "type": "string", "source": "constant", "constantValue": "phone" }
    ],
    "timeoutSecs": 20,
    "requireConfirmation": false,
    "createdAt": 1756111000000,
    "updatedAt": 1756111000000,
    "agents": [{ "id": "ag_kx91fa2b", "name": "Vastuvõtt" }]
  }
}

Veaolekud

  • 404tool_not_foundTööriista ei ole olemas või see ei kuulu teie kontole.

PATCH/v1/tools/{id}

Uuendab tööriista - kõik väljad valikulised, muudetakse ainult saadetud. Kaks asja, mida jälgida: params ja headers asendavad mõlemad kogu olemasoleva loendi ja label muutmine kirjutab ümber ka nime, mille all mudel tööriista tunneb - kui viitate sellele systemPrompt-is, uuendage seda samal ajal.

Päised tulevad alati tagasi ainult maskeeritult ("Bear***"). Kui saadate selle täpse maskeeritud väärtuse tagasi, käsitleme seda kui "säilita originaal" - nii et tavaline voog "laadi tööriist, muuda üht välja, saada kogu objekt tagasi" ei hävita teie volitusandmeid. Saatke tegelik väärtus täies mahus, et seda tõesti muuta.

Päring

bash
curl -X PATCH https://volai.cz/v1/tools/tl_5c2a91f4 \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"timeoutSecs": 10}'

Vastus

json
{
  "tool": {
    "id": "tl_5c2a91f4",
    "name": "verify_order",
    "label": "Kontrolli tellimust",
    "description": "Otsib tellimuse olekut numbri järgi. Kasutage siis, kui helistaja küsib, kus tema tellimus on.",
    "url": "https://api.yourapp.com/orders",
    "method": "POST",
    "headers": { "Authorization": "Bear***" },
    "params": [
      {
        "name": "order_number",
        "type": "string",
        "source": "llm",
        "description": "Tellimuse number, mille helistaja dikteeris.",
        "required": true
      },
      { "name": "phone", "type": "string", "source": "caller_number" },
      { "name": "source", "type": "string", "source": "constant", "constantValue": "phone" }
    ],
    "timeoutSecs": 10,
    "requireConfirmation": false,
    "createdAt": 1756111000000,
    "updatedAt": 1756111890000
  }
}

Veaolekud

  • 400invalid_tool_urlurl ei ole kehtiv aadress või ei ole https.
  • 400private_addressurl osutab sisevõrku või loopback'i.
  • 400invalid_tool_paramsParameetril on vigane nimi, tüüp või allikas.
  • 400invalid_tool_headersPäis on keelatud, dubleeritud või tühi.
  • 400validationdescription (kui saadetud) on väljaspool 10 kuni 1000 märki, timeoutSecs on väljaspool 5 kuni 30, requireConfirmation ei ole tõeväärtus või method on midagi muud kui GET/POST.
  • 404tool_not_foundTööriista ei ole olemas või see ei kuulu teie kontole.
  • 502eleven_labs_mismatchMuudatust ei salvestatud häälplatvormis täpselt nii, nagu määratud - me ei kirjutanud lokaalselt midagi üle.

DELETE/v1/tools/{id}

Kustutab tööriista ja tagastab agendid, mille jaoks see lakkab töötamast (ainult id ja name; täieliku agendi saate päringuga GET /v1/agents/{id}). Erinevalt numbri vabastamisest on see taastatav kaotus - sama tööriista saab uuesti luua, lihtsalt uue id-ga, mis tuleb seejärel agentidele uuesti määrata.

Päring

bash
curl -X DELETE https://volai.cz/v1/tools/tl_5c2a91f4 \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "deleted": true,
  "agents": [
    { "id": "ag_kx91fa2b", "name": "Vastuvõtt" }
  ]
}

Veaolekud

  • 404tool_not_foundTööriista ei ole olemas või see ei kuulu teie kontole.
  • 502eleven_labs_errorTööriista ei õnnestunud häälplatvormist kustutada - palun proovige uuesti.

POST/v1/tools/test

Saadab TÕELISE päringu teie saadetud definitsiooni järgi ja tagastab, mis tuli tagasi - tööriista EI salvestata (erinevalt POST /v1/tools-ist on label/description siin valikulised). Mugav aadressi proovimiseks enne agendi tööriistana salvestamist. timeoutSecs valideeritakse siin ainult (5 kuni 30) - test ootab alati kindlad 10 sekundit, et te ei peaks ootama täielikku töö ajalõppu; see on väärtus, mida tööriist salvestamisel töö ajal kasutaks. Jagab päringupiirangut allolevaga POST /v1/tools/{id}/test - 10 katset minutis konto kohta kokku.

Päring

bash
curl -X POST https://volai.cz/v1/tools/test \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://api.yourapp.com/orders", "method": "GET", "params": [{"name": "order", "type": "string", "source": "llm", "description": "Order number."}]}'

Vastus

json
{
  "status": 200,
  "durationMs": 214,
  "body": "{\"status\":\"shipped\"}",
  "note": null
}

Veaolekud

  • 400validationmethod on midagi muud kui GET/POST või timeoutSecs on väljaspool 5 kuni 30.
  • 400invalid_tool_urlurl ei ole kehtiv aadress või päringu saatmisel tekkis võrgu-/DNS-/TLS-viga (kõikjal selles faasis - sh ajalõpp - variseb kokku samaks koodiks).
  • 400private_addressurl osutab sisevõrku või loopback'i (SSRF-kaitse) - kontrollitakse ENNE saatmist.
  • 400invalid_tool_paramsParameetril on vigane nimi, tüüp, allikas või neid on rohkem kui 10.
  • 400invalid_tool_headersPäis on keelatud, dubleeritud, tühi või neid on rohkem kui 5.
  • 429rate_limitedOlete kasutanud ära 10 katset minutis (jagatud päringuga POST /v1/tools/{id}/test) - proovige hetke pärast uuesti.

POST/v1/tools/{id}/test

Testib JUBA SALVESTATUD tööriista id järgi - keha on alati tühi {}, lõpp-punkt võtab aadressi, meetodi ja TÕELISED (maskeerimata) päised salvestatud kirjest, mitte päringu kehast. private_address/invalid_tool_params/invalid_tool_headers ei saa siin tagasi tulla (salvestatud kirje ei läbi sisendi valideerimist uuesti) - võrguviga variseb endiselt kokku koodiks invalid_tool_url.

Päring

bash
curl -X POST https://volai.cz/v1/tools/tl_5c2a91f4/test \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Vastus

json
{
  "status": 200,
  "durationMs": 214,
  "body": "{\"status\":\"shipped\"}",
  "note": null
}

Veaolekud

  • 400validationPäringu keha ei ole tühi - saatke {} või üldse mitte keha.
  • 400invalid_tool_urlVõrgu-/DNS-/TLS-viga (sh ajalõpp) tõelise päringu saatmisel.
  • 404tool_not_foundTööriista ei ole olemas või see ei kuulu teie kontole.

Tööriista parameetrid: väli source

Igal parameetril on name, type (string, number, boolean) ja source - kust selle väärtus tuleb. GET puhul lähevad parameetrid päringustringi, POST puhul JSON-kehasse.

sourceKust väärtus tulebMida veel täita
llmMudel võtab selle kõnest.description (täpselt, mida sinna panna) ja valikuliselt required.
caller_numberHelistaja number kujul E.164, täidetakse automaatselt.Mitte midagi. Mudel ei näe seda välja kunagi.
called_numberTeie valitud number kujul E.164, täidetakse automaatselt.Mitte midagi. Mudel ei näe seda välja kunagi.
constantFikseeritud väärtus, mille te annate.constantValue.

Testkõne

"Laske oma agendil endale helistada" - tegelik väljaminev kõne läbi makeAgentCall, lihtsalt oma päevalimiidiga 3 kõnet konto kohta (kõigi agentide peale kokku), nii et testkõnet ei saa kasutada tavalisest helistamispiirangust möödaminemiseks.

POST/v1/agents/{id}/test-call

Helistab teile tagasi teie enda agendilt - sama hind ja samad reeglid nagu päringul POST /v1/calls, ilma allahindluseta ja ilma erihinnata. volai enda häälmootoril olev agent helistab ka ILMA määratud numbrita - ühiselt volai liinilt, seega näeb adressaat volai numbrit, mitte teie oma. Määrake olemasolevale agendile oma number päringuga PATCH /v1/numbers/{e164} (marsruutimine agent) või agendi väljaga numberE164 (POST/PATCH /v1/agents) või portaali jaotises Numbrid. Vastus kannab testCalls - max, remaining ja resetAt (millal lõpeb 24-tunnine aken, mis algas esimese katsega, epoch ms) - ja GET /v1/account tagastab sama välja, nii et saate enne helistamist kontrollida, mis on järel. Iga valitud katse loeb, sh vastamata katse, mille eest ei arveldata.

Päring

bash
curl -X POST https://volai.cz/v1/agents/ag_kx91fa2b/test-call \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to": "+420777123456"}'

Vastus

json
{
  "id": "c_9d4e2b7f",
  "status": "initiated",
  "testCalls": { "max": 3, "remaining": 2, "resetAt": 1755086400000 }
}

Veaolekud

  • 400validationto puudub või on üle 32 märgi või keha ei ole kehtiv JSON.
  • 400destination_not_allowedAgent kasutab number kõnede ja SMS-ide jaoks-i ja to ei ole Tšehhi number (+420): number kõnede ja SMS-ide jaoks saab helistada ainult Tšehhi numbritele. Edastage Tšehhi to. Midagi ei arveldata.
  • 404agent_not_foundagentId ei ole olemas või ei kuulu teie kontole.
  • 404agent_no_numberAgendile ei ole telefoninumbrit määratud - see viga tagastatakse ainult ElevenLabsi agendi puhul; volai enda mootoril olev agent helistab ka ilma numbrita, ühiselt volai liinilt.
  • 403agent_suspendedvolai operaator on selle agendi käsitsi peatanud - testkõnet ei saa praegu teha. Peatatud konto tagastab selle asemel account_suspended.
  • 402insufficient_creditTeie saldo ei kata kõne alustamiseks vajalikku miinimumi.
  • 402subscription_cap_reachedKontol on kulutuste ülempiiriga kuupakett, kuusaldo on ära kasutatud ja täiendatud saldo ei kata toimingut. See asendab sellise konto puhul vea insufficient_credit (sama HTTP-olek). Midagi ei arveldatud.
  • 402spend_cap_reachedTeie seatud kuine kulutuste ülempiir on saavutatud. Midagi ei tehtud ega saadetud ning midagi ei arvestatud. Tõstke või eemaldage ülempiir päringuga PUT või DELETE /v1/account/spend-cap või oodake järgmist kalendrikuud.
  • 503capacity_busyKõik väljaminevad liinid on praegu hõivatud, proovige minuti pärast uuesti. Number kõnede ja SMS-ide jaoks saab korraga teha ainult ühte väljaminevat kõnet.
  • 429rate_limitedPäevalimiit 3 testkõnet konto kohta on ammendatud - tavalisel kõnel päringu POST /v1/calls kaudu seda piirangut ei ole.

Relay - tooge oma agent

SIP-nime ühekordne rent relay-varust väljamineva kõne jaoks teie enda häälagendilt (ElevenLabs või mis tahes muu platvorm) - ilma agendi lisatasuta (see on tavaliselt 2.50 CZK/min (~EUR 0.10), kuid siin maksate selle eest oma platvormil). Täielik seadistusjuhend ElevenLabsi jaoks on lehel Tooge oma agent.

POST/v1/relay

Loob rendi - to on sihtnumber, from on teie enda volai number, millelt kõne peaks paistma tulevat. Tagastatud sipName on ElevenLabsi to_number PALJAS nimi (mitte sipUri - ElevenLabs lükkab täieliku SIP URI tagasi). Seadke oma platvormi väljaminev trunk väärtusele outboundTrunkAddress päringust GET /v1/numbers/{e164}/sip - teistsugune aadress tähendab, et kõnet võrgus ei marsruudita ja platvorm teatab ajalõpust.

ttlSecs (valikuline, vaikimisi 120) - mitu sekundit rent ootab esimest kõnet, enne kui kasutamata rent aegub. Lubatud vahemik on 15 kuni 300 sekundit - sellest väljas tagastab see 400 validation.

Päring

bash
curl -X POST https://volai.cz/v1/relay \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to": "+420777123456", "from": "+420601234567"}'

Vastus

json
{
  "id": "rl_4f2a91cd",
  "sipName": "volai_relay_2",
  "sipUri": "sip:volai_relay_2@sip.volai.cz",
  "expiresAt": 1756111760000,
  "callId": "c_9d4e2b7f"
}

Veaolekud

  • 400invalid_numberto või from ei ole kehtiv telefoninumber.
  • 400validationttlSecs on väljaspool lubatud vahemikku 15 kuni 300 sekundit.
  • 404from_number_not_ownedfrom ei kuulu teie kontole.
  • 400unsupported_for_number_typefrom on teie enda number kõnede ja SMS-ide jaoks ja sellelt võib helistada ainult volai agent sisseehitatud häälmootoril, seega relay kolmanda osapoole agendi kaudu ei ole sellelt saadaval. Kasutage relay jaoks häälnumbrit. Midagi ei arveldata.
  • 400on_dncto on teie helistamiskeeluloendis.
  • 400relay_lease_limitTeil on sellel numbril juba aktiivne rent või kogu kontol kaks.
  • 402insufficient_creditTeie saldo ei kata kõne alustamiseks vajalikku miinimumi.
  • 402subscription_cap_reachedKontol on kulutuste ülempiiriga kuupakett, kuusaldo on ära kasutatud ja täiendatud saldo ei kata toimingut. See asendab sellise konto puhul vea insufficient_credit (sama HTTP-olek). Midagi ei arveldatud.
  • 402spend_cap_reachedTeie seatud kuine kulutuste ülempiir on saavutatud. Midagi ei tehtud ega saadetud ning midagi ei arvestatud. Tõstke või eemaldage ülempiir päringuga PUT või DELETE /v1/account/spend-cap või oodake järgmist kalendrikuud.
  • 409destination_busySellele numbrile käib juba mõni teine kõne.
  • 503capacity_busyRelay-varu on praegu täis, proovige varsti uuesti - selle eest me teilt tasu ei võta.

GET/v1/relay

Teie relay-rentide loend - pending ootab oma esimest kõnet, active tähendab, et kõne käib praegu.

Päring

bash
curl https://volai.cz/v1/relay \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "leases": [
    {
      "id": "rl_4f2a91cd",
      "sipName": "volai_relay_2",
      "sipUri": "sip:volai_relay_2@sip.volai.cz",
      "from": "+420601234567",
      "to": "+420777123456",
      "callId": "c_9d4e2b7f",
      "status": "active",
      "createdAt": 1756111640000,
      "expiresAt": 1756111760000
    }
  ]
}

DELETE/v1/relay/{id}

Vabastab rendi ja tagastab pesa varusse, kui see ootab veel oma esimest kõnet (pending). See ei lõpeta käimasolevat kõnet - ükski API ei suuda seda täna (ei telefonivõrk ega ElevenLabs) - selline rent (active) lihtsalt kulgeb oma tsükli; see ainult takistab sama rendi uuesti kasutamist.

Päring

bash
curl -X DELETE https://volai.cz/v1/relay/rl_4f2a91cd \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "cancelled": true
}

Veaolekud

  • 404lease_not_foundRent ei ole olemas, on aegunud või ei kuulu teie kontole.
  • 409lease_already_activeRendil käib juba kõne - sellist rendi ei saa tühistada (see kulgeb oma tsükli ise). Kehtib ainult päringule DELETE /v1/relay/{id}, mitte uue rendi loomisele.

Helistamiskeeluloend (DNC)

Numbrid, millele teie agent (teie enda või sisseehitatud) ei tohi helistada - olgu see päringu POST /v1/calls, testkõne või relay kaudu. DNC kehtib ainult kõnedele - SMS-i saatmist loendis olevale numbrile ei piirata.

Lisaks käsitsi loendile blokeerib volai sihtkoha automaatselt (ja ajutiselt) ise - pärast 3 ebaõnnestunud katset 24 tunni jooksul (kinni, vastamata, tagasi lükatud) lõpetab see sellele numbrile helistamise 30 päevaks. Blokeeringu saab tühistada portaalis (Seaded) või päringuga POST /v1/dnc/{e164}/unblock - muidu aegub see ise.

GET/v1/dnc

Käsitsi loend (numbers) pluss automaatselt blokeeritud sihtkohad (blocked) - blockedAt ja expiresAt on Unix-millisekundid. Automaatne blokeering, mis algas enne versiooni 1.8.0, võib blocked-ist puududa; kui kõne tagastab destination_auto_blocked, kutsuge blokeeringu tühistamise lõpp-punkti otse selle numbriga isegi ilma reata loendis.

Päring

bash
curl https://volai.cz/v1/dnc \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "numbers": ["+420777998877"],
  "blocked": [
    {
      "e164": "+420777123456",
      "blockedAt": 1757600000000,
      "expiresAt": 1760192000000
    }
  ]
}

POST/v1/dnc

Lisab numbrid helistamiskeeluloendisse. Saatke täpselt üks väljadest e164 (üks number) ja e164s (1 kuni 500 numbri loend). Vastus väljale e164 on { "added": true, "e164": "..." } ja on muutmata. Vastus väljale e164s kannab addedCount (numbrid, mida loendis ei olnud ja mis nüüd on), alreadyOnListCount (kehtivad kirjed, mis midagi ei muutnud, sest number oli juba loendis, sh samas päringus korduv number), rejectedCount ja rejected (kirjed, mis ei ole kehtiv telefoninumber, igaüks oma index-iga loendis, input nagu saadetud ja reason: "invalid_number"). Kolm arvu liidetuna annavad saadetud kirjete arvu. Tagasi lükatud kirje ei lase päringul ebaõnnestuda: kehtivad kirjed lisatakse alati, seega 500 kontakti import ei peatu ühe vigase numbri juures. Päring on idempotentne: sama loendi uuesti saatmine ei lisa midagi ja tagastab addedCount: 0.

Päring

bash
curl -X POST https://volai.cz/v1/dnc \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"e164": "+420777998877"}'

Vastus

json
{
  "added": true,
  "e164": "+420777998877"
}

Veaolekud

  • 400validationSaadeti ei e164 ega e164s, saadeti mõlemad, e164 ei ole kehtiv telefoninumber, e164s on tühi või sisaldab üle 500 kirje või kirje ei ole string või on pikem kui 256 märki.

Paljude numbrite import korraga

Saatke e164 asemel e164s, et lisada ühes päringus kuni 500 numbrit. API lubab 60 päringut minutis võtme kohta kõigi kõnede peale kokku, seega 5000 numbrit võtavad 10 päringut 5000 asemel. Kirjed, mis ei ole kehtivad telefoninumbrid (sh pikem tekst, nagu kaks numbrit ühes lahtris), tulevad tagasi väljal rejected sisendiga, mis on lõigatud 32 märgini; kehtivad lisatakse ikkagi. Üksi 200-vastus ei tähenda, et midagi lisati: kontrollige rejectedCount-i. alreadyOnListCount teeb kõne ajalõpu järel kordamise ohutuks. Numbreid eemaldatakse ühekaupa päringuga DELETE /v1/dnc/{e164}.

bash
curl -X POST https://volai.cz/v1/dnc \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"e164s": ["+420777998877", "00420777998878", "+420777998879", "777 99"]}'
json
{
  "addedCount": 2,
  "alreadyOnListCount": 1,
  "rejectedCount": 1,
  "rejected": [
    { "index": 3, "input": "777 99", "reason": "invalid_number" }
  ]
}

DELETE/v1/dnc/{e164}

Eemaldab numbri helistamiskeeluloendist.

Päring

bash
curl -X DELETE "https://volai.cz/v1/dnc/+420777998877" \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "removed": true,
  "e164": "+420777998877"
}

Veaolekud

  • 400validatione164 URL-is ei ole kehtiv telefoninumber.

POST/v1/dnc/{e164}/unblock

Tühistab sihtkoha automaatse blokeeringu, kui see on olemas, sh enne versiooni 1.8.0 tehtud blokeeringu, mida blocked loendis ei ole. unblocked tuleb tagasi false, mitte 404, kui seda ei olnud.

Päring

bash
curl -X POST "https://volai.cz/v1/dnc/+420777998877/unblock" \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "unblocked": true,
  "e164": "+420777998877"
}

Veaolekud

  • 400validatione164 URL-is ei ole kehtiv telefoninumber.

Webhook

GET/v1/webhook

Praegused väljamineva webhooki seaded - ilma allkirjastamise saladuseta, mis tuleb tagasi ainult päringust PUT.

Päring

bash
curl https://volai.cz/v1/webhook \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "url": "https://tvoje-appka.cz/webhooks/volai",
  "events": ["call.completed", "call.failed", "message.sent"],
  "headers": { "Authorization": "Bear***" },
  "recentDeliveries": [
    {
      "id": "whd_9f2b7a1c4e",
      "event": "call.completed",
      "url": "https://tvoje-appka.cz/webhooks/volai",
      "status": 200,
      "attempts": 1,
      "ok": true,
      "durationMs": 184,
      "createdAt": 1756111641000
    }
  ]
}

PUT/v1/webhook

Seab (või asendab) sihtkoha URL-i ja sündmused, mida tellite. Vastus sisaldab ka allkirjastamise secret-it - salvestage see kohe, GET ei tagasta seda hiljem enam. Tühi events: [] tähendab telli kõik sündmused, mitte mitte ühtegi - sh hiljem lisatud. Kui soovite ainult mõnda sündmust, loetlege need. Vastupidi, tühi url: "" tühistab webhooki - volai ei saada siis midagi ja vastus tagastab url: null. Kuidas allkirja kontrollida, on kirjeldatud lehel Webhookid. Valikulised headers on kohandatud HTTP-päised, mis saadetakse iga kohaletoimetamisega, näiteks Authorization: Bearer <key> sihtkoha jaoks, mis aktsepteerib ainult autenditud päringuid. Need tulevad tagasi lühendatult (Bear***); tagasi saadetud mask säilitab salvestatud väärtuse, välja väljajätmine säilitab salvestatud päised ja {} eemaldab need. URL-i muutmine teisele domeenile kustutab salvestatud päised.

Päring

bash
curl -X PUT "https://volai.cz/v1/webhook" \
  -H "Authorization: Bearer vk_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://tvoje-appka.cz/webhooks/volai","events":["call.completed","call.failed","message.sent"],"headers":{"Authorization":"Bearer tvuj-klic"}}'

Vastus

json
{
  "url": "https://tvoje-appka.cz/webhooks/volai",
  "secret": "whsec_9f2b7a1c4e6d8f0a",
  "events": ["call.completed", "call.failed", "message.sent"],
  "headers": { "Authorization": "Bear***" }
}

Veaolekud

  • 400validationurl puudub või on üle 2000 märgi, events sisaldab rohkem kui 20 kirjet või kirje on üle 100 märgi või headers ei ole stringiväärtuste objekt.
  • 400invalid_urlURL peab algama https:// ja osutama avalikule aadressile (localhost, sisevõrgud ja volitusandmetega aadressid lükatakse tagasi; saatke autentimine kohandatud päises väljaga headers).
  • 400invalid_eventsÜks sündmustest ei ole tuntud (call.completed, call.failed, call.missed, call.no_answer, message.sent, message.received).
  • 400invalid_webhook_headersPäist ei saa saata: keelatud, vigane või dubleeritud nimi, tühi või liiga pikk väärtus (üle 1000 märgi), märk väljaspool prinditavat ASCII-d sh reavahetus, rohkem kui 5 päist või mask (***) väärtuse asemel, kas uue päise puhul või pärast URL-i muutmist teisele domeenile.

DELETE/v1/webhook

Eemaldab webhooki - sama mõju nagu PUT /v1/webhook tühja url-iga, lihtsalt selgesõnaliselt nimetatud. Seadke uus webhook igal ajal uuesti päringuga PUT. MCP vaste on remove_webhook; list_webhook_deliveries on ülalolevat GET /v1/webhook/deliveries MCP vaste.

Päring

bash
curl -X DELETE https://volai.cz/v1/webhook \
  -H "Authorization: Bearer $VOLAI_API_KEY"

Vastus

json
{"removed":true}

POST/v1/webhook/test

Saadab ühe testkatse seadistatud URL-ile, OLENEMATA filtrist events päringust PUT /v1/webhook - see testib kohaletoimetatavust, mitte tellimust. See saadab ka teie kohandatud headers, seega kontrollib ka sihtkoha võtit. Kordamist ei ole; isegi ebaõnnestumine registreeritakse kohaletoimetamise ajaloos. Kuni 10 tunnis.

Päring

bash
curl -X POST https://volai.cz/v1/webhook/test \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "delivered": true,
  "status": 200,
  "attempts": 1,
  "durationMs": 184
}

Veaolekud

  • 404not_foundWebhooki ei ole seatud - seadke see esmalt päringuga PUT /v1/webhook.
  • 429rate_limitedOlete jõudnud piirini 10 testsündmust tunnis.

GET/v1/webhook/deliveries

Viimased 50 kohaletoimetamist (õnnestunud, ebaõnnestunud ja testkohaletoimetamised), uusimad eespool - sama kuju nagu recentDeliveries päringul GET /v1/webhook.

Päring

bash
curl https://volai.cz/v1/webhook/deliveries \
  -H "Authorization: Bearer vk_YOUR_KEY"

Vastus

json
{
  "deliveries": [
    {
      "id": "whd_9f2b7a1c4e",
      "event": "webhook.test",
      "url": "https://tvoje-appka.cz/webhooks/volai",
      "status": 200,
      "attempts": 1,
      "ok": true,
      "durationMs": 184,
      "createdAt": 1756111641000
    }
  ]
}

Google & Apple Calendar

Avage portaalis Ühendused ja ühendage konto: Google brauseri nõusoleku kaudu (kalendrite loendi ja sündmustele juurdepääsu andmine) või Apple oma Apple Accounti e-posti ja rakendusespetsiifilise parooliga (nõuab kaheastmelist autentimist); volai leiab iCloudi kalendrid automaatselt. REST ja MCP kasutavad seejärel selle konto tavalist volai API-võtit ning teenusepakkuja andmeid ei tagastata kunagi. Avage ühenduse link brauseris, olles volais sisse logitud. GET /v1/integrations sisaldab teenusepakkuja seadistuse valmisolekut ja brauseri ühenduse URL-e; ready näitab serveri seadistust, mitte kinnitatud konto ühendust.

See liides loeb ja uuendab olemasolevaid sündmusi. Enne kirjutamist lugege sündmus, näidake kasutajale selle algseid väärtusi ja ettepanekut, seejärel saatke pärast kinnitust sourceRevision, patch ja confirm: true. Revisjon on läbipaistmatu ja sisaldab võimalikke jutumärke. Kalendri vead kasutavad prefiksit calendar_: stale_revision (409) nõuab uut lugemist ja kinnitust; oauth_failed/unauthorized (409) nõuab uuesti ühendamist; provider_error (502) tähendab, et korrake hiljem. Pärast ebaselget kirjutamist või verification_failed (502) lugege sündmus esmalt uuesti ja kontrollige tulemust.

GET/v1/integrations

Loetleb omatud ühendused, teenusepakkuja seadistuse valmisoleku ja brauseri ühenduse URL-id.

Päring

bash
curl "https://volai.cz/v1/integrations" -H "Authorization: Bearer $VOLAI_API_KEY"

Vastus

json
{"integrations":[],"providers":{"google-calendar":{"ready":true,"connectUrl":"https://volai.cz/api/integrations/google-calendar/oauth/start"},"apple-calendar":{"ready":true,"connectUrl":"https://volai.cz/en/connections"},"fakturoid":{"ready":true,"connectUrl":"https://volai.cz/api/integrations/fakturoid/oauth/start"},"abra-flexi":{"ready":true,"connectUrl":"https://volai.cz/en/connections"}},"googleCalendar":{"ready":true,"connectUrl":"https://volai.cz/api/integrations/google-calendar/oauth/start"}}

POST/v1/integrations

Ühendab Apple'i kalendri või ABRA FlexiBee kehas olevate andmetega. Google'i kalendril ja Fakturoidil on ainult brauseri OAuth-voog (link connectUrl päringust GET /v1/integrations) - nende provider siia saatmine tagastab integration_unsupported. Võtab Idempotency-Key; ka ilma selleta on kordusväljakutse samade andmetega praktiliselt idempotentne - olemasolev kirje leitakse teenusepakkuja ja konto järgi, kuhu andmed kuuluvad (Apple'i puhul kasutajanimi, ABRA puhul serveri aadress ja ettevõte); label on lihtsalt kuvanimi ja kirjutatakse kordusväljakutsel üle.

Edastage andmed ainult siis, kui kasutaja on need juba pannud kohta, mida te saate lugeda (keskkonnamuutuja või tema nimetatud fail). Ärge küsige neid kunagi vestluses ja ärge neid kordage.

Päring

bash
curl -X POST https://volai.cz/v1/integrations \
  -H "Authorization: Bearer $VOLAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"provider":"apple-calendar","username":"you@icloud.com","appPassword":"abcd-efgh-ijkl-mnop"}'

Vastus

json
{"integration":{"id":"int_7f3a91cd","provider":"apple-calendar","kind":"calendar","label":"apple-calendar","createdAt":1756111640000,"updatedAt":1756111640000}}

Veaolekud

  • 409idempotency_in_progressSamaaegne kõne sama Idempotency-Key-ga töötab veel - palun proovige varsti uuesti.
  • 400validationVigase kujuga keha - Apple'ilt puudub username/appPassword, ABRA-lt puudub baseUrl/company/username/password või kehas on tundmatu väli (skeem on .strict()).
  • 400integration_unsupportedprovider on google-calendar või fakturoid - need ühenduvad ainult brauseri OAuth-voo kaudu.
  • 400integration_invalid_providerABRA FlexiBee serveri host (baseUrl) ei ole operaatori lubatud loendis - paluge volai toel domeen lubada.
  • 400integration_invalid_calendarKas Apple'i kontol ei ole ühendamiseks ühtki kalendrit või päringus saadetud calendarUrl ei ole iCloudi avastatud kalendrite seas.
  • 409integration_unauthorizedTeenusepakkuja lükkas andmed tagasi (vale kasutajanimi või parool).
  • 409integration_read_onlyApple CalDAV lükkas kirjutamise tagasi (403) - kontol on kalendrile ainult lugemisõigus.
  • 409integration_busyKontol töötab juba mõni teine integratsioonide toiming - proovige hetke pärast uuesti.
  • 404integration_not_foundIntegratsioon, mida see päring pidi uuendama, kadus vahepeal - ühendage uuesti.
  • 502integration_provider_errorViga teenusepakkuja poolel - palun proovige hetke pärast uuesti.
  • 502integration_invalid_provider_responseTeenusepakkuja tagastas ootamatu vastuse - proovige uuesti ja kui see jätkub, võtke ühendust toega.
  • 500integration_storage_errorAndmete salvestamine ebaõnnestus meie poolel - palun proovige uuesti.

DELETE/v1/integrations/{id}

Katkestab mis tahes integratsiooni (Google, Apple, Fakturoid, ABRA) - pöördumatu, ilma kinnituseta ja ilma MCP tööriistata, sest katkestamist ei saa tagasi võtta. REST-i kaudu uuesti ühendamine toimib ainult Apple'i ja ABRA puhul (vt POST /v1/integrations ülal) - Google ja Fakturoid lähevad taas läbi brauseri OAuth-voo.

Päring

bash
curl -X DELETE https://volai.cz/v1/integrations/int_7f3a91cd \
  -H "Authorization: Bearer $VOLAI_API_KEY"

Vastus

json
{"disconnected":true}

Veaolekud

  • 404integration_not_foundIntegratsiooni ei ole olemas või see ei kuulu teie kontole.
  • 409integration_busyIntegratsioonil töötab juba mõni teine toiming (tavaliselt tokeni uuendamine) - proovige hetke pärast uuesti.

GET/v1/integrations/{id}/calendars

Omatud ühenduse kalendrid. Võtke id ühenduste loendist.

Päring

bash
curl "https://volai.cz/v1/integrations/int_CONNECTION/calendars" -H "Authorization: Bearer $VOLAI_API_KEY"

Vastus

json
{"calendars":[{"id":"primary","label":"Work","timezone":"Europe/Prague","accessRole":"owner"}]}

Veaolekud

  • 404calendar_not_foundEi integratsiooni ega kalendrit selle id-ga ei ole olemas või see ei kuulu teie kontole.
  • 400calendar_unsupportedÜhendus ei ole kalender (arveldus), seega see lõpp-punkt selle suhtes ei kehti.
  • 409calendar_read_onlyKalender on ühendatud ainult lugemiseks (Apple CalDAV keeldus kirjutamisest) - kontrollige oma õigusi jagatud kalendris Apple'i kalendris.
  • 409calendar_busySellel ühendusel töötab praegu mõni teine toiming (tavaliselt tokeni uuendamine) - proovige varsti uuesti.
  • 409calendar_refresh_in_progressJuurdepääsu kontole uuendatakse taustal - proovige varsti uuesti.
  • 409calendar_unauthorizedÜhendus kaotas teenusepakkuja juures juurdepääsu - ühendage konto portaalis uuesti.
  • 409calendar_oauth_failedTeenusepakkuja kontole sisselogimine ebaõnnestus - ühendage konto portaalis uuesti.
  • 409calendar_credentials_unavailableÜhenduse salvestatud andmeid ei õnnestunud dekrüpteerida - ühendage konto portaalis uuesti; kui see jätkub, võtke ühendust toega.
  • 409calendar_invalid_credentialsTeenusepakkuja lükkas ühenduse salvestatud andmed tagasi - ühendage konto portaalis uuesti.
  • 503calendar_not_configuredKalendri integratsioon ei ole meie poolel praegu seadistatud - palun võtke ühendust toega.
  • 502calendar_provider_errorViga teenusepakkuja poolel (Google, Apple) - palun proovige varsti uuesti.
  • 502calendar_invalid_provider_responseTeenusepakkuja tagastas ootamatu vastuse - palun proovige uuesti ja kui see jätkub, võtke ühendust toega.

POST/v1/integrations/{id}/availability

Tagastab ühendatud kalendri vabad ajad ILMA salvestatud agendita - sama arvutus nagu check_availability kõne ajal, lihtsalt ilma agendi reegliteta. Kui windows puudub, tähendab see 24 tundi iga päev; kui selle saadate, ei ole väljajäetud nädalapäeval ühtki akent. to peab olema pärast from-i ja kuni 31 päeva hilisem. Vastus sisaldab ainult start/end ja timezone - ilma sündmuste pealkirjade ja kirjelduste.

Päring

bash
curl -X POST "https://volai.cz/v1/integrations/int_CONNECTION/availability" -H "Authorization: Bearer $VOLAI_API_KEY" -H "Content-Type: application/json" -d '{"calendarId":"primary","from":"2026-09-22T00:00:00+02:00","to":"2026-09-23T00:00:00+02:00","slotMinutes":30,"windows":{"tue":[{"from":"09:00","to":"17:00"}]}}'

Vastus

json
{"slots":[{"start":"2026-09-22T09:00:00+02:00","end":"2026-09-22T09:30:00+02:00"}],"timezone":"Europe/Prague"}

Veaolekud

  • 404calendar_not_foundEi integratsiooni ega kalendrit selle id-ga ei ole olemas või see ei kuulu teie kontole.
  • 400calendar_unsupportedÜhendus ei ole kalender (arveldus), seega see lõpp-punkt selle suhtes ei kehti.
  • 409calendar_read_onlyKalender on ühendatud ainult lugemiseks (Apple CalDAV keeldus kirjutamisest) - kontrollige oma õigusi jagatud kalendris Apple'i kalendris.
  • 409calendar_busySellel ühendusel töötab praegu mõni teine toiming (tavaliselt tokeni uuendamine) - proovige varsti uuesti.
  • 409calendar_refresh_in_progressJuurdepääsu kontole uuendatakse taustal - proovige varsti uuesti.
  • 409calendar_unauthorizedÜhendus kaotas teenusepakkuja juures juurdepääsu - ühendage konto portaalis uuesti.
  • 409calendar_oauth_failedTeenusepakkuja kontole sisselogimine ebaõnnestus - ühendage konto portaalis uuesti.
  • 409calendar_credentials_unavailableÜhenduse salvestatud andmeid ei õnnestunud dekrüpteerida - ühendage konto portaalis uuesti; kui see jätkub, võtke ühendust toega.
  • 409calendar_invalid_credentialsTeenusepakkuja lükkas ühenduse salvestatud andmed tagasi - ühendage konto portaalis uuesti.
  • 503calendar_not_configuredKalendri integratsioon ei ole meie poolel praegu seadistatud - palun võtke ühendust toega.
  • 502calendar_provider_errorViga teenusepakkuja poolel (Google, Apple) - palun proovige varsti uuesti.
  • 502calendar_invalid_provider_responseTeenusepakkuja tagastas ootamatu vastuse - palun proovige uuesti ja kui see jätkub, võtke ühendust toega.
  • 400validationVigase kujuga keha (calendarId, from, to, ...) - keha on .strict(), tundmatu väli lükatakse tagasi; from/to vajavad RFC3339 nihkega.
  • 400calendar_invalid_calendarcalendarId ei vasta ühelegi selle ühenduse kalendrile päringust GET .../calendars.
  • 400calendar_too_many_eventsNõutud vahemikus on rohkem sündmusi, kui üks päring suudab lugeda - küsige lühemat vahemikku (päevad nädalate asemel) ja proovige uuesti.
  • 400calendar_invalid_rangeto peab olema hilisem kui from ja kuni 31 päeva selle järel.
  • 400calendar_invalid_timezonetimezone ei ole kehtiv IANA tsoon, näiteks Europe/Prague.
  • 400calendar_invalid_windowsAken vajab from-i, mis on varasem kui to, kujul HH:MM, kuni 4 akent päevas ja sama päeva aknad ei tohi kattuda.
  • 400calendar_no_windowsÜhelgi nädalapäeval ei ole saadavuse akent - lisage vähemalt üks.
  • 400calendar_invalid_rulesÜks numbritest on vahemikust väljas või minNoticeMinutes on pikem kui kogu otsinguhorisont.

GET/v1/integrations/{id}/events

Kohustuslik päringuparameeter calendarId. Kuni 50 Google'i sündmust või Apple'i sündmust ja korduvat seeriat, vaikimisi tulevased. Valikulised search, timeMin, timeMax ja pageToken. Ajapiiridel peavad olema nihked. Jätkake väärtusega nextPageToken ja identsete filtritega, sh fikseeritud timeMin. Apple'i recurring:true tähistab tervet seeriat; selle start/end kirjeldavad algset esinemist ja uuendused muudavad seeria põhikirjet, säilitades üksikud erandid. Tundmatu päringuparameeter lükatakse siin tagasi veaga 400 validation - erinevalt ülejäänud v1-st lisaparameetreid ei ignoreerita.

Päring

bash
curl "https://volai.cz/v1/integrations/int_CONNECTION/events?calendarId=primary" -H "Authorization: Bearer $VOLAI_API_KEY"

Vastus

json
{"events":[{"calendarId":"primary","externalId":"event1","title":"Meeting","start":"2026-10-05T10:00:00+02:00","end":"2026-10-05T11:00:00+02:00","status":"confirmed","sourceRevision":"revision1"}]}

Veaolekud

  • 404calendar_not_foundEi integratsiooni ega kalendrit selle id-ga ei ole olemas või see ei kuulu teie kontole.
  • 400calendar_unsupportedÜhendus ei ole kalender (arveldus), seega see lõpp-punkt selle suhtes ei kehti.
  • 409calendar_read_onlyKalender on ühendatud ainult lugemiseks (Apple CalDAV keeldus kirjutamisest) - kontrollige oma õigusi jagatud kalendris Apple'i kalendris.
  • 409calendar_busySellel ühendusel töötab praegu mõni teine toiming (tavaliselt tokeni uuendamine) - proovige varsti uuesti.
  • 409calendar_refresh_in_progressJuurdepääsu kontole uuendatakse taustal - proovige varsti uuesti.
  • 409calendar_unauthorizedÜhendus kaotas teenusepakkuja juures juurdepääsu - ühendage konto portaalis uuesti.
  • 409calendar_oauth_failedTeenusepakkuja kontole sisselogimine ebaõnnestus - ühendage konto portaalis uuesti.
  • 409calendar_credentials_unavailableÜhenduse salvestatud andmeid ei õnnestunud dekrüpteerida - ühendage konto portaalis uuesti; kui see jätkub, võtke ühendust toega.
  • 409calendar_invalid_credentialsTeenusepakkuja lükkas ühenduse salvestatud andmed tagasi - ühendage konto portaalis uuesti.
  • 503calendar_not_configuredKalendri integratsioon ei ole meie poolel praegu seadistatud - palun võtke ühendust toega.
  • 502calendar_provider_errorViga teenusepakkuja poolel (Google, Apple) - palun proovige varsti uuesti.
  • 502calendar_invalid_provider_responseTeenusepakkuja tagastas ootamatu vastuse - palun proovige uuesti ja kui see jätkub, võtke ühendust toega.
  • 400validationVigase kujuga päring (nt timeMax ei ole pärast timeMin-i või tundmatu parameeter) - vt iga parameetri piiranguid ülal.
  • 400calendar_invalid_calendarcalendarId ei vasta ühelegi selle ühenduse kalendrile päringust GET .../calendars.
  • 400calendar_invalid_queryVigane pageToken või Apple'i eventId. Kasutage värske sündmuste loendi externalId-d ja hoidke lehitsemise filtrid muutmata.
  • 409calendar_stale_revisionsourceRevision ei vasta sündmuse praegusele revisjonile - keegi muutis seda vahepeal. Lugege see uuesti, näidake kasutajale uut olekut ja laske uus ettepanek kinnitada. Apple'i sündmuste loendis tähendab sama kood, et loend muutus lehtede vahel: jätke pageToken ära ja lugege esimene leht uuesti.

POST/v1/integrations/{id}/events

Loob ühendatud kalendrisse kohtumise pärast kasutaja selgesõnalist kinnitust (confirm: true). Andke täpselt üks väljadest end või durationMinutes. idempotencyKey on valikuline - sama väärtuse uuesti saatmine tagastab juba loodud sündmuse teise kirjutuse asemel. Enne kirjutamist kontrollitakse, et aeg on endiselt vaba; vastus on värskelt loetud sündmus, sama kujuga kui GET .../events/{eventId}.

Päring

bash
curl -X POST "https://volai.cz/v1/integrations/int_CONNECTION/events" -H "Authorization: Bearer $VOLAI_API_KEY" -H "Content-Type: application/json" -d '{"calendarId":"primary","start":"2026-09-22T09:00:00+02:00","durationMinutes":30,"title":"Meeting","confirm":true}'

Vastus

json
{
  "event": {
    "calendarId": "primary",
    "externalId": "event1",
    "title": "Meeting",
    "start": "2026-10-05T10:00:00+02:00",
    "end": "2026-10-05T11:00:00+02:00",
    "timezone": "Europe/Prague",
    "status": "confirmed",
    "sourceRevision": "revision1",
    "provider": "google-calendar",
    "sourceUrl": "https://calendar.google.com/calendar/event?eid=ZXZlbnQx",
    "fetchedAt": "2026-09-08T09:00:00.000Z"
  }
}

Veaolekud

  • 404calendar_not_foundEi integratsiooni ega kalendrit selle id-ga ei ole olemas või see ei kuulu teie kontole.
  • 400calendar_unsupportedÜhendus ei ole kalender (arveldus), seega see lõpp-punkt selle suhtes ei kehti.
  • 409calendar_read_onlyKalender on ühendatud ainult lugemiseks (Apple CalDAV keeldus kirjutamisest) - kontrollige oma õigusi jagatud kalendris Apple'i kalendris.
  • 409calendar_busySellel ühendusel töötab praegu mõni teine toiming (tavaliselt tokeni uuendamine) - proovige varsti uuesti.
  • 409calendar_refresh_in_progressJuurdepääsu kontole uuendatakse taustal - proovige varsti uuesti.
  • 409calendar_unauthorizedÜhendus kaotas teenusepakkuja juures juurdepääsu - ühendage konto portaalis uuesti.
  • 409calendar_oauth_failedTeenusepakkuja kontole sisselogimine ebaõnnestus - ühendage konto portaalis uuesti.
  • 409calendar_credentials_unavailableÜhenduse salvestatud andmeid ei õnnestunud dekrüpteerida - ühendage konto portaalis uuesti; kui see jätkub, võtke ühendust toega.
  • 409calendar_invalid_credentialsTeenusepakkuja lükkas ühenduse salvestatud andmed tagasi - ühendage konto portaalis uuesti.
  • 503calendar_not_configuredKalendri integratsioon ei ole meie poolel praegu seadistatud - palun võtke ühendust toega.
  • 502calendar_provider_errorViga teenusepakkuja poolel (Google, Apple) - palun proovige varsti uuesti.
  • 502calendar_invalid_provider_responseTeenusepakkuja tagastas ootamatu vastuse - palun proovige uuesti ja kui see jätkub, võtke ühendust toega.
  • 400validationVigase kujuga keha - puudub täpselt üks väljadest end/durationMinutes, tühi või liiga pikk title või tundmatu väli (.strict()).
  • 400calendar_invalid_calendarcalendarId ei vasta ühelegi selle ühenduse kalendrile päringust GET .../calendars.
  • 400calendar_invalid_rangeto peab olema hilisem kui from ja kuni 31 päeva selle järel.
  • 400calendar_confirmation_requiredconfirm peab olema true - ilma kasutaja selgesõnalise kinnituseta kohtumist ei looda.
  • 409calendar_slot_takenSoovitud aeg ei ole praegu vaba - lugege saadavus uuesti (POST .../availability) ja valige mõni teine aeg.
  • 503calendar_unavailableKalendrit ei saa praegu lugemiseks ega kirjutamiseks kätte - palun proovige varsti uuesti.

GET/v1/integrations/{id}/events/{eventId}

Kohustuslik päringuparameeter calendarId. Värske sündmus väljadega sourceRevision ja fetchedAt. Kodeerige ID-d URL-i jaoks nii teedel kui päringu väärtustes. Apple'i puhul andke sündmuste loendist tagastatud läbipaistmatu externalId eventId-na muutmata kujul edasi. See adresseerib CalDAV-ressurssi, mitte selle iCalendari UID-d; ärge koostage ega dekodeerige seda.

Päring

bash
curl "https://volai.cz/v1/integrations/int_CONNECTION/events/EVENT_ID?calendarId=primary" -H "Authorization: Bearer $VOLAI_API_KEY"

Vastus

json
{
  "event": {
    "calendarId": "primary",
    "externalId": "event1",
    "title": "Meeting",
    "start": "2026-10-05T10:00:00+02:00",
    "end": "2026-10-05T11:00:00+02:00",
    "timezone": "Europe/Prague",
    "status": "confirmed",
    "sourceRevision": "revision1",
    "provider": "google-calendar",
    "sourceUrl": "https://calendar.google.com/calendar/event?eid=ZXZlbnQx",
    "fetchedAt": "2026-09-08T09:00:00.000Z"
  }
}

Veaolekud

  • 404calendar_not_foundEi integratsiooni ega kalendrit selle id-ga ei ole olemas või see ei kuulu teie kontole.
  • 400calendar_unsupportedÜhendus ei ole kalender (arveldus), seega see lõpp-punkt selle suhtes ei kehti.
  • 409calendar_read_onlyKalender on ühendatud ainult lugemiseks (Apple CalDAV keeldus kirjutamisest) - kontrollige oma õigusi jagatud kalendris Apple'i kalendris.
  • 409calendar_busySellel ühendusel töötab praegu mõni teine toiming (tavaliselt tokeni uuendamine) - proovige varsti uuesti.
  • 409calendar_refresh_in_progressJuurdepääsu kontole uuendatakse taustal - proovige varsti uuesti.
  • 409calendar_unauthorizedÜhendus kaotas teenusepakkuja juures juurdepääsu - ühendage konto portaalis uuesti.
  • 409calendar_oauth_failedTeenusepakkuja kontole sisselogimine ebaõnnestus - ühendage konto portaalis uuesti.
  • 409calendar_credentials_unavailableÜhenduse salvestatud andmeid ei õnnestunud dekrüpteerida - ühendage konto portaalis uuesti; kui see jätkub, võtke ühendust toega.
  • 409calendar_invalid_credentialsTeenusepakkuja lükkas ühenduse salvestatud andmed tagasi - ühendage konto portaalis uuesti.
  • 503calendar_not_configuredKalendri integratsioon ei ole meie poolel praegu seadistatud - palun võtke ühendust toega.
  • 502calendar_provider_errorViga teenusepakkuja poolel (Google, Apple) - palun proovige varsti uuesti.
  • 502calendar_invalid_provider_responseTeenusepakkuja tagastas ootamatu vastuse - palun proovige uuesti ja kui see jätkub, võtke ühendust toega.
  • 400validationcalendarId päringus on kohustuslik ja kuni 500 märki.
  • 400calendar_invalid_calendarcalendarId ei vasta ühelegi selle ühenduse kalendrile päringust GET .../calendars.
  • 400calendar_invalid_queryVigane pageToken või Apple'i eventId. Kasutage värske sündmuste loendi externalId-d ja hoidke lehitsemise filtrid muutmata.

PATCH/v1/integrations/{id}/events/{eventId}

Muutke pealkirja, algust või lõppu. Kasutage RFC3339 ajatempleid nihetega või täispäevaseid YYYY-MM-DD kuupäevi ekskluusiivse lõpuga. Apple'i ujuvaja võib nihke ära jätta ainult olemasoleva ujuvaja sündmuse säilitamisel. Nõuab kinnitust ja kehtivat revisjoni; tagastab kontrollitud sündmuse.

Päring

bash
curl -X PATCH "https://volai.cz/v1/integrations/int_CONNECTION/events/EVENT_ID" -H "Authorization: Bearer $VOLAI_API_KEY" -H "Content-Type: application/json" -d '{"calendarId":"primary","sourceRevision":"revision1","patch":{"title":"Updated meeting"},"confirm":true}'

Vastus

json
{
  "event": {
    "calendarId": "primary",
    "externalId": "event1",
    "title": "Updated meeting",
    "start": "2026-10-05T10:00:00+02:00",
    "end": "2026-10-05T11:00:00+02:00",
    "timezone": "Europe/Prague",
    "status": "confirmed",
    "sourceRevision": "revision1",
    "provider": "google-calendar",
    "sourceUrl": "https://calendar.google.com/calendar/event?eid=ZXZlbnQx",
    "fetchedAt": "2026-09-08T09:00:00.000Z"
  }
}

Veaolekud

  • 404calendar_not_foundEi integratsiooni ega kalendrit selle id-ga ei ole olemas või see ei kuulu teie kontole.
  • 400calendar_unsupportedÜhendus ei ole kalender (arveldus), seega see lõpp-punkt selle suhtes ei kehti.
  • 409calendar_read_onlyKalender on ühendatud ainult lugemiseks (Apple CalDAV keeldus kirjutamisest) - kontrollige oma õigusi jagatud kalendris Apple'i kalendris.
  • 409calendar_busySellel ühendusel töötab praegu mõni teine toiming (tavaliselt tokeni uuendamine) - proovige varsti uuesti.
  • 409calendar_refresh_in_progressJuurdepääsu kontole uuendatakse taustal - proovige varsti uuesti.
  • 409calendar_unauthorizedÜhendus kaotas teenusepakkuja juures juurdepääsu - ühendage konto portaalis uuesti.
  • 409calendar_oauth_failedTeenusepakkuja kontole sisselogimine ebaõnnestus - ühendage konto portaalis uuesti.
  • 409calendar_credentials_unavailableÜhenduse salvestatud andmeid ei õnnestunud dekrüpteerida - ühendage konto portaalis uuesti; kui see jätkub, võtke ühendust toega.
  • 409calendar_invalid_credentialsTeenusepakkuja lükkas ühenduse salvestatud andmed tagasi - ühendage konto portaalis uuesti.
  • 503calendar_not_configuredKalendri integratsioon ei ole meie poolel praegu seadistatud - palun võtke ühendust toega.
  • 502calendar_provider_errorViga teenusepakkuja poolel (Google, Apple) - palun proovige varsti uuesti.
  • 502calendar_invalid_provider_responseTeenusepakkuja tagastas ootamatu vastuse - palun proovige uuesti ja kui see jätkub, võtke ühendust toega.
  • 400validationVigase kujuga keha (calendarId, sourceRevision, patch, confirm) - keha on .strict(), tundmatu väli lükatakse tagasi.
  • 400calendar_invalid_calendarcalendarId ei vasta ühelegi selle ühenduse kalendrile päringust GET .../calendars.
  • 400calendar_invalid_queryVigane pageToken või Apple'i eventId. Kasutage värske sündmuste loendi externalId-d ja hoidke lehitsemise filtrid muutmata.
  • 400calendar_provider_mismatchÜhendus vahetas vahepeal teenusepakkujat, seega varasema lugemise ettepanek sellele enam ei kuulu - lugege sündmus uuesti ja laske uus ettepanek kinnitada.
  • 400calendar_invalid_patchpatch on vigase kujuga või sisaldab tundmatut välja - lubatud on ainult title, start ja end; start/end vajavad nihet (või täispäevast YYYY-MM-DD hilisema lõpuga).
  • 400calendar_confirmation_requiredconfirm peab olema true - ilma kasutaja kinnituseta sündmust ei muudeta.
  • 409calendar_stale_revisionsourceRevision ei vasta sündmuse praegusele revisjonile - keegi muutis seda vahepeal. Lugege see uuesti, näidake kasutajale uut olekut ja laske uus ettepanek kinnitada. Apple'i sündmuste loendis tähendab sama kood, et loend muutus lehtede vahel: jätke pageToken ära ja lugege esimene leht uuesti.
  • 502calendar_verification_failedKirjutamine õnnestus, kuid selle tagasilugemist teenusepakkujalt ei õnnestunud kontrollida - lugege sündmus uuesti ja kontrollige tulemust.

POST/v1/integrations/{id}/events/{eventId}/propose

Koostab sündmuse pealkirja, alguse või lõpu muutmise ettepaneku ILMA teenusepakkujale kirjutamata (patch ja sourceRevision nagu PATCH .../events/{eventId}, kuid ilma confirm-ita) - puhas funktsioon salvestatud integratsioonitüübi üle, see ei pöördu kunagi teenusepakkuja poole. Näidake ettepanekut (proposal.patch) kasutajale selgesõnaliseks kinnitamiseks ja saatke seejärel PATCH .../events/{eventId} samade väärtuste ja confirm: true-ga.

Päring

bash
curl -X POST "https://volai.cz/v1/integrations/int_CONNECTION/events/EVENT_ID/propose" -H "Authorization: Bearer $VOLAI_API_KEY" -H "Content-Type: application/json" -d '{"calendarId":"primary","sourceRevision":"revision1","patch":{"title":"Updated meeting"}}'

Vastus

json
{"proposal":{"calendarId":"primary","externalId":"EVENT_ID","sourceRevision":"revision1","patch":{"title":"Updated meeting"},"provider":"google-calendar","proposedAt":"2026-09-08T09:00:00.000Z","requiresExplicitConfirmation":true}}

Veaolekud

  • 400validationVigase kujuga keha - puudub calendarId/sourceRevision või patch sisaldab muud välja kui title/start/end.
  • 404calendar_not_foundSelle ID-ga integratsiooni või kalendrit ei ole olemas või see ei kuulu teie kontole.
  • 400calendar_unsupportedÜhendus ei ole kalender (arveldus) - see lõpp-punkt selle suhtes ei kehti.
  • 400calendar_invalid_patchpatch on vigase kujuga - start/end peavad sisaldama ajavööndit (või olema täispäevane YYYY-MM-DD hilisema lõpuga).

Fakturoidi ja ABRA Flexi arved

Ühendage konto esmalt jaotises Ühendused. Fakturoid kasutab brauseri OAuth-i; kui saadaval on mitu arvete jaoks lubatud ettevõtet, valige üks selgesõnaliselt. ABRA Flexi nõuab HTTPS-serverit, ettevõtte identifikaatorit ja API-kasutaja andmeid; serveri hostinime peab volai operaator lubama. Andmed jäävad portaali. Need lõpp-punktid loevad väljastatud arveid ega loo kunagi arveid ega märgi neid tasutuks.

Arvete lõpp-punktide vead kannavad prefiksit integration_ ning cause ja action nagu iga API viga. Põhjuse järgi: account tähendab, et ühendage konto jaotises Ühendused uuesti, ilma selleta on kordamine mõttetu; busy (409) korrake mõne sekundi pärast, teie andmed on korras; service (400, 502 või 503) on meie või teenusepakkuja pool - korrake hiljem ja käsitlege arve olekut vahepeal kui TEADMATUT; request (400) parandage päring. Ärge asendage ebaõnnestunud lugemist varasema ega helistaja esitatud maksetõendiga.

GET/v1/integrations/{id}/invoices

Valikuline otsingupäring (kuni 100 märki) otsib teenusepakkujalt. Tagastab esimesed 40 Fakturoidi või 50 ABRA Flexi tulemust. Vanemate arvete leidmiseks täpsustage päringut; selles vastuses ei ole lehekülje tokenit.

Päring

bash
curl "https://volai.cz/v1/integrations/int_CONNECTION/invoices?search=2026-0001" -H "Authorization: Bearer $VOLAI_API_KEY"

Vastus

json
{"invoices":[{"externalId":"123","label":"2026-0001","status":"unpaid","amountDueMinor":1210000,"currency":"CZK","dueDate":"2026-09-30","sourceRevision":"v3"}]}

Veaolekud

  • 400validationsearch on pikem kui 100 märki või päring sisaldab tundmatut parameetrit (näiteks limit) - kalendri- ja arvete lõpp-punktid lükkavad tundmatud parameetrid tagasi, ülejäänud v1 ignoreerib neid.
  • 404integration_not_foundKontol ei ole selle id-ga ühendust; detailis ka siis, kui teenusepakkuja ei tunne selle invoiceId-ga arvet (loendis saabub teenusepakkuja 404 kujul provider_error).
  • 400integration_unsupportedÜhendus ei ole arvete oma (näiteks kalender) - arveid pakuvad ainult Fakturoid ja ABRA Flexi.
  • 400integration_invalid_providerÜhendusele salvestatud ABRA Flexi server ei ole operaatori lubatud hostide loendis. Võtke ühendust toega.
  • 409integration_busyÜhenduse andmeid uuendatakse ja kirje muutus vahepeal - korrake päringut mõne sekundi pärast.
  • 409integration_refresh_in_progressMõni teine päring uuendab juba ühenduse tokenit - korrake päringut mõne sekundi pärast.
  • 409integration_unauthorizedTeenusepakkuja lükkas salvestatud andmed tagasi (HTTP 401) - ühendage konto jaotises Ühendused uuesti.
  • 409integration_oauth_failedFakturoidi tokeni uuendamine ebaõnnestus - ühendage konto jaotises Ühendused uuesti.
  • 409integration_credentials_unavailableSalvestatud andmeid ei õnnestunud dekrüpteerida - ühendage konto jaotises Ühendused uuesti.
  • 409integration_invalid_credentialsSalvestatud andmed ei ole oodatud kujul (puudub token, slug või API-kasutaja) - ühendage konto jaotises Ühendused uuesti.
  • 503integration_not_configuredOperaator ei ole teenusepakkuja võtmeid seadistanud (näiteks Fakturoidi OAuth) - selle eest teilt tasu ei võeta, võtke ühendust toega.
  • 502integration_provider_errorTeenusepakkuja vastas veaga (sh HTTP 403) või ei vastanud - korrake päringut hiljem; käsitlege arve olekut vahepeal kui teadmatut.
  • 502integration_invalid_provider_responseTeenusepakkuja tagastas ootamatu kujuga vastuse - korrake päringut hiljem; kui see jätkub, võtke ühendust toega.
  • 400integration_invalid_queryOtsinguparameeter sisaldab kaldkriipse tagurpidi, juhtmärke või segatud jutumärke, mille ABRA Flexi otsing tagasi lükkab - lihtsustage päringut.

GET/v1/integrations/{id}/invoices/{invoiceId}

Lugege värsked maksetõendid enne, kui teatate, kas arve on tasutud. amountDueMinor on täisarv valuuta väikseimates ühikutes; null tähendab, et teenusepakkuja ei määranud jääki. status võib olla unknown. Ei unknown ega puuduv summa ei tõesta tasumist. Detail sisaldab väljasid provider, sourceUrl, fetchedAt ja evidence: provider_response. Kodeerige invoiceId URL-i jaoks.

Päring

bash
curl "https://volai.cz/v1/integrations/int_CONNECTION/invoices/123" -H "Authorization: Bearer $VOLAI_API_KEY"

Vastus

json
{"invoice":{"externalId":"123","status":"unpaid","amountDueMinor":1210000,"currency":"CZK","dueDate":"2026-09-30","sourceRevision":"v3","provider":"fakturoid","fetchedAt":"2026-09-08T09:00:00.000Z","sourceUrl":"https://app.fakturoid.cz/api/v3/accounts/firma/invoices/123.json","evidence":"provider_response"}}

Veaolekud

  • 400validationinvoiceId teel puudub või on pikem kui 500 märki.
  • 404integration_not_foundKontol ei ole selle id-ga ühendust; detailis ka siis, kui teenusepakkuja ei tunne selle invoiceId-ga arvet (loendis saabub teenusepakkuja 404 kujul provider_error).
  • 400integration_unsupportedÜhendus ei ole arvete oma (näiteks kalender) - arveid pakuvad ainult Fakturoid ja ABRA Flexi.
  • 400integration_invalid_providerÜhendusele salvestatud ABRA Flexi server ei ole operaatori lubatud hostide loendis. Võtke ühendust toega.
  • 409integration_busyÜhenduse andmeid uuendatakse ja kirje muutus vahepeal - korrake päringut mõne sekundi pärast.
  • 409integration_refresh_in_progressMõni teine päring uuendab juba ühenduse tokenit - korrake päringut mõne sekundi pärast.
  • 409integration_unauthorizedTeenusepakkuja lükkas salvestatud andmed tagasi (HTTP 401) - ühendage konto jaotises Ühendused uuesti.
  • 409integration_oauth_failedFakturoidi tokeni uuendamine ebaõnnestus - ühendage konto jaotises Ühendused uuesti.
  • 409integration_credentials_unavailableSalvestatud andmeid ei õnnestunud dekrüpteerida - ühendage konto jaotises Ühendused uuesti.
  • 409integration_invalid_credentialsSalvestatud andmed ei ole oodatud kujul (puudub token, slug või API-kasutaja) - ühendage konto jaotises Ühendused uuesti.
  • 503integration_not_configuredOperaator ei ole teenusepakkuja võtmeid seadistanud (näiteks Fakturoidi OAuth) - selle eest teilt tasu ei võeta, võtke ühendust toega.
  • 502integration_provider_errorTeenusepakkuja vastas veaga (sh HTTP 403) või ei vastanud - korrake päringut hiljem; käsitlege arve olekut vahepeal kui teadmatut.
  • 502integration_invalid_provider_responseTeenusepakkuja tagastas ootamatu kujuga vastuse - korrake päringut hiljem; kui see jätkub, võtke ühendust toega.

Seadistustellimused (Võtmed kätte)

Võtmed kätte seadistab töötava agendi lihtsas keeles kirjelduse põhjal portaali käsitsi seadistamise asemel. POST /v1/setup-orders teeb ühekordse vestlusvooru: kirjeldage agenti ja nõustaja tagastab kas hinnastatud pakkumise (quoted), palub kinnitada läve ületavaid kohandatud kirjeid (awaiting_confirmation) või keeldub automaatsest seadistamisest kasutusjuhtumi puhul, mis sobib mitte (declined). Hind ise arvutatakse koodis fikseeritud kataloogist, mitte kunagi mudeli poolt - nõustaja valib ainult paketi, lisad ja kohandatud kirjed. Pakkumise tasumine (POST .../checkout, Stripe Checkouti seanss, mis katab seadistustasu pluss esimese saldo täienduse) alustab ehitust; volai ehitab agendi käsitsi ja viib tellimuse läbi olekute paid -> building -> ready. Kui see on ready, helistage lisatud numbrile, et seda proovida, saatke muudatuste kohta sõnum (revision) ja seejärel POST .../launch, et käiku minna. GET .../{id} sisaldab alati nextStep-i, lihtsas keeles lauset selle kohta, mida praeguses olekus järgmiseks teha.

POST/v1/setup-orders

Ühekordne: kirjeldage vajalikku agenti väljal brief (vähemalt 20 märki) ja saate tagasi pakkumise või palve kohandatud kirjeid kinnitada. locale määrab nõustaja vestluse ja selle tellimuse kohta saadetavate e-kirjade keele (vaikimisi en); see ei muuda selle vastuse keelt - REST räägib alati inglise keeles. contactPhone lisatakse briifile märkusena volai jaoks, seda ei valideerita. Piiratud 5 uue seadistustellimusega konto kohta päevas. Kui nõustaja voor ebaõnnestub (advisor_unavailable, advisor_no_quote), loodi tellimus juba ja see loeti selle piirangu hulka, seega korrake, leides selle päringuga GET /v1/setup-orders ja saates järgmise katse päringuga POST .../messages, mitte kutsudes seda lõpp-punkti uuesti. Idempotency-Key puudub: iga kõne loob uue tellimuse, 5 päevas piirang on ainus pidur - korrake ajalõppu sattunud kõnet esmalt päringuga GET /v1/setup-orders.

Päring

bash
curl -X POST https://volai.cz/v1/setup-orders \
  -H "Authorization: Bearer $VOLAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"brief":"Reception for a Prague fitness studio, Czech and English, takes bookings and answers pricing questions.","locale":"en"}'

201 Created

json
{"order":{"id":"so_AbCdEf123456","status":"quoted","nextStep":"Start the checkout to pay the setup fee and begin the build.","locale":"en","source":"api","createdAt":1757980800000,"updatedAt":1757980810000,"revisionsUsed":0,"extraRevisionHal":49000,"extraRevisionsCharged":0,"revisionsIncluded":2,"quote":{"lines":[{"kind":"package","id":"provozovna","label":"Business","quantity":1,"unitHal":299000,"totalHal":299000},{"kind":"addon","id":"calendar","label":"Calendar booking","quantity":1,"unitHal":99000,"totalHal":99000}],"setupNetHal":398000,"needsConfirmation":false,"revisionsIncluded":2,"monthly":{"callsPerDay":20,"avgMinutes":3,"totalMonthlyHal":542500,"callMinutes":1800}},"selection":{"segment":"provozovna","packageId":"provozovna","addons":[{"id":"calendar","quantity":1}],"customItems":[],"industry":"fitness studio","agentLanguages":["cs","en"],"callsPerDay":20,"avgMinutes":3,"cannotDo":[],"assumptions":["Business hours 9am-6pm"]},"messages":[{"role":"user","content":"Reception for a Prague fitness studio...","at":1757980800000},{"role":"assistant","content":"Here is your quote for a location agent...","at":1757980810000}]}}

Veaolekud

  • 400validationKeha ei vasta skeemile (brief puudub või on alla 20 märgi, contactPhone on liiga pikk või locale ei ole cs/en).
  • 422advisor_no_quoteNõustaja otsustas, et peab küsimuse esitama, kuid ühekordne voor nõuab pakkumist või keeldumist - proovige uuesti või sõnastage briif üksikasjalikumalt ümber.
  • 503advisor_unavailableNõustaja ei ole ajutiselt saadaval (API-võtit ei ole seadistatud, võrguviga või mudel keeldus) - proovige hetke pärast uuesti.
  • 503setup_orders_disabledVõtmed kätte on kogu kontode ulatuses ajutiselt välja lülitatud; olemasolevad makstud tellimused edenevad tavapäraselt.

GET/v1/setup-orders

Konto seadistustellimused, ilma lehitsemiseta.

Päring

bash
curl "https://volai.cz/v1/setup-orders" -H "Authorization: Bearer $VOLAI_API_KEY"

Vastus

json
{"orders":[{"id":"so_AbCdEf123456","status":"quoted","nextStep":"Start the checkout to pay the setup fee and begin the build.","locale":"en","source":"api","createdAt":1757980800000,"updatedAt":1757980810000,"revisionsUsed":0,"extraRevisionHal":49000,"extraRevisionsCharged":0,"messages":[]}]}

GET/v1/setup-orders/{id}

Seadistustellimuse detail, sh iga vestluse sõnum (sh volai meeskonna omaniku vastused) ja nextStep.

Päring

bash
curl "https://volai.cz/v1/setup-orders/so_AbCdEf123456" -H "Authorization: Bearer $VOLAI_API_KEY"

Vastus

json
{"order":{"id":"so_AbCdEf123456","status":"ready","nextStep":"Call the number, then send a message for changes or launch.","locale":"en","source":"api","createdAt":1757980800000,"updatedAt":1758153600000,"readyAt":1758153600000,"revisionsUsed":0,"extraRevisionHal":49000,"extraRevisionsCharged":0,"revisionsIncluded":2,"agentId":"ag_XyZ987","numberE164":"+420999123456","messages":[{"role":"user","content":"Reception for a Prague fitness studio...","at":1757980800000},{"role":"owner","content":"Your agent is ready - give it a call.","at":1758153600000}]}}

Veaolekud

  • 404setup_order_not_foundKontol ei ole selle id-ga seadistustellimust.

POST/v1/setup-orders/{id}/messages

Saadab sõnumi seadistusnõustajale. Kui tellimus on quoted, võib uus sõnum käivitada värske nõustaja vooru, mis asendab pakkumise - välja arvatud juhul, kui selle jaoks on praegu avatud checkout (checkout_open), mis külmutab pakkumise, kuni see Checkouti seanss aegub või kasutatakse. Muudes olekutes (ready, paid, building, revision) salvestatakse sõnum lihtsalt volai meeskonna jaoks; selle saatmine olekus ready viib tellimuse olekusse revision. Paketti kuuluvad voorud (order.quote.revisionsIncluded, juba kasutatud order.revisionsUsed) on tasuta; kui need on ära kasutatud, arveldatakse järgmine voor, mille asutaja lõpetab, 490 CZK ilma käibemaksuta saldolt saldo liikumise kirjena setup_revision.

Päring

bash
curl -X POST https://volai.cz/v1/setup-orders/so_AbCdEf123456/messages \
  -H "Authorization: Bearer $VOLAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"message":"Can it also speak German?"}'

Vastus

json
{"order":{"id":"so_AbCdEf123456","status":"quoted","nextStep":"Start the checkout to pay the setup fee and begin the build.","locale":"en","source":"api","createdAt":1757980800000,"updatedAt":1757981200000,"revisionsUsed":0,"extraRevisionHal":49000,"extraRevisionsCharged":0,"messages":[{"role":"user","content":"Reception for a Prague fitness studio...","at":1757980800000},{"role":"assistant","content":"Here is your quote...","at":1757980810000},{"role":"user","content":"Can it also speak German?","at":1757981190000},{"role":"assistant","content":"Updated the quote to add German.","at":1757981200000}]}}

Veaolekud

  • 400validationmessage puudub, on tühi või ületab 2000 märki.
  • 404setup_order_not_foundKontol ei ole selle id-ga seadistustellimust.
  • 409order_closedTellimus on launched või cancelled - see ei võta enam sõnumeid vastu.
  • 409turn_in_progressSama tellimuse mõni teine päring on juba pooleli - oodake selle lõppu ja korrake.
  • 409checkout_openSelle tellimuse pakkumise jaoks on praegu avatud Checkouti seanss - oodake selle aegumist või lõpetamist enne sõnumi saatmist, mis võiks hinda muuta.
  • 422advisor_no_quoteNõustaja otsustas, et peab küsimuse esitama, kuid ühekordne voor nõuab pakkumist või keeldumist - proovige uuesti või sõnastage briif üksikasjalikumalt ümber.
  • 503advisor_unavailableNõustaja ei ole ajutiselt saadaval (API-võtit ei ole seadistatud, võrguviga või mudel keeldus) - proovige hetke pärast uuesti.

POST/v1/setup-orders/{id}/checkout

Loob Stripe Checkouti seansi pakutud seadistustasu pluss esimese saldo täienduse (creditCzk, üks konto toetatud täiendussummadest) jaoks. Ainult olekust quoted ja ainult tellimuse omanik. Nii edu- kui tühistamissuunamine osutavad tagasi tellimuse lehele vestluse keeles (order.locale), mitte tingimata selle päringu keeles.

Päring

bash
curl -X POST https://volai.cz/v1/setup-orders/so_AbCdEf123456/checkout \
  -H "Authorization: Bearer $VOLAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"creditCzk":500}'

Vastus

json
{"url":"https://checkout.stripe.com/c/pay/cs_test_...","sessionId":"cs_test_a1B2c3D4"}

Veaolekud

  • 400validationKeha ei vasta skeemile (creditCzk ei ole täisarv).
  • 400invalid_amountcreditCzk ei ole üks konto toetatud täiendussummadest.
  • 400billing_address_requiredKontole ei ole veel täielikku arveldusaadressi salvestatud - lisage see esmalt (PUT /v1/account/billing).
  • 404setup_order_not_foundKontol ei ole selle id-ga seadistustellimust.
  • 409checkout_openSelle tellimuse pakkumise jaoks on praegu avatud Checkouti seanss - oodake selle aegumist või lõpetamist enne sõnumi saatmist, mis võiks hinda muuta.
  • 409invalid_transitionTellimus ei ole quoted või selle pakkumine puudub - checkout avaneb ainult pakutud tellimusest.
  • 409quote_pending_confirmationPakkumine vajab enne checkouti avamist veel volai kinnitust kohandatud kirjetele (awaiting_confirmation).
  • 409turn_in_progressSama tellimuse mõni teine päring on juba pooleli - oodake selle lõppu ja korrake.
  • 503setup_orders_disabledVõtmed kätte on kogu kontode ulatuses ajutiselt välja lülitatud; olemasolevad makstud tellimused edenevad tavapäraselt.

POST/v1/setup-orders/{id}/launch

Käivitab valmis agendi (ready -> launched) - ainus üleminek, mida klient ise teeb; kõik muud üleminekud (ehituse algus, valmis, tühistamine) on volai meeskonna omad.

Päring

bash
curl -X POST https://volai.cz/v1/setup-orders/so_AbCdEf123456/launch -H "Authorization: Bearer $VOLAI_API_KEY"

Vastus

json
{"order":{"id":"so_AbCdEf123456","status":"launched","nextStep":"Your agent is live.","locale":"en","source":"api","createdAt":1757980800000,"updatedAt":1758160000000,"readyAt":1758153600000,"launchedAt":1758160000000,"revisionsUsed":0,"extraRevisionHal":49000,"extraRevisionsCharged":0,"agentId":"ag_XyZ987","numberE164":"+420999123456","messages":[]}}

Veaolekud

  • 404setup_order_not_foundKontol ei ole selle id-ga seadistustellimust.
  • 409invalid_transitionTellimus ei ole ready - käivitamiseks ei ole veel midagi valmis.

POST/v1/setup-orders/{id}/cancel

Tühistab tasumata seadistustellimuse (draft, quoted, awaiting_confirmation või declined -> cancelled). Makstud tellimust ei saa selle lõpp-punkti kaudu tühistada - võtke ühendust volaiga.

Päring

bash
curl -X POST https://volai.cz/v1/setup-orders/so_AbCdEf123456/cancel -H "Authorization: Bearer $VOLAI_API_KEY"

Vastus

json
{"order":{"id":"so_AbCdEf123456","status":"cancelled","nextStep":"This order was cancelled.","locale":"en","source":"api","createdAt":1757980800000,"updatedAt":1757981500000,"revisionsUsed":0,"extraRevisionHal":49000,"extraRevisionsCharged":0,"messages":[]}}

Veaolekud

  • 404setup_order_not_foundKontol ei ole selle id-ga seadistustellimust.
  • 409invalid_transitionTellimust ei saa selle praegusest olekust tühistada (see on juba makstud või juba suletud).

Muudatuste logi

Avaliku liidese masinloetav muudatuste logi - nii REST v1 kui MCP. Üks dokument ühel URL-il (päringuparameetreid ei ole - filtreerige tagastatud massiivi entries ise), seega on seda ohutu avalikult vahemällu salvestada. Samad andmed nagu /en/changelog portaalis ja MCP tööriist get_changelog. Kanooniline tõeallikas on üks fail (content/changelog.json) - kõik vaated genereeritakse sellest.

GET/v1/changelog

Tagastab liidese praeguse versiooni ja KÕIK muudatuste logi kirjed (uusimad eespool), inglise keeles olenemata konto keelest. version/technical on null, kui kirjel seda ei olnud (vanad kirjed ilma versioonita või ilma tehnilise detailita). url on kanooniline ingliskeelne tee ankruga id-le.

Päring

bash
curl https://volai.cz/v1/changelog

Vastus

json
{
  "version": "1.58.0",
  "entries": [
    {
      "id": "parita-vlna-a",
      "date": "2026-09-08",
      "version": "1.5.0",
      "areas": ["api", "mcp"],
      "audience": "developer",
      "breaking": false,
      "title": "Account, call annotations, tool test, draft rollback, numbers waitlist and more",
      "body": "See /en/docs/api and /en/docs/mcp for the new endpoints and tools.",
      "technical": null,
      "url": "https://volai.cz/en/changelog#parita-vlna-a"
    }
  ]
}

Veaolekud

  • 429rate_limitedOlete jõudnud piirini 30 päringut minutis ühelt IP-aadressilt (ilma API-võtmeta on piirang IP kohta, mitte konto kohta).

Päis x-volai-version

Absoluutselt IGA v1 vastus (õnnestunud või veaga, sh 401/429, binaarsed marsruudid nagu kõne salvestis ja GET /openapi.json) kannab päist x-volai-version liidese praeguse versiooniga. Kui see erineb viimasest teie nähtud versioonist, kutsuge GET /v1/changelog (või MCP get_changelog), et näha, mis on uut - MCP klient saab sama soovituse otse serveri SERVER_INSTRUCTIONS-is.

bash
x-volai-version: 1.58.0

MCP vaste on tööriist get_changelog (READ_ONLY) - samad andmed, pluss see oskab filtreerida väärtusega since (kuupäev või versioon - ainult uuemad kirjed), area ja piirata arvu väärtusega limit otse serveris.