Open the dashboard

Integration guide

Connect your system to DaloChat

Your customers already talk to your Telegram bot. An integration lets your own system take part: send them messages, tell DaloChat who they are, and answer questions about their payments, orders or bookings, for your team and for the AI. It works for any system in any industry, and DaloChat never needs custom work for yours.

Overview

An integration is a connection between one DaloChat project and one other system (a shop, a booking engine, a payments app, a CRM). It has its own key. It can do any of three things, and each is optional:

1. Send messages

Your system sends a text to a customer through the project's bot. The team sees it in the customer's topic.

2. Say who someone is

When a customer arrives from your sign-in page, DaloChat asks your system who they are and keeps their account details on their card.

3. Look up their records

Payments, orders, bookings, tickets: your team can look one up from the chat, and the AI can answer from the live result.

The rules every integration follows.
  • Your system keeps its data and decides who may see what. DaloChat asks narrow questions and shows only what comes back.
  • A person must connect their Telegram to their account on your side before anything about them is looked up. DaloChat never searches your data on its own.
  • The AI may only state what your system returned, and says where it came from. If your system has no answer, it tells the customer the team will check.
  • One standard format for every system. You don't build anything specific to DaloChat beyond the endpoints below, and we don't build anything specific to you.

Quick start

  1. In the dashboard open Settings → Integrations → Add an integration. Give it a name (customers never see it, but your team does) and tick what it may do. Add the addresses of the endpoints you build (all optional, all https).
  2. Copy the key (Show key any time). Keep it as a secret on your server. It starts with dc_.
  3. Build the endpoints you want from the sections below.
  4. Press Send a test on the integration card to send a real test message to a person who has started your bot.
  5. Put a Telegram link next to the sign-in of your product: https://t.me/<your bot>?start=<code> (see Linking a person).

Keys and signatures

Your system calling DaloChat (sending a message): send the key in a header, either one.

X-Partner-Token: dc_...
Authorization: Bearer dc_...

DaloChat calling your system (identity and records lookups): it sends the same key, so you know the call is meant for you, and signs the request so you can be sure it comes from DaloChat:

X-Partner-Token: dc_...
X-DaloChat-Timestamp: 1760865600
X-DaloChat-Signature: 9f1c...   (hex HMAC-SHA256)

The signature is the hex HMAC-SHA256, with the key as the secret, of the text <timestamp>.<telegram_user_id>.<code or q>. For an identity lookup the last part is the start code (empty when there is none); for a records lookup it is q (empty when there is none). Checking it is recommended: reject a missing or wrong signature, and reject timestamps older than five minutes.

// Node
const crypto = require("crypto");
function valid(req, key, last) {            // last = req.query.code || req.query.q || ""
  const ts = req.get("X-DaloChat-Timestamp"), sig = req.get("X-DaloChat-Signature");
  const id = req.query.telegram_user_id || req.query.user_id;
  if (!ts || !sig || Math.abs(Date.now() / 1000 - ts) > 300) return false;
  const want = crypto.createHmac("sha256", key).update(`${ts}.${id}.${last}`).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(want), Buffer.from(sig));
}
# Python
import hmac, hashlib, time
def valid(headers, args, key, last=""):
    ts, sig = headers.get("X-DaloChat-Timestamp"), headers.get("X-DaloChat-Signature")
    uid = args.get("telegram_user_id") or args.get("user_id")
    if not ts or not sig or abs(time.time() - int(ts)) > 300: return False
    want = hmac.new(key.encode(), f"{ts}.{uid}.{last}".encode(), hashlib.sha256).hexdigest()
    return hmac.compare_digest(want, sig)

A key belongs to one integration in one project. If it leaks, press New key: the old one stops working immediately. Remove deletes the integration.

Customers write to your bot anonymously. To connect a person to their account in your system:

  1. In your product, create a one-time code for the signed-in account (6 to 64 characters: letters, digits, - or _; expiring in a day or so) and show the link https://t.me/<your bot>?start=<code>.
  2. The customer taps it and presses Start. Telegram sends /start <code> to your bot.
  3. DaloChat calls your lookup address, with the key and signature:
GET https://yourapp.com/api/who-is?code=abc12345&telegram_user_id=123456789

Answer 200 with whatever of these you have, as JSON. account_id is required; the rest is shown to your team on the customer's card.

{ "account_id": "acc_77", "email": "[email protected]", "name": "Sokha",
  "store_name": "Sokha Coffee", "plan": "pro", "status": "active" }
FieldWho sees it
account_idYour team. Required.
emailYour team only. Never given to the AI.
name, store_name (the business or account title), plan, statusYour team and the AI, so it can greet them properly and know what they're on.

The customer is welcomed, labelled with the integration's label (default “<name> customer”), and their card is kept fresh: DaloChat asks again when someone writes after a day, or when the title is missing.

Answers: 404, 410 or 400 mean “not a valid code / not someone I know” (the customer is told the link has expired). Any other error or a timeout (4 seconds) is treated as temporary: the chat carries on and DaloChat tries again on their next message. A person who writes without a code is looked up once by telegram_user_id alone; answer 404 if you don't know them.

Sending messages to a customer

POST https://dalochat.dalo-chat.workers.dev/api/partner/messages
X-Partner-Token: dc_...
Content-Type: application/json

{ "telegram_user_id": "123456789", "text": "Payment received: $12.00" }

The customer receives the text from your bot. The team sees it in the customer's topic as “From <your integration>”, and on the dashboard in a purple bubble. It does not count as a reply to a question, so a chat waiting for the team keeps waiting. It is never read or changed by the AI.

StatusMeaningWhat to do
200 {"ok":true}Delivered.Mark as sent.
400Bad telegram_user_id (digits only), empty text, or over 4,000 characters.Fix the call.
401Missing or wrong key.Check the key.
403 reason: not_allowed | inactiveSending is switched off for this integration, or the project isn't active.Ask the project owner.
404 reason: not_startedThat person has never pressed Start in the bot. Telegram only lets a bot write to people who did.Use another channel (email).
502 reason: blocked | telegramThe person blocked the bot, or Telegram refused.Use another channel. Don't retry in a loop.
Plain text only, for now. No images, files or formatting. There is no idempotency key yet, so if you retry after a timeout the person may get the message twice: retry at most once.

Looking up a customer's records

A “record” is whatever your system holds about a person that they may ask about: a payment, an order, a booking, a ticket, an invoice. You choose what to call them (for example Payments, Orders or Bookings) and give one address. DaloChat uses it in two places:

GET https://yourapp.com/api/records?user_id=123456789[&q=ORD-20481]

Answer with a list, an object holding the list, or a single record. The list may sit under records, payments, data or items, whichever your system already uses (extra keys such as account_id or query are ignored). DaloChat keeps this standard shape for each record. Common alternative field names are understood, so you don't have to rename anything:

FieldWhat it isAlso understood
idYour internal id.record_id
referenceWhat the customer would quote.reference_id, ref, number, code
titleWhat it is, in a few words.name, description, item, summary; or store_name + branch_name
amount, currencyMoney, if it has any.total, price
statusOne short word or phrase: paid, shipped, confirmed, expired…state
dateWhen it was made (ISO 8601).created_at, created, timestamp
done_atWhen it was completed (paid, delivered).paid_at, completed_at, fulfilled_at
expires_atWhen it lapses.due_at
noteA plain sentence the customer may be told, repeated as written. Put the explanation here: “Expired: not paid within 5 minutes. Create a new payment to try again.”reason, message, details
flagA short “needs attention” phrase.attention
testtrue if it isn't real (a sandbox record).livemode: false

Anything else you send is ignored, so there is no risk in a richer answer. Don't include email addresses, links or internal metadata. Keep note to one clear sentence in the language you want the customer to hear.

{ "records": [
  { "id": "ord_881", "reference": "ORD-20481", "title": "2 x Iced latte, 1 x Croissant",
    "amount": "9.50", "currency": "USD", "status": "out for delivery",
    "date": "2026-10-18T03:15:00Z",
    "note": "Your driver is on the way and should arrive by 4:30 PM." } ] }

Expect one call per customer message about a record, plus one per Look up press. Please rate-limit per key on your side (a generous limit is fine: 120 a minute) and answer within five seconds.

If something goes wrong

Your system answersThe team seesThe AI does
404 (nothing matches)“No record … for this person.”Says it can't find it and the team will check.
404 account_not_found“Isn't paired with an account.”Says the team will check.
401 / 403“Didn't accept the key.”Says the team will check.
429“Busy, try again in a minute.”Says the team will check.
Timeout or 5xx“Didn't answer.”Says the team will check.

The AI never guesses an amount, date, status or reason. When it has nothing, a person on the team takes over.

Privacy and safety

Testing

  1. Send a test: on the integration card, type a Telegram id (someone who has pressed Start in your bot) and press Send.
  2. By hand:
    curl -X POST https://dalochat.dalo-chat.workers.dev/api/partner/messages \
      -H "X-Partner-Token: $KEY" -H "content-type: application/json" \
      -d '{"telegram_user_id":"123456789","text":"Hello from my system"}'
  3. Linking: open your own link, press Start, and check that the customer's card in the Inbox shows your account details.
  4. Records: open that customer's chat and press Look up. Try an empty search, a real reference and a made-up one.
  5. The AI: write to the bot from the same account with a message containing one of your trigger words and check the answer matches your system.

Limits today

Tell us what you need next; this guide is the contract, and it only grows in ways that work for every system.