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
emailandnamemap straight to your CRM contact or lead. - →Contact
conversation_countis a quick engagement score. - →A
conversationbecomes an activity, a deal note, or a ticket. - →The joined
messagesbecome 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.