Skip to main content

SMS Agent

Audience: Engineering · Where in app: Settings → AI Agents → SMS Agent · Plan availability: admin gate company.sms_agents_allowed

The text twin of the Outbound Call Agent: each agent is a slot in company.sms_agents with its own instructions, webhook_secret, and sending number (ms-ai elabs_phone_numbers, purpose: 'sms', bound to the agent_key). Send-only — inbound replies are not handled yet.

Model & config

  • company.sms_agents — Mixed array (schema-evolution freedom; required fields enforced in AiSmsAgentController). Per agent: agent_key, agent_name, agent_instructions, max_length (clamped server-side), webhook_secret.
  • Gate: company.sms_agents_allowed (default 0; the SMS card shows when > 0, create enforces it as a hard cap; admin-controlled per company).
  • Message log: SmsAgentMessageModel (sms_agent_messages) — one row per send attempt, status honesty-gated like NoxActionModel: sent only when Twilio returned a message SID (delivery receipts not tracked), else failed / suppressed. Carries from_phone, body (the actual text, for AI sends the model output), ai_generated, context, source (test | webhook | scheduled | api), ghl_contact_id.

Backend routes

RoutePurpose
GET/POST /ai-sms-agents, GET/PATCH/DELETE /ai-sms-agents/:agent_keyAiSmsAgentController CRUD (backend/app/routes/aiSmsAgentRoutes.js)
POST /ai-sms-agents/:agent_key/rotate-secret · /clonesecret rotation, agent clone
GET /ai-sms-agents/:agent_key/messagesthe Logs tab (reads sms_agent_messages)
POST /ai-sms/webhookpublic trigger (AiSmsWebhookController@send)

Trigger webhook

POST /ai-sms/webhook{ company_id, agent_key, secret_key, to_phone, action, … }:

  • Auth: secret_key must equal that agent's webhook_secret (403 on mismatch) — same scheme as the outbound-call webhook. 400 missing fields / unknown action, 404 unknown company/agent.
  • Actions: send_sms (caller supplies the literal message) · generate_sms (agent writes the message from context with its instructions, then sends).
  • Policy lives in the backend, not ms-ai (mirrors the call path): global do-not-contact via NoxGhlActionService.isSuppressed (logged as suppressed, never sent), per-agent max_length cap, signature check, and the log row — applied once for every trigger source.
  • source is trusted only as test / scheduled; anything else logs as webhook.

Trigger surfaces

  • GHL workflow action (backend/app/routes/goHighLevelRoutes.js): POST /go-high-level/action/sms-agents returns this company's agents as dynamic-field options; POST /go-high-level/action/send-sms executes — resolves the company from the GHL payload and relays through /ai-sms/webhook.
  • Scheduled SMS: ScheduledNoxActionModel rows with kind: 'sms' (ai/plain modes) fired by ScheduledNoxActionJob (schedular, every 5 min, atomic claim) → /ai-sms/webhook with source: 'scheduled'; the Twilio message SID is stamped back on the row. Surfaced in the SmsAgent Scheduled tab and the Calls-page scheduled panel.
  • Outbound call agents can also text via POST /ai-outbound/send-sms (auth identical to the call webhook; sends from the call agent's number) — see Outbound Call Agent.

ms-ai side

Endpoint (elevenlabs.controller.ts, secret auth)Does
POST /elevenlabs/send-smssends from the agent's number via the company Twilio subaccount
POST /elevenlabs/compose-smscomposes (does not send) from instructions + context; billed under cost bucket KnownAgent.SMS
POST /elevenlabs/import-phone-number/twilio/smsbind an owned SMS-capable number to an agent (purpose: 'sms')
POST /elevenlabs/buy-phone-number/twilio/smsin-app buy into the company subaccount, provisioned for SMS (wallet-gated like voice numbers)

Metering: twilio-sms-cost:meter cron (number-rental.scheduler.ts, every 10 min) — twin of the call-cost sweep, meterTwilioSmsCosts(), debits Twilio's settled per-message price against the telephony wallet, idempotent per Message SID, app-purchased numbers only. See Telephony › SMS.

Frontend

frontend/src/views/settings/ai/agents/SmsAgent/ + SmsAgentCard.vue — agent list, instructions, number tab, Webhook tab (endpoint + secret + test panel → source: 'test'), Logs tab, Scheduled tab.

Outbound Call Agent · Telephony › SMS · AI Credits