Skip to Content
AgentsEvents

Events

Marketing event ingest. Single + batch. Identity resolves email > phone > externalId. ISO-8601 timestamp is preserved on the resulting Touchpoint. Backed by MCP tool ingest_event.

Use this for any agent action that should land in the customer’s timeline: emails sent, calls placed, pages observed, signals fired. The event is identity-resolved against the existing customer graph and dropped on the right node automatically.

Request

POST /v1/events

Body is either a single EventIngest object, or { events: EventIngest[] } for batches up to 500.

FieldTypeNotes
eventstring, requiredEvent name. Pick a stable verb-tense slug. (email_sent, call_placed)
customerstring, optionalCustomer ID. If absent, identity resolves via email, then phone, then externalId.
emailstring, optionalOne of customer, email, phone, externalId MUST be present.
phonestring, optionalFalls back to +1 for bare 10-digit US numbers.
externalIdstring, optionalYour stable customer ID in another system.
propertiesobject, optionalFree-form. Lands on the Touchpoint node.
timestampstring, optionalISO-8601. Strict regex. Defaults to now if missing. 400 on malformed.

Required scope: events:write.

Examples

curl, single

curl https://api.waypath.app/v1/events \ -H "X-API-Key: wp_live_..." \ -H "Content-Type: application/json" \ -d '{ "event": "page_viewed", "email": "jane@acme.com", "properties": { "url": "/pricing", "referrer": "https://google.com" }, "timestamp": "2026-04-29T10:14:32Z" }'

curl, batch

curl https://api.waypath.app/v1/events \ -H "X-API-Key: wp_live_..." \ -H "Content-Type: application/json" \ -d '{ "events": [ { "event": "email_opened", "email": "jane@acme.com", "properties": { "campaign_id": "camp_42" } }, { "event": "link_clicked", "email": "jane@acme.com", "properties": { "url": "/book-demo" } } ] }'

node-fetch

await fetch('https://api.waypath.app/v1/events', { method: 'POST', headers: { 'X-API-Key': process.env.WAYPATH_API_KEY!, 'Content-Type': 'application/json', }, body: JSON.stringify({ event: 'page_viewed', email: 'jane@acme.com', properties: { url: '/pricing' }, }), })

python

import os, requests requests.post( 'https://api.waypath.app/v1/events', headers={'X-API-Key': os.environ['WAYPATH_API_KEY']}, json={ 'event': 'page_viewed', 'email': 'jane@acme.com', 'properties': {'url': '/pricing'}, }, timeout=5, )

MCP

await mcp.tools.ingest_event({ event: 'page_viewed', email: 'jane@acme.com', properties: { url: '/pricing' }, })

Response

Single

{ "eventId": "evt_91ab2c", "customerId": "cus_8af2", "resolved": "email" }

Batch

{ "accepted": 2, "results": [ { "eventId": "evt_91ab2c", "customerId": "cus_8af2", "resolved": "email" }, { "eventId": "evt_91ab2d", "customerId": "cus_8af2", "resolved": "email" } ] }

resolved reports which key matched. new means a new Customer node was created.

Identity resolution

Match priority is email (1.0), then phone (0.9), then externalId (0.8). Phone numbers are normalized to E.164. When nothing matches, a new Customer node is created using whichever keys you provided.

If you already have the canonical customer ID (e.g. from a previous /v1/context call), pass it directly and skip resolution.

Errors

StatusCodeCause
400invalid_payloadMissing event, no identity key, or malformed timestamp.
401unauthenticatedMissing or invalid X-API-Key.
403forbidden_scopeKey lacks events:write.
429rate_limitedPer-key cap. Honor Retry-After.

See also


SYNC · OK© 2026 WAYPATHBUILD · D-03SOC2 · IN PROGRESSWAYPATH.APP