# Track

Learn how to track an event using a standalone function.

This function tracks an [event](/reference/event/overview) on behalf of a user from any JavaScript environment, such as a server or a sandboxed script.

Unlike the [`track`](/reference/sdk/javascript/api/plug/track) method of the SDK instance, which completes the event with the details of the current session, this function sends the event as given. You provide everything needed to attribute the event to the user: the client ID, the time it occurred, and the tab and page where it happened.

## Signature

This function has the following signature:

```ts
function track<T extends EventType>(event: TrackedEvent<T>, options: TrackOptions): Promise<void>;
```

The result is a `Promise` that resolves once the event is sent, or rejects if the request fails.

## Example

Here is a minimal example of how to use this function:

```ts
import {track} from '@croct/plug/api';

await track(
  {
    type: 'goalCompleted',
    payload: {
      goalId: 'signup',
    },
    clientId: '00000000-0000-0000-0000-000000000001',
    timestamp: Date.now(),
    context: {
      tabId: '00000000-0000-0000-0000-000000000002',
      url: 'https://example.com/signup',
    },
  },
  {
    appId: '00000000-0000-0000-0000-000000000000',
  },
);
```

## Parameters

The following list describes the supported parameters:

- `event`: `object`

  The event to track.

  - `type`: `string`

    The type of the event, such as `goalCompleted` or `orderPlaced`.

    For a list of supported events, see the [Event reference](/reference/event/overview#event-types).

  - `payload`: [`EventPayload`](/reference/event/overview#event-types)

    The properties of the event.

    The function sends the payload as given, so it follows the **Processed properties** of the event type in the [Event reference](/reference/event/overview#event-types), rather than the input properties the SDK instance accepts. For example, a [`userSignedUp`](/reference/event/types/user-account/user-signed-up) event takes a `patch` instead of a `profile`, and cart events take the `lastUpdateTime` of the cart.

    > **User ID**
    >
    > Events that identify a user take a `userId`, which the function sends as the `externalUserId` processed property.

  - `clientId`: `string`

    The ID of the client (browser), in the form of a UUID.

    This must be a persistent identifier that uniquely identifies the user across sessions.

  - `timestamp`: `number`

    The time the event occurred, in milliseconds since the Unix epoch.

  - `context`: `EventContext`

    The context in which the event occurred.

    - `url`: `string`

      The URL of the page the client was on when the event was tracked.

    - `tabId`: `string` (optional)

      The UUID that uniquely identifies the tab across the session.

    - `timeZone`: `string` (optional)

      The user's time zone as an [IANA time zone ID](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones), such as `America/New_York`.

    - `metadata`: `object` (optional)

      Additional information that may be useful to include as part of the event metadata.

      A common use case is to record the version of the application that generated the event for later analysis when exporting the events.

      The following restrictions apply:

      - Up to 5 entries
      - Keys must be strings up to 20 characters long, starting with a letter or underscore and optionally followed by letters, digits, or underscores
      - Values must be strings up to 300 characters long

  - `userToken`: `string` (optional)

    A base64-encoded [JSON Web Token (JWT)](https://jwt.io) that identifies the user.

    If the **Require signed token** option is enabled in the [Application settings](https://app.croct.com/redirect/organizations/-organization-/workspaces/-workspace-/applications/-application-/settings), a signed JWT is required. In this case, the [token must be signed](/explanation/application/signed-tokens) using an [API key](/explanation/application/api-keys) with **Issue user tokens** permission, or the request will fail with an authorization error.

  - `clientIp`: `string` (optional)

    The IP address of the client (end-user).

    Passing `127.0.0.1` makes the API uses IP address of the incoming request, which is useful for local development.

    If not specified or unknown, [geographic location information](/reference/cql/context#location) will be limited or unavailable.

  - `clientAgent`: `string` (optional)

    The user agent of the client (browser).

    If not specified or unknown, [device technology information](/reference/cql/context#technology) will be limited or unavailable.

- `options`: `object`

  The tracking options.

  - `appId`: `string` (optional)

    The Application ID to use for client-side requests.

    This option is required for client-side applications. For server-side applications, use the [`apiKey`](#options-apikey-prop) option instead. Specifying both will result in an error.

  - `apiKey`: `string` (optional)

    The [API key](/explanation/application/api-keys) to use for server-side requests.

    This option is required for server-side applications. For client-side applications, use the [`appId`](#options-appid-prop) option instead. Specifying both will result in an error.

    > **Keep your API key safe**
    >
    > Never use your API key in client-side code, only in server-side environments.

  - `timeout`: `number` (optional)

    The maximum fetch time in milliseconds.

    Once reached, the SDK will abort the request and reject the promise with a timeout error.

  - `baseEndpointUrl`: `string` (optional)

    The base URL to use for the API calls.

    By default, the SDK uses the production endpoint. This option is helpful for testing purposes and allows you to point the SDK to another environment, such as a [mock server](../../testing/integration-testing#create-a-mock-server).

    These are the endpoints that use the base URL:

    | Path                  | Description                        |
    | --------------------- | ---------------------------------- |
    | `/client/web/track`   | Endpoint for client-side tracking. |
    | `/external/web/track` | Endpoint for server-side tracking. |

    See [Integration tests](../../testing/integration-testing) for more information on how to mock the API calls.

  - `extra`: `object` (optional)

    Additional options to pass to the [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) function.

  - `logger`: `object` (optional)

    A custom logger to handle log messages.

    By default, all logs are suppressed.

    - `debug`: `(message: string) => void`

      A function to log debug messages.

    - `info`: `(message: string) => void`

      A function to log informational messages.

    - `warn`: `(message: string) => void`

      A function to log warning messages.

    - `error`: `(message: string) => void`

      A function to log error messages.
