Chat Endpoints

SDK endpoints for NPC conversations. All requests require the X-API-Key header.

Note
All SDK chat endpoints require the X-API-Key header. You can only access your own published personas.

List Personas

GET /api/v1/sdk/personas

Returns all published personas owned by your API key. Use this to discover persona IDs for chat endpoints.

Response

Returns an array of persona objects:

FieldTypeDescription
idstring (UUID)Persona ID to use in chat endpoints
namestringPersona display name
descriptionstring | nullPersona description
created_atstring (ISO 8601)When the persona was created
updated_atstring (ISO 8601)When the persona was last updated
curl /api/v1/sdk/personas \
  -H "X-API-Key: pk_live_..."

Response:

[
  {
    "id": "a1b2c3d4-...",
    "name": "Grumpy Barista",
    "description": "A coffee shop NPC with a bad attitude",
    "created_at": "2026-03-10T12:00:00Z",
    "updated_at": "2026-03-10T12:00:00Z"
  }
]

Initialize Session

POST /api/v1/sdk/chat/{persona_id}/init-session

Starts a new chat session. Returns the NPC's opening greeting, session ID, and persona metadata.

Warning
Calling init-session with an existing user_session_id will reset the previous session. Use the Check Session endpoint first if you want to resume an existing conversation.

Query Parameters

ParameterTypeRequiredDescription
machine_idstring (UUID)NoTarget a specific state machine. Defaults to the persona's default machine.

Request Body

FieldTypeRequiredDescription
user_session_idstringYesYour unique identifier for this player (e.g. player UUID from your game)
player_namestringYesPlayer's display name, used in NPC responses
player_genderstringYesOne of female, male, or non-binary

Response

FieldTypeDescription
session_idstring (UUID)Server-assigned internal session UUID
user_session_idstringYour player identifier (echoed back)
persona_namestringThe NPC's display name
persona_descriptionstring | nullThe NPC's description
player_namestringEchoed player name
player_genderstringEchoed player gender
messagestringThe NPC's opening greeting
machine_idstring (UUID)The active state machine ID

Send Message

POST /api/v1/sdk/chat/{persona_id}/message

Sends a player message and returns the NPC response with state machine metadata.

Request Body

FieldTypeRequiredDescription
messagestringYesThe player's message text
user_session_idstringYesThe user_session_id you provided during init

Response

FieldTypeDescription
messagestringThe NPC's response
current_statestringCurrent state machine state key
scorenumberCumulative session score
outcomestring | nullTerminal outcome if reached (ACCEPT, REJECT, KICK_OUT)
decisionstring | nullAI's evaluation decision (pass, redirect, reject, kick_out)
follow_upbooleanWhether the NPC expects a follow-up
redirect_countnumber | nullNumber of redirects used in the current state
session_idstring (UUID)Internal session identifier
scoring_modestringScoring mode (scoring or pass_fail)
machine_completedbooleanWhether the conversation reached a terminal state
unlocked_machinesarrayNewly unlocked machines (for multi-machine personas)

Check Session

GET /api/v1/sdk/chat/{persona_id}/session

Check if a player already has an active session with a persona. Returns session status or 404 if no session exists. Useful for resuming conversations on reconnect instead of re-initializing.

Query Parameters

ParameterTypeRequiredDescription
user_session_idstringYesThe player identifier to check
machine_idstring (UUID)NoCheck a specific state machine

Response

FieldTypeDescription
session_idstring (UUID)Internal session identifier
persona_idstring (UUID)Persona this session belongs to
machine_idstring (UUID)Active state machine
current_statestringCurrent state key in the state machine
scorenumberCurrent session score
outcomestring | nullTerminal outcome if session is complete
player_namestring | nullPlayer name set during init
started_atstring (ISO 8601)When the session started
last_message_atstring (ISO 8601)When the last message was sent

List Available Machines

GET /api/v1/sdk/chat/{persona_id}/machines

Lists all machines (scenarios) available to a player for a persona. Includes entry machines, unlocked machines, and unlinked standalone machines. Use this to discover which machines a player can interact with.

Query Parameters

ParameterTypeRequiredDescription
user_session_idstringYesThe player identifier to check availability for

Response

Returns an array of available machine objects:

FieldTypeDescription
machine_idstring (UUID)Machine ID to pass to chat endpoints
machine_keystringHuman-readable machine identifier
namestringMachine display name
descriptionstring | nullMachine description
has_sessionbooleanWhether the player has an active session on this machine
session_outcomestring | nullOutcome if the machine was completed (ACCEPT, REJECT, etc.)
is_linkedbooleanWhether this machine is part of a progression chain (has links to/from other machines)
curl "/api/v1/sdk/chat/{persona_id}/machines?user_session_id=player-001" \
  -H "X-API-Key: pk_live_..."

Response:

[
  {
    "machine_id": "a1b2c3d4-...",
    "machine_key": "opening_scene",
    "name": "Opening Scene",
    "description": "The first encounter with the barista",
    "has_session": true,
    "session_outcome": null,
    "is_linked": true
  },
  {
    "machine_id": "e5f6a7b8-...",
    "machine_key": "side_quest",
    "name": "Side Quest",
    "description": "An optional standalone scenario",
    "has_session": false,
    "session_outcome": null,
    "is_linked": false
  }
]

Get Chat History

GET /api/v1/sdk/chat/{persona_id}/history

Retrieves the full message history for a session.

Query Parameters

ParameterTypeRequiredDescription
user_session_idstringYesThe session to retrieve history for
machine_idstring (UUID)NoFilter to a specific state machine

Reset Session

POST /api/v1/sdk/chat/{persona_id}/reset

Resets a chat session, clearing all history and returning the state machine to its initial state.

Query Parameters

ParameterTypeRequiredDescription
user_session_idstringYesThe session to reset
machine_idstring (UUID)NoReset only a specific state machine

Error Responses

All errors return a consistent JSON format:

{
  "error": {
    "message": "Description of what went wrong"
  }
}
StatusMeaning
400Invalid ID format or request body
401Missing or invalid API key
403API key doesn't own the persona, or persona is unpublished
404Persona, session, or machine not found
429Rate limited (30/min for messages, 60/min for other endpoints)

Example: Full Conversation Flow

1. Discover your personas

curl /api/v1/sdk/personas \
  -H "X-API-Key: pk_live_..."

2. Check for existing session

curl "/api/v1/sdk/chat/{persona_id}/session?user_session_id=player-001" \
  -H "X-API-Key: pk_live_..."
# Returns 404 if no session — proceed to init

3. Initialize

curl -X POST /api/v1/sdk/chat/{persona_id}/init-session \
  -H "X-API-Key: pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "user_session_id": "player-001",
    "player_name": "Alex",
    "player_gender": "non-binary"
  }'

Response:

{
  "session_id": "f7a8b9c0-...",
  "user_session_id": "player-001",
  "persona_name": "Grumpy Barista",
  "persona_description": "A coffee shop NPC with a bad attitude",
  "player_name": "Alex",
  "player_gender": "non-binary",
  "message": "Well, well... another traveler. What brings you here, Alex?",
  "machine_id": "d4e5f6a7-..."
}

4. Send a message

curl -X POST /api/v1/sdk/chat/{persona_id}/message \
  -H "X-API-Key: pk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "message": "I heard you have something rare for sale.",
    "user_session_id": "player-001"
  }'

Response:

{
  "message": "Rare? Everything here is rare, friend. But the real question is — can you afford it?",
  "current_state": "negotiation",
  "score": 15,
  "outcome": null,
  "decision": "pass",
  "follow_up": true,
  "session_id": "f7a8b9c0-...",
  "scoring_mode": "scoring",
  "machine_completed": false,
  "unlocked_machines": []
}

5. Reset when done

curl -X POST "/api/v1/sdk/chat/{persona_id}/reset?user_session_id=player-001" \
  -H "X-API-Key: pk_live_..."