Skip to main content
Sending a template couples your application to messaging: the template name, its language, the order of its placeholders. Change the copy and you deploy code. Events invert that. Your application says what happened:
LazyApp resolves the event to a template, maps the properties onto its placeholders, and sends. The mapping lives in your workspace — set it in the console or provision it over the API — so marketing can change the wording without touching your code.

Listing mappings

Required scope: templates:read.

Provisioning mappings

Platforms can create or update mappings without the console:
Or pass an explicit list (not both pack and mappings):
Required scope: templates:write. To also seed workflows and Flows for a vertical, use automation packs.

Addressing

By phone number:
or with type and value, the same shape as a contact:
Or by contact, when you already track people in LazyApp:

Record without sending

Not every business event should message the customer. A lead being qualified, a visit booked by an agent or a ticket created are worth keeping, and worth starting a workflow from, without a WhatsApp message. Send "deliver": false:
The answer is 202. The event appears in GET /v1/events with status recorded and starts api_event workflows. It needs no template mapping: a type with no mapping is refused only when you ask for it to be delivered.

Event types

type accepts the built-in library plus any event you define in your workspace. Defining your own also lets you declare a property schema, so a malformed event is rejected at the API rather than producing a message with an empty placeholder. Define a type over the API with PUT /v1/event-definitions/{type}. Namespace it (real_estate.visit_booked, clinic.appointment_booked) so two products sharing a workspace never fight over one type:
The call is idempotent, so run it from your setup script on every deploy. GET /v1/event-definitions lists your types, and DELETE /v1/event-definitions/{type} archives one: new events of that type are refused, and past ones stay in the history.

Idempotency

Events are the natural place for permanent deduplication. The body-level idempotency_key is enforced by a unique constraint, so one business event produces one message — forever, not just for 24 hours:
That matters when your own job runner might replay a task weeks later. See idempotency for how this differs from the header.

Replaying

If an event failed for a transient reason, replay it:
The replay runs under a fresh idempotency key, so the original deduplication does not block it.

Ingesting from another system

For a CRM or storefront that cannot be taught LazyApp’s event shape, there is a generic ingress:
The body is handed to your workflows as the trigger payload, filtered by source, so an automation can be authored against whatever that system already sends.