SendSetsDocs
Endpoint reference

Product events

Record what a contact did in your product and resume the campaign steps waiting for it.

A product event is your app telling SendSets that a contact did something: trial.started, report.opened, plan.upgraded. A wait_for_event step holds a contact until a named event arrives for them (or its timeout passes), so an outbound sequence can follow what the person actually did instead of a calendar.

Events are stored per workspace under the engagement-event retention window and are searchable afterwards.

Send a product event

POST /events

Auth: Scope WRITE_EVENTS · Org permission send_campaigns · Idempotency-Key required

FieldTypeRequiredDescription
namestringyesDotted lowercase words: [a-z0-9_-]+(\.[a-z0-9_-]+)*, up to 120 characters.
emailstringone ofThe contact's email.
contact_idstring (UUID)one ofThe contact's id. Exactly one of email or contact_id.
occurred_atstring (RFC 3339)noWhen it happened. Default: now. A wait only matches events that occurred after the contact entered it.
dataobjectnoEvent properties, up to 64 KiB. Becomes .App.<output_key> of the wait step that consumed it.
{
  "name": "trial.started",
  "email": "jane@acme.com",
  "data": { "plan": "pro" }
}

Response: 202 Accepted

{
  "event_id": "8b0a...",
  "contact_id": "c1d2...",
  "name": "trial.started",
  "received_at": "2026-09-01T10:00:00Z",
  "matched_waits": 1,
  "matched_runs": [
    { "run_id": "run_123", "campaign_id": "camp_1", "step_id": "wait_456", "contact_id": "c1d2...", "state": "waiting", "mode": "live" }
  ]
}

matched_runs names every step run the event resumed; an empty list means nothing was waiting. A replay with the same Idempotency-Key returns the stored event and resumes nothing new. An email or id that matches no contact answers 404 event_contact_not_found with a fix.

List product events

GET /events

Auth: Scope READ_CAMPAIGNS · Org permission view_campaigns

ParameterInTypeDescription
namequerystringOnly this event name.
emailquerystringOnly this contact, by email.
contact_idquerystring (UUID)Only this contact, by id.
sincequerystring (RFC 3339)Only events received after this time.
limitqueryintegerPage size, 1 to 200. Default 50.
cursorquerystringOpaque cursor from pagination.next_cursor.
{
  "data": [
    { "id": "8b0a...", "organization_id": "...", "contact_id": "c1d2...", "name": "trial.started", "data": { "plan": "pro" }, "occurred_at": "...", "received_at": "..." }
  ],
  "pagination": { "next_cursor": "", "has_more": false }
}

Get a product event

GET /events/:id

Auth: Scope READ_CAMPAIGNS · Org permission view_campaigns

Returns one event, or 404 event_not_found.

From the CLI

sendsets events send trial.started --email jane@acme.com --data '{"plan":"pro"}'
sendsets events list --name trial.started --since 2026-09-01T00:00:00Z
sendsets events tail --intent CAMPAIGN

events send mints an Idempotency-Key per call; pass --idempotency-key to make a retry a replay.

On this page