A lighweight Unofficial Character.AI API in Node/Deno/Bun JS, It does not require a puppeteer to interact with c.ai because the interaction is conducted with websocket and HTTPS Request (fetch).
CAINode is now using ESM. Please read at Getting Started first before using CAINode.
- Lightweight library (WebSocket and Fetch)
- Easy to use
- Almost all Character.AI Support
- Voice Call
- Single/Group chat
- Image Generate
- User
- Persona
- Explore list
- Getting Started
- Main Function List
- User Function List
- Image Function List
- Persona Function List
- Explore Function List
- Character Function list
- character.votes
- character.votes_array
- character.vote
- character.search
- character.search_suggest
- character.info
- character.recent_list
- character.connect
- character.disconnect
- character.send_message
- character.generate_turn
- character.generate_turn_candidate
- character.create_new_conversation
- character.delete_message
- character.edit_message
- character.replay_tts
- character.current_voice
- Group Chat Function List
- group_chat.list
- group_chat.connect
- group_chat.disconnect
- group_chat.create
- group_chat.delete
- group_chat.rename
- group_chat.join_group_invite
- group_chat.char_add
- group_chat.char_remove
- group_chat.send_message
- group_chat.generate_turn
- group_chat.generate_turn_candidate
- group_chat.reset_conversation
- group_chat.delete_message
- group_chat.edit_message
- group_chat.select_turn
- Chat Function List
- Voice Function List
- Issues
To install CAINode, you can simply do
- using NPM (Node Package Manager)
npm install -g cainode
- Using Deno
import CAINode from "npm:cainode@latest";
- Using Bun.JS
bun install cainode
- CommonJS
(async function() { const client = new (await import("cainode")).CAINode(); await client.login("Your token"); console.log("Logged in!"); await client.logout(); })()
- TypeScript/ESM
import {CAINode} from "cainode" // import {CAINode} from "npm:cainode@latest"; for Deno const client = new CAINode(); await client.login("Your token"); console.log("Logged in!"); await client.logout();
-
Start client initialization with login, make sure your token is valid so that the login session can run properly.
To get Character.AI Session Token, You can use generate_token() function.
await client.login("YOUR_CHARACTER_AI_TOKEN");
Param Require Type Description Token true
string
Your Character.AI token used for client login. -
Generate your Character.AI Token by email.
-
Without timeout
await client.generate_token("[email protected]", 0);
-
With timeout (per 2 seconds)
await client.generate_token("[email protected]", 30); // and it will end in 60 seconds.
-
With callback
await client.generate_token("[email protected]", 30, function() { console.log("Please check your email.") }, function() { console.log("Time is up! Please try again later.") });
Param Require Type Description email true
string
Your email to send a verification link. timeout_per_2s false
number
Max waiting for verification. (default = 30) mail_sent_cb false
Function
Callback when the mail was sent to the target. timeout_cb false
Function
Callback when the timeout was reached. -
-
Logout from the client.
await client.logout();
Param Require Type Description none false
null
Used for client logout from character ai.
-
Get current information account.
console.log(client.user.info);
Param Require Type Description none false
null
Get user information account. -
Get user public information account.
await client.user.public_info();
Param Require Type Description username false
string
Target Character.AI username account. (default = null, and it will target to your own account.) -
Change current information account.
await client.user.change_info();
Param Require Type Description username false
string
Change your old username to new username. name false
string
Change your old name to new name. avatar_rel_path false
string
Change your old avatar_rel_path link to new avatar_rel_path link.
Warning: avatar_rel_path image link must be generated/uploaded to Character.AI server.bio false
string
Change your old bio to new bio. -
Get account settings information data.
await client.user.settings();
Param Require Type Description none false
null
Get user settings information. -
Get public user following list.
await client.user.public_following_list();
Param Require Type Description username true
string
Target Character.AI username account. page_param false
number
Page parameter. -
Get public user followers list.
await client.user.public_followers_list();
Param Require Type Description username true
string
Target Character.AI username account. page_param false
number
Page parameter. -
Get account following name list.
await client.user.following_list_name();
Param Require Type Description none false
null
Get account following name list. -
Get account followers name list.
await client.user.followers_list_name();
Param Require Type Description none false
null
Get account followers name list. -
Follow user account.
await client.user.follow();
Param Require Type Description username true
string
Target Character.AI username account. -
Unfollow user account.
await client.user.unfollow();
Param Require Type Description username true
string
Target Character.AI username account.
-
Generate avatar image using prompt.
await client.image.generate_avatar(prompt_name);
Param Require Type Description prompt_name true
String
Prompt used for generating avatar image. -
Generate image using prompt.
await client.image.generate_image(prompt_name);
Param Require Type Description prompt_name true
String
Prompt used for generating AI image.
-
Create your personality for your character.
await client.persona.create(name, description);
Param Require Type Description name true
String
Your persona name description true
String
Description of your personality, this section is used to describe yourself so that your AI character knows who you are. -
Set your default personality specifically.
await client.persona.set_default(external_persona_id);
Param Require Type Description external_persona_id true
String
External personality id that you have. -
Get all your personality data.
await client.persona.list();
Param Require Type Description none false
null
Get all your personality data. -
Get your personality information.
await client.persona.info(external_persona_id);
Param Require Type Description external_persona_id true
String
External personality id that you have. -
Update your personality specifically.
await client.persona.update(external_persona_id, name, description);
Param Require Type Description external_persona_id true
String
External personality id that you have. name true
String
Your new personality name. description true
String
Your new personality detail. -
Used for deleting your personality spesifically.
await client.persona.delete(external_persona_id);
Param Require Type Description external_persona_id true
String
External personality id that you have. -
Set a custom personality for your character specifically.
await client.persona.set_character(character_id, external_persona_id);
Param Require Type Description character_id true
String
A character id that you want to set a custom personality. external_persona_id true
String
Your personality id that you use to let AI characters know who you are.
-
Get the list of characters displayed by the character.ai server.
await client.explore.featured();
Param Require Type Description none false
null
Get all featured data. -
Get a list of characters recommended by the character.ai server.
await client.explore.for_you();
Param Require Type Description none false
null
Get all for you data. -
Get the list simillar character from ID character.
await client.explore.simillar_char(char_id);
Param Require Type Description char_id true
string
Character ID. -
Get the list of characters from the character category exploration.
await client.explore.character_categories();
Param Require Type Description none false
null
Get all character categories data.
-
Get character vote information.
await client.character.votes(character_id);
Param Require Type Description character_id true
String
The character id you are aiming for. -
Get character vote information in array.
await client.character.votes_array(character_id);
Param Require Type Description character_id true
String
The character id you are aiming for. -
Used for vote the character.
await client.character.vote(character_id, vote);
Param Require Type Description character_id true
String
The character id you are aiming for. vote true
Boolean
Character vote options, true = like
,false = dislike
, andnull = cancel
-
Search for a character by name or query.
await client.character.search(name);
Param Require Type Description name true
String
Search queries to find characters. -
Search character by name and suggested by Character.AI Server
await client.character.search_suggest(name);
Param Require Type Description name true
String
Character name query. -
Get detailed information about characters.
await client.character.info(character_id);
Param Require Type Description character_id true
String
Your character id. -
Get a list of recent chat activity
await client.character.recent_list();
Param Require Type Description none false
null
Get recent character chats. -
Connect client to character chat
await client.character.connect(character_id);
Param Require Type Description character_id true
String
Your character id. -
Disconnecting client from character chat
await client.character.disconnect();
Param Require Type Description none false
null
Disconnecting client from character chat. -
Send message to character.
await client.character.send_message(message, manual_turn, image_url);
Param Require Type Description message true
String
Message content. manual_turn false
Boolean
If the value of manual_turn
is set totrue
then the message that the client receives must be generated withcharacter.generate_turn()
so that the message is obtained by the client.image_url false
String
The image content that the character will see, must be a url and not a file type or a file with a type other than image. -
Generating message response from character.
await client.character.generate_turn();
Param Require Type Description none false
null
Generate message response -
Regenerate character message.
await client.character.generate_turn_candidate(turn_id);
Param Require Type Description turn_id true
String
turn_id
ormessage_id
from the character. -
it will create a new conversation and your current conversation will save on the history.
- With greeting
await client.character.create_new_conversation();
- Without greeting
await client.character.create_new_conversation(false);
Param Require Type Description with_greeting false
Boolean
The character will send you a greeting when you create a new conversation. (Default = true) - With greeting
-
Delete character message.
await client.character.delete_message(turn_id);
Param Require Type Description turn_id true
String
turn_id
ormessage_id
from the character. -
Edit the character message.
await client.character.edit_message(candidate_id, turn_id, new_message);
Param Require Type Description candidate_id true
String
turn_id true
String
turn_id
ormessage_id
from the character.new_message true
String
New character message -
Generate text messages from character to voice audio.
- if you have Voice ID
await client.character.replay_tts("Turn ID", "Candidate ID", "fill the Voice Character ID here")
- if you don't have Voice ID and want to use Voice Query instead
await client.character.replay_tts("Turn ID", "Candidate ID", "Sonic the Hedgehog", true)
Param Require Type Description turn_id true
String
turn_id
from the character.candidate_id true
String
candidate_id
from the character.voice_id_or_query true
String
Input Voice character ID or you can use Voice Query. using_query false
Boolean
Using Query (if You're using Voice Query, then set this parameter to true
.) - if you have Voice ID
-
Get character current voice info.
- Auto (you must already connected with character)
await client.character.current_voice()
- Manual
await client.character.current_voice("Character ID")
Param Require Type Description character_id true
String
Target of Character ID. - Auto (you must already connected with character)
-
Get all list available group chat in account.
await client.group_chat.list();
Param Require Type Description none false
null
none -
Connecting to group chat by the
room_id
, btw you can't connect the group chat before you create it.await client.group_chat.connect(room_id);
Param Require Type Description room_id true
String
Your group chat id. -
Disconnecting from group chat by the
room_id
.await client.group_chat.disconnect(room_id);
Param Require Type Description room_id true
String
Your group chat id. -
Create a custom room chat.
await client.group_chat.create(title_room, character_id);
Param Require Type Description title_room true
String
Your custom title room name. character_id true
String
Your character id will be added to the group chat. -
Delete group chat.
await client.group_chat.delete(room_id);
Param Require Type Description room_id true
String
Your group chat id. -
Rename group chat.
await client.group_chat.rename(new_name, room_id);
Param Require Type Description new_name true
String
New name for your group chat. room_id true
String
Your group chat id. -
Joining group chat using invite code.
await client.group_chat.join_group_invite(invite_code);
Param Require Type Description invite_code true
String
The group chat miinvite code. -
Add a character with
character_id
to the group chat.await client.group_chat.char_add(character_id);
Param Require Type Description character_id true
String
Character id to be added to the group chat. -
Remove a character with
character_id
from the group chat.await client.group_chat.char_remove(character_id);
Param Require Type Description character_id true
String
Character id to be removed from the group chat. -
Send message to character in group chat.
await client.group_chat.send_message(message, image_url);
Param Require Type Description message true
String
Message content. image_url false
String
The image content that the character will see, must be a url and not a file type or a file with a type other than image. -
Generating message response character from group chat.
await client.group_chat.generate_turn();
Param Require Type Description none false
null
Generate message response -
Regenerate character message.
await client.group_chat.generate_turn_candidate(turn_id);
Param Require Type Description turn_id true
String
turn_id
ormessage_id
from the character. -
Reset conversation in group chat.
await client.group_chat.reset_conversation();
Param Require Type Description none false
null
Reset conversation. -
Delete character message.
await client.group_chat.delete_message(turn_id);
Param Require Type Description turn_id true
String
turn_id
ormessage_id
from the character. -
Edit character message in group chat.
await client.group_chat.edit_message(candidate_id, turn_id, new_message);
Param Require Type Description candidate_id true
String
turn_id true
String
turn_id
ormessage_id
from the character.new_message true
String
New character message -
Select the turn of character chat by yourself.
await client.group_chat.select_turn(turn_id);
Param Require Type Description turn_id true
String
turn_id
ormessage_id
from the character.
-
Get a history chat from group or single chat.
await client.chat.history_chat_turns(chat_id);
Param Require Type Description chat_id true
String
Group chat or single chat ID. -
Get converastion information.
await client.chat.conversation_info(chat_id);
Param Require Type Description chat_id true
String
Group chat ID or single chat ID. -
Get list of your history conversation from character. This function is for Single character only.
- Auto (Already connected to the Single character chat)
await client.chat.history_conversation_list()
- Manual
await client.chat.history_conversation_list("Character ID")
Param Require Type Description character_id false
String
Target of Character ID. - Auto (Already connected to the Single character chat)
-
Set conversation chat, and bring the history chat into current chat. This function is for Single character only.
await client.chat.set_conversation_chat(chat_id)
Param Require Type Description chat_id true
String
single chat ID. -
Pin message. This function is for Single character only.
- Auto (if your're already connected to the single character)
await client.chat.pin_message("Turn ID")
- Manual
await client.chat.pin_message("Turn ID", true, "Chat ID")
Param Require Type Description turn_id true
String
Turn ID Message. pinned false
Boolean
Set the message pinned or not. (set true
if you want to pin the message, setfalse
if you want to unpin the message.)chat_id false
String
Chat ID Message. (Set the Chat ID if you not connected to the Single character.) - Auto (if your're already connected to the single character)
-
Get list pinned message from chat. This function works only for single character chat.
await client.chat.list_pinned_message("Chat ID")
Param Require Type Description chat_id true
String
Chat ID Message. -
Archive your conversation. This function works only for single character chat.
- If you want archive the conversation
await client.chat.archive_conversation("Chat ID", true)
- If you want unarchive the conversation
await client.chat.archive_conversation("Chat ID", false)
Param Require Type Description chat_id true
String
Chat ID message that you want to archive. set_archive false
Boolean
Set Archive (to archive the Conversation, you can set it to true
. If you want to unarchive the Converastion, you can set it tofalse
.) - If you want archive the conversation
-
Duplicate your conversation. This function works only for single character chat.
await client.chat.duplicate_conversation("Chat ID", "Turn ID")
Param Require Type Description chat_id true
String
Chat ID message that you want to duplicate. turn_id true
String
Turn ID message that you want to duplicate. -
Rename your conversation title. This function works only for single character chat.
await client.chat.rename_conversation("Chat ID", "Custom Name")
Param Require Type Description chat_id true
String
Chat ID message that you want to rename. name true
String
Name that you want to rename.
-
Get list of user created voice information.
- Get your own created voice list
await client.voice.user_list()
- Get user created voice list
await client.voice.user_list("username")
Param Require Type Description username false
String
A username that wants you to check the created voice list. - Get your own created voice list
-
Get a voice information.
await client.voice.info("Voice ID")
Param Require Type Description voice_id true
String
A Voice ID that wants you to check the voice information. -
WARNING: This feature only supports Single character chat, not Group chat.
Connect to voice character chat, and this function works only for single character chat.
- Using Query
await client.voice.connect("Query", true)
- Using Voice ID
await client.voice.connec("Voice ID")
Example to use
-
Without microphone
const Speaker = require("speaker"); // import Speaker from "speaker" const speaker = new Speaker({ channels: 1, // 1 channel bitDepth: 16, // 16-bit samples sampleRate: 48000 // 48,000 Hz sample rate }); await client.character.connect("Character ID"); let test = await client.voice.connect("Sonic The Hedgehog", true); console.log("Character voice ready!"); test.output.on("frameReceived", ev => { speaker.write(Buffer.from(ev.frame.data.buffer)); // PCM buffer write into speaker and you'll hear the sound. }); await client.character.generate_turn(); // Test is voice character is working or not.
-
With microphone (Voice call)
const Speaker = require("speaker"); // import Speaker from "speaker" const { spawn } = require('child_process'); // import { spawn } from "child_process". //for microphone, I'll using sox. so Ineed child_process const speaker = new Speaker({ channels: 1, // 1 channel bitDepth: 16, // 16-bit samples sampleRate: 48000 // 48,000 Hz sample rate }); const recordMic = spawn('sox', [ '-q', '-t', 'waveaudio', '-d', // Input windows audio (add '-d' if you want set default) '-r', '48000', // Sample rate: 48 kHz '-e', 'signed-integer', // Encoding: signed PCM '-b', '16', // Bit depth: 16-bit '-c', '1', // Channel: 1 (mono) '-t', 'raw', // Output format: raw PCM '-' // stdout ]); let test = await client.voice.connect("Sonic The Hedgehog", true, true); console.log("Voice call ready!"); test.output.on("frameReceived", ev => { speaker.write(Buffer.from(ev.frame.data.buffer)); // PCM buffer write into speaker and you'll hear the sound. }); recordMic.stdout.on("data", data => { if (test.is_speech(data)) test.input_write(data); // Mic PCM Buffer output send it to Livekit server. });
Param Require Type Description voice_query_or_id true
String
Target Voice query or Voice ID. using_voice_query false
Boolean
Using Voice Query (set it to true if voice_query_or_id
using Voice Query)using_mic false
Boolean
Using Microphone (You can talk to the Character using Microphone. Livekit needed.) mic_opt false
{framerate: number, channel: number}
Mic options. Default = {framerate: 48000, channel: 1}
- Using Query
-
WARNING: This feature only supports Single character chat, not Group chat.
Disconnect from voice character chat.
await client.voice.disconnect()
Param Require Type Description none false
null
Disconnect from voice character chat.
Feel free to open the issue, I hope this documentation can help you maximally and make it easier for you to use this package.
Thanks to ZTRdiamond for helping me making a documentation.