API Reference

Complete reference for interacting with the Chat API

Chat CompletionsPOST
Create a chat completion response for the given conversation

Endpoint

POST https://uncensored.chat/api/v1/chat/completions

Headers

AuthorizationBearer YOUR_API_KEY
Content-Typeapplication/json

Request Parameters

modelrequiredstring

The model to use for completion. E.g., "uncensored-v2"

messagesrequiredarray

Array of message objects. Each message has a "role" (user/assistant/system) and "content".

streamoptionalboolean

Whether to stream partial progress. Default: false

temperatureoptionalnumber

Sampling temperature between 0 and 2. Higher values make output more random.

max_tokensoptionalinteger

Maximum number of tokens to generate in the completion.

Request Example

{
    "model": "uncensored-v2",
    "messages": [
        {
            "role": "user",
            "content": "tell me a big story"
        }
    ],
    "stream": true,
    "temperature": 0.7,
    "max_tokens": 1000
}

Response Examples

{
    "id": "chatcmpl-123",
    "object": "chat.completion",
    "created": 1728345600,
    "model": "uncensored-v2",
    "choices": [
        {
            "index": 0,
            "message": {
                "role": "assistant",
                "content": "Here's a big story for you..."
            },
            "finish_reason": "stop"
        }
    ],
    "usage": {
        "prompt_tokens": 10,
        "completion_tokens": 150,
        "total_tokens": 160
    }
}

Code Examples

curl -X POST https://uncensored.chat/api/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "model": "uncensored-v2",
    "messages": [
      {
        "role": "user",
        "content": "tell me a big story"
      }
    ],
    "stream": true
  }'
List Voice CharactersGET
List characters available for voice calling

Endpoint

GET https://uncensored.chat/api/v1/voice/characters

Headers

AuthorizationBearer YOUR_API_KEY

Response Example

{
  "object": "list",
  "data": [
    {
      "id": 1,
      "slug": "elon-musk",
      "name": "Elon Musk",
      "title": "CEO of Tesla & SpaceX",
      "thumbnail": "https://...",
      "first_message": "Hello there.",
      "voice_sample_url": "https://...",
      "voice_synced_at": "2024-01-01T00:00:00Z"
    }
  ]
}
Start Voice CallPOST
Start a real-time voice conversation with an AI character

Endpoint

POST https://uncensored.chat/api/v1/voice/calls

Headers

AuthorizationBearer YOUR_API_KEY
Content-Typeapplication/json

Request Parameters

character_slugrequiredstring

The slug of the voice-ready character to talk with. Get available slugs from the List Voice Characters endpoint.

Request Example

{
  "character_slug": "elon-musk"
}

Response Example

{
  "object": "voice.call",
  "chat_id": "550e8400-e29b-41d4-a716-446655440000",
  "ws_url": "wss://uncensored.chat/voice-ws?chat_id=...&exp=...&sig=...",
  "mode": "live",
  "minutes_remaining": 30,
  "character": {
    "slug": "elon-musk",
    "name": "Elon Musk",
    "thumbnail": "https://...",
    "first_message": "Hello there.",
    "voice_sample_url": "https://..."
  }
}

Code Examples

curl -X POST https://uncensored.chat/api/v1/voice/calls \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "character_slug": "elon-musk"
  }'
WebSocket Protocol
Real-time audio streaming protocol for voice calls

Connection Flow

  1. Call POST /api/v1/voice/calls to get a signed ws_url
  2. Open a WebSocket connection to the ws_url
  3. Stream PCM audio to the server and receive PCM audio back
  4. Close the WebSocket when finished — usage is tracked automatically

Connection URL

wss://uncensored.chat/voice-ws?chat_id=UUID&exp=TIMESTAMP&sig=HMAC

The ws_url from the start call response is pre-signed and expires after 10 minutes.

Protobuf Framing

All WebSocket messages use protobuf varint-length-prefixed framing. Each frame is a binary message with the following top-level structure:

FieldNumberTypeDescription
text1bytesText frame (bot text output)
audio2bytesAudio frame (PCM data)
transcription3bytesTranscription frame (user speech)
transport4bytesTransport message (JSON events)

Audio Input (Client → Server)

Send microphone audio as binary protobuf frames. Each audio message contains:

FieldNumberTypeValue
audio_data3bytesRaw PCM Int16 samples
sample_rate4int3216000 Hz
num_channels5int321 (mono)

Recommended chunk size: 50ms frames (800 samples at 16kHz).

Audio Output (Server → Client)

Receive TTS audio as binary protobuf frames with the same structure, but at 24kHz:

FieldNumberTypeValue
audio_data3bytesRaw PCM Int16 samples
sample_rate4int3224000 Hz
num_channels5int321 (mono)

Transport Messages

Server sends JSON transport messages (field 4) with label: "rtvi-ai" and event data:

user-started-speaking

The user began speaking. Interrupt any playing bot audio.

user-stopped-speaking

The user finished speaking. The bot will start processing.

user-transcription

Final transcription of user speech. data.text contains the transcribed text.

bot-llm-started

The bot started generating a response.

bot-llm-text

Token-level streaming text. data.text contains the delta.

bot-llm-stopped

The bot finished generating text. TTS synthesis begins.

bot-started-speaking

The bot started speaking (audio frames incoming).

bot-stopped-speaking

The bot finished speaking. Commit the transcript.

bot-output

Sentence-level aggregation of what the bot will speak. data.text contains the sentence.

error

An error occurred. data.error contains the message.

WebSocket Example (JavaScript)

// 1. Start the call via REST API
const response = await fetch('https://uncensored.chat/api/v1/voice/calls', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ character_slug: 'elon-musk' })
});
const { ws_url } = await response.json();

// 2. Connect to the WebSocket
const ws = new WebSocket(ws_url);
ws.binaryType = 'arraybuffer';

ws.addEventListener('open', () => {
  console.log('Voice call connected');
  // Start sending microphone audio...
});

ws.addEventListener('message', (event) => {
  if (event.data instanceof ArrayBuffer) {
    // Decode protobuf frame (audio or transport message)
    // See voice-call-client.ts for full decoder
  }
});

ws.addEventListener('close', () => {
  console.log('Voice call ended');
});
Response Codes
HTTP status codes returned by the API
200OK
Request successful
400Bad Request
Invalid request parameters
401Unauthorized
Invalid or missing API key
429Rate Limited
Too many requests
500Server Error
Internal server error