> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vibefollow.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Track event

> POST /api/v1/events &mdash; emit a single user event.

Emit a single event for a user. The endpoint accepts both the 10 canonical lifecycle event names and any custom name you choose.

<Snippet file="auth-headers.mdx" />

## Request

```http theme={null}
POST /api/v1/events HTTP/1.1
Host: api.vibefollow.com
Authorization: Bearer sk_live_••••
Content-Type: application/json
Idempotency-Key: 7b6c7e9e-2c2d-4a8d-9d3a-4f3d2c1b0a99
```

### Body

```json theme={null}
{
  "external_user_id": "usr_42",
  "name": "user_signed_up",
  "properties": {
    "plan": "trial",
    "source": "organic"
  }
}
```

<ParamField body="external_user_id" type="string" required>
  External user ID. Should match the ID used in [Upsert user](/api-reference/users/upsert). If the user hasn't been identified yet, the event is buffered and attached when they're first seen.
</ParamField>

<ParamField body="name" type="string" required>
  Event name. One of the [canonical 10](/events/lifecycle-events) or any custom string (snake\_case recommended).
</ParamField>

<ParamField body="properties" type="object">
  JSON-serialisable property bag. Optional — defaults to `{}`.
</ParamField>

## Response

```http theme={null}
HTTP/1.1 202 Accepted
Content-Type: application/json
```

```json theme={null}
{ "data": { "accepted": true } }
```

<ResponseField name="data.accepted" type="boolean">
  Always `true` on success. The event is enqueued and processed asynchronously.
</ResponseField>

## Examples

<CodeGroup>
  ```ts Node (SDK) theme={null}
  import { VibeFollow } from '@vibefollow/sdk';

  const vf = new VibeFollow({ apiKey: process.env.VIBEFOLLOW_API_KEY! });

  // Typed helper for canonical events
  await vf.users.signedUp('usr_42', { plan: 'trial', source: 'organic' });

  // Generic track for custom events
  await vf.events.track('dashboard_created', 'usr_42', {
    source: 'wizard',
  });
  ```

  ```bash cURL theme={null}
  curl https://api.vibefollow.com/api/v1/events \
    -X POST \
    -H "Authorization: Bearer $VIBEFOLLOW_API_KEY" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: $(uuidgen)" \
    -d '{
      "external_user_id": "usr_42",
      "name": "user_signed_up",
      "properties": { "plan": "trial", "source": "organic" }
    }'
  ```
</CodeGroup>

## Common errors

<AccordionGroup>
  <Accordion title="401 auth_required" icon="key">
    Missing or malformed `Authorization` header.
  </Accordion>

  <Accordion title="403 forbidden" icon="shield-halved">
    API key valid but not authorised for this resource.
  </Accordion>

  <Accordion title="422 validation_failed" icon="circle-exclamation">
    Body failed schema validation; `errors[0].field` indicates the offending field.
  </Accordion>

  <Accordion title="429 rate_limited" icon="gauge-high">
    Wait `Retry-After` seconds.
  </Accordion>

  <Accordion title="5xx server_error" icon="server">
    Retry — the `Idempotency-Key` prevents duplicates.
  </Accordion>
</AccordionGroup>
