Authentication
Two mechanisms, for two different callers.
| Caller | Mechanism | Scope |
|---|---|---|
| You, or your automation | Session cookie | Your whole account |
| The embedded widget | X-Widget-Key header | One chatbot |
Session authentication
Used by every endpoint under /chatbots, /uploads and /admin.
Register
POST /auth/register
{
"email": "you@example.com",
"password": "a-strong-password",
"name": "Your Name"
}
Log in
POST /auth/login
{
"email": "you@example.com",
"password": "a-strong-password"
}
On success, the response sets two httpOnly cookies: a short-lived access token and a longer-lived refresh token. Subsequent requests are authenticated by sending those cookies.
With curl, use a cookie jar:
# Log in and store the cookies
curl -c cookies.txt -X POST https://apimesh.byteleaps.tech/api/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"you@example.com","password":"..."}'
# Reuse them
curl -b cookies.txt https://apimesh.byteleaps.tech/api/chatbots
The cookies are httpOnly, so JavaScript in a page cannot read them. That removes the most common route to stolen sessions. The trade-off is that your HTTP client must handle cookies — which every mainstream one does.
Current user
GET /auth/me
Returns the signed-in user. Useful as a cheap check that your session is still valid.
Refresh the session
POST /auth/refresh
Exchanges the refresh token for a new access token. Refresh tokens rotate on use.
Call this when a request fails with 401 and you believe the session should
still be alive. If the refresh itself fails, log in again.
Log out
POST /auth/logout
Clears the cookies and invalidates the refresh token server-side.
Rate limiting
Registration, login and refresh are limited to 10 requests per 15 minutes. This is deliberately tight — it is the defence against password guessing. Do not build a retry loop against these endpoints.
Widget key authentication
Used by every endpoint under /chat. These are the calls the embedded widget
makes.
Send the key in a header:
X-Widget-Key: your_widget_key
curl https://apimesh.byteleaps.tech/api/chat/CHATBOT_ID/config \
-H 'X-Widget-Key: your_widget_key' \
-H 'Origin: https://example.com'
Origin checking
The request's Origin is checked against the key's allowed domains. Requests
from anywhere else are rejected with 403 Domain not authorized.
This is enforced server-side and cannot be bypassed from the client.
| Allowed domain entry | Matches |
|---|---|
example.com | Exactly example.com |
*.example.com | example.com and any subdomain |
* | Any origin |
A key with an empty allowed-domains list rejects everything. It is not an open key.
Errors
| Status | Message | Cause |
|---|---|---|
401 | Missing widget key | No X-Widget-Key header |
401 | Invalid or revoked API key | Key does not exist or was revoked |
403 | Domain not authorized | Origin not in the key's allowed list |
403 | Origin header missing | No origin, and the key restricts domains |
403 | Invalid Origin | The origin could not be parsed |
The chatbot is resolved from the key
Widget chat paths include a chatbot id, but the chatbot that actually gets used is resolved from the key, not the URL. Changing the id in the path does not reach another chatbot.
Admin endpoints
/admin routes require a session and an account with the admin role. They are
for platform operators, not customers, and are not documented here.