Bastio

Sessions & Observability

Group related API requests into sessions for easier analysis and conversation tracking.

Sessions & Observability

Sessions group related API requests together, making it easy to track multi-turn conversations and analyze user behavior patterns in the Observe dashboard.

Sessions are automatically created based on end-user identity, but you can override this with explicit session IDs for precise conversation grouping.

How Sessions Work

Bastio supports two methods for session management:

1. Auto-Sessions (Default)

Sessions are automatically created and managed based on the end-user identity:

  • Grouping: Requests are grouped by end_user_id (or device fingerprint if no user ID is provided)
  • Timeout: 30-minute inactivity window - after 30 minutes without requests, a new session is created
  • Zero configuration: Works out of the box with no additional headers required
Request 1 (user_123, 10:00) → Session A
Request 2 (user_123, 10:05) → Session A (same session)
Request 3 (user_123, 10:50) → Session B (new session - 30+ min gap)

2. Explicit Sessions

Override auto-sessions by providing your own session ID via the X-Session-ID header:

  • Priority: Explicit session IDs take precedence over auto-sessions
  • Custom grouping: Perfect for multi-turn conversations or workflow tracking
  • Consistent: Same session ID always groups requests together, regardless of timing

Using Sessions

Explicit Session ID

Pass the X-Session-ID header to group requests into a specific session:

import openai

client = openai.OpenAI(
    api_key="bastio_sk_your_key_here",
    base_url="https://api.bastio.com/v1"
)

# Group all messages in this conversation under one session
session_id = "conversation_abc123"

response = client.chat.completions.create(
    model="gpt-4",
    messages=[
        {"role": "user", "content": "Hello, I need help with my order"}
    ],
    extra_headers={
        "X-Session-ID": session_id
    }
)

# Follow-up message in the same session
response = client.chat.completions.create(
    model="gpt-4",
    messages=[
        {"role": "user", "content": "Hello, I need help with my order"},
        {"role": "assistant", "content": response.choices[0].message.content},
        {"role": "user", "content": "Can you check order #12345?"}
    ],
    extra_headers={
        "X-Session-ID": session_id  # Same session
    }
)
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: 'bastio_sk_your_key_here',
  baseURL: 'https://api.bastio.com/v1'
});

const sessionId = 'conversation_abc123';

// First message
const response1 = await client.chat.completions.create({
  model: 'gpt-4',
  messages: [
    { role: 'user', content: 'Hello, I need help with my order' }
  ]
}, {
  headers: {
    'X-Session-ID': sessionId
  }
});

// Follow-up in same session
const response2 = await client.chat.completions.create({
  model: 'gpt-4',
  messages: [
    { role: 'user', content: 'Hello, I need help with my order' },
    { role: 'assistant', content: response1.choices[0].message.content },
    { role: 'user', content: 'Can you check order #12345?' }
  ]
}, {
  headers: {
    'X-Session-ID': sessionId
  }
});
# First message in conversation
curl -X POST https://api.bastio.com/v1/chat/completions \
  -H "Authorization: Bearer bastio_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -H "X-Session-ID: conversation_abc123" \
  -d '{
    "model": "gpt-4",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'

# Follow-up (same session ID)
curl -X POST https://api.bastio.com/v1/chat/completions \
  -H "Authorization: Bearer bastio_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -H "X-Session-ID: conversation_abc123" \
  -d '{
    "model": "gpt-4",
    "messages": [
      {"role": "user", "content": "Hello!"},
      {"role": "assistant", "content": "Hi there!"},
      {"role": "user", "content": "What is 2+2?"}
    ]
  }'
package main

import (
    "context"
    "net/http"

    openai "github.com/sashabaranov/go-openai"
)

func main() {
    config := openai.DefaultConfig("bastio_sk_your_key_here")
    config.BaseURL = "https://api.bastio.com/v1"

    // Add custom header for session ID
    config.HTTPClient = &http.Client{
        Transport: &sessionTransport{
            sessionID: "conversation_abc123",
            base:      http.DefaultTransport,
        },
    }

    client := openai.NewClientWithConfig(config)

    resp, _ := client.CreateChatCompletion(
        context.Background(),
        openai.ChatCompletionRequest{
            Model: openai.GPT4,
            Messages: []openai.ChatCompletionMessage{
                {Role: openai.ChatMessageRoleUser, Content: "Hello!"},
            },
        },
    )
}

type sessionTransport struct {
    sessionID string
    base      http.RoundTripper
}

func (t *sessionTransport) RoundTrip(req *http.Request) (*http.Response, error) {
    req.Header.Set("X-Session-ID", t.sessionID)
    return t.base.RoundTrip(req)
}

End User Identification

For auto-sessions to work effectively, provide user identification:

# Option 1: Using the 'user' field (recommended)
response = client.chat.completions.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "Hello"}],
    user="user_12345"  # Your internal user ID
)

# Option 2: Using X-End-User-ID header
response = client.chat.completions.create(
    model="gpt-4",
    messages=[{"role": "user", "content": "Hello"}],
    extra_headers={
        "X-End-User-ID": "user_12345"
    }
)
// Option 1: Using the 'user' field (recommended)
const response = await client.chat.completions.create({
  model: 'gpt-4',
  messages: [{ role: 'user', content: 'Hello' }],
  user: 'user_12345'
});

// Option 2: Using X-End-User-ID header
const response = await client.chat.completions.create({
  model: 'gpt-4',
  messages: [{ role: 'user', content: 'Hello' }]
}, {
  headers: {
    'X-End-User-ID': 'user_12345'
  }
});

When no user ID is provided, Bastio generates a device fingerprint based on IP address and user agent. This allows session grouping even for anonymous users.

Session Headers Reference

HeaderDescriptionExample
X-Session-IDExplicit session identifierconversation_abc123
X-End-User-IDEnd user identifier for auto-sessionsuser_12345
X-EnvironmentEnvironment tag for filteringproduction, staging

Viewing Sessions in Dashboard

Sessions are visible in Observe > Sessions in your Bastio dashboard:

Session List View

  • Session ID: Unique identifier (auto-generated or your custom ID)
  • End User: The user associated with the session
  • Trace Count: Number of API requests in the session
  • Duration: Time span from first to last request
  • Status: Active or completed based on inactivity timeout

Session Detail View

Click on a session to see:

  • Timeline: All traces in chronological order
  • Metrics: Total tokens, cost, and latency
  • Security Events: Any threats or blocks during the session
  • Conversation Flow: Full request/response history

Best Practices

Use Meaningful Session IDs

# Good - descriptive and traceable
session_id = f"support_ticket_{ticket_id}"
session_id = f"checkout_{cart_id}"
session_id = f"chat_{user_id}_{timestamp}"

# Avoid - generic or non-unique
session_id = "session1"
session_id = str(uuid.uuid4())  # Hard to correlate later

Session Lifecycle Management

import time

class ConversationSession:
    def __init__(self, user_id: str):
        self.session_id = f"conv_{user_id}_{int(time.time())}"
        self.messages = []

    def add_message(self, role: str, content: str):
        self.messages.append({"role": role, "content": content})

    def send(self, client, model="gpt-4"):
        return client.chat.completions.create(
            model=model,
            messages=self.messages,
            extra_headers={"X-Session-ID": self.session_id}
        )

# Usage
session = ConversationSession("user_123")
session.add_message("user", "Hello!")
response = session.send(client)
session.add_message("assistant", response.choices[0].message.content)
session.add_message("user", "Tell me more")
response = session.send(client)  # Same session, full context

When to Use Explicit vs Auto Sessions

ScenarioRecommendation
Multi-turn chat conversationsExplicit X-Session-ID
Single-request APIsAuto-sessions (default)
User support ticketsExplicit with ticket ID
Anonymous/guest usersAuto-sessions with fingerprint
Workflow trackingExplicit with workflow ID

Troubleshooting

Next Steps