[Telegram] | [LinuxDO] | [BiliBili]
This project allows various AI clients to call a human using the OpenAI Responses style API, and comes with a web console interface to help you assemble Tool Calling requests or set up auto-reply rules.
Through this project, you can let others configure you as an Agent or chatbot, and then you play the role of an AI assistant being called.
You can also use it as a Mock LLM when developing your own Agent.
- Backend: Flask
- Frontend: React + Vite + Ant Design
- Data storage: SQLite
Default features:
- Login with username/password based on
.env, optional TOTP support - Support for three API interfaces:
/v1/chat/completions,/v1/responses,/messages - Conversation list and message persistence for debugging and context inspection
- Automated reply output, supports scheduled streaming, loop output, conditional auto-reply, etc.
- Optional ntfy message push
Run from the repository root:
make build EMBED_FRONTEND=1This builds the frontend and compiles it into build/chatapi with the Go
embed_frontend build tag. The executable does not require
CHATAPI_WEB_DIST_DIR at runtime. Use make build to keep the external
frontend directory mode.
cd ./frontend
npm i
npm run buildThe homepage shows the current access source as the API base URL by default; if you need to specify another base URL at build time, set VITE_HOMEPAGE_API_BASE_URL before building.
CHATAPI_USERNAME=your_username
CHATAPI_PASSWORD=your_password
# Optional; if not provided, the backend will auto-generate and write to the database config table on first start
# CHATAPI_SESSION_SECRET=random_string
CHATAPI_DB_PATH=./data/chatapi.sqlite3
CHATAPI_DATA_DIR=./data
CHATAPI_HOST=0.0.0.0
CHATAPI_PORT=443
CHATAPI_WEB_DIST_DIR=../frontend/dist
CHATAPI_TLS_CERT_FILE=../certs/server.crt
CHATAPI_TLS_KEY_FILE=../certs/server.keycd ./backend
uv sync
uv run main.pycd ./backend
uv sync
uv run main.pycd ./frontend
npm i
npm run devFirst copy the configuration template:
cp .env.example .envAt a minimum, modify the following:
CHATAPI_USERNAME=admin
CHATAPI_PASSWORD=change-me
# Optional; if not provided, the backend will auto-generate and write to the database config table on first start
# CHATAPI_SESSION_SECRET=change-this-session-secretIf deployment configuration is stored outside the project directory, you can set an external env file path:
CHATAPI_ENV_FILE=/path/to/chatapi.envThe external env file uses the same format as .env inside the project; existing process environment variables will not be overwritten by values in the file.
It is recommended to also verify the following configuration:
CHATAPI_DB_PATH=./data/chatapi.sqlite3
CHATAPI_DATA_DIR=./data
CHATAPI_HOST=0.0.0.0
CHATAPI_PORT=5000
CHATAPI_CORS_ORIGINS=http://localhost:5173,http://127.0.0.1:5173After logging in, you can enable and save API Key, site title, ntfy address, rate limiting, and TOTP in "System Settings"; these no longer need to be placed in .env.
Optional configuration:
# Let Flask directly host frontend static files (e.g., Vite build dist)
# CHATAPI_WEB_DIST_DIR=./frontend/dist
# Use when Flask directly provides HTTPS
# CHATAPI_TLS_CERT_FILE=./certs/server.crt
# CHATAPI_TLS_KEY_FILE=./certs/server.key
# Optional email sending configuration:
# CHATAPI_EMAIL_FROM=noreply@kirari.fun
# CHATAPI_SMTP_HOST=smtp.example.com
# CHATAPI_RESEND_API_KEY=re_xxxxxxxxx
# CHATAPI_BREVO_API_KEY=YOUR_BREVO_API_KEY
# CHATAPI_TENCENTCLOUD_SECRET_ID=AKIDxxxxxxxxxxxxxxxx
# CHATAPI_TENCENTCLOUD_SECRET_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# CHATAPI_TENCENTCLOUD_SES_REGION=ap-guangzhou
# A standard SES account also requires a template ID; template data will be dynamically generated by the program.
# CHATAPI_TENCENTCLOUD_TEMPLATE_ID=100091Note: Make sure your system is normal and you are using [Termux] downloaded from Github or F-Droid, or the domestic packaged version [ZeroTermux]. Ensure the system is 64-bit (Arm64 or aarch64) to guarantee proper operation and deployment. You can check your device architecture with the following command. For better management, you can use a file manager such as [MT Manager]. If you encounter problems, first update the project to the latest version, or ask AI or others. To avoid confusing behavior from Doubao, you can use other AIs (e.g., DeepSeek, Qwen). If you encounter a genuine bug, please report it to the creator.
uname -mCheck the output against the following; it should output aarch64 to meet the requirement.
At least Android 5 or higher, preferably Android 12 or higher.
Note: This project is originally designed for computers and has no optimization for mobile, but it can still run on mobile. Also ensure you have updated Termux related files to the latest. Now for preparation, enter the following commands to install some dependencies, etc.
termux-setup-storage # grant file permissions
termux-change-repo # change mirror source, steps: ok, ↓↓, ok, wait for completion, choose Chinese
pkg update && pkg upgrade -y # update
pkg install -y git wget curl vim binutils clang make pkg-config # install essential dependencies
pkg install -y python python-pip build-essential
pkg install -y libjpeg-turbo libpng freetype harfbuzz libtiff libwebp openjpeg
pip install uv
uname -m # check architecture again
pkg install -y nodejs # install the indispensable thing
node --version && npm --version # verify installationcd ~/
git clone https://github.com/zyf2007/ChatAPI.git # If Github cannot be accessed, see [Other Requirements]
cd ChatAPI
cd frontend
npm i
npm run buildThe homepage shows the current access source as the API base URL by default; if you need to specify another base URL at build time, set VITE_HOMEPAGE_API_BASE_URL before building.
First copy the configuration template:
cd ~/ChatAPI/backend
cp .env.example .envAt a minimum, modify the following:
CHATAPI_USERNAME=admin # username (admin name)
CHATAPI_PASSWORD=change-me # user password (admin password)
# Optional; if not provided, the backend will auto-generate and write to the database config table on first start
# CHATAPI_SESSION_SECRET=change-this-session-secretIf deployment configuration is stored outside the project directory, you can set an external env file path:
CHATAPI_ENV_FILE=/path/to/chatapi.envThe external env file uses the same format as .env inside the project; existing process environment variables will not be overwritten by values in the file.
It is recommended to also verify the following configuration:
CHATAPI_DB_PATH=./data/chatapi.sqlite3
CHATAPI_DATA_DIR=./data
CHATAPI_HOST=0.0.0.0
CHATAPI_PORT=5000
CHATAPI_CORS_ORIGINS=http://localhost:5173,http://127.0.0.1:5173After logging in, you can enable and save API Key, site title, ntfy address, rate limiting, and TOTP in "System Settings"; these no longer need to be placed in .env.
Optional configuration:
# Let Flask directly host frontend static files (e.g., Vite build dist)
# CHATAPI_WEB_DIST_DIR=./frontend/dist
# Use when Flask directly provides HTTPS
# CHATAPI_TLS_CERT_FILE=./certs/server.crt
# CHATAPI_TLS_KEY_FILE=./certs/server.key
# Optional email sending configuration:
# CHATAPI_EMAIL_FROM=noreply@kirari.fun
# CHATAPI_SMTP_HOST=smtp.example.com
# CHATAPI_RESEND_API_KEY=re_xxxxxxxxx
# CHATAPI_BREVO_API_KEY=YOUR_BREVO_API_KEY
# CHATAPI_TENCENTCLOUD_SECRET_ID=AKIDxxxxxxxxxxxxxxxx
# CHATAPI_TENCENTCLOUD_SECRET_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# CHATAPI_TENCENTCLOUD_SES_REGION=ap-guangzhou
# A standard SES account also requires a template ID; template data will be dynamically generated by the program.
# CHATAPI_TENCENTCLOUD_TEMPLATE_ID=100091cd ~/ChatAPI/backend
uv sync
uv run main.pySince both need to run simultaneously, you need to create a new session. Two sessions will run backend and frontend separately. The frontend provides a web management interface.
cd ~/ChatAPI/frontend
npm i
npm run devpkg install tmux -ytmux new -s chatapi-backend
cd ~/ChatAPI/backend
uv run main.pyCtrl+B, D detach session
tmux new -s chatapi-frontend
cd ~/ChatAPI/frontend
npm run dev -- --host 0.0.0.0Ctrl+B, D detach session
tmux lstmux attach -t chatapi-backendcd ~/ChatAPI/backend
nohup uv run main.py > backend.log 2>&1 &cd ~/ChatAPI/frontend
nohup npm run dev -- --host 0.0.0.0 > frontend.log 2>&1 &- Install Termux:Boot add-on/[(ZT)Termux:Boot]
- Create startup script ~/.termux/boot/start-chatapi.sh:
#!/data/data/com.termux/files/usr/bin/bash
cd ~/ChatAPI/backend
nohup uv run main.py > backend.log 2>&1 &
sleep 3
cd ~/ChatAPI/frontend
nohup npm run dev -- --host 0.0.0.0 > frontend.log 2>&1 &Grant execute permission:
chmod +x ~/.termux/boot/start-chatapi.shServices in Termux usually run on the local area network. For public access, you can use the following intranet penetration tools:
pkg install cloudflared -y
cloudflared tunnel --url http://localhost:5000pkg install wget -y
wget https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-arm64.tgz
tar xzf ngrok-v3-stable-linux-arm64.tgz
./ngrok config add-authtoken YOUR_TOKEN
./ngrok http 5000-
Change the default admin password: Modify CHATAPI_PASSWORD immediately after deployment, avoid weak passwords.
-
Enable TOTP two-factor authentication: Enable TOTP in the web console's "System Settings", use with Google Authenticator or other authenticators. The TOTP secret should be stored securely in the database.
-
Enable API Key authentication: Enable Bearer Token authentication for API calls; calls must carry the Authorization: Bearer <api_key> header.
-
Enable rate limiting: Configure request rate limiting in system settings to prevent abuse.
-
Use HTTPS in production: Strongly recommended to use Nginx reverse proxy + Let's Encrypt free certificate
-
Restrict CORS origins: Only allow necessary domains, avoid using wildcards
-
Configure firewall: In Termux you can use iptables or nftables to restrict access source IPs
-
After login, enable and save API Key, site title, ntfy address, and TOTP in the web console; these configurations should not be placed in the .env file
-
If SESSION_SECRET is not provided, the backend will auto-generate it on first start and write it to the database config table
ChatAPI supports sending message notifications via ntfy. Users can enter an ntfy push URL in "My Settings".
In most cases, leaving it as the default "Disabled" is sufficient. Only enable it when you self-host ntfy on the same machine, same internal network, or a private network as ChatAPI, for example: http://127.0.0.1:8080/topic or http://192.168.1.10:8080/topic.
If you use the official https://ntfy.sh/your-topic, or a self‑hosted ntfy with a public domain name (e.g., https://ntfy.example.com/topic), you do not need to change this setting.
Meaning of the three options:
- Disabled: No user may fill in a local or intranet push URL.
- Admin only: Only the administrator may fill in a local or intranet push URL.
- All users: Any logged‑in user may fill in a local or intranet push URL.
It is recommended to use "Admin only" first, and only select "All users" if you fully trust every user. The default is disabled to prevent SSRF risks where users could force the server to access 127.0.0.1, localhost, internal IP addresses, or cloud metadata addresses via the push URL.
Cause: SQLite may encounter lock conflicts under high concurrency writes.
Solutions:
-
Enable WAL mode (?journal_mode=WAL)
-
Use connection pooling to limit concurrent connections
-
Wrap busy write operations in transactions
Cause: CHATAPI_SESSION_SECRET not set in .env.
Solution: Leave it blank; the backend will auto-generate on first start and write to the database config table. If you need to specify manually, use a high-entropy random string.
Check items:
-
SMTP server address and port are correct
-
SMTP authentication is enabled (some providers require it)
-
The sender email has been verified
-
When using third-party APIs (e.g., Resend, Tencent Cloud SES), the API key is valid and has correct permissions. Resend suggests setting permissions to "only send" to reduce leakage risk.
Solutions:
-
Increase swap space: dd if=/dev/zero of=$PREFIX/swapfile bs=1M count=1024 && chmod 600 $PREFIX/swapfile && mkswap $PREFIX/swapfile && swapon $PREFIX/swapfile
-
Ensure sufficient memory before running npm run build (1GB+ available RAM recommended)
Defaults to the latest version; if your device is not supported, please find an adapted version yourself. [ZeroTermux‖0.118.3.58‖all architectures]
[Termux‖V0.119.0-beta3‖all architectures]
Defaults to the latest version; if your device is not supported, please find an adapted version yourself. Use download site: [gh-proxy], Cloudflare
[Termux‖V0.119.0-beta3‖all architectures] Main site acceleration, global high-speed distribution
[Termux‖V0.119.0-beta3‖all architectures] Preferred acceleration server, IPv4 only, smart DNS resolution
[Termux‖V0.119.0-beta3‖all architectures] Preferred acceleration server, supports IPv6/IPv4 smart DNS resolution
[ZeroTermux‖0.118.3.58‖all architectures] Main site acceleration, global high-speed distribution
[ZeroTermux‖0.118.3.58‖all architectures] Preferred acceleration server, IPv4 only, smart DNS resolution
[ZeroTermux‖0.118.3.58‖all architectures] Preferred acceleration server, supports IPv6/IPv4 smart DNS resolution
Domestic software uses domestic channels; for Github, use the [download site]. Defaults to the latest version; if your device is not supported, please find an adapted version yourself.
git clone https://gh-proxy.org/https://github.com/zyf2007/ChatAPI.gitgit clone https://v4.gh-proxy.org/https://github.com/zyf2007/ChatAPI.gitgit clone https://v6.gh-proxy.org/https://github.com/zyf2007/ChatAPI.gitThe following example assumes:
- Frontend static file directory:
/path/to/ChatAPI/frontend/dist - Backend address:
http://127.0.0.1:5000 - Domain name:
chat.example.com
server {
listen 80;
server_name chat.example.com;
root /path/to/ChatAPI/frontend/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://127.0.0.1:5000/api/;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /v1/ {
proxy_pass http://127.0.0.1:5000/v1/;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}If you want to enable HTTPS, it is recommended that Nginx handles the certificate rather than using Flask's built-in server.
If you do not want to deploy Nginx additionally, you can also let Flask directly serve both the API and frontend static files:
CHATAPI_WEB_DIST_DIR=./frontend/distAfter setting:
/api/*and/v1/*continue to go to the backend interface- Other paths will return static files directly from that directory
- When the requested path does not exist and the directory contains
index.html, it will automatically fall back toindex.html, which can be used for frontend single-page application routing
curl https://127.0.0.1:5000/v1/responses \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer sk-i-love-you-hutao' \
-d '{
"model": "胡桃酱",
"input": [
{
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "Type here to talk directly with Hu Tao!"
}
]
}
],
"stream": true
}'
Anthropic Messages compatible interface uses /messages, for example:
curl https://127.0.0.1:5000/messages \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer sk-i-love-you-hutao' \
-d '{
"model": "claude-sonnet-4-20250514",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": "Hello"
}
],
"stream": true
}'