> ## 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.

# Adestra

> Integrate with Adestra 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/adestra.svg?fit=max&auto=format&n=pNhz39ducTVcQczh&q=85&s=8875e063e98b87073576a1682be1670a" alt="Adestra" style={{ maxWidth: '32px', maxHeight: '32px', display: 'block' }} width="32" height="32" data-path="images/integrations/logos/adestra.svg" />
    </div>

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

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

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

        <EnvironmentBadge environment="iOS" />

        <EnvironmentBadge environment="Android" />

        <EnvironmentBadge environment="CTV" />

        <EnvironmentBadge environment="API Direct" />
      </BadgeContainer>
    </BadgeRowCenter>

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

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

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

  <p style={{ margin: 0, fontSize: '0.875rem', color: '#6b7280', lineHeight: '1.5' }}>
    Adestra enables publishers to deliver personalized email campaigns and newsletters using audience segmentation and analytics.
  </p>
</Card>

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

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

## Overview

Adestra is an email service provider (ESP) that enables publishers to deliver personalized email campaigns, newsletters, and automated marketing communications. The Adestra integration is a Destination integration that allows you to activate Permutive cohorts directly into Adestra for use in email marketing campaigns.

This integration is a Destination:

* **Destination:** Permutive sends cohort memberships to Adestra, where they are represented as Contact lists. These lists can be used to trigger automated email campaigns or target users in marketing workflows.

Use cases include:

* Send Permutive cohorts to Adestra to trigger automated email campaigns when users enter a cohort
* Use behavioral and demographic cohorts for personalized email experiences
* Leverage Permutive's first-party data for email targeting and segmentation
* Create timely, relevant email campaigns based on real-time user actions and cohort membership

## Environment Compatibility

| Environment    | Supported    | Notes                                                    |
| -------------- | ------------ | -------------------------------------------------------- |
| **Web**        | <YesBadge /> | Requires Contact ID to be passed via identity management |
| **iOS**        | <YesBadge /> | Requires Contact ID to be passed via identity management |
| **Android**    | <YesBadge /> | Requires Contact ID to be passed via identity management |
| **CTV**        | <YesBadge /> | Requires Contact ID to be passed via identity management |
| **API Direct** | <YesBadge /> | Requires Contact ID to be passed via identity management |

## Prerequisites

* **Adestra Account** - You must have an active Adestra account with API access enabled.
* **Adestra API Key** - You will need your Adestra API key to configure the integration in the Permutive dashboard. This key should have permissions to manage contacts and lists.
* **Adestra Contact Lists** - You must create Contact lists in Adestra ahead of time. The integration will add and remove users from these pre-existing lists based on cohort membership, but it will not automatically create new lists.
* **Contact ID Configuration** - You must configure Permutive to collect Adestra Contact IDs (Adestra's internal user identifier) and pass them to Permutive via identity management. The identity type must match the "Alias tag" configured in the Permutive dashboard.
* **Identity Management Setup** - You need to implement identity management to associate Permutive users with Adestra Contact IDs. This is typically done using the Permutive Identify API or SDK identify methods.

## Setup

<Tabs>
  <Tab title="Primary Setup Steps">
    <Steps>
      <Step title="Create Contact Lists in Adestra">
        Before enabling the integration in Permutive, create the Contact lists in Adestra that you want to sync cohorts to. Make note of each list's List ID, as you'll need these when activating cohorts.

        You can find List IDs in the Adestra UI by navigating to your lists and viewing the list details.
      </Step>

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

        You will be asked to provide:

        * **Adestra API Key** - Your Adestra API authentication key
        * **Alias tag** - The identity type name you'll use to sync Contact IDs with Permutive (defaults to `adestra`)

        The "Alias tag" field specifies the name of the identity type that Permutive will use to match users with their Adestra Contact IDs. This must correspond to the identity type you use when calling Permutive's identity management APIs.
      </Step>

      <Step title="Configure Identity Management">
        Implement identity management to pass Adestra Contact IDs to Permutive. You can use the Permutive SDK or the Identify API.

        **Example using Web SDK:**

        ```javascript theme={"dark"}
        permutive.identify([
          {
            id: "12345", // Adestra Contact ID
            tag: "adestra", // Must match the Alias tag from Step 2
            priority: 0
          }
        ]);
        ```

        **Example using Identify API:**

        ```bash theme={"dark"}
        curl -XPOST https://api.permutive.com/v2.0/identify \
          -H 'X-API-Key: <PUBLIC_API_KEY>' \
          -H 'Content-Type: application/json' \
          -d '{
            "user_id": "<PERMUTIVE_ID>",
            "aliases": [
              {
                "id": "<ADESTRA_CONTACT_ID>",
                "tag": "adestra",
                "priority": 0
              }
            ]
          }'
        ```

        The Contact ID is Adestra's internal identifier for a user. You'll need to retrieve this from Adestra and pass it to Permutive whenever you identify a user.
      </Step>

      <Step title="Activate Cohorts to Adestra">
        In the Permutive Dashboard, navigate to one of your cohorts. You should see the Adestra activation option available.

        When enabling a cohort activation, you'll need to provide:

        * **Adestra List ID** - The ID of the Adestra Contact list you want to sync this cohort to

        Toggle the activation to *On*. Once enabled, Permutive will begin sending cohort membership updates to Adestra in near real-time (typically within 10 seconds of a user entering or exiting a cohort).
      </Step>

      <Step title="Verify Setup">
        After activating a cohort, verify that users are being added to the corresponding Contact list in Adestra:

        1. Check the Contact list in the Adestra UI to see if users are appearing
        2. Monitor the Permutive Events page to ensure identity events are being collected with the correct Adestra Contact IDs
        3. Verify that cohort membership changes are reflected in Adestra within the expected timeframe
      </Step>
    </Steps>
  </Tab>

  <Tab title="Web">
    For web properties, implement identity management using the Permutive Web SDK:

    ```javascript theme={"dark"}
    // Identify users with their Adestra Contact ID
    permutive.identify([
      {
        id: "12345", // Adestra Contact ID
        tag: "adestra", // Must match the Alias tag configured in dashboard
        priority: 0
      }
    ]);
    ```

    You should call `permutive.identify()` whenever you have the user's Adestra Contact ID available (typically after login or when the Contact ID is retrieved from your authentication system).
  </Tab>

  <Tab title="iOS">
    For iOS applications, implement identity management using the Permutive iOS SDK:

    ```swift theme={"dark"}
    // Identify users with their Adestra Contact ID
    Permutive.shared.identify(
      identifiers: [
        Identifier(
          id: "12345", // Adestra Contact ID
          tag: "adestra", // Must match the Alias tag configured in dashboard
          priority: 0
        )
      ]
    )
    ```

    You should call `Permutive.shared.identify()` whenever you have the user's Adestra Contact ID available.
  </Tab>

  <Tab title="Android">
    For Android applications, implement identity management using the Permutive Android SDK:

    ```kotlin theme={"dark"}
    // Identify users with their Adestra Contact ID
    Permutive.getInstance().identify(
      listOf(
        Identifier(
          id = "12345", // Adestra Contact ID
          tag = "adestra", // Must match the Alias tag configured in dashboard
          priority = 0
        )
      )
    )
    ```

    You should call `Permutive.getInstance().identify()` whenever you have the user's Adestra Contact ID available.
  </Tab>

  <Tab title="CTV">
    For CTV applications, implement identity management using the relevant Permutive CTV SDK to pass Adestra Contact IDs to Permutive.

    The specific implementation will depend on your CTV platform. Use the SDK's identify method to pass the user's Adestra Contact ID with the identity type configured in the Permutive dashboard (Alias tag).

    You should call the identify method whenever you have the user's Adestra Contact ID available.
  </Tab>

  <Tab title="API Direct">
    For server-side implementations or environments without an SDK, use Permutive's Identify API directly to pass Adestra Contact IDs to Permutive:

    ```bash theme={"dark"}
    curl -XPOST https://api.permutive.com/v2.0/identify \
      -H 'X-API-Key: <PUBLIC_API_KEY>' \
      -H 'Content-Type: application/json' \
      -d '{
        "user_id": "<PERMUTIVE_ID>",
        "aliases": [
          {
            "id": "<ADESTRA_CONTACT_ID>",
            "tag": "adestra",
            "priority": 0
          }
        ]
      }'
    ```

    The `tag` value must match the Alias tag configured in the Permutive dashboard. You can retrieve your Public API Key from the Permutive dashboard.
  </Tab>
</Tabs>

## Data Types

The Adestra integration activates cohort memberships to Adestra. Permutive sends cohort membership data to Adestra by adding and removing users from Contact lists.

<AccordionGroup>
  <Accordion title="Cohort Membership Data">
    Permutive sends user cohort memberships to Adestra by managing Contact list memberships via the Adestra API. The integration uses the Adestra Contact ID (configured via the Alias tag) to identify users.

    **API Operations:**

    When a user enters a cohort:

    * **POST** `/contacts/{contact_id}/lists/{list_id}` - Adds the user to the specified Contact list

    When a user exits a cohort:

    * **DELETE** `/contacts/{contact_id}/lists/{list_id}` - Removes the user from the specified Contact list

    <ResponseField name="contact_id" type="string">
      The Adestra Contact ID for the user. This is Adestra's internal identifier that you pass to Permutive via identity management.
    </ResponseField>

    <ResponseField name="list_id" type="string">
      The Adestra List ID of the Contact list to add/remove the user from. This is configured when you activate a cohort in the Permutive dashboard.
    </ResponseField>
  </Accordion>

  <Accordion title="Identity Data Requirements">
    For the integration to work, Permutive must be able to match users with their Adestra Contact IDs. This requires implementing identity management.

    <ResponseField name="id" type="string" required>
      The Adestra Contact ID for the user. This must be passed to Permutive using the `identify` method in the SDK or via the Identify API.
    </ResponseField>

    <ResponseField name="tag" type="string" required>
      The identity type name. This must exactly match the "Alias tag" configured in the Permutive dashboard (defaults to `adestra`).
    </ResponseField>

    <ResponseField name="priority" type="integer" required>
      The priority of this identifier. Set to `0` for most use cases.
    </ResponseField>
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Users not appearing in Adestra Contact lists">
    If users are not being added to Adestra Contact lists, verify the following:

    * Ensure you have implemented identity management correctly and are passing Adestra Contact IDs to Permutive
    * Verify that the "Alias tag" configured in the Permutive dashboard matches the `tag` value you're using in identity management calls
    * Check that the Adestra List ID is correct when activating cohorts
    * Confirm that the Adestra API key is valid and has the correct permissions to manage contacts and lists
    * Verify that the Contact lists exist in Adestra before activating cohorts (the integration will not create lists automatically)
    * Check the Permutive Events page to ensure identity events are being collected with Adestra Contact IDs
  </Accordion>

  <Accordion title="Invalid API key error">
    If you receive an invalid API key error when setting up the integration:

    * Verify that you have copied the full API key from Adestra without any extra spaces or characters
    * Confirm that the API key has not expired or been revoked in Adestra
    * Check that the API key has the necessary permissions to access the Adestra API (specifically, permissions to manage contacts and lists)
    * Contact your Adestra account administrator if you're unsure about API key permissions
  </Accordion>

  <Accordion title="Invalid List ID error">
    If you receive an error about an invalid List ID when activating a cohort:

    * Verify that you have entered the correct List ID from Adestra
    * Confirm that the Contact list still exists in Adestra and has not been deleted
    * Check that the API key has permission to access and manage the specified list
    * Ensure you're using the List ID (numeric identifier) and not the list name
  </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
    * Confirm that identity management is implemented correctly and Contact IDs are being passed to Permutive
    * Contact Permutive Support if delays persist beyond expected timeframes
  </Accordion>

  <Accordion title="Missing Contact IDs">
    If some users are not being synced to Adestra, it may be because their Contact IDs are not available in Permutive:

    * Verify that you're calling `identify` with the Adestra Contact ID for all authenticated users
    * Check that the Contact ID is available before the user enters a cohort (identity must be established before cohort membership)
    * Review your identity management implementation to ensure Contact IDs are being passed consistently across all platforms (Web, iOS, Android, CTV)
    * Consider implementing server-side identity resolution if Contact IDs are only available in your backend systems
  </Accordion>

  <Accordion title="Adestra API rate limits">
    Adestra has API usage limits (10 concurrent connections). If you're experiencing throttling or rate limit errors:

    * Contact Permutive Support to review your integration configuration
    * Consider reducing the number of cohorts synced to Adestra if you're activating a very large number of cohorts
    * Review Adestra's API documentation for current rate limits and usage restrictions
  </Accordion>
</AccordionGroup>

## Changelog

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