Personas
A persona is the idea: what an agent says and how it sounds saying it. An agent is one way of putting that idea on a telephone. Point three agents at one persona and you have an inbound line, an outbound campaign and a web widget running the same script — with one prompt between them, edited once.
The problem this splits
An agent carries everything on one record: the prompt and the carrier, the voice and the caller IDs, the knowledge and the direction. Because those sit together, one idea can only be deployed one way. An account that wants its collections script to answer the support line, chase callbacks and run in the widget ends up keeping three copies of the prompt — and the day somebody edits two of them, the third starts saying something else.
What goes where
| The persona owns — the idea | The agent owns — the telephone |
|---|---|
languages (prompt, greeting, voice, vendors) | mode —
conversation, keypad, normal, webrtc |
language_detection | autonomy — who holds its end of the
call |
timezone, voice_engine | direction,
carrier, caller IDs |
knowledge_base_ids, tools | transfer_number,
ring_seconds |
flow | record_calls, transcribe_calls,
webhook_url |
conversation, keypad, no_match,
no_input | project_id, group_id |
post_call | its own name and
description |
model, models, temperature,
max_tokens, speed, pitch,
filler_phrase |
A persona has no number, no carrier, no direction and no mode, because none of those are facts about the idea.
Nothing changes until you ask
An agent that names no persona carries its idea inline and behaves exactly as it always has. This is additive: no migration runs, and no existing integration changes behaviour.
Adopting the split never means retyping a prompt. One request lifts an agent's whole idea — prompt, languages, knowledge, tools, flow, conversation settings, post-call fields, model and voice — into a new persona and points the agent at it.
/v1/agents/{id}/personacurl -s -X POST https://voice.sphoro.com/v1/agents/$AGENT_ID/persona \
-H "Authorization: Bearer $SPHORO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Collections script"}'{
"id": "psn_4a19c8e0b7d23f61",
"name": "Collections script",
"agent_count": 1
}The agent keeps its inline copy, which is what lets a persona that cannot be loaded degrade to "this agent's own settings" rather than to a line with no prompt at all.
Deploying it three ways
/v1/agents/{id}# The inbound support line.
curl -s -X PATCH https://voice.sphoro.com/v1/agents/$INBOUND_AGENT \
-H "Authorization: Bearer $SPHORO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"persona_id": "psn_4a19c8e0b7d23f61"}'
# The outbound chase campaign — same idea, different telephone.
curl -s -X PATCH https://voice.sphoro.com/v1/agents/$OUTBOUND_AGENT \
-H "Authorization: Bearer $SPHORO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"persona_id": "psn_4a19c8e0b7d23f61", "carrier": "twilio"}'Setting persona_id to "" gives the agent its own idea back. The
inline fields are still on the record, so detaching needs no restore step.
The endpoints
| Endpoint | Does |
|---|---|
POST /v1/personas | Create an idea from scratch. |
GET /v1/personas | List them. |
GET /v1/personas/{id} | Read one. |
PATCH /v1/personas/{id} | Edit it — changes every agent using it, from the next call. |
DELETE /v1/personas/{id} | Refused while any agent still names it. |
GET /v1/personas/{id}/agents | Which lines are built on it. Read this before editing. |
POST /v1/agents/{id}/persona | Lift an agent's inline idea out into one. |
Personas cost the same scope as agents — agents:read and
agents:write. A persona is an agent's configuration, and a credential that
may rewrite a prompt through /v1/agents is not made safer by being refused the
endpoint holding the same prompt.
Two rules worth knowing
The pair is validated where it meets. A persona is checked by the agent
validator, as the agent it would produce, so the two can never disagree about what a valid prompt
or language list is. That also catches combinations that are individually fine and jointly wrong
— a keypad line whose persona defines no menu would answer, offer nothing, and hang up. The
problem is reported against persona.<field>, naming the record that can fix
it.
Writing an idea field to an agent that has a persona
It is refused, not ignored. There the write could never take effect at read
time, and a 200 for a change that can never happen is the worst of the available
answers. On an agent that carries its idea inline, the same write still works and comes back with
a deprecation header.
Persona or group?
| Persona | Agent group | |
|---|---|---|
| Holds | The whole idea — prompt, voice, knowledge, flow | A handful of fleet-wide defaults |
| Members may differ | No. It wins outright | Yes, per field, via overrides |
| Reach for it when | One script on several telephones | Forty lines that should share a model and a transfer number |
They compose: an agent can name a persona and belong to a group. The persona settles what it says; the group settles the fleet-wide plumbing around it.