Skip to main content
POST
/
v1
/
sessions
/
{session_id}
/
turns
Turns API
curl --request POST \
  --url https://api.statebase.org/v1/sessions/{session_id}/turns

Turns API

Turns represent individual conversation exchanges between a user and your agent. Each turn captures the complete interaction context including input, output, state changes, and reasoning.

Why Log Turns?

Turns provide:
  • Complete audit trail of all agent decisions
  • Debugging capability (replay exact conversations)
  • Analytics (measure success rates, latency, tool usage)
  • Rollback points (revert to any previous turn)

Add Turn

POST /v1/sessions/{session_id}/turns Logs a new conversation turn. This is typically called after your agent generates a response.

Path Parameters

ParameterTypeRequiredDescription
session_idstring✅ YesSession ID to add turn to

Request Body

FieldTypeRequiredDescription
inputobject✅ YesUser’s input (see Input Object below)
outputobject✅ YesAgent’s response (see Output Object below)
reasoningstringNoWhy the agent made this decision (for debugging)
metadataobjectNoCustom data (e.g., {"tool_used": "weather_api", "latency_ms": 450})
state_beforeobjectNoSession state before this turn
state_afterobjectNoSession state after this turn

Input Object

FieldTypeRequiredDescription
typestring✅ YesContent type: "text", "audio", "image", "tool_call"
contentstring✅ YesThe actual input content

Output Object

FieldTypeRequiredDescription
typestring✅ YesContent type: "text", "audio", "image", "tool_result", "error"
contentstring✅ YesThe actual output content

Response

FieldTypeDescription
idstringUnique turn ID (format: turn_<12_chars>)
session_idstringParent session ID
turn_numberintegerSequential turn number (starts at 1)
created_atstringISO 8601 timestamp
inputobjectUser input
outputobjectAgent output
reasoningstringAgent’s reasoning (if provided)
metadataobjectCustom metadata
state_beforeobjectState snapshot before turn
state_afterobjectState snapshot after turn

Example

curl -X POST https://api.statebase.org/v1/sessions/sess_abc123/turns \
  -H "X-API-Key: sb_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "type": "text",
      "content": "What is the weather in San Francisco?"
    },
    "output": {
      "type": "text",
      "content": "The weather in San Francisco is currently 72°F and sunny."
    },
    "reasoning": "Called weather API for San Francisco, returned current conditions",
    "metadata": {
      "tool_used": "weather_api",
      "latency_ms": 450,
      "model": "gpt-4"
    }
  }'

Get Turn

GET /v1/sessions/{session_id}/turns/{turn_id} Retrieves a specific turn by ID.

Path Parameters

ParameterTypeRequiredDescription
session_idstring✅ YesSession ID
turn_idstring✅ YesTurn ID

Example

curl https://api.statebase.org/v1/sessions/sess_abc123/turns/turn_xyz789 \
  -H "X-API-Key: sb_your_key"

List Turns

GET /v1/sessions/{session_id}/turns Lists all turns for a session, ordered by creation time (newest first).

Path Parameters

ParameterTypeRequiredDescription
session_idstring✅ YesSession ID

Query Parameters

ParameterTypeRequiredDescription
limitintegerNoMax turns to return (default: 20, max: 100)
starting_afterstringNoTurn ID to start after (for pagination)
orderstringNoSort order: "asc" or "desc" (default: "desc")

Example

curl "https://api.statebase.org/v1/sessions/sess_abc123/turns?limit=10" \
  -H "X-API-Key: sb_your_key"

Common Use Cases

1. Logging Tool Calls

Track when your agent uses external tools:
# Agent calls weather API
weather_data = call_weather_api("San Francisco")

# Log the tool call
sb.sessions.add_turn(
    session_id=session.id,
    input={"type": "tool_call", "content": "get_weather(city='San Francisco')"},
    output={"type": "tool_result", "content": json.dumps(weather_data)},
    reasoning="Weather API call succeeded",
    metadata={
        "tool_name": "weather_api",
        "latency_ms": 450,
        "success": True
    }
)

2. Logging Errors

Track when things go wrong:
try:
    result = risky_operation()
except Exception as e:
    # Log the error
    sb.sessions.add_turn(
        session_id=session.id,
        input={"type": "text", "content": user_message},
        output={"type": "error", "content": str(e)},
        reasoning=f"Operation failed: {type(e).__name__}",
        metadata={
            "error_type": type(e).__name__,
            "error_message": str(e),
            "stack_trace": traceback.format_exc()
        }
    )

3. State Tracking

Log state changes with each turn:
# Before agent processes input
state_before = sb.sessions.get(session.id).state

# Agent processes and updates state
response = agent.process(user_message)
sb.sessions.update_state(session.id, new_state)

# Log turn with state snapshots
sb.sessions.add_turn(
    session_id=session.id,
    input={"type": "text", "content": user_message},
    output={"type": "text", "content": response},
    state_before=state_before,
    state_after=new_state,
    reasoning="Updated state based on user input"
)

4. Analytics

Analyze agent performance:
# Get all turns for a session
turns = sb.sessions.list_turns(session_id=session.id, limit=100)

# Calculate metrics
total_turns = len(turns)
tool_calls = [t for t in turns if t.metadata.get("tool_used")]
errors = [t for t in turns if t.output.type == "error"]
avg_latency = sum(t.metadata.get("latency_ms", 0) for t in turns) / total_turns

print(f"Total turns: {total_turns}")
print(f"Tool calls: {len(tool_calls)}")
print(f"Errors: {len(errors)}")
print(f"Avg latency: {avg_latency:.0f}ms")

Best Practices

✅ Do This

  • Always include reasoning (invaluable for debugging)
  • Log metadata (tool names, latency, model used, etc.)
  • Log errors (don’t just catch and ignore)
  • Use structured types ("text", "tool_call", "error")
  • Include state snapshots for critical turns

❌ Avoid This

  • Don’t skip turn logging (you’ll regret it when debugging)
  • Don’t log sensitive data in content (use encrypted metadata)
  • Don’t log every internal step (only user-facing interactions)
  • Don’t forget to paginate when listing turns

Turn Types Reference

Input Types

TypeDescriptionExample
textPlain text input"What's the weather?"
audioAudio transcription"[Audio: 5.2s]"
imageImage description"[Image: screenshot.png]"
tool_callTool invocation"get_weather(city='SF')"

Output Types

TypeDescriptionExample
textPlain text response"It's 72°F and sunny"
audioAudio response"[Audio: response.mp3]"
imageGenerated image"[Image: chart.png]"
tool_resultTool output{"temp": 72, "condition": "sunny"}
errorError message"API timeout after 5s"

Error Responses

Status CodeError CodeDescription
400invalid_requestMissing required fields
404session_not_foundSession doesn’t exist
404turn_not_foundTurn doesn’t exist
429rate_limit_exceededToo many requests

Next Steps


Key Takeaway: Turns are your time machine. Log everything, and you can replay any conversation to debug production issues.