CrioX PBXDocumentația API

Click-to-call

Pornește un apel din aplicația ta: centrala sună telefonul colegului, iar când răspunde, formează numărul cerut.

Cazul obișnuit este un buton „Sună” lângă numărul unui client, în CRM-ul sau în aplicația internă a firmei tale. Apelul se face de pe interiorul colegului, de pe telefonul lui fix, cu aceleași reguli ca un apel format de mână: numărul afișat, înregistrarea, accesul pe destinații și limitele contului. În istoric și în evenimente apare ca un apel efectuat de acel interior.

Cum funcționează

  1. Aplicația ta trimite cererea, cu interiorul colegului în adresă și numărul de format în corp.
  2. Centrala sună telefoanele înregistrate pe interior: telefonul fix și, dacă există, aplicația de mobil. Softphone-ul din browser nu sună. Pe ecranul telefonului apare numărul care urmează să fie format și, dacă l-ai trimis, numele contactului.
  3. Când colegul ridică, centrala formează numărul. Colegul aude tonul de apel, apoi vorbește ca într-un apel obișnuit.
  4. Răspunsul la cerere vine după ce colegul a ridicat sau după ce telefonul a sunat fără răspuns. Cererea durează cât sună telefonul, cel mult 15 secunde.

Apelul pornește doar când cineva ridică receptorul. API-ul nu activează răspunsul automat al telefonului, deci un număr nu poate fi format fără o persoană la telefon. Dacă nimeni nu răspunde, nimic nu se formează, iar cererea primește 409 phone_no_answer.

Permisiunea

Ruta cere o cheie cu permisiunea calls:dial. Permisiunea se bifează la crearea cheii, în CrioX, la Integrări → API, cu opțiunea „Poate porni apeluri (click-to-call)”. Cheile create fără ea au doar calls:read și primesc 403 insufficient_scope; permisiunea nu se poate adăuga ulterior, deci creează o cheie nouă pentru aplicația care pornește apeluri. Verifici permisiunile unei chei cu GET /v1/account, în câmpul scopes.

Ține această cheie cu aceeași grijă ca pe celelalte: cine o are poate face să sune telefoanele colegilor tăi, cu orice număr pe ecran. Apelul se formează totuși doar după ce un coleg ridică.

Pornirea unui apel

POST/v1/extensions/{extension}/dial

extension este interiorul colegului de pe care se face apelul, de exemplu 101. Corpul cererii este JSON, cu antetul Content-Type: application/json:

CâmpTipDescriere
numberstringNumărul de format, obligatoriu: internațional (+40743755549), național (0743755549) sau un interior (102), pentru un apel către un coleg. Spațiile, punctele, parantezele și liniuțele sunt ignorate, deci numărul poate fi trimis așa cum este salvat în sistemul tău.
namestringNumele afișat pe ecranul telefonului, lângă număr. Opțional, cel mult 80 de caractere; pe telefon apar primele 40. Fără el, centrala afișează numele din agendă sau din CRM, dacă îl cunoaște, altfel doar numărul.

Exemplu

curl -X POST https://api.criox.ro/v1/extensions/101/dial \
  -H "Authorization: Bearer cxk_…" \
  -H "Content-Type: application/json" \
  -d '{ "number": "+40743755549", "name": "Ion Popescu" }'

Răspuns, după ce colegul a ridicat:

{
  "extension": "101",
  "number": "+40743755549",
  "devices": 1
}
CâmpTipDescriere
extensionstringInteriorul de pe care se face apelul.
numberstringNumărul format, după eliminarea separatorilor.
devicesinteger · nullCâte telefoane ale interiorului au sunat. Când colegul are un telefon fix și aplicația de mobil, ambele sună, iar cel care ridică face apelul.

Răspunsul 200 înseamnă că colegul a ridicat și centrala formează numărul. Ce se întâmplă mai departe (răspuns, ocupat, fără răspuns) nu este cunoscut în acel moment; vezi Apelul după pornire.

Din Node.js, cu un timp de așteptare potrivit pentru o cerere care durează cât sună telefonul:

const res = await fetch("https://api.criox.ro/v1/extensions/101/dial", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CRIOX_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ number: "+40743755549", name: "Ion Popescu" }),
  signal: AbortSignal.timeout(30_000),
});
const body = await res.json();
if (res.ok) {
  console.log(`Colegul a ridicat; centrala formează ${body.number}.`);
} else if (body.error === "phone_no_answer") {
  console.log("Colegul nu a răspuns la telefon.");
} else {
  console.log(`Apelul nu a pornit: ${body.error} (${body.message})`);
}

Erori

Pe lângă erorile comune, descrise în Prezentare, ruta are coduri proprii. Codurile 409 descriu starea telefonului colegului și nu dispar la reîncercare imediată; spune-i utilizatorului ce s-a întâmplat.

CodHTTPDescriere
invalid_parameter400extension nu este un interior, number lipsește sau nu este un număr de telefon, ori name este prea lung. message indică problema.
invalid_body400Corpul cererii nu este JSON valid.
insufficient_scope403Cheia nu are permisiunea calls:dial. Creează o cheie nouă, cu permisiunea bifată.
extension_not_found404Interiorul nu există în contul tău sau este oprit.
own_number409Numărul cerut este chiar interiorul de pe care se face apelul.
phone_offline409Interiorul nu are niciun telefon fix sau aplicație de mobil conectată. Dacă colegul are deschis doar softphone-ul din browser, message spune acest lucru; din browser, colegul poate suna direct din CrioX.
phone_ringing409Telefonul interiorului sună deja, pentru o cerere trimisă mai devreme. Așteaptă răspunsul acelei cereri.
phone_busy409Telefonul este ocupat sau are „nu deranja” pornit.
phone_no_answer409Telefonul a sunat 15 secunde și nimeni nu a răspuns. Nimic nu a fost format.
dial_failed502Centrala nu a putut porni apelul dintr-un alt motiv. Dacă se repetă, scrie-ne la suport@criox.ro.
unavailable503Centrala nu răspunde momentan. Reîncearcă după câteva secunde.

Apelul după pornire

După răspunsul 200, apelul continuă pe centrală ca orice apel efectuat de colegul tău. Rezultatul lui ajunge în aplicația ta pe două căi:

Răspunsul la cerere nu conține id-ul apelului, pentru că apelul se creează pe centrală abia după ce colegul a ridicat. Pentru a lega apelul de cererea ta, folosește interiorul, numărul și momentul: started_at al apelului este la câteva secunde după răspunsul 200.

Un apel pornit prin API care nu a fost preluat de celălalt capăt apare în istoric cu result no_answer, busy sau failed, ca orice apel efectuat.

Întrebări frecvente

Pot suna un coleg, nu un număr extern?

Da. Trimite interiorul colegului ca number, de exemplu "number": "102". Apelul este intern și nu apare în GET /v1/calls, nici în evenimente.

Colegul lucrează doar din browser. Cum îl ajut să sune?

Prin API, apelul se face de pe un telefon fix sau de pe aplicația de mobil înregistrată pe interior. Când colegul are deschis doar softphone-ul din browser, cererea primește 409 phone_offline, iar message spune că softphone-ul este deschis. În acest caz, colegul sună din CrioX, unde numerele sunt deja legături de apel.

De ce nu răspunde telefonul singur, ca să nu mai fie nevoie de ridicare?

Pentru că apelul ar pleca atunci fără nicio persoană la telefon. O cheie compromisă ar putea forma orice număr, în afara programului, pe factura ta. Ridicarea receptorului este singura confirmare care nu depinde de nicio setare.

Cât durează cererea?

Cât sună telefonul colegului: de la o secundă, dacă ridică imediat, până la aproximativ 15 secunde, dacă nu răspunde. Setează un timp de așteptare de cel puțin 30 de secunde pentru această cerere, mai mare decât cel folosit pentru citiri.

Pot trimite două cereri una după alta pentru același coleg?

Cât timp telefonul sună pentru prima cerere, a doua primește 409 phone_ringing. După ce colegul a ridicat, o cerere nouă este acceptată: telefonul decide dacă o arată ca apel în așteptare sau o respinge ca ocupat.

CrioX · suport@criox.ro · live.criox.ro