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

# Events API

> Send lifecycle and revenue events to FloKit.

## POST /v1/events

Send a single event from your server.

### Headers

| Header            | Value                                                                   |
| ----------------- | ----------------------------------------------------------------------- |
| `Authorization`   | `Bearer $FLOKIT_API_KEY`                                                |
| `Content-Type`    | `application/json`                                                      |
| `Idempotency-Key` | *(optional)* Unique key for safe retries — deduplicated within 24 hours |

### Request body

<ParamField body="event" type="string" required>
  Event name from the [event taxonomy](/send-data/event-taxonomy). E.g. `paywall_viewed`, `subscription_started`.
</ParamField>

<ParamField body="user_id" type="string">
  Your backend user identifier. Required if `anonymous_id` is not present.
</ParamField>

<ParamField body="anonymous_id" type="string">
  Pre-login device or session identifier. Recommended for events that occur before the user has an account. FloKit links `anonymous_id` to `user_id` when both appear in the same event.
</ParamField>

<ParamField body="timestamp" type="string" required>
  ISO 8601 datetime of when the event occurred. Use the actual event time, not the request time.
</ParamField>

<ParamField body="properties" type="object">
  Additional event properties as key/value pairs. See the [event taxonomy](/send-data/event-taxonomy) for recommended properties per event type.
</ParamField>

### Examples

<CodeGroup>
  ```bash paywall_viewed theme={null}
  curl -X POST https://api.flokit.ai/v1/events \
    -H "Authorization: Bearer $FLOKIT_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "event": "paywall_viewed",
      "user_id": "usr_abc123",
      "timestamp": "2024-03-15T14:22:00Z",
      "properties": {
        "paywall_id": "pw_annual_v3",
        "offer_id": "offer_intro_50pct",
        "plan_ids": ["plan_annual_usd", "plan_monthly_usd"],
        "context": "onboarding_step_3"
      }
    }'
  ```

  ```bash subscription_started theme={null}
  curl -X POST https://api.flokit.ai/v1/events \
    -H "Authorization: Bearer $FLOKIT_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "event": "subscription_started",
      "user_id": "usr_abc123",
      "timestamp": "2024-03-22T14:22:00Z",
      "properties": {
        "plan_id": "plan_annual_usd",
        "revenue": 49.99,
        "currency": "USD",
        "transaction_id": "txn_3OZ9kL2eZvKYlo2C0FL1nGdU",
        "trial_converted": true,
        "paywall_id": "pw_annual_v3",
        "store": "apple"
      }
    }'
  ```

  ```typescript Node.js / TypeScript theme={null}
  const response = await fetch('https://api.flokit.ai/v1/events', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.FLOKIT_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      event: 'subscription_started',
      user_id: 'usr_abc123',
      timestamp: new Date().toISOString(),
      properties: {
        plan_id: 'plan_annual_usd',
        revenue: 49.99,
        currency: 'USD',
        transaction_id: 'txn_3OZ9kL2eZvKYlo2C0FL1nGdU',
        trial_converted: true,
        paywall_id: 'pw_annual_v3',
        store: 'apple',
      },
    }),
  });

  const data = await response.json();
  // { status: 'ok', event_id: 'evt_01hx4j7k9m2n3p5q6r8s' }
  ```
</CodeGroup>

### Response

```json theme={null}
{
  "status": "ok",
  "event_id": "evt_01hx4j7k9m2n3p5q6r8s"
}
```

### Error responses

| Status                  | Description                                                      |
| ----------------------- | ---------------------------------------------------------------- |
| `400 Bad Request`       | Validation error — `error` and `message` fields in response body |
| `401 Unauthorized`      | Missing or invalid API key                                       |
| `429 Too Many Requests` | Rate limit exceeded — check `Retry-After` header                 |

***

## POST /v1/batch/events

Send up to 1,000 events in a single request.

### Request body

<ParamField body="events" type="array" required>
  Array of event objects. Each object accepts the same fields as the single-event endpoint: `event`, `user_id`, `anonymous_id`, `timestamp`, `properties`.
</ParamField>

### Example

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.flokit.ai/v1/batch/events \
    -H "Authorization: Bearer $FLOKIT_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "events": [
        {
          "event": "paywall_viewed",
          "user_id": "usr_abc123",
          "timestamp": "2024-03-15T14:20:00Z",
          "properties": {
            "paywall_id": "pw_annual_v3",
            "context": "onboarding_step_3"
          }
        },
        {
          "event": "trial_started",
          "user_id": "usr_abc123",
          "timestamp": "2024-03-15T14:22:00Z",
          "properties": {
            "plan_id": "plan_annual_usd",
            "trial_length_days": 7
          }
        }
      ]
    }'
  ```

  ```typescript Node.js / TypeScript theme={null}
  const response = await fetch('https://api.flokit.ai/v1/batch/events', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.FLOKIT_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      events: [
        {
          event: 'paywall_viewed',
          user_id: 'usr_abc123',
          timestamp: '2024-03-15T14:20:00Z',
          properties: { paywall_id: 'pw_annual_v3', context: 'onboarding_step_3' },
        },
        {
          event: 'trial_started',
          user_id: 'usr_abc123',
          timestamp: '2024-03-15T14:22:00Z',
          properties: { plan_id: 'plan_annual_usd', trial_length_days: 7 },
        },
      ],
    }),
  });

  const data = await response.json();
  ```
</CodeGroup>

### Response

```json theme={null}
{
  "status": "ok",
  "accepted": 2,
  "rejected": 0,
  "event_ids": [
    "evt_01hx4j7k9m2n3p5q6r8s",
    "evt_01hx4j7k9m2n3p5q6r9t"
  ],
  "errors": []
}
```

If some events fail validation, accepted events are still processed. Rejected events appear in `errors` with the array index and reason.

### Rate limits

| Limit               | Value             |
| ------------------- | ----------------- |
| Events per request  | 1,000             |
| Requests per minute | 100 per workspace |

Contact FloKit for higher throughput capacity.
