Skip to content
Start free

Developers · API

v1

Configure the agent

get/v1/tenants/{customerId}/agent
put/v1/tenants/{customerId}/agent

Decide how a line answers the phone. PUT is a partial update that changes only the fields you send — to change just the greeting, send just the greeting.

Settings

Six things can change — the persona (persona), the greeting (greeting), tone (tone), business hours information (businessHours), what happens when a caller asks for a person (transfer) and summary email recipients (summaryRecipients). Format and length limits for each are in the API reference.

Only these six are accepted. Any other name is rejected with 400 without saving, and the response lists the names it accepts.

Writing the personapersona

Describe only how to treat callers and how to speak. You do not need to describe how features work — anything that is connected works on its own.

Write thisNot this
"Be polite, brief and friendly.""Call the order lookup function and read out the result."
"If you are not sure, say you will check and call back.""If the lookup returns nothing, ask again; if it fails, apologize."
"Refunds are accepted within 7 days of purchase."Notation like order_id or "title":

A persona that contains feature names or code-like notation is rejected — it would make the agent sound wrong on a call. The rejection code starts with persona. and says which rule failed (Errors & limits). error explains what to fix in a Korean sentence, so you can show it to the operator as is.

When saved, a sentence saying this is a live phone call is added in front and comes back with the value. Leave it there — sending it back does not duplicate it.

Business hours informationbusinessHours

Business hours are information. The stored value lets call statistics and summaries tell calls inside and outside business hours apart; it does not decide whether to answer — a line answers calls at any time. Set 24/7, or custom with a time zone (an IANA name such as Asia/Seoul) and open and close times per weekday; send null to clear it. The example below shows what custom looks like; the field structure is in the API reference.

When a caller asks for a persontransfer

Decide what happens when a caller asks for a person. The default is taking a message (take_message); to give a fixed answer instead, use standard_response. Put what the agent says in message. The value transfer_human is also accepted, but it behaves like taking a message — transferring to a person during a call is not provided. Send null to clear the setting.

Summary email recipientssummaryRecipients

A summary email goes out after each call. List up to 20 addresses (email), each with an optional list of keywords (keywords).

Keywords work as a switch that picks who receives a given call. They apply to the list as a whole, not per address.

  • If any keyword in the list appears in the call → that call's summary goes only to the addresses whose keywords matched.
  • If no keyword matches → the summary goes to everyone in the list.

So an address without keywords is not an "every call" address — it receives only the calls no keyword matched. With one address tagged refund, a call that mentions refunds goes to that address alone and the others do not get it. If an address must receive every call, it is safest to use no keywords at all.

Matching ignores case. A keyword made only of ASCII characters (letters, digits, symbols) matches at word boundaries only — kim does not match inside skimming, and AB- does not match inside AB-123. A keyword that contains non-ASCII characters, such as Korean, matches anywhere in the text, even inside a longer word.

Save settings

TENANT_ID="<customerId from the create response>"

curl -s -X PUT "$LS_BASE_URL/v1/tenants/$TENANT_ID/agent" \
  -H "Authorization: Bearer $LS_PARTNER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "persona": "You are the customer service agent for Example Mall. Be polite, brief and friendly.",
    "greeting": "Hello, this is Example Mall customer service.",
    "tone": ["friendly", "concise"],
    "businessHours": {
      "mode": "custom",
      "timezone": "Asia/Seoul",
      "schedule": {
        "mon": { "enabled": true, "open": "09:00", "close": "18:00" },
        "sat": { "enabled": false }
      }
    },
    "transfer": { "type": "take_message", "message": "Would you like to leave a message for the staff?" },
    "summaryRecipients": [{ "email": "cs@example.com", "keywords": ["refund"] }]
  }'
const BASE_URL = process.env.LS_BASE_URL;
const API_KEY = process.env.LS_PARTNER_KEY;
const tenantId = '<customerId from the create response>';

const res = await fetch(`${BASE_URL}/v1/tenants/${tenantId}/agent`, {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    persona: 'You are the customer service agent for Example Mall. Be polite, brief and friendly.',
    greeting: 'Hello, this is Example Mall customer service.',
    tone: ['friendly', 'concise'],
    businessHours: {
      mode: 'custom',
      timezone: 'Asia/Seoul',
      schedule: {
        mon: { enabled: true, open: '09:00', close: '18:00' },
        sat: { enabled: false },
      },
    },
    transfer: { type: 'take_message', message: 'Would you like to leave a message for the staff?' },
    summaryRecipients: [{ email: 'cs@example.com', keywords: ['refund'] }],
  }),
});
if (res.status === 400) {
  const body = await res.json();
  // If body.code starts with persona., body.error can be shown to the operator as is.
}
import os, requests

BASE_URL = os.environ["LS_BASE_URL"]
API_KEY = os.environ["LS_PARTNER_KEY"]
tenant_id = "<customerId from the create response>"

res = requests.put(
    f"{BASE_URL}/v1/tenants/{tenant_id}/agent",
    headers={
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    },
    json={
        "persona": "You are the customer service agent for Example Mall. Be polite, brief and friendly.",
        "greeting": "Hello, this is Example Mall customer service.",
        "tone": ["friendly", "concise"],
        "businessHours": {
            "mode": "custom",
            "timezone": "Asia/Seoul",
            "schedule": {
                "mon": {"enabled": True, "open": "09:00", "close": "18:00"},
                "sat": {"enabled": False},
            },
        },
        "transfer": {"type": "take_message", "message": "Would you like to leave a message for the staff?"},
        "summaryRecipients": [{"email": "cs@example.com", "keywords": ["refund"]}],
    },
)
if res.status_code == 400:
    body = res.json()  # If body["code"] starts with persona., body["error"] can be shown to the operator as is.

200 — the response is always the full settings after the update.

{
  "persona": "You are handling a live phone call.\n\nYou are the customer service agent for Example Mall. Be polite, brief and friendly.",
  "greeting": "Hello, this is Example Mall customer service.",
  "tone": ["friendly", "concise"],
  "businessHours": {
    "mode": "custom",
    "timezone": "Asia/Seoul",
    "schedule": {
      "mon": { "enabled": true, "open": "09:00", "close": "18:00" },
      "sat": { "enabled": false }
    }
  },
  "transfer": { "type": "take_message", "message": "Would you like to leave a message for the staff?" },
  "summaryRecipients": [{ "email": "cs@example.com", "keywords": ["refund"] }]
}

Read current settings

TENANT_ID="<customerId from the create response>"

curl -s "$LS_BASE_URL/v1/tenants/$TENANT_ID/agent" \
  -H "Authorization: Bearer $LS_PARTNER_KEY"
const BASE_URL = process.env.LS_BASE_URL;
const API_KEY = process.env.LS_PARTNER_KEY;
const tenantId = '<customerId from the create response>';

const agent = await (
  await fetch(`${BASE_URL}/v1/tenants/${tenantId}/agent`, {
    headers: { Authorization: `Bearer ${API_KEY}` },
  })
).json();
import os, requests

BASE_URL = os.environ["LS_BASE_URL"]
API_KEY = os.environ["LS_PARTNER_KEY"]
tenant_id = "<customerId from the create response>"

agent = requests.get(
    f"{BASE_URL}/v1/tenants/{tenant_id}/agent",
    headers={"Authorization": f"Bearer {API_KEY}"},
).json()

Every request and response field is in the API reference; failure responses are in Errors & limits.

The answering language (Korean, English, Spanish) and call recording are not changed through this API. Email support@livespeech.ai with the line's tenantId if you need them.