Senlo

Send an event

POST /api/events creates or updates a contact and starts automations.

curl -X POST https://senlo.io/api/events \
  -H "Authorization: Bearer $SENLO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event": "contact_added",
    "email": "ada@example.com",
    "name": "Ada",
    "locale": "en",
    "metadata": { "plan": "trial" }
  }'

Body

FieldTypeRequiredDescription
eventstringyesOne of the events below.
emailstringyesIdentifies the contact in this workspace.
namestringnoThe contact's name.
localestringnoThe contact's locale; automations send the template for it.
metadataobjectnoContact attributes. For tag_added, metadata.tags is an array of strings.

Events

EventContact must existEffect on the contact
contact_addednoCreates it. For an existing address: updates name, replaces meta with metadata if sent.
contact_updatedyesUpdates name and locale, merges metadata into meta.
tag_addedyesAdds metadata.tags to its tags, without duplicates.
order_creatednoCreates it if new.
event_triggerednoCreates it if new. Your own event; put its data in metadata.

Then every active automation whose trigger listens for the event starts a run for the contact, unless one is already running for them.

Response

{
  "success": true,
  "data": {
    "id": 31,
    "projectId": 4,
    "email": "ada@example.com",
    "name": "Ada",
    "locale": "en",
    "meta": { "plan": "trial" },
    "unsubscribed": false,
    "unsubscribedAt": null,
    "createdAt": "2026-11-03T10:15:00.000Z"
  }
}

data is the contact after the event. projectId is the workspace id.

Errors

StatusWhen
400email missing or invalid, unknown event.
401No key, or a wrong one.
402Cloud only: an automation run was refused by the plan's limits. The contact change is already saved.
404contact_updated or tag_added for an address that is not a contact. Send contact_added first.
429Rate limited.

See Errors.

Idempotency

There is no idempotency key. Sending the same event twice applies it twice; for contact_added and the update events that is harmless, but it can start an automation again once the first run has finished.

Reference

POST /api/events in the API reference.

Edit this page on GitHub