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

# Segment

> Learn how to set up Segment as a data source for Novu using Destination Functions. Send user events from Segment to trigger notifications in Novu.

This guide demonstrates how to use Segment's Destination Functions to send user events and traits to Novu. You'll learn how to:

* Create a custom Segment destination for Novu
* Map Segment identify calls to Novu subscribers
* Trigger notification workflows from Segment track events
* Handle errors and retry logic for reliable delivery

By the end, you'll have a working integration that creates subscribers and triggers notification workflows in Novu based on Segment events.

<Info>
  Before you start, ensure you have:

  * A **Segment account** with access to **Functions** (check your workspace permissions)
  * A **Novu account** with an **API key** (find this in your Novu dashboard under **Settings** > **API Keys**)
</Info>

<Steps>
  <Step>
    ## Create a Destination Function in Segment

    1. Log in to your Segment account
    2. Navigate to **Connections** > **Functions** in the left sidebar
    3. Click **New Function** and select **Destination**
    4. Name your function (for example, Novu Destination) and click **Create Function**
  </Step>

  <Step>
    ## Configure the Destination Function

    The Destination Function will handle two key Segment event types:

    * **identify**: Creates or updates a subscriber in Novu
    * **track**: Triggers a notification workflow in Novu

    Paste the following complete code into the Segment Function editor:

    ```jsx theme={null}
    // US: https://api.novu.co | EU: https://eu.api.novu.co
    const NOVU_API_BASE_URL = 'https://api.novu.co';

    /**
     * Posts to the Novu API. Retries on 5xx and 429. Fails fast on other 4xx responses.
     */
    async function novuRequest(path, apiKey, body) {
      if (!apiKey) throw new Error('Novu API key is missing in settings');

      let response;
      try {
        response = await fetch(`${NOVU_API_BASE_URL}${path}`, {
          method: 'POST',
          headers: {
            'Authorization': `ApiKey ${apiKey}`,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify(body)
        });
      } catch (error) {
        throw new RetryError(error.message);
      }

      const responseBody = await response.json().catch(() => ({}));
      if (!response.ok) {
        if (response.status >= 500 || response.status === 429) {
          throw new RetryError(`Server error: ${response.status}`);
        }
        throw new Error(`API error: ${response.status} - ${responseBody.message || 'Unknown error'}`);
      }
    }

    /**
     * Handles identify events: Creates or updates a subscriber in Novu
     * @param {SegmentIdentifyEvent} event - The Segment identify event
     * @param {FunctionSettings} settings - Function settings including API key
     */
    async function onIdentify(event, settings) {
      if (!event.userId) throw new Error('userId is required in identify event');

      await novuRequest('/v2/subscribers', settings.apiKey, {
        subscriberId: event.userId,
        firstName: event.traits?.firstName,
        lastName: event.traits?.lastName,
        email: event.traits?.email,
        phone: event.traits?.phone,
        avatar: event.traits?.avatar,
      });
    }

    // Mapping of Segment track events to Novu workflows
    const EVENT_TO_WORKFLOW_MAPPINGS = {
      'User Registered': 'welcome',
      // Add more mappings: 'Event Name': 'novu-workflow-name'
    };

    /**
     * Handles track events: Triggers a notification workflow in Novu
     * @param {SegmentTrackEvent} event - The Segment track event
     * @param {FunctionSettings} settings - Function settings including API key
     */
    async function onTrack(event, settings) {
      if (!event.userId) throw new Error('userId is required in track event');

      const workflow = EVENT_TO_WORKFLOW_MAPPINGS[event.event];
      if (!workflow) throw new Error(`No workflow mapped for event: ${event.event}`);

      await novuRequest('/v1/events/trigger', settings.apiKey, {
        name: workflow,
        to: { subscriberId: event.userId },
        payload: event.properties || {}
      });
    }
    ```

    <AccordionGroup>
      <Accordion title="Code Explanation">
        * **`novuRequest`**: Shared helper for Novu API calls. Retries on server errors (`5xx`) and rate limits (`429`). Fails fast on other client errors so bad payloads are not retried forever.
        * **`onIdentify`**:
          * Maps Segment traits (`firstName`, `lastName`, `email`, `phone`, `avatar`) to Novu subscriber fields
          * Uses `POST /v2/subscribers`, which creates a subscriber or updates the existing one when `subscriberId` matches
        * **`onTrack`**:
          * Maps Segment `track` events to Novu workflows using `EVENT_TO_WORKFLOW_MAPPINGS`
          * Sends the event properties as the payload via `POST /v1/events/trigger`
          * Novu can [create a subscriber just in time](/platform/concepts/subscribers#just-in-time) from `to.subscriberId`, so a prior `identify` is useful for enrichment but not required for the trigger to succeed
      </Accordion>
    </AccordionGroup>

    <Tip>
      Update `EVENT_TO_WORKFLOW_MAPPINGS` with your Segment event names and corresponding Novu workflow identifiers. For EU accounts, set `NOVU_API_BASE_URL` to `https://eu.api.novu.co`.
    </Tip>
  </Step>

  <Step>
    ## Deploy the Function

    1. Click **Save** in the Function editor
    2. Enable the function by toggling it to **Active**
  </Step>

  <Step>
    ## Connect the Function to a Source

    1. Go to **Connections** > Select your **Source** (for example, website or app)
    2. In the **Destinations** tab, click **Add Destination**
    3. Choose your **Novu Destination Function** from the list
    4. Click **Connect**. When prompted, enter your **Novu API key** in the `apiKey` field
    5. Save the configuration
  </Step>

  <Step>
    ## Testing the Integration

    Verify everything works:

    <AccordionGroup>
      <Accordion title="1. Send an identify event">
        Example:

        ```json theme={null}
        {
          "type": "identify",
          "userId": "97980cfea0067",
          "traits": {
            "firstName": "Peter",
            "lastName": "Gibbons",
            "email": "peter@example.com",
            "phone": "+14158675309"
          }
        }
        ```

        Check Novu's **Subscribers** list to confirm the subscriber appears with the mapped fields.
      </Accordion>

      <Accordion title="2. Send a track event">
        Example:

        ```json theme={null}
        {
          "type": "track",
          "event": "User Registered",
          "userId": "97980cfea0067",
          "properties": {
            "plan": "Pro Annual",
            "accountType": "Facebook"
          }
        }
        ```

        Verify the `welcome` workflow triggers in Novu's **Activity Feed**.
      </Accordion>
    </AccordionGroup>

    Use Segment's **Debugger** to monitor function calls and catch any errors.
  </Step>
</Steps>

<AccordionGroup>
  <Accordion title="Troubleshooting">
    * **401 Unauthorized**: Double-check your Novu API key in the function settings. The key must match your Novu environment (Development or Production) and region (US vs EU).
    * **Subscriber not created**: Ensure `userId` is included in the `identify` event. Traits must use the field names your function maps (`firstName`, `lastName`, `email`, and so on).
    * **Workflow not triggering**: Confirm the event name matches a key in `EVENT_TO_WORKFLOW_MAPPINGS`, the workflow exists and is active in Novu, and the track event includes `userId`.
    * **429 Too Many Requests**: Segment will retry when the function throws `RetryError`. If you hit limits often, reduce event volume or upgrade your Novu plan. See [Rate limiting](/api-reference/rate-limiting).
  </Accordion>

  <Accordion title="Additional Notes">
    * **Subscriber updates**: `POST /v2/subscribers` updates an existing subscriber when `subscriberId` matches, so each `identify` keeps the profile current.
    * **Expanding functionality**: Add more event types (for example, `group` or `page`) by defining additional handlers such as `onGroup` in the function.
  </Accordion>
</AccordionGroup>

With this setup, Segment `identify` and `track` events map into Novu subscribers and workflow triggers.

## Related guides

* [Hightouch HTTP Request destination](/guides/analytics/hightouch)
* [Rate limiting](/api-reference/rate-limiting)
