Lelemon
  • Get started
  • Use cases
  • Guides
  • API basics
  • Webhooks
  • SDK, CLI and MCP
  • API reference
  • Changelog
  • v1 (legacy)
Configure your account
Talk to people
    Build your own inboxWhatsApp messagesWrite by emailMessage on eventsRun a campaignSchedule meetingsShow who is online
Run and protect
powered by Zudoku
Talk to people

Show who is online

You will

Send presence signals from your backend and read online and last seen on contacts and cases.

You need

  • A key with contacts:presence, and contacts:presence-read to read it
  • Contacts that carry your user id as externalRef
  • The organization setting presenceEnabled turned on

Presence is one fact per contact: is this person in your app right now. Your backend reports it. Lelemon does not watch anyone by itself.

Turn presence on

Presence is off until you turn it on. While it is off, reading presence or filtering with presence=online answers 409 presence_not_configured. Reporting signals needs contacts:presence; reading or changing the settings needs presence:configure, which a key issued by an admin or the owner can hold.

GET /v2/presence/settings says why presence does not show: it needs enabled true and hasSignals true, which becomes true after the first signal arrives.

Create the contact first

A signal does not create contacts. Create them with your own id as externalRef:

Send signals

Send active about every 60 seconds while the person is in your app, and offline when they leave. One call takes up to 100 signals.

PresenceSignalobject, 2 fields
  • externalRefstringrequired

    The externalRef you set on the contact. A reference that matches no contact of this organization is ignored.

    Example crm-4471

  • stateenumrequired

    active: the person is in your app right now, send it about every 60 seconds while they are. offline: they left; they stop showing as online at once.

    activeoffline

accepted is how many signals matched a contact of your organization. It never says which ones did not. A reference that matches no contact is ignored. Sending the same signal twice is harmless.

What Lelemon keeps

Only the last signal of each contact. There is no history and no webhook.

A contact is online while its last active signal is less than 120 seconds old and no offline came after it. Once offline, lastSeenAt can be up to 5 minutes behind.

Read presence

Presence appears in contacts and cases when presenceEnabled is on, at least one signal has arrived and the key has contacts:presence-read.

Presenceobject, 2 fields
  • onlinebooleanrequired

    true when the last active signal is less than 120 seconds old and no offline signal came after.

  • lastSeenAtstring or null (date-time)required

    The last time a signal arrived. While online it is exact; once offline it can be up to 5 minutes behind. null when no signal ever arrived for this contact.

presence=online also works on GET /v2/contacts. Without the scope, the presence field is left out. If presence is not active, the filter answers 409 presence_not_configured.

Schedule meetingsGive an agent a job
On this page
  • Turn presence on
  • Create the contact first
  • Send signals
  • What Lelemon keeps
  • Read presence
curl -X PUT https://api.lelemon.cl/v2/presence/settings \ -H "Authorization: Bearer $LELEMON_API_KEY" \ --json '{ "enabled": true }'
curl -X PUT https://api.lelemon.cl/v2/contacts/by-external-ref/crm-4471 \ -H "Authorization: Bearer $LELEMON_API_KEY" \ --json '{ "name": "Ana Pérez" }'
curl https://api.lelemon.cl/v2/presence-signals \ -H "Authorization: Bearer $LELEMON_API_KEY" \ --json '{ "signals": [ { "externalRef": "crm-4471", "state": "active" }, { "externalRef": "crm-4480", "state": "offline" } ] }'
{ "object": "presence_signals_result", "accepted": 1 }
curl "https://api.lelemon.cl/v2/cases?presence=online" \ -H "Authorization: Bearer $LELEMON_API_KEY"
{ "online": true, "lastSeenAt": "2026-11-02T15:04:11.000Z" }