HelloMeDocumentation

HelloMe Platform: messaging for your own app

Messages, voice notes, files, audio and video calls, support: in your app, in your colours, on HelloMe’s infrastructure.

Last updated October 17, 2026

You keep your app; HelloMe runs the messaging behind it. Your server creates your users, opens and closes conversations and hands your app a short session. Your app shows the conversations, sends and receives in real time, and places calls.

Nothing is tied to one trade. A user, a conversation, a free role, a reference and free fields: a mobility platform, a clinic, a school, a shop or a full messenger all use the same building blocks.

Your users stay yours. They appear nowhere in HelloMe, cannot write to anyone outside your conversations, and we never use their data for anything but your service.

1.API reference

The complete reference of every route, with a playground to try it with your key: hello-me.net/developers/api.

2.How it fits together

text
Your app ──(short session)──► HelloMe API: conversations, messages, files, calls, realtime
    ▲
    │ session
Your server ──(server key hm_sk_…)──► HelloMe API /platform: users, conversations, sessions
    ▲
    └────────── signed webhooks: message, call, closing, report
  • The server key never leaves your server. It carries the `messaging` scope and opens your workspace only.
  • A session is handed to your app for one person and one device; it expires (24 h by default, configurable) and can be revoked instantly.
  • Webhooks tell your server what happens, so your own logic can react.

3.In ten minutes

In the HelloMe console, open your workspace, Integrations tab, and create a key with “For my app’s messaging” ticked. Then, from your server:

1. Your two users
curl -X PUT https://api.hello-me.net/api/v1/platform/users/customer-4521 \
  -H "X-HelloMe-Key: hm_sk_…" -H "content-type: application/json" \
  -d '{"name":"Amina Kossi","role":"customer"}'

curl -X PUT https://api.hello-me.net/api/v1/platform/users/agent-77 \
  -H "X-HelloMe-Key: hm_sk_…" -H "content-type: application/json" \
  -d '{"name":"Kofi","role":"agent"}'
2. A conversation between them, with your reference
curl -X POST https://api.hello-me.net/api/v1/platform/conversations \
  -H "X-HelloMe-Key: hm_sk_…" -H "Idempotency-Key: $(uuidgen)" -H "content-type: application/json" \
  -d '{"ref":"case-42","title":"Case 42","participants":[{"externalId":"customer-4521"},{"externalId":"agent-77"}],"metadata":{"branch":"Lomé"}}'
3. A session for Amina’s app
curl -X POST https://api.hello-me.net/api/v1/platform/users/customer-4521/sessions \
  -H "X-HelloMe-Key: hm_sk_…" -H "content-type: application/json" \
  -d '{"deviceId":"install-abc","platform":"android","pushKey":"<FCM token>"}'
# → {"accessToken":"…","expiresAt":"…"}

The app sends this token as `Authorization: Bearer …` on the messaging routes (`GET /channel`, `POST /channel/{roomId}/message`…) and as the `auth` query on the realtime socket. The `roomId` is the one of the conversation created.

4.The JavaScript SDK

`@hellome/platform` holds three things: the server client, the app client and webhook verification. It retries a lost request (network, 429, 5xx) by itself with the same idempotency key, so a retry never acts twice.

Server
import {HelloMeServer} from "@hellome/platform/server";

const hm = new HelloMeServer({key: process.env.HELLOME_KEY!});
await hm.users.upsert("customer-4521", {name: "Amina Kossi"});
const conv = await hm.conversations.create({
  ref: "case-42", title: "Case 42",
  participants: [{externalId: "customer-4521"}, {externalId: "agent-77"}],
});
const {accessToken} = await hm.sessions.create("customer-4521", {deviceId: "install-abc"});
await hm.conversations.close(conv.id, "Case closed, thank you!");
App
import {HelloMeClient} from "@hellome/platform/client";
import {io} from "socket.io-client";

const chat = new HelloMeClient({
  // your server, which calls sessions.create
  getSession: () => fetch("/api/chat-session").then((r) => r.json()).then((r) => r.accessToken),
});
const socket = await chat.realtime(io);
socket.on("v1OnNewMessage", (raw: string) => show(JSON.parse(raw)));
await chat.sendText(roomId, "Hello!");
await chat.sendFile(roomId, photo, {type: "image", name: "photo.jpg"});

An expired or revoked session is asked again from your server once, without the user noticing. The app client refuses to run with a server key: it has no place in an app.

5.Conversations

ActionRoute
Open (same `ref` = same conversation)POST /platform/conversations
List and filter (`status`, `ref`, `participant`, `metadata.<key>`)GET /platform/conversations
Change title, picture, fields, scheduled closing, settingsPATCH /platform/conversations/{id}
Add / remove a participantPOST …/participants · DELETE …/participants/{externalId}
Write as your company or as a participantPOST …/messages
Export every messageGET …/messages
Close (read only), reopen, archivePOST …/close · …/reopen · …/archive
Bring in your supportPOST …/support

A closed conversation stays readable; nobody writes or calls in it any more. `closeAt` closes it by itself at the chosen moment. Per conversation, you allow calls and files or not; the largest file size is set for the whole workspace.

Support: your agents are members of your HelloMe workspace. `POST …/support` brings in the least busy available agent (or one of a team), who answers from their HelloMe app. Customer ↔ support, staff ↔ support and customer ↔ staff all go through one system.

6.Building a full messenger

With `directory: true` (`PATCH /platform/config`), your users can find each other (`GET /platform-app/people`) and open a conversation themselves (`POST /platform-app/conversations`) — always inside your workspace, never with anyone else.

7.Notifications

Your notifications leave with your own keys: your Firebase project (`PUT /platform/config/push/fcm`, the service account JSON) and your Apple `.p8` key for incoming calls on iPhone (`PUT /platform/config/push/apns`). They never go through HelloMe’s project.

The device token is given when the session is created (`pushKey`, `voipKey`) or from the app (`POST /profile/push`). Without keys, nothing is sent: the `platform.message.created` webhook lets you notify by yourself.

8.Webhooks

Declare an https address in the console. Events: `platform.message.created`, `platform.conversation.opened`, `.closed`, `.archived`, `platform.participant.added`, `.removed`, `platform.call.started`, `.ended` (duration and minutes), `platform.report.created`.

Verify a delivery, on the raw body
import {parseWebhook} from "@hellome/platform/webhooks";

app.post("/hellome", express.raw({type: "application/json"}), (req, res) => {
  const event = parseWebhook(process.env.HELLOME_WEBHOOK_SECRET!, req.header("x-hellome-signature")!, req.body);
  // event.event, event.data …
  res.sendStatus(200);
});

Every delivery is signed (HMAC-SHA256 of `timestamp.body`) and timestamped: a forged delivery, or one replayed more than five minutes later, is refused. A failed delivery is sent again after 2 s and 10 s; after 20 failures in a row the address is put to sleep rather than hammered.

9.Test environment

Create a test key (console → Integrations → “Test key”): it starts with `hm_sk_test_` and reaches only a twin of your workspace, with its own users, conversations, settings and webhooks. Nothing there is billed and nothing there touches your real data: a test key gets 404 on everything live, and the other way round.

  • Every answer carries the `x-hellome-environment: test` or `live` header.
  • Open on every plan, so you integrate before you pay; 50 active users a month at most.
  • One-time codes are not sent from a test key (`403 test_key_not_allowed_here`): a test never sends a real SMS.
  • In the console, the Live / Test switch shows one or the other, never both mixed.

10.The voice

When HelloMe opened them, three voice features come with ElevenLabs’ voice:

  • Voice message: `POST /platform/conversations/{id}/voice-messages` with `{text, from?}` — your text, spoken and sent as a voice note (its words stay on the message). Paid from your credit, per 1,000 characters.
  • Hear a message, and hear a voice note in another language: `POST /voice/messages/{roomId}/{messageId}/read-aloud` (answers `audio/mpeg`) and `…/translate` with `{to}`, called by your app with its session.
  • Voice agent: turn it on in your console (Platform → Settings); your app then calls `POST /voice/agent/session` with its session, gets a `conversationToken` and runs `Conversation.startSession({conversationToken, connectionType: "webrtc"})` from `@elevenlabs/client`; at the end, `POST /voice/agent/session/{id}/end` with the conversation id. Minutes are taken from your credit.
  • Never an encrypted, deleted or view-once message, nor a conversation under advanced privacy. `app-config` says what is open: `features.readAloud`, `features.voiceTranslate`, `features.voiceAgent`, `voice.languages`.

11.Billing beyond the plan

Your plan includes a number of active users a month (at least one session or one message). Beyond it:

  • If your plan has a price per extra user, it is taken from your HelloMe credit at each new person’s first session of the month. Short credit: that new session is refused (`402 insufficient_credit`); people already active and conversations going on continue.
  • Without that price, the ceiling is firm: `403 plan_platform_users_reached` for a new person.
  • Call minutes, when your plan prices them, are taken after the call: a call is never cut for credit.
  • The test environment is never billed.
  • The console shows your prices, your credit and the month’s usage.

12.Security: what we guarantee

  • Server keys are never stored: only their SHA-256 fingerprint is kept. A lost key is replaced, not recovered.
  • Push keys are sealed with AES-256-GCM before they are stored, and never sent back by the API.
  • Strict isolation: a user of your app reaches only the messaging routes they need; every other route answers 403. They are absent from every HelloMe search, and their phone and e-mail are kept apart — never used for a HelloMe sign-in, never taken as verified.
  • Workspaces are sealed from each other: a key sees its own workspace only. Any resource of another workspace answers 404; our end-to-end tests check it.
  • Short sessions, bound to one device, revocable at once (`DELETE …/sessions`).
  • Webhooks over https only, signed, never following a redirect, and never to an internal address: the address is checked when declared and again at every connection.
  • Every input is validated: identifiers, free fields (4 KB, keys without operators), https pictures only.
  • Every change of settings, keys or sessions is written to your workspace’s audit trail.
  • Encryption in transit (TLS) between your app, your server and HelloMe. Messages are not end-to-end encrypted: that is what makes the export, the retention you set and your support’s access possible.

13.Reliability

  • Idempotency: every creation accepts `Idempotency-Key`. The same request sent again gets the first answer; two simultaneous copies cannot both act.
  • The same `ref` always gives the same conversation, even when two calls arrive together.
  • Stateless API: any copy of the API answers; realtime, locks and limits are shared.
  • A slow server of yours never slows a message: webhooks, notifications and meters run in the background.
  • Scheduled jobs (scheduled closings, retention) run once, even with several copies.
  • Rate limit per company (`x-ratelimit-*` headers, `Retry-After`): another company in a loop does not slow you down.
  • Versioned API (`/api/v1`): a breaking change is announced in advance, never imposed.

14.Your data

You remain responsible for your users’ data; HelloMe processes it on your behalf and for nothing else. Export it at any time (`GET …/messages`), set how long it is kept (`retentionDays`) and close a user when they ask (`DELETE /platform/users/{externalId}`).

15.Errors and limits

CodeMeaning
401 server_key_invalidKey missing, wrong or revoked
403 scope_required:messagingThe key lacks the messaging scope
403 plan_no_platformYour plan does not include the platform
402 insufficient_creditNot enough credit for a user beyond the plan
403 plan_platform_users_reachedMonthly active user ceiling reached (conversations going on continue)
403 platform_conversation_closedClosed conversation: read only
403 platform_session_not_allowedAn app session on a route not open to it
404 platform_user_not_found / platform_conversation_not_foundUnknown in your workspace
409 platform_request_in_progressThe same Idempotency-Key is in progress: retry in a moment
413 platform_file_too_large:<n>MBBeyond the size your workspace set
429 platform_rate_limitedToo many calls this minute; see Retry-After
HelloMe Platform: messaging for your own app · HelloMe