Move from a traditional chat provider to Heyyo with minimal disruption. This
guide maps common concepts, explains the authentication model (API key + secret →
JWT), and provides a practical checklist.
Server credentialsapi_key + api_secret (backend only)
Client authUser JWT (REST + WebSocket)
TransportREST + Socket.IO real-time events
Important: Don’t ship your api_secret to browsers or mobile apps.
Keep it on your backend and mint short-lived user tokens.
1) Concept mapping
Most chat platforms share the same building blocks. The names differ, but the intent
is similar.
Traditional provider
App / Project (tenant container)
User (often created server-side)
Channel / Conversation (room, thread, group)
Membership (user ↔ channel relationship)
Message (text + optional metadata)
Token (sometimes long-lived, sometimes session-based)
Heyyo
Application (tenant): created via POST /api/apps
User: identified by your user_id (in JWT claims)
Channel: created via POST /api/channels (e.g.
type: messaging)
Membership: join semantics are channel-based (see REST API docs)
Message: POST /api/channels/:id/messages
User token: short-lived JWT issued by your backend
If your existing provider uses “roles” or “capabilities”, model those rules in your
backend and mint JWTs accordingly.
2) Authentication model differences
A common migration pain is auth: older systems often rely on server-signed requests,
per-user access tokens, or provider-managed user sessions. Heyyo is intentionally
simple:
Heyyo auth in one sentence
Your backend uses api_key + api_secret to mint a
user JWT, then clients use that JWT for both REST and WebSocket.
Why it helps during migrations
You can keep your existing login system (email/password, OAuth, SSO). Heyyo only
needs a stable user_id and optional profile fields.
POST/api/auth/token
Server creds
Exchange api_key + api_secret + your
user_id for a user JWT. This is typically called from your backend
after the user signs in.
Clients use Authorization: Bearer <USER_JWT> for REST requests
and auth.token for WebSocket connections.
3) API differences (REST + real-time)
Traditional providers often split their surface area into multiple base URLs, separate
“admin” vs “client” APIs, or distinct auth schemes. Heyyo keeps the mental model
tight:
What changes
REST base URL: Heyyo uses a single origin for REST + Socket.IO.
Auth header: most endpoints use
Authorization: Bearer <USER_JWT>.
WebSocket: connect once, then listen for message.new and
related events.
Traditional provider (typical)
Many endpoints require a server key or request signing.
Clients often need separate session tokens or provider-managed login.
Real-time might require a distinct product/add-on.
Heyyo
Your backend mints user JWTs via /api/auth/token.
Clients use the same JWT across REST and Socket.IO.
Real-time is first-class: message.new is the default update path.
POST/api/channels
User JWT
Create a channel. In most migrations, this is the first entity you recreate.
curl -sS -X POST https://api.heyyo.dev/api/channels/<CHANNEL_ID>/messages \
-H 'Authorization: Bearer <USER_JWT>' \
-H 'Content-Type: application/json' \
-d '{"text":"Hello from the new system"}'
4) Side-by-side code comparison
The fastest way to migrate is to isolate your existing provider behind a small
interface (e.g. sendMessage, watchChannel,
listChannels) and swap the implementation.
Send a message
Traditional provider (illustrative)
// Client or server, depending on provider.
// Often requires provider-specific SDK + credential config.
await chat.messages.send({
conversationId: conversationId,
text: 'Hello!',
});
Heyyo SDK
import { HeyyoClient } from '@heyyo/sdk';
const cb = new HeyyoClient({
apiUrl: 'https://api.heyyo.dev',
token: '<USER_JWT>',
});
await cb.messages.send('<CHANNEL_ID>', 'Hello!');
Subscribe to new messages
Traditional provider (illustrative)
// Providers often have a "watch" call that syncs state.
const sub = chat.watchConversation(conversationId);
sub.on('message', (m) => {
render(m);
});