Client Development & Integration

Last updated: 2026-04-13

Client Development Guide

This guide specifies the protocol for building client applications (Web, Mobile, Bots) that interact with the StopCyberViolences API. It covers authentication, session management, capability negotiation, feature flags, and real-time communication.

1. Client Identification & Origin Tracking

All clients must identify themselves using an Origin Identifier. This field is mandatory for telemetry tracking (Langfuse) and capability profile resolution.

  • Field: origin (string) - Mandatory
  • Common Values: web_react, discord, dev_terminal.
  • Custom Clients: Use a unique slug (e.g., ios_app, android_app).

2. Authentication Flow

The application uses an IDP-based authentication flow. Clients obtain a signed token from an Identity Provider (IDP) and exchange it for an application-scoped session.

sequenceDiagram
    autonumber
    participant C   as Client
    participant IDP as Mock IDP<br/>/mock-idp/*
    participant A   as Auth Router<br/>/auth/login
    participant ADS as AppDataService
    participant DB  as PostgreSQL<br/>(app schema)

    note over C,IDP: Step 1 — Obtain IDP token (development only)

    C   ->>  IDP: POST /mock-idp/authenticate<br/>{ idp_user_id }
    IDP -->>  C:  { access_token: JWT(sub=idp_user_id) }

    note over C,DB: Step 2 — Exchange IDP token for App Session

    C   ->>   A: POST /auth/login<br/>{ idp_token, id_provider, user_type,<br/>language, origin, capabilities }
    A   ->>  IDP: GET /.well-known/jwks.json
    IDP -->>  A:  { keys: [{ alg: HS256, k: secret_key }] }
    A   ->>   A: jwt.decode(idp_token, secret_key)<br/>→ extract sub claim (login_id)
    A   ->>  ADS: initialize_app_session(context)

    ADS ->>  DB: SELECT IDPLogin<br/>WHERE (idp, login_id)

    alt Returning user
        DB  -->> ADS: IDPLogin found
        ADS ->>  DB: SELECT User WHERE id = idp_login.user_id
        DB  -->> ADS: User record
        ADS ->>  DB: UPDATE User SET last_seen_at = now()
    else New user
        DB  -->> ADS: No IDPLogin found
        ADS ->>  DB: INSERT User (user_type, language, age_class)
        DB  -->> ADS: New User record
        ADS ->>  DB: INSERT IDPLogin (idp, login_id, user_id)
    end

    ADS ->>  DB: UPSERT AppSession (user_id, origin, capabilities)
    DB  -->> ADS: AppSession record
    ADS ->>  DB: COMMIT

    opt Returning user
        ADS ->> DB: SELECT Conversations<br/>WHERE user_id ORDER BY updated_at DESC
        DB  -->> ADS: UserHistory
    end

    ADS -->>  A: AuthResponse
    A   -->>  C: { bearer_token, app_session, user_history }

    note over C: Store bearer_token → Authorization: Bearer token;

Step 1 — Obtain an IDP Token

Clients authenticate with the Identity Provider (e.g., Orange IDP, Google, or the mock IDP for development) and receive a JWT token.

Development (Mock IDP):

POST /api/v1/mock-idp/authenticate
Body: { "idp_user_id": "test-user-123" }
# Returns: { "access_token": "<signed-jwt>" }

The mock IDP signs the token with a symmetric key (HS256). Its public key is exposed at GET /mock-idp/.well-known/jwks.json so the auth router can verify it without out-of-band configuration.

Step 2 — Exchange Token for App Session

POST /api/v1/auth/login

Request Body:

{
  "idp_token": "<jwt-from-step-1>",
  "id_provider": "mock-idp",
  "user_type": "teenager",
  "age_class": "cycle3",
  "language": "FR",
  "origin": "web_react",
  "capabilities": {
    "supports_sse": true
  }
}

Response (AuthResponse):

{
  "bearer_token": "uuid-of-app-session",
  "app_session": { "id": "uuid-of-app-session", "origin": "web_react", ... },
  "user_history": {
    "user_id": "uuid",
    "conversations": [
      {
        "id": "uuid",
        "current_monster": "betty",
        "summary": "...",
        "updated_at": "2026-04-01T12:00:00Z"
      }
    ]
  }
}

The bearer_token (currently the app_session UUID) must be stored and sent as Authorization: Bearer <token> on all subsequent requests. user_history contains the user’s previous conversations and can be used to offer session resumption.

3. Capability Negotiation

The system uses a 3-tier negotiation system to adapt its behavior to the client’s features.

Priority Levels

  1. Explicit Declaration: Capabilities provided by the client in the auth/login request (Highest priority).
  2. Registry Lookup: Backend looks up the origin in the client_registry (defined in api/config.py).
  3. Safe Defaults: System-wide safe defaults used if the origin is unknown.

Note: If the provided capabilities fail validation, the system automatically falls back to the origin’s registry profile or safe system defaults.

Supported Capabilities

Flag Type Description
supports_sse Boolean If true, the backend enables streaming callbacks (Server-Sent Events) for this session.

4. Feature Flags

Before rendering the UI, clients should fetch the current feature flags:

GET /api/v1/features?variant=teenager&environment=development

Response:

{
  "enable_monster_flip_animation": true,
  "enable_simple_resume_prompt": true,
  "enable_login_screen": true,
  "collective_management": false
}

Flags are evaluated against variant and environment context. Frontend clients should respect these flags to enable or disable UI features.

5. Session Lifecycle

Initializing a Chat Session

Endpoint: POST /api/v1/chat/init

After authentication, clients must initialize a chat session before sending messages. This endpoint requires the Authorization: Bearer <bearer_token> header obtained from /auth/login.

Request Body:

{
  "resume_conversation_id": null
}

Response Metadata: The response contains a session_id (a UUID) which must be included in all subsequent requests.

Resuming a Previous Conversation

If user_history.conversations is non-empty, offer the user the option to resume. To resume, call /chat/init with the specific resume_conversation_id. If enable_simple_resume_prompt is true, the backend will automatically restore the conversation summary from the persistent store and prime the agent with the previous context.

Sending Messages

Endpoint: POST /api/v1/chat

{
  "message": "Hello, I need help.",
  "session_id": "uuid-from-init",
  "attachments": ["path/to/previously/uploaded/file.png"]
}

Interactive State Selection

When the bot is awaiting a specific selection (emotion or dropdown), use these endpoints:

Emotion Selection

Endpoint: POST /api/v1/chat/emotion

{
  "emotion": "sad",
  "session_id": "uuid-from-init"
}

Handling Dynamic State

Clients must synchronize their UI based on the ChatResponse metadata returned in every turn:

  • Active Monster: The monster field indicates which character is speaking.
  • Interactive Flags:
    • awaiting_emotion_selection: If true, render an emotion picker using emotion_options.
    • awaiting_dropdown_selection: If true, render a selection menu using dropdown_options. The question to display is in dropdown_question.

6. Real-time Streaming (SSE)

If supports_sse is negotiated as true, establish a persistent connection for real-time updates.

Endpoint: GET /api/v1/chat/{session_id}/events/listen

Event Protocol

  1. handshake: Payload: {} (connection confirmation)
  2. settings: Payload: {"data": {"monster": "..."}} or {"data": {"language": "..."}} (state updates)
  3. terminate: Payload: {} (stream end signal)

7. Conversation History

Endpoint: GET /api/v1/chat/history

Returns a UserHistory object with all past conversations for the authenticated user. Used to populate the ConversationHistoryModal or the SimpleResumePrompt in the web client.

8. Session Settings

Endpoint: POST /api/v1/chat/settings/change

Allows changing the language or the monster for the active session.

Request Body:

{
  "session_id": "uuid",
  "language": "EN",
  "monster": "moustache"
}

9. Media & Accessibility

File Uploads

Upload media (screenshots, pasted images) to POST /api/v1/files/upload before sending the chat message. Use the returned file paths in the attachments array. Images pasted directly into the chat input are automatically uploaded by the web client.

Voice Integration

For voice-first clients, use POST /api/v1/audio/transcribe to convert speech to text.

9. General Implementation Checklist