---
title: "Track an event"
method: POST
path: "/v1/events"
tags: ["Events"]
---

# Track an event

`POST /v1/events`

## Request

- Base URL: `https://api.volanea.com`
- URL: `https://api.volanea.com/v1/events`
- Auth: HTTP bearer

Ingest a product event for a contact (auto-created if unknown). Accepts the public key (`pk_…`), so it is safe to call from client-side code. Names with the `email.`/`contact.`/`segment.`/`workflow.` prefixes are reserved for system events. Events feed segments, workflow triggers, and webhooks.

## Request body

- object
  - `name` string, required: Your event name, e.g. `user.signup` (reserved prefixes excluded).
  - `email` string, email, required: The contact the event belongs to.
  - `data` object: Properties of the event — what happened. Point-in-time; never applied to the contact.
  - `contact` object: Who the contact is. Applied to the contact record, so a workflow triggered by this event can personalise its email with `{{firstName}}`. Omit a field to leave the existing value untouched; omit the whole object and the contact is created with only an address.
    - `firstName` string, nullable
    - `lastName` string, nullable
    - `locale` string, nullable
    - `data` object, nullable: Custom contact fields, merged into the contact's existing `data`.

## Response `200`

Event recorded, with what it set off.

- object
  - `eventId` string, required
  - `contactId` string, required: The contact the event was attributed to, created if it did not exist.
  - `triggered` TriggeredWorkflow[], required: The active workflows this event just handed to the automation engine. **An empty array means nothing matched** — that is the point of the field. Firing automations is what this endpoint is for, and before this existed the only way to find out whether anything happened was to list every workflow and compare trigger strings by hand; a typo in an event name looked exactly like a working integration.
    - `workflowId` string, required
    - `name` string, required
    - `trigger` string, required: The workflow's trigger string that this event matched.
    - `status` 'dispatched', required
  - `skipped` SkippedWorkflow[], required: Workflows whose trigger matched but that are `draft` or `paused`, so nothing ran. Check this before concluding your trigger string is wrong: an empty `triggered` with a non-empty `skipped` means the wiring is correct and the workflow simply is not live yet.
    - `workflowId` string, required
    - `name` string, required
    - `trigger` string, required
    - `reason` 'workflow_paused' | 'workflow_draft', required

## Other responses

- `401`: Missing or invalid API key.
- `422`: Request validation failed (code `validation_error`, 422).

---

[API](https://skmtc.dev/volanea/apis/volanea-api.md) · [All operations](https://skmtc.dev/volanea/apis/volanea-api/llms.txt) · [OpenAPI document](https://skmtc.dev/volanea/apis/volanea-api/revisions/9e187ae84fda?raw)
