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

# Track events

> Record events for users in Retain

After identifying a user, track events as they happen in your product.

<Note>
  The user must have been identified first using the
  [Identify](/docs/guides/identify) endpoint.
</Note>

## Creating and configuring events

There are two ways to start tracking events in Retain.

### 1. Create the event first

You can create and configure an event in advance from the [**Events**](https://retain.so/dashboard/events) page.\
After that, simply use the same event name when calling `track`.

This approach is useful if you want to define the event configuration before sending any data.

### 2. Send the event directly with `track`

You can also start sending events immediately using `track`.

If the event does not exist yet, **Retain will automatically create it for you.**
This makes it easy to start tracking quickly and refine the configuration later.

After the event appears in the Events page, you only need to configure:

* **Importance**\
  Defines how critical this event is for your product. Retain uses this information when calculating customer health and identifying churn risk. High-importance events typically represent moments where users extract significant value from your product.

* **Expected frequency**\
  Indicates how often you expect this event to happen. This helps Retain understand normal usage patterns and detect when an account’s activity drops below expected levels.

## Tracking events

<CodeGroup>
  ```typescript Node.js icon=square-js theme={"theme":"vesper"}
  import { Retain } from '@retain-so/sdk';

  const retain = new Retain(process.env.RETAIN_WRITE_KEY);

  retain.track({
    userId: 'user_123',
    event: 'report_exported',
    properties: {
      format: 'csv',
      // Add anything else about the event here
    },
  });
  ```

  ```python Python icon=python theme={"theme":"vesper"}
  import os
  import requests

  requests.post(
      'https://api.retain.so/track',
      headers={
          'Content-Type': 'application/json',
          'Authorization': f'Basic {os.environ["RETAIN_WRITE_KEY"]}',
      },
      json={
          'userId': 'user_123',
          'event': 'report_exported',
          'properties': {
              'format': 'csv',
              # Add anything else about the event here
          },
      },
  )
  ```

  ```php PHP icon=php theme={"theme":"vesper"}
  $payload = json_encode([
      'userId' => 'user_123',
      'event' => 'report_exported',
      'properties' => [
          'format' => 'csv',
          // Add anything else about the event here
      ],
  ]);

  $ch = curl_init('https://api.retain.so/track');
  curl_setopt_array($ch, [
      CURLOPT_POST => true,
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_HTTPHEADER => [
          'Content-Type: application/json',
          'Authorization: Basic ' . getenv('RETAIN_WRITE_KEY'),
      ],
      CURLOPT_POSTFIELDS => $payload,
  ]);
  curl_exec($ch);
  curl_close($ch);
  ```

  ```ruby Ruby icon=gem theme={"theme":"vesper"}
  require 'net/http'
  require 'json'

  uri = URI('https://api.retain.so/track')
  req = Net::HTTP::Post.new(uri)
  req['Content-Type'] = 'application/json'
  req['Authorization'] = "Basic #{ENV.fetch('RETAIN_WRITE_KEY')}"
  req.body = {
    userId: 'user_123',
    event: 'report_exported',
    properties: {
      format: 'csv',
      # Add anything else about the event here
    },
  }.to_json

  Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
  ```

  ```java Java icon=java theme={"theme":"vesper"}
  import java.net.URI;
  import java.net.http.HttpClient;
  import java.net.http.HttpRequest;
  import java.net.http.HttpResponse;

  // Add anything else about the event inside "properties"
  String json = """
    {
      "userId": "user_123",
      "event": "report_exported",
      "properties": { "format": "csv" }
    }
    """;

  HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://api.retain.so/track"))
      .header("Content-Type", "application/json")
      .header("Authorization", "Basic " + System.getenv("RETAIN_WRITE_KEY"))
      .POST(HttpRequest.BodyPublishers.ofString(json))
      .build();

  HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
  ```

  ```bash cURL theme={"theme":"vesper"}
  # Add anything else about the event inside "properties"
  curl -X POST https://api.retain.so/track \
    -H "Content-Type: application/json" \
    -H "Authorization: Basic $RETAIN_WRITE_KEY" \
    -d '{
      "userId": "user_123",
      "event": "report_exported",
      "properties": { "format": "csv" }
    }'
  ```
</CodeGroup>

See [POST /track](/docs/api-reference/track/track-an-event) in the API Reference for more details.

That’s it. You’re now tracking events with Retain. Nice, now the fun part begins.
