Events and goals

Tell Runearc what your customers do. Events trigger sequences, update contacts through sync rules and count as conversions for goals.

These are customer events on a contact. The signed events Runearc sends to your URL (message.delivered and so on) are on Webhooks and events; they share the path /v1/events but use GET.

Track an event

curl -X POST https://api.runearc.com/v1/events \
  -H "Authorization: Bearer $RUNEARC_API_KEY" \
  -H "Idempotency-Key: ord_42" \
  -H "Content-Type: application/json" \
  -d '{ "email": "ana@acme.com", "name": "plan_upgraded",
        "properties": { "plan": "pro", "amount": 4900 } }'
FieldTypeDescription
emailstringRequired. The contact must already exist (contact_not_found otherwise). contact_email is accepted too.
namestringRequired. Lowercase letters, digits and _ . : -, starting with a letter, at most 64 characters.
propertiesobjectFree JSON, at most 16 KB.
idempotency_keystringRepeating a key records the event once. The Idempotency-Key header does the same. A repeat returns 200 with duplicate: true; a new event returns 201.
occurred_atstringISO 8601. Defaults to now.

Names Runearc records itself are reserved and cannot be sent: contact.created, contact.updated, contact.unsubscribed, contact.resubscribed, list.added, list.removed, tag.added, tag.removed, email.sent, email.delivered, email.opened, email.clicked, email.bounced, email.complained, sequence.entered, sequence.completed, subscription.started, subscription.renewed, subscription.canceled, payment.succeeded, payment.failed and form.submitted. GET /v1/event-definitions/system returns the list. They can still trigger sequences and rules.

RequestQuery or bodyReturns
POST /v1/eventsemail, name, properties, idempotency_key, occurred_atThe event, with duplicate.
GET /v1/contacts/{id}/eventslimit (default 20), cursor, namedata and next_cursor, newest first.

Event definitions

Optional documentation for your own event names: a description and the property names and types. Tracking does not require a definition.

RequestBodyReturns
GET /v1/event-definitionsnoneDefinitions.
POST /v1/event-definitionsname, description, properties: [{name, type}]201. Duplicate names give event_definition_exists.
PATCH, DELETE /v1/event-definitions/{id}description, propertiesThe definition, or 204.

Sync rules

When an event happens and its conditions hold, a rule changes the contact. Conditions look at the event properties by dotted path (plan, order.total) with the ops eq, neq, gt, gte, lt, lte, contains and exists. All conditions must hold.

curl -X POST https://api.runearc.com/v1/sync-rules \
  -H "Authorization: Bearer $RUNEARC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Tag pro", "event_name": "plan_upgraded",
        "conditions": [{ "path": "plan", "op": "eq", "value": "pro" }],
        "action": { "type": "add_tag", "tag": "customer" } }'

The action is one of { "type": "add_tag", "tag" }, remove_tag, { "type": "set_field", "key", "value" } or { "type": "add_to_list", "list_id" }. Endpoints: GET, POST /v1/sync-rules and PATCH, DELETE /v1/sync-rules/{id} (patch name, conditions, action, enabled).

Goals

A goal is an event that counts as a conversion. A contact who tracks it within window_days (1 to 90, default 7) of an email they received is attributed to that email. value_property names the event property holding revenue, in cents.

curl -X POST https://api.runearc.com/v1/goals \
  -H "Authorization: Bearer $RUNEARC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Upgraded to pro", "event_name": "plan_upgraded",
        "window_days": 7, "value_property": "amount" }'

GET /v1/goals/{id}/stats?days=30 (1 to 365) returns conversions, contacts, attributed, revenue_cents and top_emails. GET, POST /v1/goals and PATCH, DELETE /v1/goals/{id} manage goals (patch name, conditions, window_days, value_property). A sequence can also stop when its goal event is tracked; see Sequences. Revenue from payments is in Billing integrations.

CLI and MCP

runearc events track ana@acme.com plan_upgraded --prop plan=pro --prop amount=4900 --key ord_42
runearc events list ana@acme.com --name plan_upgraded
runearc events define plan_upgraded --description "User upgraded"
runearc events definitions
runearc rules add "Tag pro" --event plan_upgraded --action add_tag --arg customer --when plan=eq:pro
runearc rules list | delete <id>
runearc goals add "Upgraded" --event plan_upgraded --window 7 --value-property amount
runearc goals stats <id> --days 30

MCP tools: track_event, list_contact_events, list_event_definitions, create_event_definition, list_sync_rules, create_sync_rule, delete_sync_rule, list_goals, create_goal and goal_stats.

Errors

CodeStatusMeaning and fix
contact_not_found404Add the contact first; events never create one.
invalid_event_name400Use lowercase letters, digits and _ . : -, at most 64 characters.
reserved_event_name, unknown_builtin_event400System names cannot be tracked by you. Pick another name.
invalid_properties, properties_too_large400Properties are a JSON object of at most 16 KB.
invalid_idempotency_key400Use a short ASCII id.
idempotency_key_reused409That key was used for a different event. Use a new key.
event_definition_exists, goal_exists409That name is taken.
invalid_window400window_days is 1 to 90.
field_not_found, list_not_found, invalid_tag400A rule action points at something that does not exist.

Something unclear or wrong? The API answers every error with a fix, and so should these docs. Back to runearc.com