Skip to main content

Actors

Actors are people, bots, or other participants within a project. A common use is external contacts such as WhatsApp numbers, with external_id holding the phone number.

Overview​

An Actor belongs to a project and has a display name, an optional external_id, and optional links to an Agent or Chat. Actors are identified by a public id prefixed with actor_. The internal database primary key is never returned.

See the Permissions Reference for the IAM action strings for this module.

Data Model​

FieldTypeRequiredDescription
idstring—Public identifier prefixed with actor_
project_idstring—Public ID of the owning project (proj_ prefix)
namestringYesDisplay name of the actor
external_idstringNoExternal identifier (e.g. WhatsApp phone number). Unique per project; null is never unique
instructionsstring | nullNoPersona-specific instructions composed into the effective system prompt for generate calls
agent_idstring | nullNoPublic ID of the linked Agent (agent_ prefix). Mutually exclusive with chat_id
chat_idstring | nullNoPublic ID of the linked Chat (chat_ prefix). Mutually exclusive with agent_id
tagsobjectNoKey-value string pairs used for ABAC conditions (see Tags)
created_atstring—ISO 8601 creation timestamp
updated_atstring—ISO 8601 last-updated timestamp

Key Concepts​

external_id and Idempotent Creation​

external_id correlates an Actor with an external record (WhatsApp number, CRM contact ID). Unique per project at the database level; the same value may recur across projects. null/absent is never a duplicate (PostgreSQL NULL semantics).

Choose this value knowing it egresses

Whenever a generation runs in a session bound to this actor, external_id is auto-populated into tool_context and sent as the X-Soat-Context-actor_external_id header to every http and mcp tool the agent calls, including endpoints you do not control.

With third-party endpoints in the tool set, prefer an opaque internal identifier and correlate on your side. See Tool Context.

With external_id, POST /actors is find-or-create:

  • No match: created, 201 Created.
  • Match: the existing actor is returned as-is with 200 OK; other request fields (name, instructions, etc.) are not applied.

This makes creation safe to repeat from event-driven pipelines (e.g. an inbound WhatsApp message). Without external_id, POST /actors always creates and returns 201 Created.

Agent and Chat Linking​

An Actor links to an Agent or a Chat, not both; the link selects the AI backend for generate calls for the actor.

  • agent_id links an Agent; chat_id a Chat. Either must be in the actor's project.
  • null in PATCH /actors/:id unlinks.
  • Both in one request: 400 Bad Request.

Per-Actor Memory​

An actor has no memory field; retrieval scope comes from the agent's knowledge_config only. Keep the actor→store mapping in your application and pass it per call.

Create one memory store per end user (keyed by external_id, for instance) and name it in the generate body:

{
"knowledge_config": {
"memory_store_ids": ["mstore_V1StGXR8Z5jdHi6B"],
"write_memory_store_id": "mstore_V1StGXR8Z5jdHi6B"
}
}

memory_store_ids is unioned with the agent's stored config and tags pairs are merged, so a per-actor store extends the shared scope. Without a mapping table, tag the store (tags, e.g. { "actor": "<external_id>" }) or name it after the external_id and look it up with GET /memory-stores.

Deleting an actor deletes nothing in any memory store.

Instructions​

instructions is injected into the system prompt when a generation is scoped to this actor: persona context (tone, name, constraints) consistent across interactions. null in PATCH /actors/:id clears it.

Filtering​

GET /actors filters by project_id, external_id (exact match — use it to resolve an external identifier to an actor_ ID), and name (partial, case-insensitive), with limit/offset pagination in a { data, total, limit, offset } envelope.

Project Scope​

Project-scoped API keys make project_id optional (omitted defaults to the key's project; a different project is 403); JWT callers must supply it on writes. See Implicit project id.

Tags​

Key-value string pairs managed via tags or the tag sub-endpoints, matched by soat:ResourceTag/<key>. GET /api/v1/actors filters by pair with ?tags=key:value (repeatable, all must match). SRN type actor (srn:proj_ABC:actor:actor_123). See IAM — Tags and SRNs.

Examples​

Create an actor​

soat create-actor \
--project-id proj_ABC \
--name Alice \
--external-id +15551234567

With external_id the call is an idempotent upsert: 201 first, 200 thereafter (external_id and Idempotent Creation). Policy examples: IAM — Examples.

Get an actor​

soat get-actor --actor-id actor_123