sphoroVOICEdocs
Markdown

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 ideaThe agent owns — the telephone
languages (prompt, greeting, voice, vendors)mode — conversation, keypad, normal, webrtc
language_detectionautonomy — who holds its end of the call
timezone, voice_enginedirection, carrier, caller IDs
knowledge_base_ids, toolstransfer_number, ring_seconds
flowrecord_calls, transcribe_calls, webhook_url
conversation, keypad, no_match, no_inputproject_id, group_id
post_callits 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.

POST/v1/agents/{id}/persona
Shell
curl -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"}'
Response201 Created
{
  "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

PATCH/v1/agents/{id}
Shell
# 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

EndpointDoes
POST /v1/personasCreate an idea from scratch.
GET /v1/personasList 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}/agentsWhich lines are built on it. Read this before editing.
POST /v1/agents/{id}/personaLift 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 persona wins outright. A field on a persona is not a default the agent may override. Agent groups already provide a per-field override axis, and a second one would make "what does this agent actually run on" a three-way puzzle. If a line needs a different greeting, it needs a different persona — they are free.

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?

PersonaAgent group
HoldsThe whole idea — prompt, voice, knowledge, flowA handful of fleet-wide defaults
Members may differNo. It wins outright Yes, per field, via overrides
Reach for it whenOne script on several telephonesForty 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.