← All posts
Integrations6 min read

[INTEGRATIONS] · Jun 5, 2026 · 09:40

Sync live chat conversations and contacts to your CRM

Keep your CRM current with every chat: who wrote in, what they asked, and how it ended. Two ways to do it, real-time and batch, both on the muro API.

Tm

The muro team

muro.chat

#crm#integrations#api#sync#contacts#webhooks
Sync live chat conversations and contacts to your CRM

Your CRM is only as good as what reaches it. Every chat is a signal: a question, an objection, a lead handing over their email. The muro API gives you two clean ways to keep your CRM in sync, and most teams use both.

Two ways to sync

Real-time uses webhooks: muro pushes an event the moment it happens, so your CRM updates within seconds. Batch uses the REST API: you pull contacts and conversations on a schedule, which is simpler to operate and great for backfills. Real-time keeps things fresh; batch keeps things complete. Run real-time for live updates and a nightly batch as a safety net.

Real-time: push on identification

Subscribe to visitor.identified. It fires when a visitor hands over their email, which is exactly the moment they become a CRM-worthy lead. In your receiver, verify the signature, then upsert the contact and attach the conversation as a note. Our webhooks guide has a copy-paste receiver with signature verification.

Batch: pull with the API

On a schedule, page through contacts, then fetch each conversation's transcript. Contacts are keyset-paginated by last activity, so you can sync only what changed since your last run by stopping once you reach contacts you have already seen.

typescriptconst BASE = 'https://muro.chat/api/v1';
const headers = { Authorization: 'Bearer ' + process.env.MURO_KEY };

// 1. Page through contacts (most recently seen first)
let cursor: string | null = null;
do {
  const url = BASE + '/contacts?limit=100' + (cursor ? '&cursor=' + cursor : '');
  const page = await fetch(url, { headers }).then((r) => r.json());
  for (const contact of page.data) {
    if (contact.email) await upsertCrmContact(contact);
  }
  cursor = page.has_more ? page.next_cursor : null;
} while (cursor);

// 2. Pull a conversation transcript for a contact record
const convs = await fetch(BASE + '/conversations?limit=100', { headers }).then((r) => r.json());
const msgs = await fetch(BASE + '/conversations/' + convs.data[0].id + '/messages', { headers })
  .then((r) => r.json());
const transcript = msgs.data.map((m) => m.sender_type + ': ' + m.content).join('\n');

Mapping the fields

  • Contact email and name map straight to your CRM contact or lead.
  • Contact conversation_count is a quick engagement score.
  • A conversation becomes an activity, a deal note, or a ticket.
  • The joined messages become the transcript attached to that record.
✦ ✦ ✦

Webhooks for the moment it matters, the REST API for everything else. Wire both and your CRM stops missing the conversations that turn into customers.

✦ Try it

One support inbox for all your projects, one flat price.

muro is live chat, an AI that answers from your own docs, and a shared inbox for every site you run. See it both sides in the live demo, check the flat pricing, or see how muro compares. It's the same snippet on every platform — browse every install guide.

Tm

✎ Written by

The muro team

muro.chat