Build an email engagement report
engagement_reportUse this when the user pastes an email event export (Customer.io reporting webhook, SendGrid or Mailgun events) and wants a per-recipient engagement report, a CSV or the events with no recipient. Input tips: send the raw export text itself as events, never a file name or link; the events field lists the shapes read. Add recipients_csv or campaigns_csv only when the user gives them. Rules default to: dedup on, a 14 day window, machine opens as impressions only, bounce clears delivered. Set a rule only when the user names a different window or rule. Returns: a per-send summary, up to 500 recipient rows (csv holds every row), up to 100 exceptions, parse_errors and the rules used. A file that mixes platforms is read event by event. Only for the user's own sends: it reads event types, times and ids, and reads or returns no IP address, user agent, device or location. Next step: when events_kept is 0 or parse_errors is not empty, show the errors and ask for the raw export. Not for: sending mail or calling a mail platform API.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| rules | No | ||
| events | Yes | The pasted export text itself, not a file name or link, such as {"event_id":"e1","metric":"sent","timestamp":1789480800,"data":{"identifiers":{"id":"R-1"}}}. NDJSON (one event per line) or a JSON array. Read shapes: Customer.io (event_id, metric, timestamp, data.identifiers.id or email, data.delivery_id); SendGrid (flat email, event, timestamp, sg_event_id, sg_message_id); Mailgun (event, id, recipient, timestamp, tags, flat or inside "event-data"). Timestamps are unix seconds; milliseconds are converted. At most 20,000 events and 1,500,000 characters. | |
| campaigns_csv | No | Optional CSV text with a header row: deployment_key,deployment_code,campaign_name,client,deploy_date. deployment_key must equal the send key the report gives each send, such as newsletter:12, campaign:5:action:7, broadcast:3:action:9, transactional:4, sendgrid:<template id> or mailgun:<tag>; run the report once to read the keys from summary. | |
| recipients_csv | No | Optional CSV text with a header row, then one row per recipient: recipient_id,email,external_id (external_id may be empty). Example: recipient_id,email,external_id\nR-1,ada@example.com,CRM-1001. Events join by recipient_id, then delivery id, then email. Without it every send is a row and nothing is an exception. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| csv | Yes | Every recipient row as CSV with a header row. | |
| join | No | How events matched recipients_csv. | |
| rules | No | The rules this report used, defaults filled in. | |
| notice | Yes | Privacy note: nothing is stored. | |
| effects | No | How many events each rule changed. | |
| summary | Yes | One row per send. Sum its recipients for the full row count. | |
| platform | Yes | Platform read from the first event; email when it is not known, none when no email event was found. | |
| events_in | Yes | Email events read from the export. | |
| exceptions | Yes | Events with no recipient match, at most 100. Empty without recipients_csv. | |
| recipients | Yes | Per-recipient rows, at most 500; csv holds every row. | |
| events_kept | Yes | Events left after removing repeated event ids. | |
| parse_errors | No | Lines or values that are not valid JSON, at most 20. Show them and ask for the raw export when events_kept is 0. | |
| duplicates_removed | No | Events dropped because their event id was already seen. |