Session affinity

Reuse a conversation identifier while sending its message history.

Use the same x-session-id for requests in one conversation. A new conversation gets a new ID. Session affinity helps eligible requests reuse a provider, but does not guarantee a fixed provider or a cache hit.

The ID does not store Chat Completions history for you. Send the messages needed for each turn; use Responses if you want to continue by response ID.

1. Prepare your terminal

Use Python 3.10+ and uv. Put your Praxis cloud API Key in PRAXIS_API_KEY; do not put it in source code or logs.

test -n "$PRAXIS_API_KEY"

Expected: exit code 0. Exit code 1 means the variable is missing. Examples default to https://api.deepraxis.com. To switch environments, set PRAXIS_API_BASE to the API origin without a trailing slash or API path.

2. Reuse an ID across two turns

This example generates a UUID and sends it on both requests. It also includes the first exchange in the second request.

Save as session-affinity.py and run uv run -q --no-project --with openai --with anthropic --with google-genai python session-affinity.py.

import os
import uuid
from openai import OpenAI

client = OpenAI(api_key=os.environ['PRAXIS_API_KEY'],
    base_url=os.environ.get('PRAXIS_API_BASE', 'https://api.deepraxis.com') + '/openai/v1')
session_id = str(uuid.uuid4())
messages = [{'role': 'user', 'content': 'Remember this code: LIME-742. Reply OK.'}]
for turn in range(2):
    response = client.chat.completions.create(model='deepseek-flash',
        messages=messages, reasoning_effort='none', max_tokens=256,
        extra_headers={'x-session-id': session_id})
    print('X-Request-Id:', response._request_id)
    assert response.choices[0].finish_reason == 'stop'
    answer = response.choices[0].message.content or ''
    assert answer
    print('turn', turn + 1, answer)
    if turn == 0:
        messages.append({'role': 'assistant', 'content': answer})
        messages.append({'role': 'user', 'content': 'What was the code? Reply with only the code.'})
    else:
        assert 'LIME-742' in answer, answer

Expected: two completed responses, two request IDs, and LIME-742 in the second answer. Exit code 0. This verifies the requests and conversation history; it does not prove a particular provider or cache hit. Verify cache usage separately with the prompt cache guide.

Observed failure and recovery

An empty body session_id returned HTTP 400: session_id must not be empty. Use a nonempty conversation ID. When the body also contains session_id, it takes precedence over the header; avoid keeping conflicting values in two places. Do not reuse one global ID for unrelated conversations.

Field details: Chat Completions.

API reference → · Cookbook →

Export

On this page