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

# Sailthru

> Integrate with Sailthru for email service provider functionality

export const NoBadge = () => {
  return <span style={{
    display: 'inline-block',
    padding: '0.125rem 0.5rem',
    borderRadius: '0.25rem',
    fontSize: '0.625rem',
    background: '#F7D0E2',
    color: '#1A1A1A',
    fontWeight: '500'
  }}>
      No
    </span>;
};

export const YesBadge = () => {
  return <span style={{
    display: 'inline-block',
    padding: '0.125rem 0.5rem',
    borderRadius: '0.25rem',
    fontSize: '0.625rem',
    background: '#C7E8F9',
    color: '#1A1A1A',
    fontWeight: '500'
  }}>
      Yes
    </span>;
};

export const BadgeRowCenter = ({label, children}) => {
  return <div style={{
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: '0.5rem'
  }}>
      <span style={{
    fontSize: '0.625rem',
    color: '#6b7280',
    textTransform: 'uppercase',
    fontWeight: '500',
    letterSpacing: '0.05em'
  }}>
        {label}
      </span>
      {children}
    </div>;
};

export const BadgeRow = ({label, children}) => {
  return <div style={{
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'flex-start',
    marginBottom: '0.5rem'
  }}>
      <span style={{
    fontSize: '0.625rem',
    color: '#6b7280',
    textTransform: 'uppercase',
    fontWeight: '500',
    letterSpacing: '0.05em'
  }}>
        {label}
      </span>
      {children}
    </div>;
};

export const BadgeContainer = ({children}) => {
  return <div style={{
    display: 'flex',
    gap: '0.25rem',
    flexWrap: 'wrap',
    justifyContent: 'flex-end',
    minWidth: '0',
    flex: '1'
  }}>
      {children}
    </div>;
};

export const ProductRequiredBadge = ({product}) => {
  const getBadgeStyle = product => {
    switch (product) {
      case 'Core Platform':
        return {
          background: '#CB88FC',
          color: '#1A1A1A'
        };
        --purple;
      case 'Routing':
        return {
          background: '#CB88FC',
          color: '#1A1A1A'
        };
        --purple;
      case 'Contextual':
        return {
          background: '#CB88FC',
          color: '#1A1A1A'
        };
        --purple;
      default:
        return {
          background: '#A7B3D9',
          color: '#1A1A1A'
        };
        --haze;
    }
  };
  const style = getBadgeStyle(product);
  return <span style={{
    display: 'inline-block',
    padding: '0.125rem 0.375rem',
    borderRadius: '0.25rem',
    fontSize: '0.625rem',
    background: style.background,
    color: style.color,
    fontWeight: '500'
  }}>
      {product}
    </span>;
};

export const SdkRequiredBadge = ({required}) => {
  const getBadgeStyle = required => {
    switch (required) {
      case 'Yes':
        return {
          background: '#C7E8F9',
          color: '#1A1A1A'
        };
        --blue;
      case 'No':
        return {
          background: '#F7D0E2',
          color: '#1A1A1A'
        };
        --pink;
      default:
        return {
          background: '#A7B3D9',
          color: '#1A1A1A'
        };
        --haze;
    }
  };
  const style = getBadgeStyle(required);
  return <span style={{
    display: 'inline-block',
    padding: '0.125rem 0.375rem',
    borderRadius: '0.25rem',
    fontSize: '0.625rem',
    background: style.background,
    color: style.color,
    fontWeight: '500'
  }}>
      {required}
    </span>;
};

export const CapabilityBadge = ({capability}) => {
  const getBadgeStyle = capability => {
    switch (capability) {
      case 'Event Collection':
        return {
          background: '#EFDFC8',
          color: '#1A1A1A'
        };
        --clay;
      case 'Cohort Activation':
        return {
          background: '#EFDFC8',
          color: '#1A1A1A'
        };
        --clay;
      case 'Campaign Optimization':
        return {
          background: '#EFDFC8',
          color: '#1A1A1A'
        };
        --clay;
      case 'Identity Signal':
        return {
          background: '#EFDFC8',
          color: '#1A1A1A'
        };
        --clay;
      case 'Contextual Signal':
        return {
          background: '#EFDFC8',
          color: '#1A1A1A'
        };
        --clay;
      case 'Connectivity':
        return {
          background: '#EFDFC8',
          color: '#1A1A1A'
        };
        --clay;
      case 'Routing':
        return {
          background: '#EFDFC8',
          color: '#1A1A1A'
        };
        --clay;
      case 'Data Collaboration':
        return {
          background: '#EFDFC8',
          color: '#1A1A1A'
        };
        --clay;
      default:
        return {
          background: '#A7B3D9',
          color: '#1A1A1A'
        };
        --haze;
    }
  };
  const style = getBadgeStyle(capability);
  return <span style={{
    display: 'inline-block',
    padding: '0.125rem 0.375rem',
    borderRadius: '0.25rem',
    fontSize: '0.625rem',
    background: style.background,
    color: style.color,
    fontWeight: '500',
    whiteSpace: 'nowrap'
  }}>
      {capability}
    </span>;
};

export const EnvironmentBadge = ({environment}) => {
  const getBadgeStyle = environment => {
    switch (environment) {
      case 'Web':
        return {
          background: '#F9C1A8',
          color: '#1A1A1A'
        };
        --peach;
      case 'iOS':
        return {
          background: '#F9C1A8',
          color: '#1A1A1A'
        };
        --peach;
      case 'Android':
        return {
          background: '#F9C1A8',
          color: '#1A1A1A'
        };
        --peach;
      case 'CTV':
        return {
          background: '#F9C1A8',
          color: '#1A1A1A'
        };
        --peach;
      case 'API Direct':
        return {
          background: '#F9C1A8',
          color: '#1A1A1A'
        };
        --peach;
      default:
        return {
          background: '#A7B3D9',
          color: '#1A1A1A'
        };
        --haze;
    }
  };
  const style = getBadgeStyle(environment);
  return <span style={{
    display: 'inline-block',
    padding: '0.125rem 0.375rem',
    borderRadius: '0.25rem',
    fontSize: '0.625rem',
    background: style.background,
    color: style.color,
    fontWeight: '500',
    whiteSpace: 'nowrap'
  }}>
      {environment}
    </span>;
};

export const DirectionBadge = ({direction}) => {
  const getBadgeStyle = direction => {
    switch (direction) {
      case 'Bidirectional':
        return {
          background: '#FA8784',
          color: '#1A1A1A'
        };
        --tomato;
      case 'Destination':
        return {
          background: '#FA8784',
          color: '#1A1A1A'
        };
        --tomato;
      case 'Source':
        return {
          background: '#FA8784',
          color: '#1A1A1A'
        };
        --tomato;
      default:
        return {
          background: '#A7B3D9',
          color: '#1A1A1A'
        };
        --haze;
    }
  };
  const style = getBadgeStyle(direction);
  return <span style={{
    display: 'inline-block',
    padding: '0.125rem 0.375rem',
    borderRadius: '0.25rem',
    fontSize: '0.625rem',
    background: style.background,
    color: style.color,
    fontWeight: '500'
  }}>
      {direction}
    </span>;
};

<Card title="">
  <div style={{ display: 'flex', alignItems: 'center', marginBottom: '1rem' }}>
    <div style={{ width: '32px', height: '32px', marginRight: '0.75rem', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
      <img src="https://mintcdn.com/permutive/pNhz39ducTVcQczh/images/integrations/logos/sailthru.svg?fit=max&auto=format&n=pNhz39ducTVcQczh&q=85&s=7e224dc185ead35b1a093d5d6dcae94c" alt="Sailthru" style={{ maxWidth: '32px', maxHeight: '32px', display: 'block' }} width="32" height="32" data-path="images/integrations/logos/sailthru.svg" />
    </div>

    <h3 style={{ margin: 0, fontSize: '1.125rem', fontWeight: '600' }}>Sailthru</h3>
  </div>

  <div style={{ marginBottom: '1rem' }}>
    <BadgeRowCenter label="Direction">
      <DirectionBadge direction="Destination" />
    </BadgeRowCenter>

    <BadgeRowCenter label="Environment">
      <BadgeContainer>
        <EnvironmentBadge environment="Web" />
      </BadgeContainer>
    </BadgeRowCenter>

    <BadgeRowCenter label="Capability">
      <BadgeContainer>
        <CapabilityBadge capability="Cohort Activation" />
      </BadgeContainer>
    </BadgeRowCenter>

    <BadgeRowCenter label="SDK Required">
      <SdkRequiredBadge required="Yes" />
    </BadgeRowCenter>

    <BadgeRowCenter label="Product(s) Required">
      <ProductRequiredBadge product="Core Platform" />
    </BadgeRowCenter>
  </div>

  <p style={{ margin: 0, fontSize: '0.875rem', color: '#6b7280', lineHeight: '1.5' }}>
    Sailthru helps publishers personalize emails and on-site experiences using behavioral and demographic data.
  </p>
</Card>

<CardGroup cols={2}>
  <Card title="Setup" href="#setup" icon="gear" />

  <Card title="Troubleshooting" href="#troubleshooting" icon="wrench" />
</CardGroup>

## Overview

Sailthru is an email service provider (ESP) and marketing automation platform that enables publishers to personalize customer experiences across email and other channels. The Sailthru integration is a Destination integration that allows you to activate Permutive cohorts directly into Sailthru for use in email marketing campaigns and other marketing inventory.

This integration is a Destination:

* **Destination:** Permutive is able to send cohort memberships to Sailthru for targeting in email campaigns.

Use cases include:

* Send Permutive cohorts to Sailthru to target users in email marketing campaigns
* Use behavioral and demographic cohorts for personalized email experiences
* Leverage Permutive's first-party data for email targeting and segmentation

## Environment Compatibility

| Environment    | Supported    | Notes                                                                |
| -------------- | ------------ | -------------------------------------------------------------------- |
| **Web**        | <YesBadge /> | Sailthru cookie ID (`sailthru_hid`) is collected from web properties |
| **iOS**        | <NoBadge />  | --                                                                   |
| **Android**    | <NoBadge />  | --                                                                   |
| **CTV**        | <NoBadge />  | --                                                                   |
| **API Direct** | <NoBadge />  | --                                                                   |

## Prerequisites

* **Sailthru Account** - You must have Sailthru installed and configured on your website prior to enabling the Permutive integration.
* **Sailthru Cookie** - The Sailthru cookie (`sailthru_hid`) must be present on your web properties for Permutive to collect the Sailthru user ID.
* **Sailthru API Credentials** - You will need your Sailthru API credentials to configure the integration in the Permutive dashboard.
* **IP Whitelist** - Depending on the type of API key, you may need to whitelist Permutive IPs within Sailthru for the integration to work. Contact Permutive to get the IP list.

## Setup

<Tabs>
  <Tab title="Primary Setup Steps">
    <Steps>
      <Step title="Enable in Permutive Dashboard">
        In the Permutive dashboard, navigate to your workspace's integrations page. Click *Add Integration* and select *Sailthru*.

        You will be asked to enter your Sailthru API credentials at this stage.
      </Step>

      <Step title="Whitelist Permutive IPs in Sailthru (if required)">
        Depending on the type of API key, you may need to whitelist Permutive IPs within Sailthru for the integration to work. Contact Permutive to get the IP list.

        To whitelist the IPs in Sailthru, navigate to **Settings → Setup → API & Postbacks** in the Sailthru UI.
      </Step>

      <Step title="Verify Setup">
        In the Permutive Dashboard, navigate to one of your cohorts. Check that the Sailthru activation sync is visible. You can try toggling this to *On*.

        Once enabled, Permutive will begin sending cohort membership updates to Sailthru in near real-time (typically within 10 seconds of a user entering or exiting a cohort).
      </Step>
    </Steps>
  </Tab>

  <Tab title="Web">
    No additional web-specific configuration is required. The Permutive Web SDK will automatically collect the Sailthru cookie ID (`sailthru_hid`) from your web properties once the integration is enabled.
  </Tab>
</Tabs>

## Data Types

The Sailthru integration activates cohort memberships to Sailthru. Permutive sends cohort membership data to Sailthru in the following format:

<AccordionGroup>
  <Accordion title="Cohort Membership Data">
    Permutive sends user cohort memberships to Sailthru by updating user profiles via the Sailthru API. The integration uses the Sailthru cookie ID (`sailthru_hid`) to identify users.

    <ResponseField name="id" type="string">
      The Sailthru user ID (from the `sailthru_hid` cookie).
    </ResponseField>

    <ResponseField name="vars.permutive_segments" type="array">
      An array of Permutive cohort IDs that the user is a member of. This field is updated on the user's Sailthru profile and can be used for targeting in Sailthru campaigns.
    </ResponseField>
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Cohort memberships not appearing in Sailthru">
    If cohort memberships are not appearing in Sailthru user profiles, verify the following:

    * Ensure the Sailthru cookie (`sailthru_hid`) is present on your web properties
    * Verify that Permutive's fixed IP address has been added to your Sailthru allowlist
    * Check that the cohort activation toggle is enabled in the Permutive dashboard
    * Confirm that your Sailthru API credentials are correctly configured in the Permutive dashboard
  </Accordion>

  <Accordion title="Delay in cohort updates">
    Cohort membership updates are processed in near real-time, typically within 10 seconds of a user entering or exiting a cohort. If you're experiencing significant delays:

    * Check the Permutive Events page to ensure events are being collected properly
    * Verify that the integration is enabled and properly configured
    * Contact Permutive Support if delays persist beyond expected timeframes
  </Accordion>
</AccordionGroup>

## Changelog

<Info>
  For detailed changelog information, visit our
  [Changelog](https://changelog.permutive.com/).
</Info>
