Your users join the chat with the name they already have in your application: no second sign-up, no passwords. Show it as a full page or as a messenger widget in the corner of your site.
You vouch for the user. Eligo.chat trusts the username in the token, so only request tokens for users you have authenticated yourself.
Each application gets its own name and secret API key from the Eligo.chat team. Tell us your site address, the channel your users should land in, and whether you want the messenger widget.
The widget's look (side of the screen, button colour, panel size, light or dark) is configured on our side for your application. Ask us to change it; no code change is needed on your site.
Keep the API key on your server. Never put it in JavaScript, HTML or a mobile app: anyone who has it can enter the chat under any name.
Call this from your backend every time you render a page that shows the chat.
POST https://app.eligo.chat/api/token
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{ "username": "maria", "channel": "#romania", "widget": true }| Field | Required | Meaning |
|---|---|---|
username | yes | The user's name in your application (up to 64 characters). It becomes their chat nickname. |
channel | no | Channel to land in, starting with #. Leave it out to use your application's default channel. channels (an array, up to 10) is also accepted. |
widget | no | true to show the chat as a messenger widget. Without it you get the full-page chat. |
ttl | no | Token lifetime in seconds (60 to 604800). Default: 12 hours. |
{
"token": "yourapp.eyJ1Ijoi...",
"nick": "maria",
"channels": ["#romania"],
"expires": 1791679230,
"mode": "widget",
"url": "https://app.eligo.chat/#token=yourapp.eyJ1Ijoi...",
"embed": "<script src=\"https://app.eligo.chat/widget.js\" data-token=\"yourapp.eyJ1Ijoi...\" async></script>"
}| Field | Meaning |
|---|---|
mode | widget or page. It is page when you did not ask for the widget, or when the widget is not enabled for your application. |
embed | The widget tag, ready to print into your HTML. Empty when mode is page. |
url | Address of the full-page chat for this user. |
nick | The nickname the user will have (see Rules). |
expires | Unix time after which the token no longer works. |
| Status | Body | Cause |
|---|---|---|
| 401 | invalid app key | Missing or wrong Authorization header, or your application is disabled. |
| 400 | username is required | Empty username, longer than 64 characters, or without any letter or digit. |
| 400 | channel must look like #name | The channel does not start with #, or contains spaces or commas. |
| 400 | body must be JSON | The request body is not valid JSON. |
| 405 | POST only | The request was not a POST. |
Print embed into your page, just before </body>, on every page where the chat button should appear. A round button shows up in the corner; the chat opens in a panel above it, and full screen on phones. The chat only connects when the user first opens the panel, and the button shows the number of unread messages while it is closed.
Optionally control it from your own JavaScript:
EligoChat.open(); // open the panel EligoChat.close(); // close it EligoChat.toggle(); // switch
Send the user to url: as a link, a redirect, or inside your own <iframe> or webview.
<a href="URL_FROM_THE_RESPONSE">Open chat</a>
<iframe src="URL_FROM_THE_RESPONSE" allow="clipboard-write"
style="width:100%;height:640px;border:0"></iframe><?php
function eligo_chat(string $username, bool $widget = true, ?string $channel = null): ?array {
$body = ['username' => $username, 'widget' => $widget];
if ($channel) $body['channel'] = $channel;
$ch = curl_init('https://app.eligo.chat/api/token');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 5,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('ELIGO_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($body),
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $status === 200 ? json_decode($response, true) : null;
}
$chat = eligo_chat($currentUser->username);
?>
<!-- ... your page ... -->
<?php if ($chat): ?>
<?php if ($chat['mode'] === 'widget'): ?>
<?= $chat['embed'] ?>
<?php else: ?>
<a href="<?= htmlspecialchars($chat['url']) ?>">Open chat</a>
<?php endif; ?>
<?php endif; ?>async function eligoChat(username, { widget = true, channel } = {}) {
const res = await fetch('https://app.eligo.chat/api/token', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.ELIGO_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ username, widget, channel }),
});
return res.ok ? res.json() : null;
}
// Express example
app.get('/', async (req, res) => {
const chat = await eligoChat(req.user.username);
res.render('home', { chatEmbed: chat?.embed ?? '', chatUrl: chat?.url ?? '' });
});import os, requests
def eligo_chat(username, widget=True, channel=None):
body = {"username": username, "widget": widget}
if channel:
body["channel"] = channel
r = requests.post(
"https://app.eligo.chat/api/token",
headers={"Authorization": f"Bearer {os.environ['ELIGO_API_KEY']}"},
json=body,
timeout=5,
)
return r.json() if r.status_code == 200 else None
chat = eligo_chat(current_user.username)
# in the template: {{ chat.embed | safe }} or <a href="{{ chat.url }}">Open chat</a>curl -X POST https://app.eligo.chat/api/token \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"username": "testuser", "widget": true}'To see the widget without touching your site, open https://app.eligo.chat/widget-demo.html?token=TOKEN with the token from the answer.
_ - [ ] { } | ^ ` are kept; other characters (spaces, dots, accents) are removed, and the result is cut to 30 characters. A name that starts with a digit gets a leading _. If the nickname is already in use on the network, _ is added at the end. The nick field in the answer shows the result.yourapp: @username, so it is clear which application they came from.https://app.eligo.chat in script-src, frame-src and connect-src.| What you see | What to check |
|---|---|
| No button on the page | Is mode in the answer widget? If it is page, you did not send "widget": true or the widget is not enabled for your application. Also check that embed is printed without HTML escaping. |
401 invalid app key | The header must be exactly Authorization: Bearer YOUR_API_KEY. Some hosts strip this header; check what your server actually sends. |
| Panel shows a sign-in screen with an error | The token expired or was changed. Request a new one on each page load. |
| Stuck on "Connecting…" | Usually temporary on our side. If it lasts more than a minute, contact us with the time and the username. |
| The nickname differs from the username | See the nickname rules above; unsupported characters are removed. |