Skip to content

Phone

The phone module manages phone number lifecycle: listing owned numbers, purchasing new ones via Twilio, and assigning agents to handle inbound calls.

src/mods/phone/
├── api/ # CRUD endpoints for phone numbers and agent assignment
├── components/ # UI: phone list, card, details form, buy flow, confirm modal
├── types/ # Phone, PhoneData, BuyPhoneResponse, SearchAvailableResponse
└── views/ # PhoneListView, PhoneDetailsView, BuyPhoneView

All endpoints require an authenticated Session.

RouteMethodDescription
/api/phonesGETList all org phone numbers
/api/phones/{id}GETGet a single phone by UUID
/api/phones/{phone_number_id}/agent/{agent_id}PUTAssign an agent to a phone
/api/phones/{phone_number_id}/agentDELETERemove agent assignment

The purchase endpoints live in the twilio module but are part of the buy flow:

RouteMethodDescription
/api/twilio/search-available-numbersPOSTSearch by area code
/api/twilio/buy-phone-numberPOSTPurchase an E.164 number
pub struct Phone {
pub id: Uuid,
pub number: String, // E.164 format, e.g. "+15551234567"
pub agent_id: Option<Uuid>, // None = no agent assigned
}

BuyPhoneResponse maps to HTTP status codes:

VariantHTTP Status
Success(String)201
InvalidPhoneNumber400
NoNumbersAvailable404
TwilioNotConfigured500
TwilioError(String)502
InternalError(String)500

SearchAvailableResponse follows the same pattern, returning Vec<AvailablePhone> on success (200).

User enters 3-digit area code
→ POST /api/twilio/search-available-numbers
→ Results grid: friendly name, location, capability badges (Voice/SMS/Fax)
→ User selects a number → ConfirmPurchaseModal
→ POST /api/twilio/buy-phone-number (E.164 number)
Server side:
1. Validate E.164 format
2. Fetch org Twilio credentials
3. Call Twilio API to purchase
4. Insert phone_number record (id, org_id, number, twilio_sid, agent_id=None)
5. Auto-assign default analyzers to the new number
6. Set voice webhook URL on Twilio to {APP_HOST}/twilio/voice
→ Navigate to phone list

The phone details view loads both the phone and all available agents. A dropdown lets the user pick an agent or select “No agent”:

  • Assign: PUT /api/phones/{phone_number_id}/agent/{agent_id} — sets agent_id on the phone record
  • Clear: DELETE /api/phones/{phone_number_id}/agent — sets agent_id to None

After saving, the phone data refetches to reflect the change.

PhoneListView — Grid of phone cards (1/2/3 columns responsive). Each card links to the details view. Empty state shows a prompt to buy a number. Header includes a “Buy Number” button.

PhoneDetailsView — Loads phone + all agents in parallel. Renders a form with agent selector and save button.

BuyPhoneView — Hosts the purchase flow. Navigates to the phone list on successful purchase.

  • Agent — agents are assigned to phone numbers to handle calls
  • Twilio — provides the purchase and search APIs, receives inbound calls