Skip to main content

Textify Voice: Product & Functional Specification

Status: draft for implementation · Owner: Joshua Saimon Sakweli (QBIT SPARK) Companion· doc:Updated 2026-11-08 Companion: ARCHITECTURE.md (components, flows, data model, APIs, infra). This file is writtenWritten so a new engineer, or a new AI coding session, can pick up the work with no prior context.


1. Background

Textify Africa (textify.africa) is an existing bulk SMS + WhatsApp platform, written in Go, live in Tanzania, Uganda and Nigeria. Its main model is white-label: agencies and resellers ("partners")partners brand the platformit as their own, set their own prices, and onboard their own customers.customers, Customerswho top up a prepaid wallet with mobile money or card..

We areWe're adding avoice third/ channel:call center as a new Textify module, so the callsame centerTextify / business phone linecustomers product,can use it from the same portal and wallet. The product is similar in spirit to SemaCall (semacall.com):com: "One business. One number. Every team."team"), Customersplus call one number; the call reaches the right person (or an AI answers) in the customer'Textify's language.own strength, bulk: voice broadcast with SMS fallback.

The voice capabilityVoice is built as a separate serviceservice, the Voice Engine ("Voice Service") in Java Spring BootBoot). It is an engine: it knows nothing about users, logins, roles or money. It is told what to do with numbers and calls and reports what happened. Textify consumes it aslike any other API. Other QBIT SPARK products (JikoXpress, Mauzodukani, NexGate) can consume it later.

Status: we already have a client.working TheTanzanian Voicenumber Servicefrom must not know about Textify'Africa's users, auth or money.Talking.

2. Goals

  1. A Textify customer can getgets a Tanzaniannumber phonewith numbera greeting + keypad menu, and havecalls every incoming call answered, by an AI receptionist (Swahili first, English supported) or byreach human agents answering in the browser.
  2. AIOutbound: canagents make handclick-to-call calls from the callerbrowser.
  3. over
  4. Broadcast: send a recorded voice message to athousands humanof numbers, with "press 1 to talk to us", retries, opt-out, and SMS fallback for people who didn't answer when needed..
  5. Every call is logged, optionally recorded, transcribedrecorded, and (Phase 2) transcribed + summarized by AI.
  6. Missed calls trigger an→ automatic SMS/WhatsApp follow-upfrom (Textify already does messaging).Textify.
  7. Usage is billedBilling per minute / per answered call from the existing Textify wallet.wallet.
  8. The(Phase Voice Service is3) reusableAI receptionist byand otherAI QBIToutbound SPARKcalls productson laterthe (JikoXpress,same Mauzodukani, NexGate) without changes.engine.

3. Non-goals (for now)

  • No videousers, calls over phone lines (LiveKit SIP does not support video over SIP anyway).
  • No user accounts,auth, roles, plans or pricingprices insidein the Voice Service.engine.
  • No approval workflows anywhere. Keep everythingEverything self-serviceservice.
  • and
  • No simple.video over phone lines.
  • No message broker (Kafka/RabbitMQ/MQTT) in v1 (see ARCHITECTURE §7).
  • Countries other than Tanzania (Uganda/Nigeria later, using the same design).
  • Building our own telco connection. We use Africa's Talking for numbers and the PSTN.

4. Key terms (plain language)

Term Meaning
PSTN / telco network The normalNormal phone network (Vodacom, Airtel, Yas, Halotel, TTCL).
ATAfrica's Talking: our numbers and connection to all TZ networks.
Voice callbackAT POSTs to our URL when something happens on a call; we reply with XML instructions (Say, Play, GetDigits, Dial, Record…).
SIP The protocolProtocol internet phones use to set up calls (ring, answer, hang up). Like HTTP but for calls. Voice audioAudio travels separately over RTP.
SIP accountOne login for one phone/softphone (like an email account but for calls)RTP).
SIP trunk A connectionConnection carrying many calls at once between two systems over SIP.systems. Here: Africa'sAT Talking ⇄→ our LiveKit.
Human agentA staff member who answers calls (in the browser app).
AI agentA bot that talks on the phone: listens → thinks → speaks.
STT / LLM / TTSSpeech-to-text, the language model (the "brain"), and text-to-speech (the voice).
Realtime / speech-to-speech modelOne model that hears and speaks directly (e.g. OpenAI Realtime).
LiveKit room A live audio session. Each phoneanswered call = one room.room; Thethe caller joinsand asagents a(and "SIPlater participant";AI) AIare or humans join the same room.participants.
DispatchBrowser ruleagent Staff answering calls in the Textify web app (LiveKit configJS SDK).
FlowWhat happens when a number rings: greeting → menu → route. Stored as JSON.
EndpointSomething that decidescan whichtake rooma ancall: incomingring callgroup goesof agents, voicemail, AI (later).
CampaignA broadcast: one audio message to anda whichlist AIof agent joins.numbers.
DTMF Keypad presses during a call ("press 1").
Cold / warm transferCold: just forward the call. Warm: AI briefs the human first, then hands over.

5. Providers we use and why

3)controlled
Provider Role Why
Africa's Talking (AT) TanzanianNumbers, phonePSTN numbersboth +directions, connectionvoice tocallbacks/XML, alloutbound TZcall telcosAPI, +call recording, SIP trunk Localto numbers and licensing. LiveKit's own phone numbers are US-only.LiveKit
LiveKit (self-hosted, opendedicated source)box) MediaRooms server: rooms, SIP,+ browser agents (WebRTC), hold audio, recording,(Phase transfers AlreadyAI usedparticipant. inWe productionalready byrun usLiveKit for NexGateNexGate; (video,Voice spaces,gets audioits calls).own Self-hosted = no per-minute LiveKit fee.box
OpenAI AIPhase brain2: transcription + summaries (REST). Phase 3: live AI voice (Realtime model),over transcription,SIP, summaries Bestfrom overall quality. Swahili quality must be tested; TTS can be swapped.Java)

6. Costs (Africa's TalkingAT Tanzania, as published on africastalking.com/pricing, Oct 2026)

in
Item Price
Regular number (Airtel) Setup TZS 100,000 + 18% VAT; TZS 35,000/month + 18% VAT
Toll-free number Same as regular, plus+ TZS 170,000 deposit
Regular incomingIncoming TZS 17 / min
Regular outgoingOutgoing TZS 60 / min
Toll-free incoming TZS 200 / min
SIP agent legTZS 4.30 / min
SIP trunk TZS 8.61 / min
ConferenceSIP agent TZS 8.614.30 / min
TTS (Google,not viaused AT) perour characterdesign)

6.1

How the costs combine

Every call has leg 1 (customer ⇄ our ATcalls number) and, if someone answers, leg 2 (our number ⇄ whoever answers).combine:

Customer ──leg 1──> AT number ──leg 2──> answerer
          17 in / 60 out          SIP trunk to LiveKit: 8.61
                                  forward to a mobile: 60   (avoid)
ScenarioCall type Approx. costTZS per/ minutemin
Inbound, only greeting/menu/voicemail (no agent)17
Inbound callanswered into LiveKit (AI orby browser agent)agent (via LiveKit) 17 + 8.61 ≈ TZS 25.61 + AI cost if AI answers
Outbound Click-to-call fromoutbound LiveKit(agent toin a customerbrowser) 60 + 8.61 ≈ TZS 68.61 (to confirm)
InboundBroadcast, forwardedmessage to a staff mobile (fallback only)only 1760 per answered minute (unanswered likely free, confirm)
Broadcast, caller presses 1 → agent60 + 608.61 ≈for TZSthe 77talking part

KeyAgreed facts already agreed:facts:

  • Cost follows call minutes, not the number of agents. IdleUnlimited agents costper nothing, so customers can add unlimited agents.account.
  • AvoidNo forwarding to mobiles.mobiles by default Agents(17 answer+ in60 the= browser/app.77/min).
  • Design decision: money is not the constraint, so all calls go through the SIP trunk into LiveKitAI (onePhase call path, simpler code). We don't split IVR onto AT XML to save the 8.61.

6.2 AI cost (on top of telco)

An AI-answered minute3) adds OpenAI cost (Realtime, or STT + LLM + TTS). This is several times the telco cost per minute. ExactMeasure per-minute figures must be measured duringin the PoC frombefore realpricing. calls (token/audio usage logged per call).

6.3

Indicative selling prices (suggestion, to be finalizedfinalize after PoC)

: number 90–100/min;broadcast100–150
ItemSuggested price
Number rentalTZS 60–75k75k/month; /inbound month
Inbound minute, human-answeredTZS 40–5050/min; /outbound min
Outboundper answered call; AI minuteTZS 90–100 / min
AI-answered minuteTZS 150–250 / min
AI250; summary add-on + TZS X / min (set after measuring)

Pricing livesTBD. Prices live in Textify onlyonly.. The Voice Service only reports usage.

7. Users & personasPersonas

  • Business owner / admin (Textify customer): getsnumber asetup, number,greeting, sets the AI greeting and business info, addsmenu, agents, seesring calls,groups, recordingscampaigns, andcall summaries.logs, recordings.
  • Human agentAgent: logs into the Textify web app,Textify, sets themselves available,Available, answers calls in the browser, makes click-to-call outbound calls.call.
  • Caller / call recipient: aanyone member of the public calling the business number fromon any TZ network.
  • Partner (reseller)later): later phase. Resellsresells voice under their own brand (same white-label model as SMS).brand.

8. Functional requirements

8.1 Numbers & flows

  • FR-N1: TextifyOps admin (QBIT/Textify ops) obtains numbers fromregisters AT and registers themnumbers in the Voiceengine; Service.Textify assigns a number to an account.
  • FR-N2: AEach number is assigned to exactlyhas one accountflow (JSON, built in Textify's tenantUI, id,stored opaqueand toexecuted by the Voice Service)engine).
  • FR-N3: EachFlow numbernode hastypes an(keep answer modesmall): AI_FIRSTsay, play, menu (AIGetDigits answers,with can hand over)options), HUMAN_ONLYring (ring agents)group), AI_ONLYvoicemail, hangup. Phase 3: ai.
  • FR-N4: ReassigningFlow oroptions: releasingbusiness hours (open/closed branch), recording on/off, ring timeout, no-answer action.
  • FR-N5: Saving a numberflow istakes aeffect singleon APIthe next call. No approval.

8.2 Inbound calls

  • FR-I1: CallerAT dialscallback the→ engine looks up number → call arrives over the SIP trunkaccount → LiveKit creates a room → Voice Service records a call RINGING.flow.
  • FR-I2: BeforeBalance answering,check: the Voice Serviceengine asks Textify "can this account take a call?" (prepaid balance). If Textify isunreachable unreachable,→ allow the call (fail-open) and bill later..
  • FR-I3: IfNo thebalance account can't pay: play a→ short politemessage, messagehang and end the call (no AI cost).up.
  • FR-I4: Play a recording consentRecording notice when recording is on ("Simu hii inaweza kurekodiwa kwa ajili ya ubora wa huduma"; in English: "This call may be recorded for quality of service").
  • FR-I5: AI_FIRST / AI_ONLY → AI receptionist joinsGreeting and greetsmenu withrun theon account'sAT greeting.XML (no LiveKit cost).
  • FR-I6: HUMAN_ONLYring node → ringcall is dialed into LiveKit → caller hears hold audio → engine rings the account'group's available agents (ringin group).their If nobody answers within N seconds (default 30) → voicemail or AI fallback (configurable) → mark MISSED if nobody handled it.browsers.
  • FR-I7: CallerWaiting: keypressesif (DTMF)all agents are supportedbusy, forthe simplecaller menusstays on hold and the engine rings again as agents become free ("pressengine-side 1queue), foruntil sales").the timeout.
  • FR-I8: Timeout → noAnswer action: voicemail, hangup, (Phase 3) AI.
  • FR-I9: Not handled by anyone → MISSED → event → Textify sends the SMS/WhatsApp follow-up.

8.3 AI receptionist

  • FR-A1: Speaks Swahili first, switches to English if the caller does. Handles code-switching (Swahili and English mixed).
  • FR-A2: Uses the account's instructions (business info, FAQs, hours, tone) supplied by Textify.
  • FR-A3: Short, spoken-style answers. Never invents prices or policies. If unsure → offer a human.
  • FR-A4: Tools the AI can use (v1): transfer_to_human, take_message, end_call. Later: account-defined tools (check order, book appointment) via webhooks to the client app.
  • FR-A5: Handover: AI calls transfer_to_human → Voice Service rings availableBrowser agents → first to accept joins the room → AI briefly introduces the context (warm transfer), then leaves.
  • FR-A6: If no agent is available: AI takes a message (name, number, reason) → stored on the call → event to Textify.
  • FR-A7: Barge-in/interruptions and turn detection are handled by LiveKit Agents.

8.4 Human agents (browser)

  • FR-H1: Agents are identified only by an opaque agentRef from+ Textify.display name in the engine. Textify owns the user, login and role.user.
  • FR-H2: Agent sets statusStatus AVAILABLE / BUSY / OFFLINE. throughOnline Textify,presence whichis forwardsautomatic it towhile the Voiceagent's Service.browser is connected.
  • FR-H3: IncomingRing callpopup →+ available agentsringtone in the group get abrowser; ringfirst to accept wins; inothers' thepopups browser (data message over LiveKit). Accept → join the call room. Reject or timeout → next.close.
  • FR-H4: Ring strategy:strategy per group: ALL_AT_ONCE (default) or ROUND_ROBIN.
  • FR-H5: Agent can mute, hold,Mute, hang up, and transfer to another agent.agent or group.
  • FR-H6: Click-to-call outbound from the dashboard: agent clicks a number → Voice Service dials out via the trunk → agent and customer in one room.
  • FR-H7: FallbackOptional transfer to an external mobile is allowed (costs about TZS 60/min). Offoff by default.default; extra cost).

8.4 Outbound: click-to-call

  • FR-O1: Agent clicks a number in Textify → engine places the call via AT from the account's number (caller ID = that number).
  • FR-O2: Agent is already in the call room in the browser and hears ringing. Customer answers → connected.
  • FR-O3: Balance check before dialing.

8.5 Outbound: broadcast campaigns

  • FR-C1: Textify creates a campaign: account, from-number, audio (uploaded file URL) or TTS text, recipients list, start time, calling window (default 08:00–20:00 EAT), max calls per second / concurrent, retry policy (default 2 retries, 30 min apart, for no-answer/busy).
  • FR-C2: Optional keypad options after the message: 1 → talk to agents (ring group), 9 → opt out. (Phase 3: 1 → AI.)
  • FR-C3: Opt-out / do-not-call list per account, always checked before dialing.
  • FR-C4: Pause / resume / cancel any time (Textify pauses automatically when the wallet runs low).
  • FR-C5: Per-recipient result: ANSWERED (seconds, keypress), NO_ANSWER, BUSY, FAILED, OPTED_OUT.
  • FR-C6: Progress events (batched) + completion event. Textify can SMS everyone who didn't answer (key selling point).
  • FR-C7: Throughput limited by AT's calls-per-second / concurrent-call limits for our account (confirm).

8.6 Recording, transcription, summary

  • FR-R1: Recording on/off per numbernumber/campaign (default on, for agent calls, with consent notice).
  • FR-R2: AfterEngine thedownloads call:every audiorecording fileinto stored in our object storage (never rely on provider links).immediately.
  • FR-R3:R3 Transcription(Phase 2): transcript (Swahili/English) →+ summary containing:JSON:
    • 2–3 line summary
    • customersummary, intent, resolvedresolved, yes/no
    • follow-ups,
    • follow-upsentiment, actions
    • sentiment (positive / neutral / negative)
    • topic tag (sales, support, complaint, inquiry, other)
    topic.
  • FR-R4: TranscriptRetention + summary attached to the call record; event summary.ready sent to the client app.
  • FR-R5: Retention: recordings deleted afterdefault 90 days by(per-account default (configurable per account)setting). Tanzania Personal Data Protection Act applies.
  • FR-R6: Summary is a billable add-on (Textify decides price; Voice Service reports summaryMinutes).

8.6 Missed calls & follow-ups

  • FR-M1: A call is MISSED if no human or AI handled it (e.g. HUMAN_ONLY with nobody answering and no fallback, or the caller hung up while ringing).
  • FR-M2: Voice Service emits call.missed with the caller number. Textify sends the SMS/WhatsApp follow-up ("Samahani tumekukosa, tutakupigia tena"; in English: "Sorry we missed you, we'll call you back") using its existing messaging.

8.7 Usage & billing

  • FR-B1: On every call end,end the Voice Serviceengine emits call.endedusage: withdirection, usageseconds broken down byper leg (seconds): inboundSeconds, outboundSecondspstnSeconds, trunkSeconds, aiSeconds), AT's reported externalTransferSecondsamount, recordedrecorded, (bool), summarySeconds.summary.
  • FR-B2: Textify prices and deducts from the wallet.deducts. The Voice Serviceengine never deals withhandles money.
  • FR-B3: Events are idempotent (event id), andsigned, retried until Textify returns 2xx.

8.8 Dashboard (built in Textify,Textify; data from the Voice Service)engine)

  • Call log:log, time,call direction,detail caller,(audio, number,transcript, handledsummary), number + flow editor, agents and status, ring groups, campaigns (progress, results, "SMS non-answerers"), simple stats (answered/missed, by (AIagent, / agent), duration, status, cost (Textify-computed).

  • Call detail: audio player, transcript, summary, AI message taken.
  • Number settings:campaign answer mode, greeting, AI instructions, recording on/off, ring group, timeout, fallback.
  • Agents: availability, calls handled.
  • Simple stats: calls per day, answered vs missed, AI-handled vs human, average duration.
rate).

9. Non-functional requirements

beyondphonenumbers.
Area Requirement
LatencyAI response start < ~1 s after the caller stops speaking (target). Call connect < 3 s.
Availability VoiceCalls Service must keep taking callswork if Textify is down (fail-open balance check, queued webhooks).events)
Isolation Dedicated LiveKitVoice boxbox, for Textify Voice. Notnot shared with NexGate.NexGate's LiveKit
Security SIP/RTP portsSIP open only to Africa'sAT; TalkingAPI IPs.keys Service+ tokensHMAC between apps.services; Signedsigned/verified webhooks.webhooks Noeverywhere user(ARCHITECTURE PII§8)
LatencyCallback XML response < 500 ms; call reaches agent browser ring < 3 s
Privacy ConsentRecording notice, retention policy, recordings inretention, our own storage, accesssigned only via the client app.
LanguageSwahili first-class. Test quality with real Tanzanian callers before selling AI.URLs
Simplicity REST + webhooks + Postgres + Redis + LiveKit. No broker, no OAuth, no approval workflows, no internal OAuth, minimal moving parts.flows

10. Phases

Phase 0: Proof of concept (goal: one real call end-to-end)

  1. Confirm withWorking AT (see §11). Get one TZ number +(done) SIP→ trunk.set callback URL to the engine → Say greeting works.
  2. DedicatedDial box:sip:{callId}@<livekit-sip-host> from the XML → caller lands in LiveKit serverroom + LiveKit SIP + Redis. Firewall restricted to AT.call-{callId}.
  3. InboundBrowser trunktest +page dispatch rule → Spring Boot dials OpenAI Realtime intojoins the room over→ SIPtwo-way audio with the caller.
  4. Check AT final callback: duration, amount, recording URL.
  5. Outbound: AT call API → AIanswer greets→ inDial Swahili.
  6. into
  7. Measure:LiveKit latency,→ audiobrowser quality, OpenAI cost per minute.
  8. Swahili test: 10–20 real people (Swahili, English, mixed). Judge understanding and voice. Swap TTS ifhears the voice is weak.customer.

Phase 1: Call center MVP (sellable)

  • Spring Boot Voice Service: accounts,Accounts, numbers, config,flows calls, events, LiveKit integration.
  • AI receptionist with handover to(say/play/menu/ring/voicemail/hangup), browser agents.
  • Browser agent clientagents (inlobby, Textify'sring, web app) +accept), ring groups + waiting, click-to-call.
  • call,
  • Recordingrecording to our storage, missed-call events, usage events, balance check.

    Phase 2: Bulk + storageintelligence Broadcast campaigns (throttle, window, retries, opt-out, press-1-to-agent, results, SMS fallback via Textify), OpenAI transcription + retention.

  • summaries,
  • Balancebusiness checkhours, +stats.

    Phase 3: AI call.endedai usageflow eventsnode: OpenAI Realtime joins the LiveKit room over SIP, controlled from Java; AI → wallethuman deductionhandover; in Textify.

  • Missed-call SMS/WhatsApp.

Phase 2

  • Transcripts + AI summaries (if not already in MVP).
  • Account-defined AI tools (webhooks to the client app: check order, booking).
  • Voicemail, business hours / after-hours behaviour.
  • Stats dashboard.

Phase 3

  • Voice broadcast (recorded message to a contact list: "bulk voice", fits Textify's bulk DNA). Check TZ calls-per-second limits.
  • AI outbound campaigns (remindersreminders, thatconfirmations, talksurveys). back).
  • Swahili
  • quality test with real callers first.

    White-Later: partner white-label voicevoice, forother partners.

  • countries,
  • Other countries (Uganda/Nigeria) through AT.
  • Otherother QBIT products as clientsengine of the Voice Service.
clients.

11. Open questionsQuestions for Africa's Talking (must answer before Phase 1)

  1. Can theXML TZDial SIP trunk route inbound calls for our number totarget an external SIP URI with a custom user part (our LiveKit SIP endpoint)sip:{callId}@our-host)? Note:Transport, LiveKitport, SIPcodecs does not support SIP REGISTER(G.711), soDTMF AT must send calls to us directly.method?
  2. Can it accept outbound calls from our server IP (and what auth: IP allowlist or username/password)?
  3. What are AT's SIP signalling and+ media IP addressesIPs (for our firewall and LiveKit allowlist).
  4. Billing for Dial-to-SIP: is it 17 (or 60 outbound) + 8.61 trunk? Anything else?
  5. Does Dial record="true" record a Dial to SIP, and what's the recording format and retention on AT's side?
  6. Calls-per-second and max concurrent calls (inbound + outbound) for our account; can they be raised?
  7. Outbound billing per second or per started minute? Are unanswered/busy calls free?
  8. Can the outbound call API take multiple numbers per request? What does it return (session ids)?
  9. ExactDo billingvoice forcallbacks come from fixed IPs? Is there any inboundcallback to trunksignature: 17 + 8.61? Any extra??
  10. Exact billing for outbound via trunk: 60 + 8.61? Any extra?
  11. Is the SIP agent TZS 4.30 charged on inbound calls too? Any setup/monthly fee for SIP agents?
  12. Are unanswered rings to SIP endpoints billed? 7b. The listed regular number is Airtel.: Howany doissues for callers onfrom Vodacom, Yas, HalotelHalotel, and TTCL reach it, and at what cost to them and to us?TTCL?
  13. Calls-per-secondTCRA: (CPS) limits and pricing in Tanzania (needed for broadcast).
  14. Supported codecs (G.711 PCMU/PCMA expected) and DTMF method (RFC 2833/4733).
  15. Doesdoes reselling voice to our customers need any TCRAa licence on our side,side? orRules isfor AT'sautomated/marketing licencecalls enough?(consent, Gethours, itcaller inID)? In writing.
  16. Number porting / getting several numbers quickly; toll-free availability.

AT is not on LiveKit's list of tested SIP providers (Twilio, Telnyx, Exotel, Plivo, Wavix, Sinch, didlogic). LiveKit is designed to work with any SIP provider, so the PoC must prove compatibility.

12. Risks

AIlimited.
Risk Mitigation
AT trunk can't deliverDial to an externalour SIP URI VerifyPhase first0 (§11test Q1).step 2 first. Fallback: AT VoiceSIP XMLnumbers +on ATsoftphones SIPfor agents for(no humans;LiveKit)
AT throughput limits slow broadcastsConfirm Q5; engine throttles; show ETA in Textify
Swahili STT/TTSAI quality poor(Phase 3) Early real-userReal-caller test; swapAI TTSonly provider;where keepit passes; human fallback prominent.
AI cost higher than expectedMeasure in PoC; short answers; pre-recorded greetings; cheap model for simple turns; price AI minutes higher.
SIP fraud/attacks Firewall + LiveKit allowlist to AT IPs only; LiveKit inbound trunk allowed_addresses + numbers.only
Textify outage blocks calls Fail-open balance check; queuedoutbox + retried webhooks.retries
RegulatoryRegulation (TCRA, PDPA) Written confirmationanswers; fromnotices; AT; consent notice;opt-out; retention policy.
Single box failure Fine for Phase 11–2; singleLiveKit/engine boxcan isscale OK;out addwith aRedis second node (LiveKit supports multi-node via Redis) when volume grows.later

13. Decisions log

# Decision
D1 NumbersEngine andmodel: telcoseparate Java Spring Boot Voice Engine, blind to users/auth/money; Textify (Go) consumes it via Africa'sREST Talking;+ media via self-hosted LiveKit; AI via OpenAI.webhooks
D2 AllAT calls go throughis the SIPonly trunkPSTN intopath, LiveKitboth directions (noinbound splitcallbacks; IVR on AT XML), for oneoutbound call path.API)
D3 AgentsGreetings/menus/voicemail/broadcast answeraudio inrun theon browserAT XML (no forwardingLiveKit to mobiles by default).cost)
D4 Any call that needs a person (or AI) is Dedicateddialed into LiveKit box forvia TextifyDial Voice, separate from NexGate's LiveKit.sip:{callId}@livekit
D5 SeparateAll Voiceagents Serviceanswer in Javathe Springbrowser Bootvia LiveKit. Knows(no AT SIP softphones, no users/auth/money;mobile ownsforwarding numbers,by routing, calls, recordings, usage events.default)
D6 Three adapters inside the engine: TextifyTelephony (Go)AT), Media (LiveKit), AI (OpenAI), ownsplain users,Java tenants,interfaces, partners,one wallet,implementation pricing, dashboard, messaging follow-ups.each
D7 Preferred:No noPython: Python.AI later via OpenAI Realtime joinsover the LiveKit room as a SIP participant,SIP, controlled from Spring Boot via OpenAI's call-control REST + WebSocket (ARCHITECTURE §2.5). Fallback: thinJava. Python LiveKit Agents worker (§2.2)only ifas OpenAI SIP interop or Swahili voice quality fails the PoC.fallback
D8 BillingService isauth: API key per minuteclient app from(in), theHMAC-signed Textifywebhooks wallet;(out), Voicesecret ServiceURL emits+ usageIP eventsallowlist only.for AT callbacks, built-in signatures for LiveKit/OpenAI
D9 RecordingCommunication: defaultREST on+ withwebhooks consent+ notice;Postgres 90-dayoutbox/job retentiontables default.+ Redis + LiveKit data messages. No Kafka/RabbitMQ/MQTT in v1
D10 Billing per minute / per answered call from the Textify wallet; engine reports usage only
D11Dedicated Voice box, separate from NexGate's LiveKit
D12No approval workflows anywhere.