Hosted Mode
Hosted mode is the easiest way to ship something useful.
You provide the prompt. Saperly handles the call loop.
compliance_enabled: true on the line. With the flag off, TCPA, GDPR, and local telecom compliance are the customer’s responsibility. See Compliance and Consent for the full liability framing and how to opt in.When to use it
Use hosted mode if:
- you want to launch quickly
- your call logic is mostly prompt-driven
- you do not want to run a webhook server yet
- you want a receptionist, intake agent, reminder bot, or FAQ line
Create a hosted line
Important fields
system_prompt
This is the core behavior contract for the line.
Be specific. Tell the agent:
- who it is
- what it can help with
- what it must never do
- when it should escalate or stop
begin_message
Use this to avoid dead air at the start of the call.
If you leave it out, the line waits for the caller to speak first.
voice
Use GET /api/v1/voices to list available voice slugs before you pick one.
context_limit
Higher values preserve more conversation history but use more tokens and may slow longer calls.
Prompt engineering examples
The quality of your system_prompt (or topic for one-off calls) decides how the line behaves. Two concrete patterns to start from:
Receptionist
Appointment reminder (one-off conversation call)
One-off conversation calls
If the prompt changes per call, use the conversation call endpoint instead of creating a new line every time.
Good first hosted-mode use cases
- front desk and receptionist
- FAQ line
- appointment reminders
- after-hours triage
- simple order status assistant
When not to use hosted mode
Do not start here if your call needs:
- deep internal business logic
- privileged backend actions
- strict deterministic flow control
- your own model runtime
In those cases, use Webhook Mode or Audio Mode.
Testing your hosted line
Once the line is created, walk through the full loop end to end before you put it in front of real callers.
Verify the greeting
You should hear begin_message spoken aloud in the voice you selected. If there is silence, the line is likely waiting for you to speak first because begin_message was not set.
Have a short conversation
Ask 2-3 questions your system_prompt covers. Listen for on-topic answers and for the refusal behavior you defined (for example, the emergency handoff in the dental example).
GET /api/v1/voices), (3) your balance is sufficient.Call recording
Enable recording per line:
Retrieve the recording URL from the call object after the call ends:
The response includes recording_url and transcript fields when recording is enabled.
Receiving call events on your webhook
Hosted-mode lines deliver two call lifecycle events:
call_incomingfires when an inbound call arrives, before the agent connects. Delivered tostatus_callback_url.call_endedfires after the call ends and includes the full transcript incontext. Delivered to the first URL set on your line, in this order:webhook_url(per-line, explicit)- Account
default_webhook_url(account-level fallback) status_callback_url(per-line, used as fallback)
To receive both events at one endpoint, set status_callback_url. To send call_ended to a different endpoint than call_incoming, also set webhook_url or account default_webhook_url.
Inbound SMS
Hosted mode handles voice for you. Voice mode does not gate SMS.
Every line — hosted, webhook, or audio — receives inbound SMS. Saperly records the consent record and logs a sms_received compliance event regardless of voice mode.
To auto-reply, set webhookUrl on the line. Your server receives the sms_received event and replies by calling POST /api/v1/messages with text generated by your own LLM:
A hosted line without webhookUrl still records consent and the compliance event on inbound SMS, but Saperly will not deliver the event to a customer endpoint and your code has nothing to reply with. See SMS and Conversations for the reply API and 24-hour conversation window.
End-to-end walkthrough
The fastest path from zero to a working hosted line. You provision one line, take an inbound call, and confirm the response path works.
1. Create a line
2. Save the returned phone number and line ID
You’ll use the phone number to place a real test call. Save the line ID for later inspection.
3. Call the number
Verify:
- the call connects
- the AI answers
- the opening message plays
- the transcript appears on the call record
sk_test_ key cannot reach a line provisioned with an sk_live_ key, and vice versa), (2) your balance is above 0, (3) the line status is active. Run GET /api/v1/lines to verify.4. Inspect the created line
5. Inspect the resulting call
If this worked, you already have a production-shaped happy path.
Outbound calls
If the line has compliance_enabled: true, outbound calls require consent first. Compliance is off by default. See Compliance and Consent to decide whether to turn it on.
1. Grant consent
2. Place the call
What to verify before you keep building
Common first-day mistakes
- Using the wrong host. Use
https://saperly.com/api/v1. - Forgetting consent before outbound calling when
compliance_enabled: true. - Mixing up hosted-mode and webhook-mode fields on the same line.
