# Optimizing your email outreach
Source: https://docs.unifygtm.com/best-practices/deliverability

Best practices for writing email copy and optimizing deliverability.

## Sequence copy

1. **Keep an individual sequence to 4 email touches max -** Within a four-touch sequence, we recommend alternating the structure between 2 new threads and 2 follow-up replies. The copy of these follow-up replies can be short and limited to 1-2 sentences. Example: "Any thoughts on my previous note?"

2. **Alternate case studies and value props between new threads -** You should vary the copy and angle you're approaching to pitch your product in email steps 1 and 3. For example, you can highlight different customer case studies or statistics across both emails.

3. **Shorten subject line and use personalization -** Keep subject titles concise and add custom variables to increase variability. This approach will also help improve deliverability. Example: "Unify x (Your Company Name)"

4. **Include statistics and case studies for social proof -** Incorporating numbers-driven, concise impact statements can catch your prospect's attention. We recommend adding concise blurbs from customer case studies into your sequence copy.

5. **Add personalization with snippets -** You can use Unify's smart snippets to personalize copy based on relevant value prop, job title, work description, industry, and more. This will make your sequence copy more compelling with targeted pain points, use cases, or case studies. More variance in email copy will also help with deliverability.

6. **Keep it concise, focus on a single product or pain point -** Don't try to fit too many points into your email - you want to be decisive and mention the most relevant product or pain point to that individual to capture their attention! Keep the language simple and avoid business jargon. We recommend keeping each email between 50-200 words.

7. **End with a compelling call to action (CTA) -** Conclude each email with a clear, specific, and actionable request. This could include scheduling a call, booking a demo, or asking the prospect to reply with a specific piece of information relevant to their needs.

## Deliverability

1. **Limit the links -** Try not to overload your emails with multiple or duplicate links. Too many links can set off spam alarms - we recommend limiting the email touch to include 1-2 links maximum.

2. **Check link safety -** Ensure the links you include are secure and no warnings are displayed by the browser when visiting them.

3. **Mix up subject lines -** Don't stick with the same old subject lines, use template variables to keep them dynamic and interesting.

4. **No all caps -** Using all caps anywhere in your email can make it look like spam, so stick to normal capitalization.

5. **Easy on the exclamation -** Too many exclamation points can trigger spam filters, especially in the subject line. Use them sparingly!

6. **Send from multiple email addresses -** Sending emails from multiple mailboxes improves deliverability by distributing volume across different IP addresses and domains. This approach reduces the risk of being flagged as spam and increases overall sending capacity.

7. **Proofread for Typos**: Typos can make your email look unprofessional, especially when you're emailing multiple contacts at a company. Make sure to proofread and catch any errors.


# Booking meetings with Plays
Source: https://docs.unifygtm.com/best-practices/plays

Best practices for using Unify Plays to book meetings from intent signals.

## Best practices

Unify is a sales engagement platform designed to help you generate pipeline. To ensure that you see the best results, we recommend a few general principles:

* **Act Quickly:** Act on intent signals within 24-48 hours to catch prospects before they make their decision. Intent gets stale over time.
* **Engage with Every Lead:** Once you define your ICP in Unify, avoid selective outreach. Avoid introducing bias into how you prospect.
* **Multiple Touchpoints:** If you’ve found that a channel works best for your team, use Unify to lean into that. Unify excels at email - if that’s your preferred channel, great. If not, use email in combination with social or phone outreach. See section 4 below to see our recommendations for email and social outreach.

## Act on intent

There are two primary ways to act on intent data in Unify:

### Automatic Plays

* **When to use:** Both for low and high volume signals. Plays automate prospecting, qualifying, sequencing, and syncing leads to your CRM.
* **Benefits:** Reduce friction and improve intent to meeting booked conversion by immediately taking action on leads.
* Learn more about how to build Plays in [How to create a Play](/tutorials/how-to-create-a-play).

### Manual alerts

* **When to use:** Ideal for low volume, high value signals. It's important to ensure the sales team is accountable for acting on alerts to ensure hot leads don’t slip through the cracks.
* **Benefits:** Immediate and contextual information delivered to where your team is working.
* Most reps use Slack alerts to trigger manual workflows. Learn how to set these up in our [Slack integration guide](/reference/integrations/slack#slack-integration-guide)

## Intent-based Plays

Intent signals are indicators that there’s an opportunity to sell your product or book an intro meeting. Our customers have seen success with these intent-based Plays:

1. **Pricing Page Visits:** Checking out pricing pages indicates that prospects are considering a purchase decision.
2. **[Repeat Buyers](https://www.unifygtm.com/plays/champion-tracking---outbound-to-past-customers-who-have-moved-jobs):** When someone you’ve sold to before is back on the website demonstrating high intent. This works well for businesses that have more transactional sales.
3. **[Inbound Form Submissions](https://www.unifygtm.com/plays/outbound-to-website-form-submitters):** A form submission is one of the strongest signs of intent. Convert those leads immediately by automating outreach as soon as they submit.
4. **[New Hires](https://www.unifygtm.com/plays/outbound-to-people-who-have-started-jobs-at-a-new-company):** People are more likely to purchase new tools in their first few months on a job. Targeting ICP fits that have just changed jobs can convert better.
5. **[Support Docs](https://www.unifygtm.com/plays/outbound-to-contacts-viewing-your-technical-docs):** Interest in support docs (e.g., integration details), suggests prospects are trying to understand how your product works and if it would work for them.
6. **[Product Tour Visits](https://www.unifygtm.com/plays/outbound-to-people-who-view-your-product-demo):** Interest in demo videos or product tours indicates a desire to understand specific product offerings in more granularity.
7. **[Retarget Paid Traffic](https://www.unifygtm.com/plays/retarget-paid-traffic):** Get more out of your spend on paid traffic by retargeting people based on UTM filters.
8. **[Closed-Lost Opportunities](https://www.unifygtm.com/plays/retarget-closed-lost-opportunities-when-they-revisit-website):** A revisit to your site by a closed-lost opportunities signals the prospect might be interested in re-engaging.

## Nailing email or social outreach

Nailing email and social messages is key to booking the most possible meetings from Unify. A few guiding principles:

1. **Use Soft Messaging:** Use your judgement, but we typically recommend against direct mentions of website activity. Instead, tailor messages to address the pain points related to the product or service they showed interest in.
2. **Keep It Short:** Many senior leaders at your target accounts read emails on their phones, concise messages under 100 words are more likely to be read and understood. Remember that people are skimming emails.
3. **Persona-Specific Messaging:** Address specific pain points and perspectives of the different personas you sell to (e.g., sales and marketing for us). Avoid generic messages that try to cater to multiple personas, as they may resonate with none.
4. **Focus on One Product:** If you sell multiple products, pitch one per email. This approach minimizes the chances that your prospect gets confused about what you solve.
5. **Highlight Relevant Pain Points:** Rather than pitching your product, focus on speaking to a specific challenge or pain point that your prospect has. Educate the prospect on your product once you’re on the phone with them.


# Writing AI prompts
Source: https://docs.unifygtm.com/best-practices/prompting

Best practices for writing prompts for AI in Unify.

## General tips

Unify has multiple AI features that can be used to improve qualification and outreach outcomes. To set yourself up for success, we recommend a few general principles for prompting when using these features:

* **Clear Instructions:** Be explicit about what you want the AI to do. Providing a clear set of instructions will help the AI understand what you want to accomplish and what steps to follow to complete the tasks.
* **Length ≠ Quality:** Writing an overly detailed or essay length prompt does not mean that the AI will provide a better response. Excessive information can be detrimental unless it is well-structured and explained, as it can lead to confusion and misinterpretation of the prompt.
* **Provide Context:** Assume AI does not know your industry, company, or product as well as you do. Provide relevant context as you reference information about your company or your goals. For example, if you are referencing a niche keyword, provide a brief explanation of what it means, how it relates to your business, and the task you are giving the AI.

## AI agents

There are two primary ways that you can provide information and instruction to Unify's AI Agents.

### Questions

* **Questions:** Questions are the minimum required input to run an AI Agent. You can ask any question about a Company or Person and select the type of response you want the Agent to provide (e.g., True/False, Text, Multi-Select, Number).
* **What information to provide:** In the question, only include the research question you want the Agent to answer. Avoid adding clarifying information or instructions to keep it focused.

### Guidance

* **When to use:** Guidance is an optional field for AI Agents that enables you to provide additional context or instructions to the AI Agent. When asking more complex questions, when you have a set of instructions or requirements that you want the AI Agent to follow, or when you want to provide clarification on the research question, guidance is the best way to provide that information.
* **How To Structure Guidance:** Similar to Prompts, Guidance should be clear, concise, and specific. Use the guidance to provide specific directions about each question that you are asking, and additional context if there is a specific way that you want the AI Agent to conduct its research. For example, if you want the AI Agent to only use information from a specific source, you can include that information in the guidance. Or, if you want to provide more direction on when the AI Agent should select a specific answer for a multi select response type, that information should also be included in the guidance.

## Smart snippets

Smart snippets are a powerful way to personalize messaging to your prospects.

* **Provide Context (Again!):** The model can only act on what you provide. This means you should specify the information you want to create copy from, select template variables to reference, or add Agent template variables to the smart snippet. Additionally, provide context around the template variable to create a coherent prompt. Think of template variables as placeholders for information and write sentences or blurbs surrounding those variables.
* **Adding References:** A common mistake is referencing information that you haven't provided to the model, which can lead to incorrect responses. To prevent this, ensure that if you're referencing data provided through a template variable or Agent output, you include that template variable in the Snippet.

### Agent outputs in Smart snippets

Using Agents to conduct research and then incorporating that research into a smart snippet is a great way to hyper-personalize your messaging. To make effective use of this feature:

* **Separation of Concerns:** Use the Agent to conduct research only, and use the Snippet to generate the copy. Each feature is optimized for its respective task.
* **Structure the Snippet prompt around the Agent variables:** When writing a smart snippet prompt with Agent output template variables, provide context and labels about what each Agent output contains so the Snippet can handle it accordingly. For example, if you have an Agent Question that asks for a True/False or Number answer, write your prompt using the Agent template variable as a placeholder in your sentences to provide context to the Snippet.
  * For example, if your Agent question was "What is the most recent product launch from this company?" then your Snippet prompt should be something like: "Research indicates that this company just launched `{{Agent Question}}`. Write a sentence to congratulate them on the launch."

## AI research

AI Research is a powerful way to automate and customize research that you want to conduct about any company that you are engaging. AI Research is powered by Unify's Observation Model, which is the system that Unify uses to run completely customized research for your company on your prospects.

### Prompting AI research

Writing prompts for AI Research is slightly different from writing prompts for AI Agents. AI Research is designed to read as much relevant information as possible before generating a report for you. We recommend following the style of the Observation prompts we generated for you as a starting point. To prompt for AI Research, follow these guidelines:

* **Pick a General Signal:** The goal with an Observation prompt is to describe a specific piece of information to the system that you'd like to monitor for any given company. For example, if you know that a company using a specific technology has a high likelihood of becoming your customer, an Observation for that could be: "Company uses an outbound sequencer (Outreach, Salesloft, Apollo, etc.) and a data/intent source (ZoomInfo, 6sense, Bombora, Clearbit, Demandbase, G2 Intent)."

* **Test and Iterate:** Once you've written your prompt, take advantage of the settings page to generate examples and see what the resulting reports look like.


# Custom events
Source: https://docs.unifygtm.com/developers/api/analytics/custom

POST /track
Send a "track" event.



# Identify events
Source: https://docs.unifygtm.com/developers/api/analytics/identify

POST /identify
Send an "identify" event.



# Unify Analytics API
Source: https://docs.unifygtm.com/developers/api/analytics/overview

Send website and product analytics data into the Unify platform.

## Overview

The Analytics API allows you to send both client-side and server-side events
into Unify. There are three types of events you can send:

* [Page events](/developers/api/analytics/page) capture page visits on your website or web application
* [Custom events](/developers/api/analytics/custom) capture actions or other custom activities that you define
* [Identify events](/developers/api/analytics/identify) capture visitor identity information (e.g., their email address)

These event types form the building blocks to track visitor behavior and actions
on your marketing website, web application, or other custom software.

## Usage

### Request format

The base URL of all API requests to the Analytics API is:

```shell theme={null}
https://api.unifyintent.com/analytics/v1
```

Note that the base URL uses a different domain than other Unify APIs.

### Authentication

<Danger>
  When sending requests to the Analytics API from client devices, you should use
  your **write key** rather than an API key. Write keys are safe to expose
  publicly whereas API keys are not.

  To prevent exposure of sensitive API keys, if you send a request to
  the Analytics API that contains an API key by accident, Unify will immediately
  expire the key as a precautionary measure.
</Danger>

Write keys are used to authenticate requests to the Analytics API. You can find
your write key in Unify by navigating to
[Settings → Web & product data → Settings](https://app.unifygtm.com/dashboard/settings/data/web-intent?webEventsTab=Settings).

To authenticate a request, include the following header in your request:

```http theme={null}
X-Write-Key: <token>
```

Replace `<token>` with your Unify write key.

### Request origin

Requests that use a write key must include an allowed `Origin` header. This
applies to requests sent from both browsers and from server-side code. For
server-side requests, set `Origin` to the website or application origin
associated with the event source.

### Rate limits

The Analytics API is rate-limited by default to 100,000 requests per five minute
window. We are able to provide higher limits upon request if needed.

### OpenAPI specification

The OpenAPI specification can be found [here](https://api.unifyintent.com/analytics/v1/openapi.json).


# Page events
Source: https://docs.unifygtm.com/developers/api/analytics/page

POST /page
Send a "page" event.



# Create option
Source: https://docs.unifygtm.com/developers/api/data/attribute-options/create

POST /objects/{object_name}/attributes/{attribute_name}/options



# Delete option
Source: https://docs.unifygtm.com/developers/api/data/attribute-options/delete

DELETE /objects/{object_name}/attributes/{attribute_name}/options/{option_name}



# Get option
Source: https://docs.unifygtm.com/developers/api/data/attribute-options/get

GET /objects/{object_name}/attributes/{attribute_name}/options/{option_name}



# List options
Source: https://docs.unifygtm.com/developers/api/data/attribute-options/list

GET /objects/{object_name}/attributes/{attribute_name}/options



# Update option
Source: https://docs.unifygtm.com/developers/api/data/attribute-options/update

PATCH /objects/{object_name}/attributes/{attribute_name}/options/{option_name}



# Create attribute
Source: https://docs.unifygtm.com/developers/api/data/attributes/create

POST /objects/{object_name}/attributes



# Delete attribute
Source: https://docs.unifygtm.com/developers/api/data/attributes/delete

DELETE /objects/{object_name}/attributes/{attribute_name}



# Get attribute
Source: https://docs.unifygtm.com/developers/api/data/attributes/get

GET /objects/{object_name}/attributes/{attribute_name}



# List attributes
Source: https://docs.unifygtm.com/developers/api/data/attributes/list

GET /objects/{object_name}/attributes



# Update attribute
Source: https://docs.unifygtm.com/developers/api/data/attributes/update

PATCH /objects/{object_name}/attributes/{attribute_name}



# Create object
Source: https://docs.unifygtm.com/developers/api/data/objects/create

POST /objects



# Delete object
Source: https://docs.unifygtm.com/developers/api/data/objects/delete

DELETE /objects/{object_name}



# Get object
Source: https://docs.unifygtm.com/developers/api/data/objects/get

GET /objects/{object_name}



# List objects
Source: https://docs.unifygtm.com/developers/api/data/objects/list

GET /objects



# Update object
Source: https://docs.unifygtm.com/developers/api/data/objects/update

PATCH /objects/{object_name}



# Unify Data API
Source: https://docs.unifygtm.com/developers/api/data/overview

Interact with Unify objects, attributes, and records.

<Note>
  The Data API is currently in public beta and may change based on feedback.
  Whenever possible, we will maintain backward compatibility and provide advance
  notice of any breaking changes.
</Note>

## Overview

Data within Unify is stored in *objects*. Objects are the building blocks that
allow you to store and interact with data in Unify. Every object has a set of
*attributes* which represent the fields that make up the object, and *records*
represent instances of the object.

The Unify Data API allows you to interact with these objects, attributes, and
associated records. The following API groups are available:

* [Object APIs](/developers/api/data/objects/create) allow you to create and manage object definitions and schemas
* [Attribute APIs](/developers/api/data/attributes/create) allow you to create and manage the attributes on objects
* [Record APIs](/developers/api/data/records/create) allow you to create and modify object records

These APIs provide the means to connect custom data sources to Unify, import
data from external tools, and export data to other systems.

## Usage

### Request format

The base URL of all API requests to the Data API is:

```shell theme={null}
https://api.unifygtm.com/data/v1
```

All APIs are built on REST principles and use standard HTTP methods to perform
CRUD operations.

### Authentication

API keys are used to authenticate requests to the Data API. You can generate an
API key in Unify by navigating to [Settings → Developers](https://app.unifygtm.com/dashboard/settings/integrations/api-keys).

To authenticate a request, include the following header in your request:

```http theme={null}
X-Api-Key: <token>
```

Replace `<token>` with your Unify API key.

<Warning>
  Treat API keys as sensitive credentials. Avoid pasting them as plaintext into
  Slack, email, or LLM chats, and store them in a password manager whenever
  possible.

  As a best practice rotate API keys regularly.
</Warning>

### Rate limits

The Data API is rate-limited to 100,000 requests per five minute window. We may
introduce daily limits in the future to prevent extraordinary usage.

### OpenAPI specification

The OpenAPI specification can be found [here](https://api.unifygtm.com/data/v1/openapi.json).


# Create record
Source: https://docs.unifygtm.com/developers/api/data/records/create

POST /objects/{object_name}/records
Create a new record.

## Overview

The *create* method creates a new record in the specified object. This method
will fail if any record already exists with conflicting unique values, which may
or may not be the desired behavior depending on your use case.

If you are not sure whether a record already exists with the same unique values,
consider using the [upsert method](/developers/api/data/records/upsert) instead.

## Examples

<AccordionGroup>
  <Accordion title="Create a company">
    This creates a new company record:

    <CodeGroup>
      ```http Request theme={null}
      POST /objects/company/records

      {
        "name": "Unify",
        "domain": "unifygtm.com",
        "description": "A nice company with a top-notch API.",
        "status": "Active"
      }
      ```

      ```json Response theme={null}
      {
        "status": "success",
        "data": {
          "object": "company",
          "id": "73fcb798-9ccd-4138-8f6a-9a801123783c",
          "created_at": "2025-09-04T01:23:45Z",
          "updated_at": "2025-09-04T01:23:45Z",
          "attributes": {
            "name": "Unify",
            "domain": "unifygtm.com",
            "description": "A nice company with a top-notch API.",
            "status": "Active"
            // ...
          }
        }
      }
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Create a person">
    This creates a new person record and links them to an existing company if it
    exists:

    <CodeGroup>
      ```http Request theme={null}
      POST /objects/person/records

      {
        "first_name": "Austin",
        "last_name": "Hughes",
        "email": "austinhughes@unifygtm.com",
        "title": "CEO",
        "company": {
          "match": {
            "domain": "unifygtm.com"
          }
        }
      }
      ```

      ```json Response theme={null}
      {
        "status": "success",
        "data": {
          "object": "person",
          "id": "bf3f4d5e-c995-496f-8774-5a1c58d05197",
          "created_at": "2025-09-04T01:23:45Z",
          "updated_at": "2025-09-04T01:23:45Z",
          "attributes": {
            "first_name": "Austin",
            "last_name": "Hughes",
            "email": "austinhughes@unifygtm.com",
            "title": "CEO",
            "company": "73fcb798-9ccd-4138-8f6a-9a801123783c"
            // ...
          }
        }
      }
      ```
    </CodeGroup>

    If a company with this domain does not exist, the `company` reference on
    this person will be `null`. If you want to create a company in that case
    instead, you can use a nested upsert:

    <CodeGroup>
      ```http Request theme={null}
      POST /objects/person/records

      {
        "first_name": "Austin",
        "last_name": "Hughes",
        "email": "austinhughes@unifygtm.com",
        "title": "CEO",
        "company": {
          "match": {
            "domain": "unifygtm.com"
          },
          "create": {
            "name": "Unify",
            "domain": "unifygtm.com",
            "linkedin_url": "https://www.linkedin.com/company/unifygtm"
          }
        }
      }
      ```

      ```json Response theme={null}
      {
        "status": "success",
        "data": {
          "object": "person",
          "id": "bf3f4d5e-c995-496f-8774-5a1c58d05197",
          "created_at": "2025-09-04T01:23:45Z",
          "updated_at": "2025-09-04T01:23:45Z",
          "attributes": {
            "first_name": "Austin",
            "last_name": "Hughes",
            "email": "austinhughes@unifygtm.com",
            "title": "CEO",
            "company": "73fcb798-9ccd-4138-8f6a-9a801123783c"
            // ...
          }
        }
      }
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Create a custom record">
    This creates a new record in a custom object called `product_user`:

    <CodeGroup>
      ```http Request theme={null}
      POST /objects/product_user/records

      {
        "user_id": "6b2a2761-3cbe-481f-8a1e-b24859c674f8",
        "full_name": "Bob Smith",
        "email_address": "bob.smith@gmail.com",
        "plan": "free_tier"
      }
      ```

      ```json Response theme={null}
      {
        "status": "success",
        "data": {
          "object": "product_user",
          "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
          "created_at": "2025-09-04T01:23:45Z",
          "updated_at": "2025-09-04T01:23:45Z",
          "attributes": {
            "user_id": "6b2a2761-3cbe-481f-8a1e-b24859c674f8",
            "full_name": "Bob Smith",
            "email_address": "bob.smith@gmail.com",
            "plan": "free_tier"
            // ...
          }
        }
      }
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

## Usage


# Delete record
Source: https://docs.unifygtm.com/developers/api/data/records/delete

DELETE /objects/{object_name}/records/{record_id}
Delete a record by ID.

## Overview

The *delete* method permanently removes a record by its unique ID from the
specified object. This operation cannot be undone.

If the record doesn't exist, the API will return a 404 error. If the record is
referenced by other records, those other records will not be deleted, but their
reference to this record will be set to `null`.

## Examples

<AccordionGroup>
  <Accordion title="Delete a company record">
    This permanently deletes a company record:

    <CodeGroup>
      ```http Request theme={null}
      DELETE /objects/company/records/349b4a49-38b7-407d-aeee-db4ead1bbae2
      ```

      ```json Response theme={null}
      {
        "status": "success"
      }
      ```
    </CodeGroup>

    This removes the company permanently. Any people associated with this
    company will have their `company` attribute set to `null`.
  </Accordion>

  <Accordion title="Delete a custom record">
    This permanently deletes a record from a custom object:

    <CodeGroup>
      ```http Request theme={null}
      DELETE /objects/product_user/records/5ff35db4-20de-4a12-9eef-ca0e9cc24818
      ```

      ```json Response theme={null}
      {
        "status": "success"
      }
      ```
    </CodeGroup>

    This removes the record from the `product_user` object permanently.
  </Accordion>
</AccordionGroup>

## Usage


# Find unique record
Source: https://docs.unifygtm.com/developers/api/data/records/find-unique

POST /objects/{object_name}/records/find-unique
Find a specific record based on unique values.

## Overview

The *find unique* method searches for a single record based on one or more
unique attribute values. The response will contain exactly zero or one record.

This method is useful when you need to find a record by its unique identifier
other than the record ID. For example, you can use it to find a company by its
domain or a person by their email address. If you have custom objects with
unique identifiers, this method can be used to locate records based on those
unique attributes.

## Examples

<AccordionGroup>
  <Accordion title="Find a company by domain">
    This finds a company record by its unique domain:

    <CodeGroup>
      ```http Request theme={null}
      POST /objects/company/records/find-unique

      {
        "domain": "unifygtm.com"
      }
      ```

      ```json Response theme={null}
      {
        "status": "success",
        "data": {
          "object": "company",
          "id": "73fcb798-9ccd-4138-8f6a-9a801123783c",
          "created_at": "2025-09-04T01:23:45Z",
          "updated_at": "2025-09-04T01:23:45Z",
          "attributes": {
            "name": "Unify",
            "domain": "unifygtm.com",
            "description": "A nice company with a top-notch API.",
            "status": "Active"
            // ...
          }
        }
      }
      ```
    </CodeGroup>

    This returns the company for Unify if it exists, otherwise the response will
    contain `null` for the record.
  </Accordion>

  <Accordion title="Find a custom record">
    This finds a record in a custom object by a unique identifier:

    <CodeGroup>
      ```http Request theme={null}
      POST /objects/product_user/records/find-unique

      {
        "user_id": "Zz9O-5O8W-s41T"
      }
      ```

      ```json Response theme={null}
      {
        "status": "success",
        "data": {
          "object": "product_user",
          "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
          "created_at": "2025-09-04T01:23:45Z",
          "updated_at": "2025-09-04T01:23:45Z",
          "attributes": {
            "user_id": "Zz9O-5O8W-s41T",
            "full_name": "Alice Smith",
            "email_address": "alice@example.com",
            "plan": "enterprise"
            // ...
          }
        }
      }
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Find using multiple attributes">
    This finds a custom object record using a combination of unique and
    non-unique attributes:

    <CodeGroup>
      ```http Request theme={null}
      POST /objects/product_user/records/find-unique

      {
        "user_id": "Zz9O-5O8W-s41T",
        "email": "alice@example.com",
        "product_code": "PRO-PLAN"
      }
      ```

      ```json Response theme={null}
      {
        "status": "success",
        "data": {
          "object": "product_user",
          "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
          "created_at": "2025-09-04T01:23:45Z",
          "updated_at": "2025-09-04T01:23:45Z",
          "attributes": {
            "user_id": "Zz9O-5O8W-s41T",
            "full_name": "Alice Smith",
            "email": "alice@example.com",
            "product_code": "PRO-PLAN"
            // ...
          }
        }
      }
      ```
    </CodeGroup>

    In this case, the custom attributes `user_id` and `email` are unique, but
    `product_code` is not. Only a record which matches all of these criteria
    will be returned.
  </Accordion>
</AccordionGroup>

## Usage


# Get record
Source: https://docs.unifygtm.com/developers/api/data/records/get

GET /objects/{object_name}/records/{record_id}
Retrieve a specific record by ID.

## Overview

The *get* method retrieves a single record by its ID from the specified object.
This is the most accurate way to fetch a specific record when you know its ID.
If the record doesn't exist, an error will be returned.

## Examples

<AccordionGroup>
  <Accordion title="Get a company record">
    This retrieves a specific company record:

    <CodeGroup>
      ```http Request theme={null}
      GET /objects/company/records/de885595-2d9a-4fb9-ae30-25ef18b6219b
      ```

      ```json Response theme={null}
      {
        "status": "success",
        "data": {
          "object": "company",
          "id": "de885595-2d9a-4fb9-ae30-25ef18b6219b",
          "created_at": "2025-09-04T01:23:45Z",
          "updated_at": "2025-09-04T01:23:45Z",
          "attributes": {
            "name": "Unify",
            "domain": "unifygtm.com",
            "description": "A nice company with a top-notch API.",
            "status": "Active"
            // ...
          }
        }
      }
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Get a custom record">
    This retrieves a record from a custom object:

    <CodeGroup>
      ```http Request theme={null}
      GET /objects/product_user/records/6741cc39-b332-45a8-a439-75b69db998b1
      ```

      ```json Response theme={null}
      {
        "status": "success",
        "data": {
          "object": "product_user",
          "id": "6741cc39-b332-45a8-a439-75b69db998b1",
          "created_at": "2025-09-04T01:23:45Z",
          "updated_at": "2025-09-04T01:23:45Z",
          "attributes": {
            "user_id": "6b2a2761-3cbe-481f-8a1e-b24859c674f8",
            "full_name": "Bob Smith",
            "email_address": "bob.smith@gmail.com",
            "plan": "free_tier"
            // ...
          }
        }
      }
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

## Usage


# Update record
Source: https://docs.unifygtm.com/developers/api/data/records/update

PATCH /objects/{object_name}/records/{record_id}
Update an existing record by ID.

## Overview

The *update* method modifies an existing record by its unique ID. You can
provide values for any attributes you want to update in the request body.
Attributes not included in the request will remain unchanged.

If the record doesn't exist, the API will return a 404 error. This method will
not create a new record. If you want to create a record if it doesn't exist, use
the [upsert method](/developers/api/data/records/upsert) instead.

<Warning>
  This method will overwrite existing values on the record, which may be
  undesirable. If you want a safer alternative, use the [upsert method](/developers/api/data/records/upsert)
  and pass `update_if_empty` instead.
</Warning>

## Examples

<AccordionGroup>
  <Accordion title="Update a company">
    This updates specific fields on a company record:

    <CodeGroup>
      ```http Request theme={null}
      PATCH /objects/company/records/11b41071-1ac7-4419-b3bd-3da132502826

      {
        "status": "Inactive",
        "description": "An updated description for this company."
      }
      ```

      ```json Response theme={null}
      {
        "status": "success",
        "data": {
          "object": "company",
          "id": "11b41071-1ac7-4419-b3bd-3da132502826",
          "created_at": "2025-09-04T01:23:45Z",
          "updated_at": "2025-09-04T01:23:45Z",
          "attributes": {
            "name": "Unify",
            "domain": "unifygtm.com",
            "status": "Inactive",
            "description": "An updated description for this company."
            // ...
          }
        }
      }
      ```
    </CodeGroup>

    This updates only the `status` and `description` fields on the company. All
    other fields remain unchanged.
  </Accordion>

  <Accordion title="Update a person">
    This updates a person's job title and associated company:

    <CodeGroup>
      ```http Request theme={null}
      PATCH /objects/person/records/5ce127ba-8d7e-42d0-9e60-76017a04caec

      {
        "title": "Senior Developer",
        "company": {
          "id": "11b41071-1ac7-4419-b3bd-3da132502826"
        }
      }
      ```

      ```json Response theme={null}
      {
        "status": "success",
        "data": {
          "object": "person",
          "id": "5ce127ba-8d7e-42d0-9e60-76017a04caec",
          "created_at": "2025-09-04T01:23:45Z",
          "updated_at": "2025-09-04T01:23:45Z",
          "attributes": {
            "first_name": "Austin",
            "last_name": "Hughes",
            "email": "austinhughes@unifygtm.com",
            "title": "Senior Developer",
            "company": "11b41071-1ac7-4419-b3bd-3da132502826"
            // ...
          }
        }
      }
      ```
    </CodeGroup>

    In this case, we knew the exact ID of the company we wanted to link this
    person to, but you could also use a nested `match` or upsert if desired.
  </Accordion>

  <Accordion title="Update a custom record">
    This updates fields on a custom object record:

    <CodeGroup>
      ```http Request theme={null}
      PATCH /objects/product_user/records/e624b659-7a50-4925-9a49-dc2dae8dcb60

      {
        "plan": "enterprise",
        "last_login": "2024-01-15T10:30:00Z"
      }
      ```

      ```json Response theme={null}
      {
        "status": "success",
        "data": {
          "object": "product_user",
          "id": "e624b659-7a50-4925-9a49-dc2dae8dcb60",
          "created_at": "2025-09-04T01:23:45Z",
          "updated_at": "2025-09-04T01:23:45Z",
          "attributes": {
            "user_id": "6b2a2761-3cbe-481f-8a1e-b24859c674f8",
            "full_name": "Bob Smith",
            "email_address": "bob.smith@gmail.com",
            "plan": "enterprise",
            "last_login": "2024-01-15T10:30:00Z"
            // ...
          }
        }
      }
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

## Usage


# Upsert record
Source: https://docs.unifygtm.com/developers/api/data/records/upsert

POST /objects/{object_name}/records/upsert
Create or update a record based on unique values.

## Overview

The *upsert* method creates or updates a record depending on whether it already
exists or not. If a matching record exists, it will be updated. Otherwise, a new
record will be created.

The request body accepts the following properties which specify how to create or
update the record:

| Property                    | Behavior                                                                                                                                                    |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `match`                     | Values to match against existing records. At least one of these values must be a unique attribute to avoid matching more than one record.                   |
| `create`                    | Values to use when creating a new record.                                                                                                                   |
| `update`                    | Values to use when updating an existing record. These values will replace any existing values on the record.                                                |
| `update_if_empty`           | Values to use when updating an existing record. These values will only be used if the attribute is currently empty.                                         |
| `create_or_update`          | Values to use when creating a new record or updating an existing record. When updating, these values will replace any existing values on the record.        |
| `create_or_update_if_empty` | Values to use when creating a new record or updating an existing record. When updating, these values will only be used if the attribute is currently empty. |

You must specify `match` and one of `create`, `create_or_update`, or `create_or_update_if_empty`.
All other properties are optional.

The upsert method is the most reliable way of sending data into Unify, so if
you're not sure what method to use, this is the one we recommend.

## Examples

<AccordionGroup>
  <Accordion title="Upsert a company">
    This creates or updates a company record:

    <CodeGroup>
      ```http Request theme={null}
      POST /objects/company/records/upsert

      {
        "match": {
          "domain": "unifygtm.com"
        },
        "create": {
          "name": "Unify",
          "domain": "unifygtm.com",
          "description": "A nice company with a top-notch API.",
          "status": "Active"
        },
        "update": {
          "status": "Active"
        }
      }
      ```

      ```json Response theme={null}
      {
        "status": "success",
        "data": {
          "object": "company",
          "id": "73fcb798-9ccd-4138-8f6a-9a801123783c",
          "created_at": "2025-09-04T01:23:45Z",
          "updated_at": "2025-09-04T01:23:45Z",
          "attributes": {
            "name": "Unify",
            "domain": "unifygtm.com",
            "description": "A nice company with a top-notch API.",
            "status": "Active"
            // ...
          }
        }
      }
      ```
    </CodeGroup>

    If there's already a company record in Unify with the domain [unifygtm.com](https://unifygtm.com),
    it will be updated with a status of "Active". Otherwise, a new record will be
    created with the specified values.
  </Accordion>

  <Accordion title="Upsert a person">
    This creates or updates a person record as well as their associated company
    and then links them together:

    <CodeGroup>
      ```http Request theme={null}
      POST /objects/company/records/upsert

      {
        "match": {
          "email": "austinhughes@unifygtm.com"
        },
        "create_or_update_if_empty": {
          "first_name": "Austin",
          "last_name": "Hughes",
          "email": "austinhughes@unifygtm.com",
          "title": "CEO",
          "company": {
            "match": {
              "domain": "unifygtm.com"
            },
            "create_or_update_if_empty": {
              "name": "Unify",
              "domain": "unifygtm.com"
            }
          }
        }
      }
      ```

      ```json Response theme={null}
      {
        "status": "success",
        "data": {
          "object": "person",
          "id": "bf3f4d5e-c995-496f-8774-5a1c58d05197",
          "created_at": "2025-09-04T01:23:45Z",
          "updated_at": "2025-09-04T01:23:45Z",
          "attributes": {
            "first_name": "Austin",
            "last_name": "Hughes",
            "email": "austinhughes@unifygtm.com",
            "title": "CEO",
            "company": "73fcb798-9ccd-4138-8f6a-9a801123783c",
            "lead_source": "LinkedIn"
            // ...
          }
        }
      }
      ```
    </CodeGroup>

    This works because `company` is the name of a *reference attribute* on the
    person object which references a company object record. This request will
    create a new company if it doesn't already exist, update it if it does, and
    then link this person to that company.
  </Accordion>

  <Accordion title="Upsert a custom record">
    This creates or updates a record in a custom object called `product_user`:

    <CodeGroup>
      ```http Request theme={null}
      POST /objects/company/records/upsert

      {
        "match": {
          "user_id": "6b2a2761-3cbe-481f-8a1e-b24859c674f8"
        },
        "create_or_update": {
          "user_id": "6b2a2761-3cbe-481f-8a1e-b24859c674f8",
          "full_name": "Bob Smith",
          "email_address": "bob.smith@gmail.com",
          "plan": "free_tier"
        }
      }
      ```

      ```json Response theme={null}
      {
        "status": "success",
        "data": {
          "object": "product_user",
          "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
          "created_at": "2025-09-04T01:23:45Z",
          "updated_at": "2025-09-04T01:23:45Z",
          "attributes": {
            "user_id": "6b2a2761-3cbe-481f-8a1e-b24859c674f8",
            "full_name": "Bob Smith",
            "email_address": "bob.smith@gmail.com",
            "plan": "free_tier"
            // ...
          }
        }
      }
      ```
    </CodeGroup>

    This is a custom object, so all of these attributes are custom attributes
    defined for the object. Since this request uses `create_or_update`, these
    values will be filled in if the record is created or overridden if an
    existing record is found.
  </Accordion>
</AccordionGroup>

## Usage


# Standard objects and attributes
Source: https://docs.unifygtm.com/developers/api/data/standard-objects

Reference the built-in attributes that ship with Unify's standard objects.

## Overview

Unify provides a set of **standard objects** that ship with built-in attributes.
The most commonly used standard objects are **Company**, **Person**,
**Opportunity**, and **User**, documented below.

Each attribute has an **API name** (used in API requests and responses) and a
[value type](/reference/objects/value-types). You can extend any standard object
with [custom attributes](/reference/objects/define-attributes), and you can link
objects to one another with [reference](/reference/objects/value-types#reference)
attributes.

<Info>
  These tables list the attributes that ship by default. A workspace may add
  custom attributes, so for the authoritative, live set on an object, list its
  attributes via the API:

  ```http theme={null}
  GET /data/v1/objects/{object_name}/attributes
  ```
</Info>

A few attributes are **read-only** and maintained by Unify. They appear in
records and query results but cannot be set directly through the API.

## Company

The **Company** object (`company`) represents an organization or business
entity, such as a customer, competitor, or partner.

| API name                   | Value type   | Required | Description                                                                             |
| :------------------------- | :----------- | :------- | :-------------------------------------------------------------------------------------- |
| `name`                     | Text         |          | Name of the company.                                                                    |
| `domain`                   | URL          | Yes      | Website domain. Normalized and deduplicated — see the note below.                       |
| `description`              | Text         |          | Description of the company.                                                             |
| `industry`                 | Text         |          | Industry the company operates in.                                                       |
| `employee_count`           | Integer      |          | Estimated employee count.                                                               |
| `revenue`                  | Currency     |          | Estimated revenue.                                                                      |
| `founded`                  | Date         |          | Date the company was founded.                                                           |
| `address`                  | Address      |          | Physical address of the company.                                                        |
| `time_zone`                | Time zone    |          | Time zone the company is located in.                                                    |
| `corporate_phone`          | Phone number |          | Corporate phone number.                                                                 |
| `linkedin_url`             | URL          |          | LinkedIn company profile. Standardized to `https://www.linkedin.com/company/<handle>/`. |
| `status`                   | Text         |          | Status of the company.                                                                  |
| `lead_source`              | Text         |          | Source of the company record.                                                           |
| `do_not_contact`           | Boolean      |          | Whether contacting this company is disallowed.                                          |
| `record_owner`             | Reference    |          | The user that owns the record. References the **User** object.                          |
| `hubspot_url`              | URL          |          | HubSpot record URL for the company.                                                     |
| `salesforce_url`           | URL          |          | Salesforce record URL for the company.                                                  |
| `last_activity_at`         | Datetime     |          | Last time any activity was recorded for the company. Read-only.                         |
| `last_website_activity_at` | Datetime     |          | Last time a website activity was recorded for the company. Read-only.                   |

<Note>
  The `domain` attribute has special validation and preprocessing to prevent
  duplicate company records. The domain is normalized (protocol and path are
  stripped). See
  [Attribute value types](/reference/objects/value-types#url) for details.
</Note>

## Person

The **Person** object (`person`) represents an individual who interacts with
your business, such as a prospect, customer, or contact at a partner company.

| API name                   | Value type    | Required | Description                                                                |
| :------------------------- | :------------ | :------- | :------------------------------------------------------------------------- |
| `email`                    | Email address | Yes      | Email address of the person.                                               |
| `first_name`               | Text          |          | First name of the person.                                                  |
| `last_name`                | Text          |          | Last name of the person.                                                   |
| `title`                    | Text          |          | Job title of the person.                                                   |
| `company`                  | Reference     |          | Company the person is associated with. References the **Company** object.  |
| `address`                  | Address       |          | Physical address of the person.                                            |
| `time_zone`                | Time zone     |          | IANA time zone identifier derived from the person's address. Read-only.    |
| `mobile_phone`             | Phone number  |          | Mobile phone number.                                                       |
| `work_phone`               | Phone number  |          | Work phone number.                                                         |
| `corporate_phone`          | Phone number  |          | Corporate phone number.                                                    |
| `phone_numbers`            | Phone number  |          | Additional phone numbers associated with the person. Returns a list.       |
| `linkedin_url`             | URL           |          | LinkedIn profile. Standardized to `https://www.linkedin.com/in/<handle>/`. |
| `status`                   | Text          |          | Status of the person.                                                      |
| `lead_source`              | Text          |          | Source of the person record.                                               |
| `do_not_call`              | Boolean       |          | Whether calling this person is disallowed.                                 |
| `do_not_email`             | Boolean       |          | Whether emailing this person is disallowed.                                |
| `email_opt_out`            | Boolean       |          | Whether the person has opted out of email communications.                  |
| `eu_resident`              | Boolean       |          | Whether the person is a resident of the European Union.                    |
| `record_owner`             | Reference     |          | The user that owns the record. References the **User** object.             |
| `hubspot_url`              | URL           |          | HubSpot record URL for the person.                                         |
| `salesforce_url`           | URL           |          | Salesforce record URL for the person.                                      |
| `last_activity_at`         | Datetime      |          | Last time any activity was recorded for the person. Read-only.             |
| `last_website_activity_at` | Datetime      |          | Last time a website activity was recorded for the person. Read-only.       |

## Opportunity

The **Opportunity** object (`opportunity`) represents a deal or potential
business relationship. Opportunities can carry a monetary value and a stage, and
can be linked to companies and people.

| API name              | Value type | Required | Description                                                                 |
| :-------------------- | :--------- | :------- | :-------------------------------------------------------------------------- |
| `name`                | Text       | Yes      | Name of the opportunity.                                                    |
| `uniqueness_key`      | Text       | Yes      | Unique identifier used to distinguish this opportunity from others.         |
| `amount`              | Currency   |          | Monetary value associated with the opportunity.                             |
| `stage`               | Text       |          | Stage of the opportunity in the sales process (such as "open" or "closed"). |
| `opportunity_type`    | Text       |          | Type of the opportunity.                                                    |
| `company`             | Reference  |          | Company associated with the opportunity. References the **Company** object. |
| `person`              | Reference  |          | Person associated with the opportunity. References the **Person** object.   |
| `lead_source`         | Text       |          | Source of the opportunity.                                                  |
| `record_owner`        | Reference  |          | The user that owns the record. References the **User** object.              |
| `original_created_at` | Datetime   |          | Date when the opportunity was originally opened.                            |
| `hubspot_url`         | URL        |          | HubSpot record URL for the opportunity.                                     |
| `salesforce_url`      | URL        |          | Salesforce record URL for the opportunity.                                  |

## User

The **User** object (`user`) represents a member of your Unify workspace. Users
are referenced by the `record_owner` attribute on other objects to indicate who
owns a record.

| API name     | Value type    | Required | Description                |
| :----------- | :------------ | :------- | :------------------------- |
| `email`      | Email address | Yes      | Email address of the user. |
| `first_name` | Text          |          | First name of the user.    |
| `last_name`  | Text          |          | Last name of the user.     |

<Note>
  Unlike other standard objects, the **User** object does not support custom
  attributes.
</Note>

## What's next

<CardGroup>
  <Card title="Attribute value types" href="/reference/objects/value-types" icon="shapes">
    Learn how each value type behaves and what it accepts.
  </Card>

  <Card title="List attributes" href="/developers/api/data/attributes/list" icon="list">
    Fetch the live set of attributes on any object via the API.
  </Card>
</CardGroup>


# Create enrollment
Source: https://docs.unifygtm.com/developers/api/sequences/enrollments/create

POST /enrollments
Enroll a person in a sequence.

## Overview

Create an enrollment to add a person to a sequence. The request body specifies:

| Property         | Behavior                                                                                                                           |
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `sequence_id`    | The sequence to enroll the person in.                                                                                              |
| `person_id`      | The person to enroll.                                                                                                              |
| `mailbox_emails` | Candidate mailbox addresses to send from. One is selected at enrollment time. At least one and at most ten addresses are accepted. |

If the person is already actively enrolled in the sequence, the request returns
`409 Conflict`.


# Delete enrollment
Source: https://docs.unifygtm.com/developers/api/sequences/enrollments/delete

DELETE /enrollments/{id}
Delete a sequence enrollment, removing the person from the sequence.



# Get enrollment
Source: https://docs.unifygtm.com/developers/api/sequences/enrollments/get

GET /enrollments/{id}
Retrieve a single sequence enrollment by its ID.



# List enrollments
Source: https://docs.unifygtm.com/developers/api/sequences/enrollments/list

GET /enrollments
List sequence enrollments, optionally filtered by sequence, person, mailbox, status, enrolling play, or update time.



# Pause enrollment
Source: https://docs.unifygtm.com/developers/api/sequences/enrollments/pause

POST /enrollments/{id}/pause
Pause a sequence enrollment, halting the person's progress through the sequence.



# Resume enrollment
Source: https://docs.unifygtm.com/developers/api/sequences/enrollments/resume

POST /enrollments/{id}/resume
Resume a paused sequence enrollment.



# Unify Sequences API
Source: https://docs.unifygtm.com/developers/api/sequences/overview

Interact with sequences and sequence enrollments in the Unify platform.

<Note>
  The Sequences API is currently in public beta and may change based on feedback.
  Whenever possible, we will maintain backward compatibility and provide advance
  notice of any breaking changes.
</Note>

## Overview

A *sequence* is an automated series of steps — emails, tasks, and conditions —
that runs against a person. Enrolling a person in a sequence creates an
*enrollment*, which tracks that person's progress through the sequence's steps
along with reply, bounce, and opt-out state.

The Sequences API lets you manage these resources programmatically. The
following API groups are available:

* [Sequence APIs](/developers/api/sequences/sequences/list) let you list and
  retrieve sequences, inspect their steps, and pause or resume them.
* [Enrollment APIs](/developers/api/sequences/enrollments/create) let you enroll
  people in sequences and manage their enrollments.

To export sequence enrollments or enrollment steps in bulk, use the
[Bulk API](/developers/guides/request-data/bulk-api) instead.

## Usage

### Request format

The base URL of all API requests to the Sequences API is:

```shell theme={null}
https://api.unifygtm.com/sequences/v1
```

All APIs are built on REST principles and use standard HTTP methods to perform
operations.

### Authentication

API keys are used to authenticate requests to the Sequences API. You can generate
an API key in Unify by navigating to [Settings → Developers](https://app.unifygtm.com/dashboard/settings/integrations/api-keys).

To authenticate a request, include the following header in your request:

```http theme={null}
X-Api-Key: <token>
```

Replace `<token>` with your Unify API key.

### Pagination

List endpoints are cursor-paginated. Each response includes a `next_cursor`
value; pass it as the `cursor` query parameter to fetch the next page. A `null`
`next_cursor` means there are no more results.

### Rate limits

The Sequences API is rate-limited to 100,000 requests per five minute window. We
may introduce daily limits in the future to prevent extraordinary usage.

### OpenAPI specification

The OpenAPI specification can be found [here](https://api.unifygtm.com/sequences/v1/openapi.json).


# Delete sequence
Source: https://docs.unifygtm.com/developers/api/sequences/sequences/delete

DELETE /sequences/{id}
Delete a sequence.



# Get sequence
Source: https://docs.unifygtm.com/developers/api/sequences/sequences/get

GET /sequences/{id}
Retrieve a single sequence by its ID.



# Get sequence step
Source: https://docs.unifygtm.com/developers/api/sequences/sequences/get-step

GET /sequences/{id}/steps/{step_id}
Retrieve a single step within a sequence.



# List sequences
Source: https://docs.unifygtm.com/developers/api/sequences/sequences/list

GET /sequences
List the sequences in your organization.



# List sequence steps
Source: https://docs.unifygtm.com/developers/api/sequences/sequences/list-steps

GET /sequences/{id}/steps
List the steps that make up a sequence.



# Pause sequence
Source: https://docs.unifygtm.com/developers/api/sequences/sequences/pause

POST /sequences/{id}/pause
Pause a sequence, halting progress for all of its enrollments.



# Resume sequence
Source: https://docs.unifygtm.com/developers/api/sequences/sequences/resume

POST /sequences/{id}/resume
Resume a paused sequence.



# Complete task
Source: https://docs.unifygtm.com/developers/api/tasks/complete

POST /tasks/{id}/complete
Mark a task as completed.



# Create task
Source: https://docs.unifygtm.com/developers/api/tasks/create

POST /tasks
Create a task for a person.



# Delete task
Source: https://docs.unifygtm.com/developers/api/tasks/delete

DELETE /tasks/{id}
Delete a task.



# Get task
Source: https://docs.unifygtm.com/developers/api/tasks/get

GET /tasks/{id}
Retrieve a single task by its ID.



# List tasks
Source: https://docs.unifygtm.com/developers/api/tasks/list

GET /tasks
List tasks, optionally filtered by status, type, priority, assignee, or person.



# Unify Tasks API
Source: https://docs.unifygtm.com/developers/api/tasks/overview

Interact with tasks in the Unify platform.

## Overview

A *task* is a unit of outreach work — sending an email, making a phone call,
engaging on LinkedIn, or completing a manual action item — tied to a person and
assigned to a user. Tasks track their own type, status, priority, and due date.

The Tasks API lets you manage these resources programmatically:

* [List tasks](/developers/api/tasks/list)
* [Create a task](/developers/api/tasks/create)
* [Get a task](/developers/api/tasks/get)
* [Update a task](/developers/api/tasks/update)
* [Delete a task](/developers/api/tasks/delete)
* [Complete a task](/developers/api/tasks/complete)

To export tasks in bulk, use the
[Bulk API](/developers/guides/request-data/bulk-api) instead.

## Usage

### Request format

The base URL of all API requests to the Tasks API is:

```shell theme={null}
https://api.unifygtm.com/tasks/v1
```

All APIs are built on REST principles and use standard HTTP methods to perform
operations.

### Authentication

API keys are used to authenticate requests to the Tasks API. You can generate
an API key in Unify by navigating to [Settings → Developers](https://app.unifygtm.com/dashboard/settings/integrations/api-keys).

To authenticate a request, include the following header in your request:

```http theme={null}
X-Api-Key: <token>
```

Replace `<token>` with your Unify API key.

### Pagination

List endpoints are cursor-paginated. Each response includes a `next_cursor`
value; pass it as the `cursor` query parameter to fetch the next page. A `null`
`next_cursor` means there are no more results.

### Rate limits

The Tasks API is rate-limited to 100,000 requests per five minute window. We
may introduce daily limits in the future to prevent extraordinary usage.

### OpenAPI specification

The OpenAPI specification can be found [here](https://api.unifygtm.com/tasks/v1/openapi.json).


# Update task
Source: https://docs.unifygtm.com/developers/api/tasks/update

PATCH /tasks/{id}
Update a task's assignee, priority, or due date.



# Connecting your data
Source: https://docs.unifygtm.com/developers/connecting-data

Choose the right approach to get your data into Unify.

## Overview

There are two fundamental ways to get data into Unify:

* **Sending events** — Real-time signals from websites and products (page
  visits, user actions, identity information)
* **Syncing object records** — Structured data from CRMs, warehouses, databases, APIs,
  and other systems (product users, subscriptions, enrichment data)

Events and records often come from different sources, but they serve the same
overall purpose of connecting all of the data relevant to your go-to-market
operations in one place.

## Sending events

Events are the real-time behavioral signals that power intent-based workflows in
Unify. They capture what visitors and users are doing on your website or in your
product and link that activity to Companies and People.

### Example use cases

* You want to identify companies visiting your marketing website (IP reveal)
* You want to track product usage to trigger sales plays (PLG motions)
* You want to capture form fills, logins, or other user interactions
* You want real-time or near-real-time signals to power automations

### Choosing an event source

The right way to send events depends on what tools you already have deployed.

#### Marketing websites

For marketing websites, blogs, docs sites, and other public-facing pages, the
goal is typically to capture page visits and identify visitors.

| Your situation                              | Recommended approach                                                                                                                                                                             |
| :------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| No existing analytics tool on the site      | **[Unify Website Tag](/developers/intent-client/website-tag)** — Copy and paste a script tag. Fastest way to get started. Automatically captures page visits and basic form fills.               |
| Already using **Segment** on the site       | **[Segment integration](/reference/integrations/segment)** — Forward existing Segment events to Unify. No additional SDK needed.                                                                 |
| Already using **PostHog** on the site       | **[PostHog integration](/reference/integrations/posthog)** — Forward existing PostHog events to Unify. No additional SDK needed.                                                                 |
| Using another tool (e.g., Google Analytics) | **[Unify Website Tag](/developers/intent-client/website-tag)** — GA doesn't forward events to Unify. The Website Tag can run alongside GA without conflicts since they serve different purposes. |

#### Web applications (product usage)

For SaaS products and web applications, the goal is typically to track user
actions (feature usage, paywall hits, milestones) and identify logged-in users.

| Your situation                                                         | Recommended approach                                                                                                                                                                                                                               |
| :--------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Already using **PostHog** in your product                              | **[PostHog integration](/reference/integrations/posthog)** — Reuse your existing PostHog instrumentation. No new SDK needed.                                                                                                                       |
| Already using **Segment** in your product                              | **[Segment integration](/reference/integrations/segment)** — Reuse your existing Segment instrumentation.                                                                                                                                          |
| Using another tool with webhook support (e.g., RudderStack, Amplitude) | **[Analytics API](/developers/api/analytics/overview)** — Configure a webhook destination in your tool pointing to Unify's Analytics API. You'll need to map events to Unify's `track` and `identify` format.                                      |
| Using another tool without webhook support                             | **[JavaScript](/developers/intent-client/js-client) or [React](/developers/intent-client/react) Library** — Install the Unify Intent Client alongside your existing tool for the specific events you want to action on in Unify.                   |
| No analytics tool                                                      | **[JavaScript](/developers/intent-client/js-client) or [React](/developers/intent-client/react) Library** — The Unify Intent Client is the default path for in-product tracking. You get `identify()` and `track()` with direct-to-Unify delivery. |

#### Backend and server-side events

Some events originate from backend systems rather than browsers—for example,
a subscription renewal, a usage limit being hit, or a derived milestone like
"onboarding completed."

| Your situation                            | Recommended approach                                                                                                                                                            |
| :---------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Need to send events from backend services | **[Analytics API](/developers/api/analytics/overview)** — Send `track` and `identify` events directly to Unify from your server. Use a stable identifier like email or user ID. |

<Info>
  Server-side events complement client-side tracking—but they are typically not
  a replacement. Client-side events provide session context, attribution data,
  and browser-based identity. Server-side events cover backend-only actions and
  provide resilience against ad blockers.
</Info>

### Quick reference: event ingestion methods

| Method                                                    | Best for                                                | Requires code changes? |
| :-------------------------------------------------------- | :------------------------------------------------------ | :--------------------- |
| [Website Tag](/developers/intent-client/website-tag)      | Marketing websites with no existing analytics           | No—copy and paste      |
| [React Library](/developers/intent-client/react)          | React web applications                                  | Yes                    |
| [JavaScript Library](/developers/intent-client/js-client) | Non-React web applications                              | Yes                    |
| [Segment integration](/reference/integrations/segment)    | Teams already using Segment                             | No—configuration only  |
| [PostHog integration](/reference/integrations/posthog)    | Teams already using PostHog                             | No—configuration only  |
| [Analytics API](/developers/api/analytics/overview)       | Server-side events, unsupported tools, custom pipelines | Yes                    |

## Syncing records

Records are the structured, persistent data that populates [objects](/reference/objects/overview)
in Unify. While events capture what's happening right now, records represent
what Unify knows—companies, people, CRM data, product users, subscriptions, and
more.

### Example use cases

* You want to sync CRM data from Salesforce or HubSpot
* You have product usage data modeled in a data warehouse (e.g., a `users`
  table in BigQuery or Snowflake)
* You want to bring in business data like subscriptions, contracts, or usage
  tiers
* You have enrichment data from a third-party tool

### Choosing a sync method

| Your situation                                                                  | Recommended approach                                                                                                                                                                                                            |
| :------------------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Data lives in a **CRM** (Salesforce, HubSpot)                                   | **[Salesforce](/reference/integrations/salesforce)** or **[HubSpot](/reference/integrations/hubspot) native integrations** — These keep your CRM data in sync with Unify objects automatically.                                 |
| Data lives in a **warehouse** (Snowflake, BigQuery, ClickHouse, Redshift, etc.) | **[Hightouch](/developers/guides/data-systems/hightouch-destination)** or **[Fivetran](/developers/guides/data-systems/fivetran-destination)** — Reverse ETL tools that sync warehouse tables into Unify objects on a schedule. |
| Data lives in a **database** (PostgreSQL, MySQL, MongoDB, etc.)                 | **[Hightouch](/developers/guides/data-systems/hightouch-destination)** or **[Fivetran](/developers/guides/data-systems/fivetran-destination)** — Both support databases as sources in addition to warehouses.                   |
| Data comes from **internal APIs or custom pipelines**                           | **[Data API](/developers/api/data/overview)** — Programmatically create objects, define attributes, and push records.                                                                                                           |
| Data comes from a **third-party tool** (e.g., Clay)                             | **[Data API](/developers/api/data/overview)** — Use webhooks or scripts to push data from external tools into Unify objects.                                                                                                    |

<Tip>
  **Model your data as objects.** Rather than adding lots of custom attributes
  directly to the Company or Person objects, create dedicated custom objects
  (e.g., **Product User**) and link them to Person or Company with reference
  attributes. This keeps your data organized and makes it easy to filter based
  on data source.
</Tip>

For a step-by-step walkthrough, see
[Connect a data system](/developers/guides/data-systems/overview).

## CRM data

If you use Salesforce or HubSpot, Unify has native integrations that sync CRM
data automatically. This is managed through the Unify UI—no developer setup is
required.

<CardGroup>
  <Card title="Salesforce" href="/reference/integrations/salesforce/overview" icon={<SalesforceLogo />}>
    Connect your Salesforce instance.
  </Card>

  <Card title="HubSpot" href="/reference/integrations/hubspot/overview" icon={<HubspotLogo />}>
    Connect your HubSpot CRM.
  </Card>
</CardGroup>

When you connect a CRM, Unify creates objects (like **Salesforce Account** or
**HubSpot Contact**) that are linked to the Company and Person objects. CRM data
flows bidirectionally and stays in sync.

## Combining data sources

Many teams use multiple data sources together. For example:

* **Website Tag** on the marketing site for anonymous visitor identification
* **PostHog integration** in the product for usage events
* **Hightouch** to sync product user records from the data warehouse
* **Salesforce integration** to keep CRM data in sync

Events and records complement each other. Events provide real-time behavioral
signals. Records provide structured context. Together, they give Unify the full
picture it needs to power targeted, timely go-to-market actions.

## Next steps

<CardGroup>
  <Card title="Connect website traffic" href="/developers/guides/website-traffic/introduction" icon="browser">
    Get started with marketing website tracking.
  </Card>

  <Card title="Connect product usage data" href="/developers/guides/product-usage-data/introduction" icon="computer-mouse-button-left">
    Track in-app user behavior and product signals.
  </Card>

  <Card title="Connect a data system" href="/developers/guides/data-systems/overview" icon="database">
    Sync structured data from warehouses and databases.
  </Card>

  <Card title="Send records via API" href="/developers/guides/send-data/overview" icon="code">
    Push data programmatically from custom pipelines.
  </Card>
</CardGroup>


# Sync data from Fivetran
Source: https://docs.unifygtm.com/developers/guides/data-systems/fivetran-destination

Learn how to connect upstream data sources to Unify via Fivetran.

## Overview

<Note>
  This guide assumes that you already have a Fivetran account. If you don't, you
  can sign up for a free plan [here](https://www.fivetran.com/).
</Note>

Unify provides a Fivetran destination which allows you to sync data from any
Fivetran data source into Unify objects. Fivetran supports a range of data
sources, including data warehouses, databases, and more.

## Connect Fivetran to Unify

<Steps>
  <Step title="Select the Unify destination type">
    Within Fivetran, navigate to **Destinations** and select **Add a destination**.

    <Frame>
      <img />
    </Frame>

    Look for the **Unify** destination type and select it.

    <Frame>
      <img />
    </Frame>
  </Step>

  <Step title="Configure the destination">
    Fill in a name for your destination and provide an API key. You can generate
    an API key within Unify by navigating to [Settings → API
    Keys](https://app.unifygtm.com/dashboard/settings/integrations/api-keys).

    <Frame>
      <img />
    </Frame>
  </Step>

  <Step title="Save the destination">
    Wait for the test to complete and then choose **Finish** to save the new
    destination.

    <Frame>
      <img />
    </Frame>

    Once saved, you will see this destination listed in the **Destinations** tab.

    <Frame>
      <img />
    </Frame>
  </Step>
</Steps>

## Sync to an object

<Steps>
  <Step title="Create a new sync">
    Within Fivetran, navigate to **Syncs** and select **Create a sync**.

    <Frame>
      <img />
    </Frame>
  </Step>

  <Step title="Select a data source">
    Select the data source you want to sync from. This can be a table in a data
    warehouse, database, or any other supported data source.

    <Frame>
      <img />
    </Frame>
  </Step>

  <Step title="Select the Unify destination">
    Select the Unify destination you created previously.

    <Frame>
      <img />
    </Frame>
  </Step>

  <Step title="Determine the sync behavior">
    Choose the sync behavior. You can choose to either **Insert** or **Upsert**
    records into Unify. Inserting records will only add new records, while
    upserting will sync changes to existing records as well.

    <Frame>
      <img />
    </Frame>
  </Step>

  <Step title="Select the sync key">
    Choose which unique key to use for the sync. This is the key that will be
    used to identify records in Unify to avoid creating duplicates and to update
    existing records (if applicable).

    <Frame>
      <img />
    </Frame>
  </Step>

  <Step title="Map fields from source to object">
    Fill in the mapping between the fields in your data source and the
    attributes on the Unify object. This is how you tell Fivetran which fields
    in your data source should be synced to which attributes in Unify.

    <Frame>
      <img />
    </Frame>

    In Unify, each object attribute has a value type which determines what kind
    of data it can hold. For example, **Text** attributes can hold any string
    value, while **Integer** and **Decimal** attributes can only hold numbers.
    You will only be able to map fields from your data source to attributes in
    Unify that support an equivalent value type.

    <Tip>
      One special value type is the **Reference** type, which is used to link to
      other objects. When mapping fields in Fivetran, you will see the unique
      attributes for each object that is referenced by the object you are
      syncing to.

      This allows you to link records in this object to other objects based on
      the data available in your data source, which is important in order to use
      the data in Unify. A common example is linking rows in a data warehouse
      table to company or person records in Unify so that they can be used for
      pesonalization or segmentation.
    </Tip>
  </Step>

  <Step title="Test sync">
    Click **Run test** to send a single record from your data source to the
    object in Unify.

    <Frame>
      <img />
    </Frame>
  </Step>

  <Step title="Confirm sync">
    Choose **Next** and verify the sync configuration. You can also choose to
    run the sync manually, on a trigger, or on a schedule.

    <Frame>
      <img />
    </Frame>

    Once you are happy with the configuration, choose **Create** to save the
    sync. You will then be able to see it in the **Syncs** tab.

    <Frame>
      <img />
    </Frame>
  </Step>
</Steps>


# Sync data from Hightouch
Source: https://docs.unifygtm.com/developers/guides/data-systems/hightouch-destination

Learn how to connect upstream data sources to Unify via Hightouch.

## Overview

<Note>
  This guide assumes that you already have a Hightouch account. If you don't,
  you can sign up for a demo [here](https://hightouch.com/demo).
</Note>

Hightouch provides a destination which allows you to sync data from any
Hightouch-supported data source into Unify objects. Hightouch supports a range
of data sources, including data warehouses, databases, and more.

## Connect Hightouch to Unify

<Steps>
  <Step title="Select the Unify destination type">
    Within Hightouch, navigate to **Destinations** and select **Add destination**.
    Look for the **Unify** destination type and select it.

    <Frame>
      <img />
    </Frame>
  </Step>

  <Step title="Configure the destination">
    Provide an API key for your destination. You can generate an API key within
    Unify by navigating to [Settings → Developers](https://app.unifygtm.com/dashboard/settings/integrations/api-keys).

    You can verify that the API key is valid and working by selecting **Test connection**.
    You should see a message that says "Successfully connected to Unify".

    <Frame>
      <img />
    </Frame>

    Next, configure any alerts you want to receive for this destination.

    <Frame>
      <img />
    </Frame>

    Lastly, choose a name for your destination, set the desired permissions,
    and select **Finish** to save the destination.

    <Frame>
      <img />
    </Frame>
  </Step>

  <Step title="Save the destination">
    Once saved, you will see this destination listed in the **Destinations** tab.

    <Frame>
      <img />
    </Frame>

    You can modify the destination settings and test the connection again from
    here.
  </Step>
</Steps>

## Sync to an object

<Steps>
  <Step title="Create a new sync">
    From the destination or syncs page, select **Add sync**. The first step is
    to select a *model* which represents the data source you want to send into
    Unify. If you haven't configured one yet, head over to **Models** and
    create one.

    <Frame>
      <img />
    </Frame>
  </Step>

  <Step title="Configure sync options">
    Select the Unify destination you created previously. Choose "Records" for
    the first option and then select the Unify object you want to sync records
    to. You can select a "standard" object (e.g., Companies or People) or a
    custom object.

    <Frame>
      <img />
    </Frame>

    Once the object is selected, choose whether you want to "upsert" records
    (create and update) or "insert" records (create only).

    <Frame>
      <img />
    </Frame>
  </Step>

  <Step title="Select the sync key">
    Choose which unique key to use for the sync. This is the key that will be
    used to identify records in Unify to avoid creating duplicates and to update
    existing records (if applicable).

    <Frame>
      <img />
    </Frame>

    This must be a unique attribute on the Unify object and in the data source.
    For example, the unique attribute on Companies is `domain`, and the unique
    attribute on People is `email`. On custom objects, you can define your own
    unique attributes.
  </Step>

  <Step title="Map fields">
    The next step is to map fields in your data source to Unify object
    attributes. This defines how record values will be copied over to Unify.

    <Frame>
      <img />
    </Frame>

    Unify objects support *reference* attributes which represent relationships
    between objects. For example, the Person object has a reference attribute
    for the Company that the person works at.

    In the above example, we are mapping our data source to the Person object,
    and we are also linking each person to a Company by mapping Company fields.
  </Step>

  <Step title="Finalize settings">
    Finally, choose how you want to run the sync and then select **Finish**.

    <Frame>
      <img />
    </Frame>
  </Step>
</Steps>

## Inspect the sync

<Steps>
  <Step title="Verify running">
    On the sync page, you can see the newly created sync, trigger a run, and
    inspect results.

    <Frame>
      <img />
    </Frame>
  </Step>

  <Step title="View results">
    Click on a sync run to view the successfully synced records and any errors
    that were encountered.

    <Frame>
      <img />
    </Frame>

    Select the **Successful** tab to view synced records.

    <Frame>
      <img />
    </Frame>

    You should then see the created records in Unify!

    <Frame>
      <img />
    </Frame>
  </Step>
</Steps>


# Connect data systems to Unify
Source: https://docs.unifygtm.com/developers/guides/data-systems/overview

Sync databases, data warehouses, data lakes, and more into Unify.

## Overview

Unify is built to support custom data models and huge volumes of data. If you
have data that lives in an external data system, you can send it over and use it
to power anything within Unify. Examples of data systems you can connect to
Unify include:

* **Data warehouses** — Snowflake, BigQuery, ClickHouse, Redshift, etc.
* **Databases** — PostgreSQL, MySQL, MongoDB, etc.
* **Data lakes** — S3, Databricks, etc.

Data within Unify is stored in *objects*. Objects are the building blocks that
allow you to store and interact with records in Unify. Every object has a set of
*attributes* which represent the fields that make up the object. You can send
external data into objects in Unify.

Unify provides a set of standard objects, such as Company and Person, that are
used throughout the platform. You can also create custom objects to store data
from external sources or represent information that doesn't fit into standard
objects.

## Modeling data

You can insert data directly into the standard Company and Person objects.
However, this loses track of where the data came from. It can also lead to lots
of custom attributes being created on those standard objects over time, many of
which are not applicable for most records.

Instead, Unify recommends defining custom objects to represent external data
sources. You can create a custom object which aligns with the data source and
then create a reference attribute to link it to the standard objects.

<Callout icon="lightbulb">
  **Example**

  Suppose you have a table of product users in your data warehouse. One thing
  you could do is insert them directly into the Person object in Unify:

  <Danger>
    **Avoid**: Directly inserting external data sources into standard objects.

    ```mermaid theme={null}
      flowchart LR
        subgraph data_warehouse["Data Warehouse"]
          external_product_user["Product Users Table"]
        end

        subgraph unify["Unify"]
          person["Person"]
        end

        external_product_user -->|Insert| person
    ```
  </Danger>

  However, a better strategy is to create a new object in Unify called "Product
  User" and connect it to the Person object using a reference attribute. Then,
  insert the product user records into that object instead:

  <Check>
    **Prefer**: Inserting external data sources into custom objects linked to
    standard objects.

    ```mermaid theme={null}
    flowchart LR
      subgraph data_warehouse["Data Warehouse"]
        external_product_user["Product Users Table"]
      end

      subgraph unify["Unify"]
        unify_product_user["Product User"] -->|Reference| person["Person"]
      end

      external_product_user -->|Insert| unify_product_user
    ```
  </Check>

  This is how Unify builds its integrations into Salesforce, HubSpot, and more.
</Callout>

This has several benefits. It allows you to connect many data sources to Unify
without adding many custom attributes to the standard objects. It also makes it
easy to filter data based on whether it came from a specific source or not.

## Getting started

<Steps>
  <Step title="Define objects and attributes">
    The first step is to define the objects and attributes that will store your
    data. This is how you declare the format of the data and how it relates to
    other objects.

    <CardGroup>
      <Card title="Manage via API" href="/developers/api/data/overview">
        Create and manage objects, attributes, and records in Unify via API.
      </Card>

      <Card title="Manage via UI" href="/reference/objects/overview">
        Create and manage objects, attributes, and records within the Unify app.
      </Card>
    </CardGroup>

    Once the objects are created, you can create, update, and delete records using
    the API. They will also become available in any tools that connect to Unify,
    such as the Hightouch and Fivetran destinations for Unify.
  </Step>

  <Step title="Sync data into Unify">
    Once the objects are created, you can sync data into Unify using the API
    directly or via a supported integration.

    <CardGroup>
      <Card title="Connect via Hightouch" href="/developers/guides/data-systems/hightouch-destination">
        Sync object records from Hightouch data sources into Unify.
      </Card>

      <Card title="Connect via Fivetran" href="/developers/guides/data-systems/fivetran-destination">
        Sync object records from Fivetran data sources into Unify.
      </Card>

      <Card title="Sync directly via API" href="/developers/api/data/overview">
        Create, update, and link object records using the Unify API and SDKs.
      </Card>
    </CardGroup>
  </Step>
</Steps>


# Connect product usage data to Unify
Source: https://docs.unifygtm.com/developers/guides/product-usage-data/introduction

Send web application and software usage data into Unify.

<Tip>
  This guide is focused on web applications and software where the goal is to
  track usage and interactions of identifiable users. If you are looking to send
  events from marketing or other public-facing website, [Connect website traffic to Unify](/developers/guides/website-traffic/introduction)
  may be more relevant.
</Tip>

## Overview

One of the most powerful strategies in Unify is to identify existing customers
and users to reach out to based on their product usage and behavior. By sending
product usage data into Unify, you can instantly launch Plays to start taking
action on these users.

Some examples of the ways this data can be used include:

* **Free plan conversions** — Identify free plan users who are actively using
  key features and send them targeted upgrade campaigns.
* **Upsells and cross-sells** — Identify existing customers who are using
  specific features and send them relevant upsell or cross-sell offers.
* **Enterprise expansion** — Identify individual users at companies, reach out
  to other contacts at those companies, and target them with enterprise offers.

Unify provides a full suite of [analytics APIs](/developers/api/analytics/overview)
for tracking user interactions and identities. All event tracking capabilities
integrate natively with the rest of the Unify data layer. This makes it easy to
link product usage data to companies or people and access that data throughout
Unify.

## Setup

Unify provides an SDK called the [Unify Intent Client](/developers/intent-client/overview)
that can be installed in your web application to start sending events. This is
the easiest and recommended way to get started.

<Card
  title="Unify Intent Client (Recommended)"
  icon={
<>
  <UnifyLogoDark />
  <UnifyLogoLight />
</>
}
  href="/developers/guides/product-usage-data/unify-intent-client"
>
  Send events using the Unify's native JavaScript or React client.
</Card>

If you're already collecting events using a third-party tool, you can also send
that data into Unify using either a supported integration or the general-purpose
[Analytics API](/developers/api/analytics/overview). You can find guides for
some popular tools below.

<CardGroup>
  <Card title="Segment" icon={<SegmentIcon />} href="/reference/integrations/segment">
    Send Segment events into Unify.
  </Card>

  <Card
    title="Posthog"
    icon={
  <>
    <PosthogLogoDark />
    <PosthogLogoLight />
  </>
}
    href="/reference/integrations/posthog"
  >
    Send Posthog events into Unify.
  </Card>
</CardGroup>

Lastly, if you already collect product usage data in a database, data warehouse,
or data lake, you can connect those systems directly to Unify. For details, see
[Connect data systems to Unify](/developers/guides/data-systems/overview).

<Warning>
  Analytics events (such as page, identify, and custom events) cannot currently
  be sent into Unify via reverse ETL tools like [Hightouch](https://hightouch.com/)
  or [Fivetran](https://www.fivetran.com/). This capability is coming soon.

  In the meantime, the recommended solution is to send data to the [Analytics API](/developers/api/analytics/overview)
  directly or via one of the supported integrations listed above. Alternatively,
  you can create [custom objects](/developers/guides/data-systems/overview) to
  represent these events and send them via reverse ETL.
</Warning>

## Examples

Once you've configured events to be sent into Unify, you can start using that
data to launch Plays based on user intent. See the following guides for
examples.

<CardGroup>
  <Card title="Capture user logins" icon="link" href="/developers/guides/product-usage-data/user-logins">
    Identify users when they sign in to your application.
  </Card>

  <Card title="Capture user interactions" icon="link" href="/developers/guides/product-usage-data/user-interactions">
    Track in‑app user activity with the Unify Intent client.
  </Card>
</CardGroup>


# Set up the Unify Intent client
Source: https://docs.unifygtm.com/developers/guides/product-usage-data/unify-intent-client

Send product usage and events directly into Unify with the native SDK.

## Installation

There are multiple ways to install the Unify Intent client depending on your
setup. When installing the client into the web application for your product,
using either the JavaScript client or the React client is recommended.

<CardGroup>
  <Card title="React library" href="/developers/intent-client/react" icon="react">
    Install the client in your React web application for a more native
    integration.
  </Card>

  <Card title="JavaScript library" href="/developers/intent-client/js-client" icon="node-js">
    Install the client in your non-React frontend application, such as a Single
    Page App (SPA).
  </Card>
</CardGroup>

<Note>
  You should only use one installation method per website or application. If the
  client is installed twice on the same site, it may not work correctly.
</Note>

## Usage

<Tabs>
  <Tab title="React library" icon="react">
    ### Automatic events

    By default, the React library will not automatically collect any events. You
    can enable automatic event collection when initializing the client. See the
    full [Usage guide](/developers/intent-client/usage-guide) for more details.

    ### Manual events

    You can manually trigger events in specific places in your web application
    by calling the client directly.

    #### Page events

    Page events record a page visit. Typically, the easiest strategy is to
    enable automatic collection of page visits, but you can also call them
    manually.

    ```javascript theme={null}
    // Enable automatic "page" event collection
    unify.startAutoPage();

    // Send a "page" event
    unify.page();
    ```

    #### Custom events

    Custom events record specific actions taken by a visitor, such as button
    clicks or form fills. You can send custom events with arbitrary
    properties anywhere in your React application.

    ```javascript theme={null}
    // Send a basic custom event
    unify.track("See More Button Clicked");

    // Send a custom event with additional properties
    unify.track("Modal Opened", {
      modalName: "Contact Sales Modal"
    });
    ```

    #### Identify events

    Identify events link a visitor to a specific company or person. You can send
    identify events whenever you have information about a visitor, such as their
    name or email address.

    ```javascript theme={null}
    // Send a basic "identify" event
    unify.identify("user@email.com");

    // Send an "identify" event with additional company or person attributes
    unify.identify("first.last@acme.com", {
      person: {
        email: "first.last@acme.com",
        first_name: "First",
        last_name: "Last",
      },
      company: {
        domain: "acme.com",
        name: "Acme Corp.",
      }
    });
    ```
  </Tab>

  <Tab title="JavaScript library" icon="node-js">
    ### Automatic events

    By default, the JavaScript library will not automatically collect any
    events. You can enable automatic event collection when initializing the
    client. See the full [Usage guide](/developers/intent-client/usage-guide)
    for more details.

    ### Manual events

    You can manually trigger events in specific places in your web application
    by calling the client directly.

    #### Page events

    Page events record a page visit. Typically, the easiest strategy is to
    enable automatic collection of page visits, but you can also call them
    manually.

    ```javascript theme={null}
    // Enable automatic "page" event collection
    unify.startAutoPage();

    // Send a "page" event
    unify.page();
    ```

    #### Custom events

    Custom events record specific actions taken by a visitor, such as button
    clicks or form fills. You can send custom events with arbitrary
    properties anywhere in your web application.

    ```javascript theme={null}
    // Send a basic custom event
    unify.track("See More Button Clicked");

    // Send a custom event with additional properties
    unify.track("Modal Opened", {
      modalName: "Contact Sales Modal"
    });
    ```

    #### Identify events

    Identify events link a visitor to a specific company or person. You can send
    identify events whenever you have information about a visitor, such as their
    name or email address.

    ```javascript theme={null}
    // Send a basic "identify" event
    unify.identify("user@email.com");

    // Send an "identify" event with additional company or person attributes
    unify.identify("first.last@acme.com", {
      person: {
        email: "first.last@acme.com",
        first_name: "First",
        last_name: "Last",
      },
      company: {
        domain: "acme.com",
        name: "Acme Corp.",
      }
    });
    ```
  </Tab>
</Tabs>

For complete instructions, see the [Usage guide](/developers/intent-client/usage-guide).


# Capture user interactions
Source: https://docs.unifygtm.com/developers/guides/product-usage-data/user-interactions

Track in‑app user activity with the Unify Intent client.

## Overview

User interactions can be used to powerful Plays that drive activation, upgrades,
expansion, and more. By tracking key in‑app events, you can identify and engage
with users based on their actual product usage and behavior.

Some examples of interaction‑based Plays include:

* **Activation Plays** — Target users who clicked on or started using key
  features but haven't yet completed the activation criteria.
* **Upsell Plays** — Reach out to users who encountered paywalls or usage limits
  to offer assistance or upgrade options.
* **Expansion Plays** — Identify users who are actively using specific features
  and target them with relevant cross-sell or upsell offers.

There is no limit to the number or types of interactions you can track. All the
activities you track can be linked to Company, Person, and other object records
in Unify. This gives a complete view of user behavior within the context of your
business.

## Prerequisites

* Ensure you've already installed the Unify Intent client in your application.
  See [Set up the Unify Intent client](#setup) for instructions.

* Ensure your users are being identified when they log in. See
  [Capture user logins](/developers/guides/product-usage-data/user-logins)
  for a walkthrough.

## Examples

Custom events can be used to capture any type of user interaction within your
application. Below are some examples of common use cases and patterns for
recording user activity.

### Feature button clicked

When a user clicks a button to open or use a feature:

```ts theme={null}
unify.track('Created a Widget', {
  feature: 'widget-builder',
  type: 'gizmo',
  number_created: 4,
});
```

### Paywall encountered

When a user hits a paywall or usage limit:

```ts theme={null}
unify.track('Widget Limit Reached', {
  feature: 'widget-builder',
  reason: 'plan_limit',
  current_plan: 'Free Tier',
  limit_reached: 10,
  number_requested: 20,
});
```

If you present upgrade options, also track the click:

```ts theme={null}
unify.track('Upgrade CTA Clicked', {
  destination: 'billing',
  source: 'widget_paywall',
  plan_selected: 'Pro',
});
```

### User added

When a user invites another user to their account:

```ts theme={null}
unify.track('User Invited', {
  added_user_email: 'bob@acme.com',
  role: 'Editor',
});
```


# Capture user logins
Source: https://docs.unifygtm.com/developers/guides/product-usage-data/user-logins

Identify users when they sign in to your application.

## Overview

All the activity you track in your application is associated with a *visitor*
who may or may not have a known identity. When a user signs in, you can send an
Identify event. This associate all their past and future activity with a known
Person (and optionally a Company) in Unify.

## Prerequisites

* Ensure you've already installed the Unify Intent client in your application.
  See [Set up the Unify Intent client](#setup) for instructions.

## Walkthrough

### Identify on login

Call `identify` as soon as the user is authenticated. Include useful traits for
the person and (optionally) the company they belong to.

```ts theme={null}
// Determine the current user however you normally do so
const currentUser = getCurrentUser();

// Send an "Identify" event
unify.identify(currentUser.emailAddress, {
  // Link this visitor to a Person
  person: {
    email: currentUser.emailAddress,
    first_name: currentUser.firstName,
    last_name: currentUser.lastName,
  },

  // If possible, link this visitor to a Company as well
  company: currentUser.organization
    ? {
        domain: currentUser.organization.domain,
        name: currentUser.organization.name,
      }
    : undefined,
});
```

### Send custom event (optional)

You may also want to track that the user logged in. Identify events link
visitors to people or companies, but they don't record an activity that can be
seen or used in Unify. If you want to see when users login or filter Plays based
on login activity, you should also send a custom event.

```ts theme={null}
unify.track('User Logged In');
```

As with all custom events, you can also include additional properties to provide
more context about the login.

## Capture interactions

Now that visitors to your application are identified, you can start tracking key
in-app interactions to power Plays. For more information, see [Capture user interactions](/developers/guides/product-usage-data/user-interactions).


# Request data with the Bulk API
Source: https://docs.unifygtm.com/developers/guides/request-data/bulk-api

Use the Bulk API to export large datasets from Unify.

## Overview

Use the Bulk API to request large datasets from Unify without waiting
for a long-running HTTP request to finish. The Bulk API is asynchronous: you
create a query job, poll the job until it is finished, and then page through the
materialized results.

Use the Bulk API when you need to export or sync many records. For small operational reads, use the standard API for
the resource instead.

<Info>
  The Bulk API is for requesting data from Unify. To create or update records in
  Unify, see [Send records via API](/developers/guides/send-data/overview).
</Info>

## Supported resources

The Bulk API currently supports these resources:

| Resource                  | Create a query job                               | Fetch results                                                    |
| :------------------------ | :----------------------------------------------- | :--------------------------------------------------------------- |
| Object records            | `POST /data/v1/objects/{object_name}/query-jobs` | `GET /data/v1/objects/{object_name}/query-jobs/{job_id}/results` |
| Events                    | `POST /data/v1/events/query-jobs`                | `GET /data/v1/events/query-jobs/{job_id}/results`                |
| Sequence enrollments      | `POST /sequences/v1/enrollments/query-jobs`      | `GET /sequences/v1/enrollments/query-jobs/{job_id}/results`      |
| Sequence enrollment steps | `POST /sequences/v1/enrollment-steps/query-jobs` | `GET /sequences/v1/enrollment-steps/query-jobs/{job_id}/results` |
| Tasks                     | `POST /tasks/v1/tasks/query-jobs`                | `GET /tasks/v1/tasks/query-jobs/{job_id}/results`                |

For `object_name`, use a [standard object](/developers/api/data/standard-objects)
such as `company` or `person`, or the API name of a custom object.

<Note>
  Task support in the Bulk API is part of the [Tasks
  API](/developers/api/tasks/overview) public beta and may change based on
  feedback.
</Note>

Each resource exposes the same set of job-management endpoints under its
`query-jobs` path:

```http theme={null}
POST   {base}/query-jobs                      Create a query job
GET    {base}/query-jobs                       List query jobs
GET    {base}/query-jobs/{job_id}              Get a single job
POST   {base}/query-jobs/{job_id}/cancel       Cancel an in-progress job
GET    {base}/query-jobs/{job_id}/results      Fetch results
```

The `{base}` for each resource is:

| Resource                  | Base path                        |
| :------------------------ | :------------------------------- |
| Object records            | `/data/v1/objects/{object_name}` |
| Events                    | `/data/v1/events`                |
| Sequence enrollments      | `/sequences/v1/enrollments`      |
| Sequence enrollment steps | `/sequences/v1/enrollment-steps` |
| Tasks                     | `/tasks/v1/tasks`                |

## Authentication

The Bulk API requires a user-backed API key. Generate an API key in
[Settings → Developers](https://app.unifygtm.com/dashboard/settings/integrations/api-keys)
and include it with each request:

```http theme={null}
X-Api-Key: <YOUR_API_KEY>
```

All examples use the main Unify API base URL:

```text theme={null}
https://api.unifygtm.com
```

## How the Bulk API works

<Steps>
  <Step title="Create a query job">
    Submit a query job for the resource you want to export. For sequences and
    events the request body is optional and defaults to an empty filter. For
    object records, a `query` with a `select` is required.

    ```bash theme={null}
    curl -X POST 'https://api.unifygtm.com/sequences/v1/enrollments/query-jobs' \
      -H 'X-Api-Key: ${UNIFY_API_KEY}' \
      -H 'Content-Type: application/json'
    ```

    The response includes the `job_id`, current `status`, and `expires_at` time:

    ```json theme={null}
    {
      "job_id": "<string>",
      "status": "IN_PROGRESS",
      "expires_at": "2026-05-13T12:00:00Z"
    }
    ```
  </Step>

  <Step title="Poll job metadata">
    Poll the job metadata endpoint until the job reaches a terminal status.
    Avoid tight polling loops; use a steady interval or exponential backoff. Most
    jobs finish within a few seconds.

    ```bash theme={null}
    curl 'https://api.unifygtm.com/sequences/v1/enrollments/query-jobs/<job_id>' \
      -H 'X-Api-Key: ${UNIFY_API_KEY}'
    ```

    A finished job includes `total_rows`:

    ```json theme={null}
    {
      "job_id": "<string>",
      "status": "FINISHED",
      "total_rows": 123,
      "error_code": null,
      "created_at": "2026-05-12T12:00:00Z",
      "expires_at": "2026-05-13T12:00:00Z",
      "canceled_at": null
    }
    ```
  </Step>

  <Step title="Fetch results">
    After the job status is `FINISHED`, fetch results by page. Results are
    immutable for a finished job, so each page is stable for that job.

    ```bash theme={null}
    curl 'https://api.unifygtm.com/sequences/v1/enrollments/query-jobs/<job_id>/results?page=1&page_size=1000' \
      -H 'X-Api-Key: ${UNIFY_API_KEY}' \
      -H 'Accept: application/json'
    ```

    ```json theme={null}
    {
      "total": 123,
      "page": 1,
      "page_size": 1000,
      "data": [
        {
          "id": "<string>",
          "updated_at": "2026-05-12T11:58:00Z"
        }
      ]
    }
    ```
  </Step>

  <Step title="Store a checkpoint">
    For recurring syncs, store a checkpoint such as the newest `updated_at`
    (or, for events, `timestamp`) value you processed. Use that checkpoint in the
    next query job so you only request new or changed records.
  </Step>
</Steps>

## Create a query job

Create-job endpoints are resource-specific:

```http theme={null}
POST /data/v1/objects/{object_name}/query-jobs
POST /data/v1/events/query-jobs
POST /sequences/v1/enrollments/query-jobs
POST /sequences/v1/enrollment-steps/query-jobs
POST /tasks/v1/tasks/query-jobs
```

The request body depends on the resource:

* **Events, sequences, and tasks** take an optional `filter` object that narrows
  the dataset.
* **Object records** take a required `query` object that selects which
  attributes to return and, optionally, filters and sorts the records.

### Filter tasks, sequences, and events

For tasks, sequences, and events, omit the body to export everything, or pass a
`filter` to narrow the dataset. For example, scope a request to exclude a
specific set of IDs:

```json theme={null}
{
  "filter": {
    "id": { "not_in": ["<string>", "<string>"] }
  }
}
```

### Query object records

Object record jobs take a `query` with a required `select` that lists the
attributes to return. Use `where` to filter by attribute value, `sort_by` to
order results, and `metadata` to filter by base record timestamps:

```json theme={null}
{
  "query": {
    "select": {
      "name": true,
      "domain": true,
      "record_owner": {
        "select": { "email": true }
      }
    },
    "where": {
      "status": { "equals": "active" }
    },
    "sort_by": { "field": "updated_at", "direction": "ASCENDING" },
    "metadata": {
      "updated_at": { "gte": "2026-05-01T00:00:00Z" }
    }
  }
}
```

* `select` — Required. Each key is an attribute API name on the queried object.
  Use `true` to return the attribute directly, or `{ "select": ... }` to expand a
  single-reference attribute and select attributes on the referenced object.
  Nested selects may be at most three levels deep. Selected attributes are
  sparse: a result row only includes keys for selected attributes that have a
  value, so attributes with no value are omitted rather than returned as `null`.
* `where` — Filter by one or more attribute conditions. `{ "equals": ... }`
  matches an attribute directly; a nested object filters through a
  single-reference attribute on the referenced object.
* `sort_by` — Sort by a base record field (`id`, `created_at`, or `updated_at`)
  in `ASCENDING` or `DESCENDING` order.
* `metadata` — Filter by base record timestamps (`created_at` / `updated_at`).
  Pairing a `created_at` / `updated_at` `metadata` filter with the matching
  `sort_by` enables incremental queries that page through every record changed
  since a prior checkpoint.

The `where` and `select` shape mirrors the standard object records API. See
[Standard objects and attributes](/developers/api/data/standard-objects) for the
built-in attributes you can select and filter on.

<Note>
  Timestamps in the object Bulk API are millisecond precision. Both the
  timestamps returned in results and the values you supply to `metadata` and
  `where` filters are interpreted at millisecond precision.
</Note>

## Filter fields

Available filter fields depend on the resource.

### Sequence filters

Sequence enrollment and enrollment-step jobs share a common set of filters:

| Filter                                                                               | Description                                            |
| :----------------------------------------------------------------------------------- | :----------------------------------------------------- |
| `updated_at`                                                                         | Range filter on the time records were last updated.    |
| `started_at`                                                                         | Range filter on when the enrollment or step started.   |
| `ended_at`                                                                           | Range filter on when the enrollment or step ended.     |
| `sequence`                                                                           | Filter by sequence ID.                                 |
| `person`                                                                             | Filter by person ID.                                   |
| `company`                                                                            | Filter by company ID.                                  |
| `mailbox`                                                                            | Filter by mailbox ID or email address.                 |
| `id`                                                                                 | Include (`in`) or exclude (`not_in`) specific row IDs. |
| `is_blocked`, `is_bounced`, `is_canceled`, `is_opted_out`, `is_paused`, `is_replied` | Boolean state filters.                                 |

Enrollment jobs also accept `status` and `enrolled_by_play` (include or exclude
enrollments by the ID of the play that created them). Enrollment-step jobs
additionally accept `status`, `enrollment` (filter by enrollment ID), `type`,
and `step_number`.

Range filters such as `updated_at` accept `gt`, `gte`, `lt`, and `lte` bounds.
`gt` is mutually exclusive with `gte`, and `lt` with `lte`. Set filters such as
`id`, `status`, and `type` accept `in` and/or `not_in` arrays.

### Event filters

Events are immutable, so the natural cursor is `timestamp`, which is also the
only datetime field you can filter on.

| Filter      | Description                                              |
| :---------- | :------------------------------------------------------- |
| `timestamp` | Range filter on when the event occurred.                 |
| `id`        | Include (`in`) or exclude (`not_in`) specific event IDs. |
| `type`      | Filter by event type (`page`, `track`, `identify`).      |
| `visitor`   | Filter by visitor ID.                                    |
| `session`   | Filter by session ID.                                    |
| `company`   | Filter by revealed company ID.                           |
| `person`    | Filter by revealed person ID.                            |
| `domain`    | Filter by the domain on which the event occurred.        |

### Task filters

Task jobs accept the following filters:

| Filter          | Description                                                        |
| :-------------- | :----------------------------------------------------------------- |
| `updated_at`    | Range filter on the time tasks were last updated.                  |
| `created_at`    | Range filter on when the task was created.                         |
| `due_at`        | Range filter on the task due date.                                 |
| `ended_at`      | Range filter on when the task was completed, skipped, or canceled. |
| `id`            | Include (`in`) or exclude (`not_in`) specific task IDs.            |
| `status`        | Filter by task status (`in` / `not_in`).                           |
| `type`          | Filter by task type (`in` / `not_in`).                             |
| `priority`      | Filter by task priority (`in` / `not_in`).                         |
| `assigned_user` | Filter by assigned user ID.                                        |
| `person`        | Filter by person ID.                                               |
| `company`       | Filter by company ID.                                              |

Range filters accept `gt`, `gte`, `lt`, and `lte` bounds; `gt` is mutually
exclusive with `gte`, and `lt` with `lte`. Set filters such as `id`, `status`,
`type`, and `priority` accept `in` and/or `not_in` arrays. The `assigned_user`,
`person`, and `company` filters match a single ID with `{ "id": "<uuid>" }`.

## Job statuses

A job can have one of the following statuses:

| Status        | Meaning                                                        |
| :------------ | :------------------------------------------------------------- |
| `IN_PROGRESS` | The job has been created and results are still being prepared. |
| `FINISHED`    | The job completed successfully and results are available.      |
| `FAILED`      | The job failed. Check `error_code` on the job metadata.        |
| `CANCELED`    | The job was canceled before completion.                        |
| `EXPIRED`     | The job or its results are no longer available.                |

Jobs and results are available until `expires_at`, which is currently 24 hours
after job creation. Download all required result pages before that time.

## List jobs

List jobs for a resource by sending a `GET` to its `query-jobs` path:

```http theme={null}
GET /data/v1/objects/{object_name}/query-jobs
GET /data/v1/events/query-jobs
GET /sequences/v1/enrollments/query-jobs
GET /sequences/v1/enrollment-steps/query-jobs
GET /tasks/v1/tasks/query-jobs
```

Query parameters:

| Parameter | Description                                                    |
| :-------- | :------------------------------------------------------------- |
| `limit`   | Number of jobs to return. Defaults to `100`; maximum is `100`. |
| `cursor`  | Opaque pagination cursor from the previous response.           |
| `status`  | Optional job status filter.                                    |

Example request:

```bash theme={null}
curl 'https://api.unifygtm.com/sequences/v1/enrollments/query-jobs?limit=100&status=FINISHED' \
  -H 'X-Api-Key: ${UNIFY_API_KEY}'
```

Example response:

```json theme={null}
{
  "jobs": [
    {
      "job_id": "<string>",
      "status": "FINISHED",
      "total_rows": 123,
      "error_code": null,
      "created_at": "2026-05-12T12:00:00Z",
      "expires_at": "2026-05-13T12:00:00Z",
      "canceled_at": null
    }
  ],
  "next_cursor": null
}
```

## Cancel a job

Cancel an in-progress job to stop it from being processed:

```bash theme={null}
curl -X POST 'https://api.unifygtm.com/sequences/v1/enrollments/query-jobs/<job_id>/cancel' \
  -H 'X-Api-Key: ${UNIFY_API_KEY}'
```

```json theme={null}
{
  "job_id": "<string>",
  "status": "CANCELED"
}
```

Only in-progress jobs can be canceled. Canceling a job that has already finished,
failed, or been canceled returns `409 Conflict` with `job_not_cancelable`.

## Fetch results

Fetch results for a finished job:

```http theme={null}
GET {base}/query-jobs/{job_id}/results?page=1&page_size=1000
```

Result pagination is page-based. Rows are ordered by a stable sort with a
tie-breaker, so pages remain stable for a finished job.

### JSON results

JSON is the default response format:

```http theme={null}
Accept: application/json
```

JSON limits:

| Limit                    | Value   |
| :----------------------- | :------ |
| Default `page_size`      | `1000`  |
| Maximum `page_size`      | `2000`  |
| Maximum raw payload size | `8 MiB` |

If a JSON page is too large, the request returns `413` with
`results_page_too_large`. Request a smaller `page_size` or use NDJSON.

### NDJSON results

Use NDJSON for larger streamed pages by providing the following
header in your request.

```http theme={null}
Accept: application/x-ndjson
```

Example request:

```bash theme={null}
curl -N 'https://api.unifygtm.com/sequences/v1/enrollments/query-jobs/<job_id>/results?page=1&page_size=10000' \
  -H 'X-Api-Key: ${UNIFY_API_KEY}' \
  -H 'Accept: application/x-ndjson'
```

NDJSON responses return one JSON object per line, streaming one line at a time. Pagination metadata is
returned in response headers instead of a JSON envelope:

```http theme={null}
x-total: 123
x-page: 1
x-page-size: 10000
```

The maximum NDJSON `page_size` is `10000`.

### Result shapes

Each item in `data` (or each NDJSON line) is a result row whose shape depends on
the resource. The examples below are representative — fields may be added before
general availability, so parse defensively and ignore unrecognized keys.

<AccordionGroup>
  <Accordion title="Object records">
    Object record rows use the same `object` / `id` / `attributes` envelope as the
    standard records API. `attributes` contains exactly the attributes named in your
    `select`; expanded single-reference attributes are nested as their own envelope.
    See [Standard objects and attributes](/developers/api/data/standard-objects) for
    the built-in attributes.

    ```json theme={null}
    {
      "object": "company",
      "id": "de885595-2d9a-4fb9-ae30-25ef18b6219b",
      "created_at": "2026-05-12T11:58:00Z",
      "updated_at": "2026-05-12T11:58:00Z",
      "attributes": {
        "name": "Unify",
        "domain": "unifygtm.com",
        "record_owner": {
          "object": "person",
          "id": "6741cc39-b332-45a8-a439-75b69db998b1",
          "attributes": { "email": "owner@unifygtm.com" }
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="Events">
    Events are flat, denormalized rows — they are not wrapped in the
    `object` / `attributes` envelope used by object records. `type` is the
    canonical event type (`page`, `track`, or `identify`). Page context
    (`domain`, `path`, `referrer_domain`, `referrer_path`), the URL `query`, UTM
    parameters, and any custom track-event properties are merged into a single
    `properties` object; `properties` is `null` when none are present.

    The revealed `company` and `person` are embedded as nested object records and
    are `null` when the visitor is unresolved. Unlike a top-level object-records
    `select` (which returns only the attributes you ask for), an embedded record
    carries every standard scalar attribute that has a value. As elsewhere in the
    API, an embedded record's attributes are sparse: attributes with no value are
    omitted rather than returned as `null`. The person's own `company` is a
    `{ "id": ... }` reference rather than an inlined record.

    ```json theme={null}
    {
      "id": "1f3c0e2a-8b6d-4c2e-9f1a-2d4e6f8a0b1c",
      "original_event_id": "evt_abc123",
      "timestamp": "2026-05-12T11:58:00Z",
      "type": "page",
      "name": "Pricing page viewed",
      "properties": {
        "plan": "pro",
        "domain": "unifygtm.com",
        "path": "/pricing",
        "referrer_domain": "google.com",
        "referrer_path": "/",
        "utm_source": "google",
        "utm_medium": "cpc",
        "utm_campaign": "brand"
      },
      "visitor_id": "7a9c0e2a-8b6d-4c2e-9f1a-2d4e6f8a0b1c",
      "anonymous_id": "anon_abc123",
      "user_id": "user_abc123",
      "session_id": "9b2a2761-3cbe-481f-8a1e-b24859c674f8",
      "company": {
        "object": "company",
        "id": "de885595-2d9a-4fb9-ae30-25ef18b6219b",
        "created_at": "2026-05-01T00:00:00Z",
        "updated_at": "2026-05-12T11:58:00Z",
        "attributes": {
          "name": "Unify",
          "domain": "unifygtm.com",
          "employee_count": 120,
          "industry": "Software"
        }
      },
      "person": {
        "object": "person",
        "id": "6741cc39-b332-45a8-a439-75b69db998b1",
        "created_at": "2026-05-01T00:00:00Z",
        "updated_at": "2026-05-12T11:58:00Z",
        "attributes": {
          "email": "lead@example.com",
          "first_name": "Alex",
          "last_name": "Rivera",
          "title": "VP Marketing",
          "company": { "id": "de885595-2d9a-4fb9-ae30-25ef18b6219b" }
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="Sequence enrollments">
    Enrollment rows include status flags and embed the related `sequence`,
    `mailbox`, and `person`. `enrolled_by_play` identifies the play that created
    the enrollment and is `null` for enrollments created manually or via the
    API. `reply_email_message` is `null` until the person replies.

    ```json theme={null}
    {
      "id": "a1b2c3d4-0000-0000-0000-000000000000",
      "updated_at": "2026-05-12T11:58:00Z",
      "status": "FINISHED",
      "is_blocked": false,
      "is_bounced": false,
      "is_canceled": false,
      "is_opted_out": false,
      "is_paused": false,
      "is_replied": true,
      "version": 1,
      "started_at": "2026-05-10T09:00:00Z",
      "ended_at": "2026-05-12T11:58:00Z",
      "sequence": { "id": "seq_123", "name": "Outbound — Q2" },
      "mailbox": {
        "id": "mbx_123",
        "email_address": "rep@unifygtm.com",
        "forward_to_email_address": null,
        "secondary_forward_to_email_address": null,
        "user": {
          "id": "usr_123",
          "email": "rep@unifygtm.com",
          "first_name": "Sam",
          "last_name": "Rep"
        },
        "secondary_forward_to_user": null
      },
      "person": {
        "id": "psn_123",
        "email": "lead@example.com",
        "first_name": "Lee",
        "last_name": "Lead",
        "linkedin_url": null,
        "company": {
          "id": "cmp_123",
          "name": "Example Inc",
          "domain": "example.com",
          "description": null,
          "linkedin_url": null
        }
      },
      "enrolled_by_play": {
        "id": "de885595-2d9a-4fb9-ae30-25ef18b6219b",
        "name": "New signup outreach"
      },
      "reply_email_message": {
        "id": "1f3c0e2a-8b6d-4c2e-9f1a-2d4e6f8a0b1c",
        "subject": "Re: Quick question",
        "classifications": [
          {
            "id": "4a8b6c0d-2e1f-4a3b-8c5d-9e7f1a2b3c4d",
            "category": "POSITIVE"
          }
        ]
      }
    }
    ```
  </Accordion>

  <Accordion title="Sequence enrollment steps">
    Step rows embed a summary of their parent `enrollment` and, for email steps,
    the sent `email_message` with open and click counts. `email_message` is `null`
    for non-email steps.

    ```json theme={null}
    {
      "id": "step_123",
      "updated_at": "2026-05-12T11:58:00Z",
      "type": "AUTOMATIC_EMAIL",
      "status": "FINISHED",
      "is_blocked": false,
      "is_bounced": false,
      "is_canceled": false,
      "is_opted_out": false,
      "is_paused": false,
      "is_replied": false,
      "sequence": { "id": "seq_123", "name": "Outbound — Q2", "version": 1 },
      "step_number": 1,
      "started_at": "2026-05-10T09:00:00Z",
      "ended_at": "2026-05-10T09:00:05Z",
      "enrollment": {
        "id": "a1b2c3d4-0000-0000-0000-000000000000",
        "mailbox": {
          "id": "mbx_123",
          "email_address": "rep@unifygtm.com",
          "forward_to_email_address": null,
          "secondary_forward_to_email_address": null,
          "user": null,
          "secondary_forward_to_user": null
        },
        "person": {
          "id": "psn_123",
          "email": "lead@example.com",
          "first_name": "Lee",
          "last_name": "Lead",
          "linkedin_url": null,
          "company": null
        }
      },
      "email_message": {
        "id": "msg_123",
        "subject": "Quick question",
        "sent_at": "2026-05-10T09:00:05Z",
        "from_email_address": "rep@unifygtm.com",
        "is_bounced": false,
        "is_opted_out": false,
        "clicks": 0,
        "opens": 2
      },
      "reply_email_message": null
    }
    ```
  </Accordion>

  <Accordion title="Tasks">
    Task rows are flat and reference related records by ID rather than embedding
    them. `assigned_user_id`, `due_at`, and `ended_at` are `null` when unset —
    for example, `ended_at` is `null` until the task is completed, skipped, or
    canceled.

    ```json theme={null}
    {
      "id": "b7f1e2c4-0000-0000-0000-000000000000",
      "type": "EMAIL",
      "status": "READY",
      "priority": "HIGH",
      "person_id": "6741cc39-b332-45a8-a439-75b69db998b1",
      "assigned_user_id": "3f2a1b8c-1111-2222-3333-444455556666",
      "due_at": "2026-05-13T12:00:00Z",
      "ended_at": null,
      "created_at": "2026-05-12T11:58:00Z",
      "updated_at": "2026-05-12T11:58:00Z"
    }
    ```
  </Accordion>
</AccordionGroup>

## Job states

The results endpoint validates the job state before returning data:

| Job state      | HTTP status | Error code               |
| :------------- | :---------- | :----------------------- |
| `IN_PROGRESS`  | `409`       | `results_not_ready`      |
| `FAILED`       | `409`       | `results_failed`         |
| `CANCELED`     | `409`       | `results_canceled`       |
| `EXPIRED`      | `410`       | `results_expired`        |
| Page too large | `413`       | `results_page_too_large` |

Only fetch results after the job status is `FINISHED`.

## Rate limiting

Bulk API rate limits are applied by operation type. Query job creation is
limited to roughly **100 jobs per day**, so create jobs only when you need a
new snapshot and use filters or checkpoints to keep each job focused.

| Operation               | Rate limit               |
| :---------------------- | :----------------------- |
| Create query jobs       | \~100 jobs per day       |
| query/list job status   | \~10 requests per second |
| list/stream job results | \~5 requests per second  |
| cancel in flight jobs   | \~1 request per second   |

Treat other job management requests, such as checking job status, listing jobs,
and canceling jobs, as low-frequency control-plane calls. When polling job
status, use a steady interval or exponential backoff instead of a tight loop.
Status checks are intended for roughly 5 requests per second, and most jobs
finish quickly enough that slower polling is usually sufficient.

When fetching results, page through data with bounded concurrency. If you receive
`429 Too Many Requests`, wait before retrying, honor the `Retry-After` header to avoid additional rate limiting.

## Best practices

* **Request only the data you need.** Use filters (and, for object records, a
  focused `select`) to keep result sets small and exports fast.
* **Prefer incremental syncs.** Use checkpoints such as `updated_at` (or
  `timestamp` for events) so recurring jobs only request new or changed records.
* **Design for retries.** Store the `job_id`, job status, and processing
  checkpoint in your system.
* **Process results idempotently.** Use stable record IDs so retrying a page
  does not create duplicate downstream records.
* **Use NDJSON for large pages.** NDJSON streams results and supports larger
  pages than JSON.
* **Download before expiration.** Jobs expire at `expires_at`; create a new job
  if you need the data again after expiration.

## Build your own connector

Want to move bulk data into your own warehouse or tool? Use our example
connectors as a starting point for building integrations on top of the Bulk API.

<Card title="Bulk API connector examples" href="https://github.com/unifygtm/bulk-api-connector-examples" icon="github">
  Reference implementations for building your own connectors on top of the Bulk
  API.
</Card>

## What's next

<CardGroup>
  <Card title="Data API reference" href="/developers/api/data/overview" icon="book">
    Review the Data API for object, attribute, and record operations.
  </Card>

  <Card title="Send records via API" href="/developers/guides/send-data/overview" icon="webhook">
    Learn how to create and update records in Unify.
  </Card>
</CardGroup>


# Send records from Clay sheet
Source: https://docs.unifygtm.com/developers/guides/send-data/clay-webhook

Learn how to send records from a Clay sheet into Unify via webhook.

## Overview

This tutorial walks through the process of sending records from a Clay sheet
into Unify. To do this, we'll set up a webhook in Clay that sends records to the
[Data API](/developers/api/data/overview).

<Tip>
  This guide uses a sheet of companies as an example, but the same approach can
  be used for any object type, such as `person` or a custom object.
</Tip>

## Prerequisites

* An existing Clay sheet that you want to send into Unify
* An existing [API key](https://app.unifygtm.com/dashboard/settings/integrations/api-keys) for Unify

## Steps

<Steps>
  <Step title="Select the webhook action">
    Navigate to your Clay sheet and open the **Actions** pane.

    <Frame>
      <img />
    </Frame>

    Under **Enrichments**, select **View all enrichments** and then choose **HTTP API**.

    <Frame>
      <img />
    </Frame>

    <Frame>
      <img />
    </Frame>
  </Step>

  <Step title="Add credentials">
    Select the **Configure** tab. Under **Select HTTP API (Headers) account**, choose **Add account**.

    <Frame>
      <img />
    </Frame>

    <Note>
      If you have already completed this step in the past, you can simply select
      your existing headers account for Unify.
    </Note>

    Give the new account a name (e.g., "unify-api") and add a header named
    `X-Api-Key` whose value is your Unify API key.

    <Frame>
      <img />
    </Frame>

    Select **Save** to confirm the credentials.
  </Step>

  <Step title="Determine which object to use">
    You can send records into Unify for any standard or custom object using the
    [Data API](/developers/api/data/overview). Before constructing the request,
    decide which object you want to send records into (e.g., company, person, or
    a custom object).

    Once you've picked an object, you will need its API name. The API name can
    be found on the [object settings page](https://app.unifygtm.com/dashboard/settings/integrations/objects).
    For example, the company object's API name is `company`.

    For an overview of how objects work in Unify, see [Objects in Unify](/reference/objects/overview).
  </Step>

  <Step title="Construct the request">
    The best way to send data into Unify is with the [Upsert method](/developers/api/data/records/upsert).
    The URL for this API method is:

    ```http theme={null}
    https://api.unifygtm.com/data/v1/objects/{object_name}/records/upsert
    ```

    <Note>
      You will need to replace `{object_name}` with the API name of the object you
      want to send records into (e.g., `company`, `person`, or a custom object).

      For example, the company object's API name is `company`, so the URL is:

      ```http theme={null}
      https://api.unifygtm.com/data/v1/objects/company/records/upsert
      ```
    </Note>

    Under **Setup Inputs**, fill in a few fields:

    * **Method**: Choose `POST` when performing an upsert. For other operations,
      use the correct method from the API reference.
    * **Endpoint**: Insert the URL of the API constructed above.
    * **Body**: A valid payload for the [Upsert method](/developers/api/data/records/upsert). For example:

      ```json theme={null}
      {
        "match": {
          "domain": "{{Website}}"
        },
        "create_or_update_if_empty": {
          "name": "{{Company Name}}",
          "domain": "{{Website}}",
          "status": "{{Status}}"
        }
      }
      ```

      A person upsert can also include a nested company match or upsert:

      ```json theme={null}
      {
        "match": {
          "email": "{{Email}}"
        },
        "create_or_update_if_empty": {
          "first_name": "{{First Name}}",
          "last_name": "{{Last Name}}",
          "email": "{{Email}}",
          "title": "{{Title}}",
          "company": {
            "match": {
              "domain": "{{Company Domain}}"
            },
            "create_or_update_if_empty": {
              "name": "{{Company Name}}",
              "domain": "{{Company Domain}}"
            }
          }
        }
      }
      ```

      Be sure to replace these placeholders with the actual column names from
      your Clay sheet. Press the slash (`/`) key to select a column when editing
      the body.

      <Warning>
        Don't forget to include quotation marks around the column placeholders!
      </Warning>

    That's it! All of the other settings can be left in their default state or
    modified as needed.

    <Frame>
      <img />
    </Frame>
  </Step>

  <Step title="Test and save">
    Once the action is configured, you can test it by clicking the **Try on 5 rows**
    button. You should see a status code in the range 200-299 if the request was
    successful.

    <Frame>
      <img />
    </Frame>

    Finally, select **Save** and choose whether you want to immediately run the
    action on all rows in the sheet. Once run, you should see successful status
    codes appear in the column.

    <Frame>
      <img />
    </Frame>

    You can click into any cell in the column to see the full response from the
    API. Typically, the Data API will return the full record that was created or
    updated.

    <Frame>
      <img />
    </Frame>

    If you search for that record in Unify, you should see it appear with the
    correct data!
  </Step>
</Steps>

## FAQ

<AccordionGroup>
  <Accordion title="Why am I getting an undefined or 400 status code error response?">
    Here are a few things to try:

    * **Inspect the response**: All error responses should contain details about
      why the request failed. Click into the cell in the sheet to view the full
      response and look for any error messages or details.
    * **Check the object API name**: The URL must use the object's API name,
      such as `company`, `person`, or the custom object API name from settings.
    * **Check the upsert body**: Upsert requests must include `match` and one of
      `create`, `create_or_update`, or `create_or_update_if_empty`.
    * **Check the body formatting**: Ensure that the JSON body correctly matches
      the expected format of the [Data API](/developers/api/data/overview)
      method you are trying to use. Double check that all Clay column variable
      placeholders are inside quotation marks.
    * **Check nested references**: If you are linking a person to a company,
      make sure the nested company value is a valid match, create, or upsert
      payload.
    * **Check for sheet errors**: Look for a red error symbol in the column name
      of the HTTP API column in the sheet. Sometimes, this will indicate an
      error in the Clay UI. For example, you may be referencing a deleted column
      name, or there may have been a subtle error when pasting the body into the
      Clay UI.
  </Accordion>
</AccordionGroup>


# Import data from a CSV
Source: https://docs.unifygtm.com/developers/guides/send-data/csv-import

Upload data from a CSV file or spreadsheet into Unify.

## Overview

This tutorial walks through the process of creating Company records via API
using a simple script. We'll assume the starting point is a CSV of company data
to upload, but in general the approach here can be used for any data source.

The **Company** object is one of the standard objects provided by default in
Unify. Along with **Person**, it powers many of the core capabilities in Unify.
The unique identifier of a company is its website domain.

## Steps

<Steps>
  <Step title="Prerequisites">
    Before you begin, be sure to [generate an API key](https://app.unifygtm.com/dashboard/settings/integrations/api-keys)
    if you don't already have one. You’ll pass it as an HTTP header on each request:

    ```http theme={null}
    X-Api-Key: <YOUR_API_KEY>
    ```

    In addition, you will need to install one of the official SDKs to follow along:

    <CodeGroup>
      ```bash Python theme={null}
      pip install unifygtm-sdk
      ```

      ```bash TypeScript theme={null}
      npm install @unifygtm/sdk csv-parse
      ```
    </CodeGroup>
  </Step>

  <Step title="Prepare a CSV of companies">
    Construct a CSV file that includes the companies you want to send into
    Unify. The columns don't need to match the attribute names in Unify since
    we'll map them over in the script.

    Here's an example CSV for the sake of this tutorial:

    ```csv example_companies.csv theme={null}
    Website,Name,LinkedIn,Score
    "tailscale.com","Tailscale","linkedin.com/company/tailscale",100
    "dagster.io","Dagster","linkedin.com/company/dagsterlabs",90
    "hashicorp.com","HashiCorp","linkedin.com/company/hashicorp",80
    "langchain.com","LangChain","linkedin.com/company/langchain",90
    "vercel.com","Vercel","linkedin.com/company/vercel",80
    "datadoghq.com","Datadog","linkedin.com/company/datadog",70
    "temporal.io","Temporal Technologies","linkedin.com/company/temporal-technologies",100
    "elastic.co","Elastic","linkedin.com/company/elastic-co",60
    "clickhouse.com","ClickHouse","linkedin.com/company/clickhouseinc",90
    "streamnative.io","StreamNative","linkedin.com/company/streamnative",70
    ```

    The only required column is a website or domain for the company. That's
    because Unify uses a company's domain as its unique identifier. Everything
    else is optional.
  </Step>

  <Step title="Understand the request payload">
    We’ll use the [upsert method](/developers/api/data/records/upsert) to create
    companies if they don't exist and update them if they do. The upsert method
    is the recommended way of sending data into Unify since it gives you the
    most control and never fails if a record already exists.

    The upsert requests we send will have two properties:

    * `match` -- This contains the value(s) used to match existing records. In
      this case, the only value we will use for matching is the `domain`.
    * `create_or_update_if_empty` -- This contains the values used when creating
      or updating the record. This will avoid overwriting existing values.

    <Tip>
      The `create_or_update_if_empty` property never overwrites values if the
      record already exists, which is a nice property. For full control over how
      existing records are updated, you can specify [more specific properties](/developers/api/data/records/upsert#overview)
      instead.
    </Tip>

    Here’s what a single request looks like for one company row:

    <CodeGroup>
      ```http Request theme={null}
      POST /data/v1/objects/company/records/upsert
      Host: api.unifygtm.com
      Content-Type: application/json
      X-Api-Key: <YOUR_API_KEY>

      {
        "match": {
          "domain": "unifygtm.com"
        },
        "create_or_update_if_empty": {
          "name": "Unify",
          "domain": "unifygtm.com",
          "description": "A nice company with a top-notch API.",
          "industry": "Software",
          "linkedin_url": "https://www.linkedin.com/company/unifygtm"
        }
      }
      ```
    </CodeGroup>
  </Step>

  <Step title="Assemble the script">
    The script needs to perform a few steps:

    1. Read the CSV
    2. Construct an upsert request payload for each row
    3. Send the requests

    Here's a complete script that does just that:

    <CodeGroup>
      ```python Python theme={null}
      import csv
      import sys
      from typing import TypedDict

      from unify import NotFoundError, Unify


      class Company(TypedDict):
          name: str | None
          domain: str
          linkedin_url: str | None
          account_score: float | None


      def read_csv(path: str) -> list[Company]:
          rows = []

          with open(path, newline="", encoding="utf-8") as f:
              reader = csv.DictReader(f)

              for i, raw in enumerate(reader, start=1):
                  domain = raw.get("Website")
                  if not domain:
                      print(f"[WARN] Row {i} skipped: missing required 'domain'")
                      continue

                  rows.append(
                      {
                          "name": raw.get("Name"),
                          "domain": domain,
                          "linkedin_url": raw.get("LinkedIn"),
                          "account_score": raw.get("Score"),
                      }
                  )

          return rows


      def main():
          if len(sys.argv) != 2:
              print("Usage: python upload_companies.py <path/to/companies.csv>")
              return 2

          # Read the CSV file
          companies = read_csv(path=sys.argv[1])
          if not companies:
              print("No valid rows to process.")
              return 0

          # Instantiate the client
          client = Unify()

          # Create a custom attribute for the account scores
          try:
              client.data.attributes.retrieve(
                  object_name="company",
                  attribute_name="account_score",
              )
          except NotFoundError:
              client.data.attributes.create(
                  object_name="company",
                  api_name="account_score",
                  display_name="Account Score",
                  description="Account score for the CSV upload guide.",
                  type="DECIMAL",
                  is_required=False,
                  is_unique=False,
              )
              print("Created custom attribute 'account_score' for companies.")

          # Create or update all records from the CSV file
          success = 0
          for row in companies:
              result = client.data.records.upsert(
                  object_name="company",
                  match={
                      "domain": row["domain"],
                  },
                  create_or_update_if_empty={
                      "domain": row["domain"],
                      "name": row["name"],
                      "linkedin_url": row["linkedin_url"],
                      "account_score": row["account_score"],
                  },
              )
              success += 1
              print(f"[OK] Upserted company {row['domain']} -> id={result.data.id}")

          print(f"Done. Upserted {success} of {len(companies)} companies.")


      if __name__ == "__main__":
          main()
      ```

      ```typescript TypeScript theme={null}
      import { readFileSync } from "fs";
      import { parse } from "csv-parse/sync";
      import Unify from "@unifygtm/sdk";
      import { UCompanyAttributes } from "@unifygtm/sdk/resources/data";

      interface CompanyRow {
        Name?: string;
        Website?: string;
        LinkedIn?: string;
        Score?: string;
      }

      function readCsv(path: string): UCompanyAttributes[] {
        const raw = readFileSync(path, "utf-8");
        const rows = parse(raw, { columns: true }) as CompanyRow[];

        const companies = new Array<UCompanyAttributes>();

        for (const row of rows) {
          if (!row.Website) {
            console.log(
              `[WARN] Skipping row with missing 'Website': ${JSON.stringify(row)}`,
            );
            continue;
          }

          companies.push({
            name: row.Name,
            domain: row.Website,
            linkedin_url: row.LinkedIn,
            score: row.Score ? parseFloat(row.Score) : undefined,
          });
        }

        return companies;
      }

      async function main(): Promise<void> {
        const path = process.argv[2];
        if (!path) {
          console.log("Usage: npx tsx upload_companies.ts <path/to/companies.csv>");
          process.exit(2);
        }

        const companies = readCsv(path);
        if (companies.length === 0) {
          console.log("No valid rows to process.");
          return;
        }

        const client = new Unify();

        // Create a custom attribute for the account scores
        try {
          await client.data.attributes.retrieve("account_score", {
            object_name: "company",
          });
        } catch (err: any) {
          if (err.status === 404) {
            await client.data.attributes.create("company", {
              api_name: "account_score",
              display_name: "Account Score",
              description: "Account score for the CSV upload guide.",
              type: "DECIMAL",
              is_required: false,
              is_unique: false,
            });
            console.log("Created custom attribute 'account_score' for companies.");
          } else {
            throw err;
          }
        }

        // Create or update all records from the CSV file
        let success = 0;
        for (const row of companies) {
          const result = await client.data.records.upsert("company", {
            match: {
              domain: row.domain,
            },
            create_or_update_if_empty: {
              name: row.name,
              domain: row.domain,
              linkedin_url: row.linkedin_url,
              account_score: row.score,
            },
          });
          success++;
          console.log(`[OK] Upserted company ${row.domain} -> id=${result.data.id}`);
        }

        console.log(`Done. Upserted ${success} of ${companies.length} companies.`);
      }

      main();
      ```
    </CodeGroup>
  </Step>

  <Step title="Run the script">
    Set your API key as an environment variable and then run the script:

    <CodeGroup>
      ```shell Python theme={null}
      export UNIFY_API_KEY="<YOUR_API_KEY>"
      python send_companies.py example_companies.csv
      ```

      ```shell TypeScript theme={null}
      export UNIFY_API_KEY="<YOUR_API_KEY>"
      npx tsx send_companies.ts example_companies.csv
      ```
    </CodeGroup>

    You should see output like this:

    ```text Output theme={null}
    [OK] Upserted company tailscale.com -> id=04caa07b-cbdd-4bb4-9de4-49abdc106aaa
    [OK] Upserted company dagster.io -> id=18cd4c36-3e6c-4778-88c3-4bd5c103f381
    ...
    Done. Upserted 10 of 10 companies.
    ```
  </Step>

  <Step title="Verify records exist (optional)">
    You can verify a specific company with the [Find unique record](/developers/api/data/records/find-unique)
    API. Simply send a request with a `match` property containing the domain of
    one of the companies the script ran on:

    <CodeGroup>
      ```http Request theme={null}
      POST /objects/company/find-unique

      {
        "domain": "tailscale.com"
      }
      ```

      ```json Response theme={null}
      {
        "status": "success",
        "data": {
          "object": "company",
          "id": "04caa07b-cbdd-4bb4-9de4-49abdc106aaa",
          "created_at": "2025-09-04T01:23:45Z",
          "updated_at": "2025-09-04T01:23:45Z",
          "attributes": {
            "name": "Tailscale",
            "domain": "tailscale.com",
            "linkedin_url": "linkedin.com/company/tailscale",
            "lead_source": "CSV Tutorial"
            // ...
          }
        }
      }
      ```
    </CodeGroup>
  </Step>
</Steps>

## Conclusion

This approach works for any type of object in Unify, including both standard
objects and custom objects that you create. This script can be used as a
starting point and customized to send additional values, read from other data
sources, or send different types of records.


# Send records via API
Source: https://docs.unifygtm.com/developers/guides/send-data/overview

Send data from external tools and systems via API.

## Overview

For tools and data sources that can't be connected using an existing
integration, Unify's [Data API](/developers/api/data/overview) can be used
instead. This general-purpose API allows you to programmatically find, create,
update, and delete records in Unify.

## Quickstart

<Steps>
  <Step title="Generate an API key">
    Navigate to
    [Settings → Developers](https://app.unifygtm.com/dashboard/settings/integrations/api-keys)
    in Unify and select **Generate API Key**.
  </Step>

  <Step title="(Optional) Install the SDK">
    If you are writing Python or TypeScript code, you can install the official
    Unify SDK to simplify interacting with the API.

    <CardGroup>
      <Card title="Python library" href="/developers/sdks/python-library" icon="python">
        Install and use the official Unify Python library.
      </Card>

      <Card title="TypeScript library" href="/developers/sdks/typescript-library" icon="js">
        Install and use the official Unify TypeScript library.
      </Card>
    </CardGroup>
  </Step>

  <Step title="Choose an object">
    You can create records for any object in Unify, including standard objects
    like `company` or `person`. But you can also create custom objects with
    whatever attributes and relationships you need.

    <CardGroup>
      <Card title="Manage via API" href="/developers/api/data/overview">
        Create and manage objects, attributes, and records in Unify via API.
      </Card>

      <Card title="Manage via UI" href="/reference/objects/overview">
        Create and manage objects, attributes, and records within the Unify app.
      </Card>
    </CardGroup>
  </Step>

  <Step title="Upsert a record">
    Now you can push records into the selected object.

    The recommended API for creating and updating records is [Upsert record](/developers/api/data/records/upsert).
    This allows you to specify a unique attribute to match existing records and
    create or update based on whether a match is found, preventing duplicates.

    <CodeGroup>
      ```python Python theme={null}
      record = client.data.records.upsert(
          object_name="my_object",
          match={
            "email": "jane@example.com",
          },
          create_or_update_if_empty={
              "email": "jane@example.com",
              "login_count": 12,
              "plan_tier": "pro",
          },
      )

      print(f"Record ID: {record.data.id}")
      print(f"Email: {record.data.attributes['email']}")
      ```

      ```typescript TypeScript theme={null}
      const record = await client.data.records.upsert('my_object', {
        match: {
          email: 'jane@example.com',
        },
        create_or_update_if_empty: {
          email: 'jane@example.com',
          login_count: 12,
          plan_tier: 'pro',
        },
      });

      console.log(`Record ID: ${record.data.id}`);
      console.log(`Email: ${record.data.attributes.email}`);
      ```

      ```shell curl theme={null}
      curl -X POST 'https://api.unifygtm.com/data/v1/objects/product_user/records/upsert' \
        -H 'X-Api-Key: ${UNIFY_API_KEY}' \
        -H 'Content-Type: application/json' \
        -d '{
          "match": {
            "email": "jane@example.com"
          },
          "create_or_update_if_empty": {
            "email": "jane@example.com",
            "login_count": 12,
            "plan_tier": "pro"
          }
        }'
      ```
    </CodeGroup>
  </Step>

  <Step title="Verify in Unify">
    The record should now exist in Unify. You can verify this by searching for
    the record in the UI or by retrieving it via API.

    <CodeGroup>
      ```python Python theme={null}
      record = client.data.records.find_unique(
          object_name="my_object",
          match={
            "email": "jane@example.com",
          },
      )

      print(f"Record ID: {record.data.id}")
      print(f"Email: {record.data.attributes['email']}")
      ```

      ```typescript TypeScript theme={null}
      const record = await client.data.records.findUnique('my_object', {
        match: {
          email: 'jane@example.com',
        },
      });

      console.log(`Record ID: ${record.data.id}`);
      console.log(`Email: ${record.data.attributes.email}`);
      ```

      ```shell curl theme={null}
      curl -X POST 'https://api.unifygtm.com/data/v1/objects/product_user/records/find-unique' \
        -H 'X-Api-Key: ${UNIFY_API_KEY}' \
        -H 'Content-Type: application/json' \
        -d '{
          "match": {
            "email": "jane@example.com"
          }
        }'
      ```
    </CodeGroup>
  </Step>
</Steps>

## What's next

<CardGroup>
  <Card title="Import data from a CSV" href="/developers/guides/send-data/csv-import" icon="file-csv">
    Sync data from a CSV file or spreadsheet into Unify.
  </Card>

  <Card title="Send records from Clay sheet" href="/developers/guides/send-data/clay-webhook" icon={<ClayLogo />}>
    Send records from a Clay sheet into Unify via webhook.
  </Card>

  <Card title="Data API reference" href="/developers/api/data/overview" icon="book">
    Explore the full Data API reference.
  </Card>
</CardGroup>


# Capture button clicks
Source: https://docs.unifygtm.com/developers/guides/website-traffic/button-clicks

Record button clicks and other interactions with the Unify Intent client.

## Overview

Website and product interactions are a strong indicator of a visitor's goal. For
example, a visitor to your marketing website who interacts with a pricing
calculator is much more likely to be an interested buyer than the average
visitor.

In Unify, you capture these types of interactions by sending a custom event when
buttons or website components are clicked. If a visitor is then identified
(e.g., from another form fill or based on company IP matches), their
interactions can be viewed in Unify and used to run Plays.

## Prerequisites

* Ensure you've already installed the Unify Intent client on your website.
  See [Set up the Unify Intent client](/developers/guides/website-traffic/unify-intent-client)
  for instructions.

## Example

Suppose you have a button that opens your pricing calculator. You can log this
interaction with a custom event that includes useful context as properties.

### Send a custom event

Call `track` when the button is clicked. Include properties that help with
attribution and routing later (e.g., `button_id`, page, placement, or variant).

```ts theme={null}
unify.track('Pricing Calculator Opened', {
  button_id: 'pricing-calculator',
  placement: 'pricing-page-hero',
});
```

### Send multiple custom events

There's no limit on the number of events you can send into Unify, and more data
is always better. You can fire off multiple custom events to capture
interactions at a more granular level.

For example, suppose your pricing calculator contains buttons to select which
pricing plan to view (e.g., "Basic," "Pro," "Enterprise"). You can send an event
each time this button is clicked:

```ts theme={null}
unify.track('Pricing Plan Selected', {
  button_id: 'select-pro-plan',
  plan: 'Pro',
});
```

Suppose that the pricing calculator also contains a slider to select the usage
quantity they expect to use. This information can be sent as well:

```ts theme={null}
unify.track('Pricing Quantity Selected', {
  slider_id: 'usage-quantity',
  credits_needed: '5000',
  plan: 'Pro',
});
```

Now, you can run a Play that segments visitors based on what pricing tier they
are most likely to be interested in. Your reps will also know what usage tier
they viewed or selected.

### Identifying the visitor

This example assumes the button click itself does not collect any information
about the visitor, such as name or email address. That's fine—if the visitor is
identified later (e.g., via form fill or IP match), Unify will link this event
to that person or company.

If you *do* have information about the visitor at click time, you should also
send an Identify event. This will immediately link the visitor to the person
or company you specify.

```ts theme={null}
// Send a basic "Identify" event
unify.identify('alice@acme.com');

// Send an "Identify" event with company and person information
unify.identify('alice@acme.com', {
  person: {
    email: 'alice@acme.com',
    first_name: 'Alice',
    last_name: 'Smith',
    title: 'Product Manager',
  },
  company: {
    name: 'Acme Inc.',
    domain: 'acme.com',
  },
});
```

You do not need to send an Identify event on every click. Send it wherever you
first learn the visitor's identity and then subsequent events will be linked
automatically.

## Launch a Play

With this custom event in place, you can create Plays in Unify that react to
high‑intent clicks like “Pricing Calculator Opened.” For example, a Play could:

1. Apply exclusions (competitors, open opportunities, current customers)
2. Launch an AI agent to research the company or person for ICP fit
3. Enroll the person in a follow‑up sequence
4. Prospect more contacts at the same company and enroll them in outreach

## FAQ

<AccordionGroup>
  <Accordion title="What properties should I include?">
    Include any information that may help you qualify and route interactions,
    such as:

    * Button or form identifier
    * Values entered by the visitor
    * Page or component context
    * Variant (for A/B tests)

    When in doubt, err on the side of including more properties.
  </Accordion>
</AccordionGroup>


# Capture form fills
Source: https://docs.unifygtm.com/developers/guides/website-traffic/form-fills

Record form submissions with the Unify Intent client.

## Overview

One of the most effective ways to capture leads on your website is through form
submissions. With Unify, you can capture these submissions and then run Plays on
them.

The Unify Intent client can be used to capture these form fills. This can be
achieved by firing two separate events:

* **Custom event** — This captures the submission and any data entered into the
  form. Any Plays will be able to filter companies or people based on whether
  they have a matching custom event.
* **Identify event** — This captures the identity of the visitor and links them
  to a company or person in Unify. The Identify event is necessary to associate
  the form submission with a specific person or company.

Typically, the simplest approach is to send both events at the same time when a
visitor completes and submits a form.

## Prerequisites

* Ensure you've already installed the Unify Intent client on your website.
  See [Set up the Unify Intent client](/developers/guides/website-traffic/unify-intent-client)
  for instructions.

## Example

Suppose you have a "demo sign-up" form that collects the following information:

* **First name** (e.g., `Alice`)
* **Last name** (e.g., `Smith`)
* **Email address** (e.g., `alice@acme.com`)
* **Company name** (e.g., `Acme Inc.`)
* **What are you most interested in seeing?** (e.g., `AI capabilities`)

To send this data into Unify, you should send two events.

### Send a custom event

First, send a custom event that records the form submission. The form fields can
be included as *properties* on the event. Properties are arbitrary key-value
pairs that can be viewed and used to filter events in Unify.

```ts theme={null}
unify.track('Demo Requested', {
  form_id: 'demo-signup',
  first_name: 'Alice',
  last_name: 'Smith',
  company: 'Acme Inc.',
  interest: 'AI capabilities',
});
```

### Send an Identify event

Next, send an Identify event that associates the submission with a known person
(using their email address). You can also include additional traits about the
person and their company. These traits will appear on the person and company
records in Unify.

```ts theme={null}
unify.identify('alice@acme.com', {
  person: {
    email: 'alice@acme.com',
    first_name: 'Alice',
    last_name: 'Smith',
  },
  company: {
    name: 'Acme Inc.',
  },
});
```

## Launch a Play

With both events sent, you can now create Plays in Unify that run on the inbound
lead. Plays can be triggered based on the custom event (e.g., "Demo Requested")
and can use filters based on the properties you sent.

For example, a Play running on inbound form fills could:

1. Apply exclusions to ensure the inbound lead is not a competitor, open
   opportunity, or existing customer
2. Launch an AI agent to research the company or person and qualify or
   disqualify them based on ICP fit or other criteria
3. Enroll the person in an outbound sequence
4. Find a few more contacts at the same company that match your ideal buyer
   persona and enroll them in another outbound sequence

## FAQ

<AccordionGroup>
  <Accordion title="What if I don't have an email address?">
    If you don't have an email address to include in the Identify event, Unify
    will not have a unique identifier to link this visitor to a person. However,
    you have other options.

    **Link to a company instead:**

    If you have a company website, you can send an Identify event with the
    visitor's company instead. This will not link the custom event to a specific
    person, but it will link it to a specific company.

    You can then run a Play on companies with matching custom events. That Play
    can prospect for contacts at the company with ICP personas.

    **Capture identity elsewhere:**

    If the visitor does not provide an email address on the form, consider
    capturing their identity elsewhere on your website. For example:

    * If you have another sign-up form that collects email addresses, you can
      send an Identify event when a visitor completes that form.
    * If you link the custom event to a company, prospect for people at that
      company, and then send sequence emails to them, you can track email link
      clicks. When a person clicks a link in an email, their website activity
      will be identified.

    If the visitor is identified through other means, all of their past activity
    will also be retroactively identified.

    **Automatically identify the company:**

    If you do not send an Identify event, Unify will still automatically attempt
    to identify the visitor's company using reveal providers based on their IP
    address.
  </Accordion>

  <Accordion title="How is a person linked to a company?">
    If you send an Identify event with a corporate email address but no company,
    Unify can infer the company from the email domain.

    For example, if you identify a visitor as `alice@acme.com`, Unify can link
    the person to the company with the `acme.com` domain. This inference is not
    performed for personal or non-corporate email domains. If the visitor uses a
    personal email address, include a company domain in the Identify event when
    you want to link the person to a company.
  </Accordion>

  <Accordion title="Can I track partial form fills?">
    Yes. If you want to track partial progress before final submission, send a
    custom event when a meaningful step is completed or enable automatic email
    input monitoring with the Unify Intent Client.

    For most lead-routing workflows, still send a final custom event when the
    form is actually submitted. This gives you a clean trigger for Plays and
    avoids treating abandoned form activity as a completed hand-raise.
  </Accordion>

  <Accordion title="Should I send both a custom event and an Identify event?">
    Usually, yes. The custom event captures what happened, such as `Demo
            Requested`. The Identify event captures who did it. Sending both gives you a
    reliable Play trigger and a person or company record to act on.
  </Accordion>
</AccordionGroup>


# Connect website traffic to Unify
Source: https://docs.unifygtm.com/developers/guides/website-traffic/introduction

Send website visitors, sessions, and events into Unify.

<Tip>
  This guide is applicable to any website, but it is especially focused on
  marketing websites. If you are looking to connect product usage or analytics
  data from your web application, see [Connect product usage data to Unify](/developers/guides/product-usage-data/introduction)
  for a more targeted guide.
</Tip>

## Overview

One of the most popular strategies in Unify is to identify the companies and
people who are visiting your website and accessing your content. By sending
website traffic data into Unify, you can instantly launch Plays to start taking
action on these visitors.

Unify can automatically identify companies visitors are associated with by using
a combination of built-in matching providers for high coverage and accuracy.
Unify also supports person-level identification through a combination of email
link click tracking, form fills, and [Identify events](/developers/api/analytics/identify).

Website traffic data in Unify consists of three types of events:

| Event type     | What it captures                                     | Common examples                                                            |
| -------------- | ---------------------------------------------------- | -------------------------------------------------------------------------- |
| Page view      | A visitor viewed a URL.                              | Pricing page viewed, docs page viewed, product page viewed.                |
| Identify event | A visitor's person or company identity became known. | Form submit, sign in, OAuth login, demo request, company domain submitted. |
| Custom event   | A named action you define.                           | Button clicked, form submitted, plan selected, product limit reached.      |

All event tracking capabilities integrate natively with the rest of the Unify
data layer. This makes it easy to link website intent to companies or people and
access that data throughout Unify.

## Setup

Unify provides an SDK called the [Unify Intent Client](/developers/intent-client/overview)
that can be installed on your website to start sending visitor events. This is
the easiest and recommended way to get started.

<Card
  title="Unify Intent Client (Recommended)"
  icon={
<>
  <UnifyLogoDark />
  <UnifyLogoLight />
</>
}
  href="/developers/guides/website-traffic/unify-intent-client"
>
  Send events using the Unify's native JavaScript or React client.
</Card>

If you're already collecting website traffic data using a third-party tool, you
can also send that data into Unify. This can be done using either a supported
integration or the general-purpose [Analytics API](/developers/api/analytics/overview).
You can find guides for popular tools below.

<CardGroup>
  <Card title="Segment" icon={<SegmentIcon />} href="/reference/integrations/segment">
    Send Segment events into Unify.
  </Card>

  <Card
    title="PostHog"
    icon={
  <>
    <PosthogLogoDark />
    <PosthogLogoLight />
  </>
}
    href="/reference/integrations/posthog"
  >
    Send PostHog events into Unify.
  </Card>
</CardGroup>

<Warning>
  If you forward events from Segment or PostHog, do not also install the Unify
  Intent Client on the same site. Running multiple event sources on the same
  site can produce duplicate data.
</Warning>

## Examples

Once you've configured events to be sent into Unify, you can start using that
data to launch Plays based on visitor intent. See the following guides for
examples.

<CardGroup>
  <Card title="Capture form fills" icon="link" href="/developers/guides/website-traffic/form-fills">
    Record form submissions with the Unify Intent client.
  </Card>

  <Card title="Capture button clicks" icon="link" href="/developers/guides/website-traffic/button-clicks">
    Record button clicks and other interactions with the Unify Intent client.
  </Card>
</CardGroup>


# Set up the Unify Intent client
Source: https://docs.unifygtm.com/developers/guides/website-traffic/unify-intent-client

Send website events directly into Unify with the native SDK.

## Installation

There are multiple ways to install the Unify Intent client depending on your
setup. In most cases, the website tag is the best option to get started.

<CardGroup>
  <Card title="Website tag" href="/developers/intent-client/website-tag" icon="code">
    Paste a pre-configured JavaScript snippet in your website's HTML. This
    method is the easiest way to get started and is suitable for most websites.
  </Card>
</CardGroup>

<CardGroup>
  <Card title="React library" href="/developers/intent-client/react" icon="react">
    Install the client in your React web application for a more native
    integration.
  </Card>

  <Card title="JavaScript library" href="/developers/intent-client/js-client" icon="node-js">
    Install the client in your non-React frontend application, such as a Single
    Page App (SPA).
  </Card>
</CardGroup>

<Note>
  You should only use one installation method per website or application. If the
  client is installed twice on the same site, it may not work correctly.
</Note>

## Usage

<Tabs>
  <Tab title="Website tag" icon="code">
    ### Automatic events

    Once the website tag is added, it will automatically start collecting
    certain types of events:

    * **Page events**: Every time a visitor loads a page on your website, a page
      view event is sent to Unify. When that visitor is identified, all their
      sessions will be linked to that identity.
    * **Custom events**: Certain button clicks and interactions will be tracked
      automatically. This does not cover all possible interactions, and you will
      likely want to manually trigger events in specific places on your website
      for more complete coverage.
    * **Identify events**: When a visitor fills out a form with their email
      address, they will be automatically identified and linked to that address.
      Other information they fill out (such as first and last name) will not be
      automatically recorded, so you may also want to manually send "identify"
      events on form fills, logins, etc.

    If desired, you can disable automatic event collection by setting specific
    options when initializing the client. See the full [Usage guide](/developers/intent-client/usage-guide)
    for more details.

    ### Manual events

    You can manually trigger events in specific places on your website by
    calling the client directly. When you include the tag in your HTML, you will
    immediately be able to access the client at `window.unify` (or simply
    `unify` since `window` is global).

    #### Page events

    Page events record a page visit. They are fired automatically by default
    when using the website tag, but you can also call them manually.

    ```javascript theme={null}
    // Send a "page" event
    unify.page();
    ```

    #### Custom events

    Custom events record specific actions taken by a visitor, such as button
    clicks or form fills. Some custom events are captured automatically when
    using the website tag, but you can also send custom events manually.

    ```javascript theme={null}
    // Send a basic custom event
    unify.track("See More Button Clicked");

    // Send a custom event with additional properties
    unify.track("Modal Opened", {
      modalName: "Contact Sales Modal"
    });
    ```

    #### Identify events

    Identify events link a visitor to a specific company or person. Basic
    identify events are sent automatically when a visitor fills out a form with
    their email address, but you can also send more detailed identify events
    when you have additional information.

    ```javascript theme={null}
    // Send a basic "identify" event
    unify.identify("user@email.com");

    // Send an "identify" event with additional company or person attributes
    unify.identify("first.last@acme.com", {
      person: {
        email: "first.last@acme.com",
        first_name: "First",
        last_name: "Last",
      },
      company: {
        domain: "acme.com",
        name: "Acme Corp.",
      }
    });
    ```
  </Tab>

  <Tab title="React library" icon="react">
    ### Automatic events

    By default, the React library will not automatically collect any events. You
    can enable automatic event collection when initializing the client. See the
    full [Usage guide](/developers/intent-client/usage-guide) for more details.

    ### Manual events

    You can manually trigger events in specific places in your web application
    by calling the client directly.

    #### Page events

    Page events record a page visit. Typically, the easiest strategy is to
    enable automatic collection of page visits, but you can also call them
    manually.

    ```javascript theme={null}
    // Enable automatic "page" event collection
    unify.startAutoPage();

    // Send a "page" event
    unify.page();
    ```

    #### Custom events

    Custom events record specific actions taken by a visitor, such as button
    clicks or form fills. You can send custom events with arbitrary
    properties anywhere in your React application.

    ```javascript theme={null}
    // Send a basic custom event
    unify.track("See More Button Clicked");

    // Send a custom event with additional properties
    unify.track("Modal Opened", {
      modalName: "Contact Sales Modal"
    });
    ```

    #### Identify events

    Identify events link a visitor to a specific company or person. You can send
    identify events whenever you have information about a visitor, such as their
    name or email address.

    ```javascript theme={null}
    // Send a basic "identify" event
    unify.identify("user@email.com");

    // Send an "identify" event with additional company or person attributes
    unify.identify("first.last@acme.com", {
      person: {
        email: "first.last@acme.com",
        first_name: "First",
        last_name: "Last",
      },
      company: {
        domain: "acme.com",
        name: "Acme Corp.",
      }
    });
    ```
  </Tab>

  <Tab title="JavaScript library" icon="node-js">
    ### Automatic events

    By default, the JavaScript library will not automatically collect any
    events. You can enable automatic event collection when initializing the
    client. See the full [Usage guide](/developers/intent-client/usage-guide)
    for more details.

    ### Manual events

    You can manually trigger events in specific places in your web application
    by calling the client directly.

    #### Page events

    Page events record a page visit. Typically, the easiest strategy is to
    enable automatic collection of page visits, but you can also call them
    manually.

    ```javascript theme={null}
    // Enable automatic "page" event collection
    unify.startAutoPage();

    // Send a "page" event
    unify.page();
    ```

    #### Custom events

    Custom events record specific actions taken by a visitor, such as button
    clicks or form fills. You can send custom events with arbitrary
    properties anywhere in your web application.

    ```javascript theme={null}
    // Send a basic custom event
    unify.track("See More Button Clicked");

    // Send a custom event with additional properties
    unify.track("Modal Opened", {
      modalName: "Contact Sales Modal"
    });
    ```

    #### Identify events

    Identify events link a visitor to a specific company or person. You can send
    identify events whenever you have information about a visitor, such as their
    name or email address.

    ```javascript theme={null}
    // Send a basic "identify" event
    unify.identify("user@email.com");

    // Send an "identify" event with additional company or person attributes
    unify.identify("first.last@acme.com", {
      person: {
        email: "first.last@acme.com",
        first_name: "First",
        last_name: "Last",
      },
      company: {
        domain: "acme.com",
        name: "Acme Corp.",
      }
    });
    ```
  </Tab>
</Tabs>

For complete instructions, see the [Usage guide](/developers/intent-client/usage-guide).


# Install JavaScript package
Source: https://docs.unifygtm.com/developers/intent-client/js-client

Install the Unify Intent client in a frontend web application framework.

<CardGroup>
  <Card title="Github" icon="github" href="https://github.com/unifygtm/intent-js-client" />

  <Card title="npm" icon="npm" href="https://www.npmjs.com/package/@unifygtm/intent-client" />
</CardGroup>

## Installation

You can install the Unify Intent JS Client with your preferred package manager:

<CodeGroup>
  ```shell npm theme={null}
  npm install @unifygtm/intent-client
  ```

  ```shell yarn theme={null}
  yarn add @unifygtm/intent-client
  ```

  ```shell pnpm theme={null}
  pnpm add @unifygtm/intent-client
  ```

  ```shell bun theme={null}
  bun add @unifygtm/intent-client
  ```
</CodeGroup>

## Usage

After installing the client, you must initialize it in your application code:

```ts index.ts theme={null}
import { UnifyIntentClient, UnifyIntentClientConfig } from '@unifygtm/intent-client';

const writeKey = 'YOUR_PUBLIC_WRITE_KEY';

const config: UnifyIntentClientConfig = {
  autoPage: true,
  autoIdentify: false,
};

const unify = new UnifyIntentClient(writeKey, config);

// Do not call mount during server side rendering. Only call it in a browser context.
unify.mount();
```

<Warning>
  Be sure to only initialize the client one time in your application.
</Warning>

For details on how to use the client to send events, see the full [Usage guide](/developers/intent-client/usage-guide).

## Cleanup

When you are done using the client, if you wish to clean up the side effects
generated by it, you can do so with the `unmount` method:

```ts cleanup.ts theme={null}
import { UnifyIntentClient, UnifyIntentClientConfig } from '@unifygtm/intent-client';

const writeKey = 'YOUR_PUBLIC_API_KEY';

const unify = new UnifyIntentClient(writeKey);
unify.mount();

// Use the client for some time, then later...

unify.unmount();
```


# Unify Intent Client
Source: https://docs.unifygtm.com/developers/intent-client/overview

Send website and product events directly into Unify with the native SDK.

## Overview

The Unify Intent client is a JavaScript library that allows you to collect
events from your website and send them to Unify. It supports page, identify, and
custom events.

<CardGroup>
  <Card title="Page events" icon="memo-pad">
    e.g. a user visits the pricing page of your marketing website
  </Card>

  <Card title="Custom events" icon="bullseye-pointer">
    e.g. a user clicks a button to open a pricing calculator
  </Card>

  <Card title="Identify events" icon="user-check">
    e.g. a user logs into your web app with their email address
  </Card>
</CardGroup>

When you install the Unify Intent client on your website, it can automatically
collect these events and send them to Unify. You can also customize its behavior
by sending events manually.

<Info>
  The Intent Client source code is [available on GitHub](https://github.com/unifygtm/intent-js-client).
</Info>

## Installation

There are multiple ways to install the Unify Intent client depending on your
setup. In most cases, the website tag is the best option to get started.

<CardGroup>
  <Card title="Website tag" href="/developers/intent-client/website-tag" icon="code">
    Paste a pre-configured JavaScript snippet in your website's HTML. This
    method is the easiest way to get started and is suitable for most websites.
  </Card>
</CardGroup>

<CardGroup>
  <Card title="React library" href="/developers/intent-client/react" icon="react">
    Install the client in your React web application for a more native
    integration.
  </Card>

  <Card title="JavaScript library" href="/developers/intent-client/js-client" icon="node-js">
    Install the client in your non-React frontend application, such as a Single
    Page App (SPA).
  </Card>
</CardGroup>

<Note>
  You should only use one installation method per website or application. If the
  client is installed twice on the same site, it may not work correctly.
</Note>

## Usage

If you install the client using the website tag method, it will start collecting
page visits automatically. Often, no further setup is required unless you wish
to track visitor interactions manually.

For other installation methods, or to learn how to manually send other types of
events, see the complete [Usage guide](/developers/intent-client/usage-guide).


# Install React package
Source: https://docs.unifygtm.com/developers/intent-client/react

Install the Unify Intent client in a React app.

<CardGroup>
  <Card title="Github" icon="github" href="https://github.com/unifygtm/intent-react" />

  <Card title="npm" icon="npm" href="https://www.npmjs.com/package/@unifygtm/intent-react" />
</CardGroup>

## Installation

You can install the Unify Intent React library with your preferred package manager:

<CodeGroup>
  ```shell npm theme={null}
  npm install @unifygtm/intent-react
  ```

  ```shell yarn theme={null}
  yarn add @unifygtm/intent-react
  ```

  ```shell pnpm theme={null}
  pnpm add @unifygtm/intent-react
  ```

  ```shell bun theme={null}
  bun add @unifygtm/intent-react
  ```
</CodeGroup>

## Usage

First, wrap your React app in a `UnifyIntentProvider`:

```tsx index.tsx theme={null}
import {
  UnifyIntentClient,
  UnifyIntentClientConfig,
  UnifyIntentProvider,
} from '@unifygtm/intent-react';

const writeKey = 'YOUR_PUBLIC_WRITE_KEY';

const config: UnifyIntentClientConfig = {
  autoPage: true,
  autoIdentify: false,
};

const intentClient = new UnifyIntentClient(writeKey, config);

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement,
);

root.render(
  <UnifyIntentProvider intentClient={intentClient}>
    <App />
  </UnifyIntentProvider>
);
```

The `UnifyIntentProvider` automatically takes care of mounting and unmounting the client
for you whenever the component mounts and unmounts. Any components rendered in your app
can access and use the intent client using the `useUnifyIntent` hook:

```tsx Example.tsx theme={null}
import { useUnifyIntent } from '@unifygtm/intent-react';

const Example = () => {
  // Get the Unify Intent Client
  const unify = useUnifyIntent();

  // However you access the current user...
  const currentUser = useCurrentUser();

  useEffect(() => {
    if (currentUser?.emailAddress) {
      // Log an identify event for the current user
      unify.identify(currentUser.emailAddress, {
        firstName: currentUser.firstName,
        lastName: currentUser.lastName,
        company: {
          name: currentUser.companyName,
          domain: currentUser.companyDomain
        },
      });
    }
  }, [currentUser, unify]);

  ...
};

export default Example;
```

For details on how to use the client to send events, see the full [Usage guide](/developers/intent-client/usage-guide).


# Usage guide
Source: https://docs.unifygtm.com/developers/intent-client/usage-guide

Learn how to send events using the Unify Intent Client.

<Tip>
  The Unify Intent Client can be used to log user activity across multiple subdomains of the
  same top-level domain. For example, if a user visits your marketing website at `www.yoursite.com`
  and then logs into your production web application at `app.yoursite.com`, the activity in both
  places will be attributed to the same person.
</Tip>

## Event types

### Page view events

Website page views are an indicator of buyer intent. You can log this information to the Unify platform for usage with the `page` method.

There are two ways to collect page data with the Unify intent client:

1. Automatic monitoring of the current page (see [here](#automatic-page-monitoring))
2. Manually via the client `page` method (see [here](#manual-page-logging))

Utilizing both of these methods when appropriate is recommended to take full advantage of intent data within Unify.

#### Automatic page monitoring

The Unify intent client is capable of automatically monitoring the user's current page to trigger page events. This will happen by default when the client is installed via the Unify JavaScript tag. If the client is installed via a package manager, you must pass the `autoPage` configuration option when instantiating the client. See [Configuration](#configuration) below for more details.

In either case, this behavior can be enabled or disabled programmatically via the `startAutoPage` and `stopAutoPage` methods on the client:

```TypeScript theme={null}
// Initialize the client and tell it to automatically monitor pages
const unify = new UnifyIntentClient(
  'YOUR_PUBLIC_WRITE_KEY',
  { autoPage: true },
);
unify.mount();

// Tell the client to stop monitoring pages
unify.stopAutoPage();

// Tell the client to start monitoring pages again
unify.startAutoPage();
```

#### Manual page logging

You can also manually trigger a page event with the `page` method on the client. This is useful when you do not want to trigger page events for *every* page.

```TypeScript theme={null}
const unify = new UnifyIntentClient('YOUR_PUBLIC_WRITE_KEY');
unify.mount();

// Trigger a page event for whatever page the user is currently on
unify.page();

// Trigger a page event for a custom page that the user is not necessarily on
unify.page({ pathname: '/some-custom-page' });
```

### Identify events

All intent data collected for users by Unify is anonymous by default. When intent events are logged, Unify will attempt to automatically de-anonymize the IP address of a user to associate them with a specific company, but their personal identity will remain anonymous until an identify event is triggered for them.

There are two ways to collect identity data with the Unify intent client:

1. Automatic monitoring of email input elements (see [here](#automatic-input-monitoring))
2. Manually via the client `identify` method (see [here](#manual-identification))

Utilizing both of these methods when appropriate is recommended to take full advantage of intent data within Unify.

#### Automatic input monitoring

The Unify intent client is capable of automatically monitoring text and email input elements on the page to collect user identity. This will happen by default when the client is installed via the Unify JavaScript tag. If the client is installed via a package manager, you must pass the `autoIdentify` configuration option when instantiating the client. See [Configuration](#configuration) below for more details.

In either case, this behavior can be enabled or disabled programmatically via the `startAutoIdentify` and `stopAutoIdentify` methods on the client:

```TypeScript theme={null}
// Initialize the client and tell it to automatically monitor inputs
const unify = new UnifyIntentClient(
  'YOUR_PUBLIC_WRITE_KEY',
  { autoIdentify: true },
);
unify.mount();

// Tell the client to stop monitoring inputs for now
unify.stopAutoIdentify();

// Tell the client to start monitoring inputs again
unify.startAutoIdentify();
```

#### Manual identification

You can also manually trigger an identify event with the `identify` method on the client. This is useful when users log-in with OAuth or SSO, for example, because they do not enter their email into an input on the page.

When using this method, you can also optionally specify a set of Person or Company attributes to upsert and associate with the identified user. This is done in the form of an optional second argument to `identify`.

```TypeScript theme={null}
const unify = new UnifyIntentClient('YOUR_PUBLIC_WRITE_KEY');
unify.mount();

// However you determine the currently logged-in user
const currentUser = getCurrentUser();

// Identify the current user
unify.identify(currentUser.emailAddress);

// OR identify the current user and upsert the associated Company/Person in Unify
unify.identify(
  currentUser.emailAddress,
  {
    person: {
      email: currentUser.emailAddress,
      first_name: currentUser.firstName,
      last_name: currentUser.lastName,
    },
    company: {
      domain: currentUser.organization.domain, // must match domain of email above
      name: currentUser.organization.name,
    }
  }
)
```

### Custom events

Certain user actions are valuable indicators of buying intent. You can use custom events to log these events along with custom properties for each event that you can then use within Unify to filter your visitors and act accordingly.

There are three ways to fire custom events with the Unify intent client:

1. Manually via the client `track` method (see [here](#manual-tracking))
2. Custom HTML data attributes (see [here](#html-data-attributes))
3. Automatically with CSS selectors (see [here](#automatic-tracking))

#### Manual tracking

You can also manually trigger a custom event with the `track` method on the client:

```TypeScript theme={null}
const unify = new UnifyIntentClient('YOUR_PUBLIC_WRITE_KEY');
unify.mount();

// Only the event name is required - we recommend spaces between capitalized words
unify.track('See More Button Clicked');

// You can also specify custom properties to include
unify.track('Modal Opened', { modalName: 'Contact Sales Modal' });
```

The `track` method accepts two arguments:

1. A string `name` (required) - this is used to identify the event downstream within Unify.
2. An object of keys and string values `properties` (optional) - this is used to specify custom properties associated with the event which can be used for filtering and identification downstream within Unify.

#### HTML data attributes

You can leverage various data attributes in the HTML of your site or application to automatically track click events for elements you care about:

##### `data-unify-click-event-name`

The presence of this attribute on an element indicates that the intent client should automatically fire an event when the element is clicked. The *value* of this attribute defines the **name** of the event which will be fired. For example, clicking the `button` in the following HTML will result in a custom event with the name `See More Button Clicked` to be fired:

```html theme={null}
<button data-unify-click-event-name="See More Button Clicked">See more</button>
```

By default, the intent client will make a best effort at identifying a **label** for the clicked element to include in the **properties** of the event which is fired. It will do so using the text content and ARIA attributes of the element. This can be used to differentiate between custom events with the *same name* fired for *different elements*. If the client is not able to determine a human-readable label, the `label` property will simply be omitted from the event properties. For example, clicking the `div` in the following HTML will result in a custom event with the name `Download Button Clicked` to be fired with `properties` containing a `label` with the value `Free sample`:

```html theme={null}
<div data-unify-click-event-name="Download Button Clicked">Free sample</div>
```

##### `data-unify-label`

This attribute can be used to override the label (or provide a label which is otherwise missing) for an element that is tracked by the client. For example, even though clicking the `button` in the following HTML would normally result in a custom event with the label `See more` to be fired, the presence of the `data-unify-label` attribute results in the event being fired with a `label` property of `Custom label`:

```html theme={null}
<button
  data-unify-click-event-name="See More Button Clicked"
  data-unify-label="Custom label"
>
  See more
</button>
```

##### `data-unify-event-prop-*`

By default, only the label of an element is included in the `properties` of auto tracked events. You can specify additional properties to include using the prefix `data-unify-event-prop-`. For example, clicking the `button` in the following HTML will result in an event being fired with `properties` including a property of `customValue` set to `100`:

```html theme={null}
<button
  data-unify-click-event-name="See More Button Clicked"
  data-unify-event-prop-custom-value="100"
>
  See more
</button>
```

#### Automatic tracking

The Unify intent client is capable of automatically monitoring elements that match a list of CSS selectors specified by you in the `UnifyIntentClientConfig`'s `autoTrackOptions.clickTrackingSelectors`. When an element matching one of these selectors is clicked by the user, the client will automatically fire an event for it.

`clickTrackingSelectors` can be a list of simple CSS string selectors, in which case the default event name `Element Clicked` will be used:

```typescript theme={null}
const options: AutoTrackOptions = {
  clickTrackingSelectors: ['.button', '.another-custom-selector'],
};

// Will fire `Element Clicked` events for clicked elements matching CSS selectors
const unify = new UnifyIntentClient('YOUR_PUBLIC_WRITE_KEY', {
  autoTrackOptions: options,
});
```

Alternatively, you can customize the event name fired for each selector by passing a list of objects for `clickTrackingSelectors`, where each object contains a `selector` string and optional `eventName` which will be used as the name of the auto tracked event:

```typescript theme={null}
const options: AutoTrackOptions = {
  clickTrackingSelectors: [
    { selector: '.button', eventName: 'Button Clicked' },
    {
      selector: '.another-custom-selector',
      eventName: 'Custom Element Clicked',
    },
  ],
};

// Will fire events with specified custom names for clicked elements matching CSS selectors
const unify = new UnifyIntentClient('YOUR_PUBLIC_WRITE_KEY', {
  autoTrackOptions: options,
});
```

You can use the `data-unify-label` to customize the element `label` in the event `properties` and the `data-unify-event-prop-` prefix to add custom `properties`. See [HTML data attributes](#html-data-attributes) for more info.

If you would like to exclude a specific element from tracking which matches your specified CSS selectors list, you can do so with the `data-unify-exclude` attribute.

This behavior can be enabled or disabled programmatically via the `startAutoTrack` and `stopAutoTrack` methods on the client:

```TypeScript theme={null}
// Initialize the client and tell it to automatically track clicks for all elements with class="button"
const unify = new UnifyIntentClient(
  'YOUR_PUBLIC_WRITE_KEY',
  { autoTrackOptions: { clickTrackingSelectors: ['.button'] } },
);
unify.mount();

// Tell the client to stop monitoring buttons for now
unify.stopAutoTrack();

// Tell the client to start monitoring buttons again
unify.startAutoTrack();

// OR tell the client to start monitoring something else
unify.startAutoTrack({ clickTrackingSelectors: ['.custom-button'] });
```

## Server side

It is possible to send requests to the Unify Intent API directly. You might do this on a web server, for example, to circumvent ad blockers. The Unify client exposes a method for each of its event types (`page`, `identify`, and `track` events) which can be used to generate the request payload for each event. This payload can then be sent to your web server which functions as a proxy to forward the request directly to the Unify Intent API.

The three methods on the client for generating event payloads are the following:

* `getPagePayload`
* `getIdentifyPayload`
* `getTrackPayload`

Below is an example of using the `getIdentifyPayload` method in a React app to generate the payload for an `identify` event, send it to a proxy web server, and forward it to the Unify Intent API.

```tsx client.tsx theme={null}
// However you make requests to your web server
const apiClient = useApiClient();

// However you get your current user object
const currentUser = useCurrentUser();

// Get the Unify client
const unify = useUnifyIntent();

useEffect(() => {
  if (currentUser.email) {
    const payload = unify.getIdentifyPayload(currentUser.email);

    // If the email is valid
    if (payload) {
      // Send event to server
      apiClient.post('/identify', payload);
    }
  }
}, [currentUser, unify, apiClient]);
```

```TypeScript server.ts theme={null}
const unifyClient = axios.create({
  // The Unify Intent API URL
  baseURL: 'https://api.unifyintent.com/analytics/v1',
  headers: {
    'Content-type': 'application/json; charset=UTF-8',
    // Your public write key which can be found at https://app.unifygtm.com/dashboard/settings/integrations/unify-intent-client
    'X-Write-Key': 'wk_5fTtsDLJ_7vx9DsjPcr79yk4FweES727w59pxS8EJ',
  },
});

router.post(
  '/identify',
  async (req: Request, res: Response) => {
    // Forward the event to the Unify Intent API
    const response = await unifyClient.post('/identify', req.body);

    return res.status(200).json({
      success: response.status === 200,
    });
  }
);
```

## Third-party tools

The intent client ships with out-of-the-box event tracking for some popular third-party tools such as [Default](https://www.default.com/) and [Navattic](https://www.navattic.com/). If these tools are embedded into a page where the intent client is running, the client will track relevant events automatically. This behavior can be disabled with the `UnifyIntentClientConfig`.

See [Configuration](#configuration) for more details on configuring the intent client.

### Default

[Default](https://www.default.com/) is a popular tool for automating inbound form submission workflows. If you use a Default form wherever the intent client is running, the client will automatically fire events for corresponding Default form events. The following Default form events are supported:

| Default event                 | Unify event name              | Unify event properties                                            | Description                                                         |
| ----------------------------- | ----------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------- |
| `default.form_completed`      | `Default Form Completed`      | `form`, `formId`                                                  | When a user completes all steps in a form.                          |
| `default.form_page_submitted` | `Default Form Page Submitted` | `form`, `formId`, `pageNumber`                                    | When a user completes a single step of a mult-step form.            |
| `default.meeting_booked`      | `Default Meeting Booked`      | `memberName`, `memberEmail`, `durationInMinutes`, `startDateTime` | When a user successfully books a meeting via the Default scheduler. |
| `default.scheduler_closed`    | `Default Scheduler Closed`    |                                                                   | When a user closes the Default scheduler UI.                        |
| `default.scheduler_displayed` | `Default Scheduler Displayed` | `formId`                                                          | When the Default scheduler UI is displayed to the user.             |

### Navattic

[Navattic](https://www.navattic.com/) is a popular tool for automating interactive product demos. If you use a Navattic demo wherever the intent client is running, the client will automatically fire events for corresponding Navattic demo events. The following Navattic demo events are supported:

| Navattic event  | Unify event name            | Unify event properties | Description                                         |
| --------------- | --------------------------- | ---------------------- | --------------------------------------------------- |
| `START_FLOW`    | `Navattic Demo Started`     | `demo`                 | When a user starts a Navattic demo.                 |
| `VIEW_STEP`     | `Navattic Demo Step Viewed` | `demo`, `step`         | When a user views a new step of the demo.           |
| `COMPLETE_FLOW` | `Navattic Demo Completed`   | `demo`                 | When a user successfully completes the entire demo. |

## Configuration

<ParamField type="boolean">
  <Note>If installed via the [Unify Website tag](./website-tag) then the `autoPage` config will default to `true`.</Note>

  Tells the client to automatically log page events whenever the current page changes.
  Works for static websites and Single Page Apps. Also logs a page event for the initial page.
</ParamField>

<ParamField type="boolean">
  <Note>If installed via the [Unify Website tag](./website-tag) then the `autoIdentify` config will default to `true`.</Note>

  Tells the client to automatically monitor text and email input elements on the
  page for changes. When the current user enters a valid email address into an input, the client
  will log an identify event for that email address.
</ParamField>

<ParamField type="AutoTrackOptions">
  Options to customize the auto-tracking of user actions such as click events.

  <Expandable title="properties">
    <ParamField type="string[] | { selector: string; eventName?: string }[]">
      Optional list of CSS selectors to customize which elements the client will automatically fire a custom event for when clicked.
      Can be a list of string selectors, in which case the default event name `Element Clicked` will be used as the event name.
      Can also be a list of objects containing a `selector` key and `eventName` key, in which case the value of `eventName` will be used as the event name.
    </ParamField>

    <ParamField type="DefaultFormAutoTrackOptions">
      By default, the intent client will fire custom events for [Default](https://www.default.com/) form events.
      This option can be used to customize which Default form events will result in Unify events being fired or disable this behavior entirely.
    </ParamField>

    <ParamField type="NavatticDemoAutoTrackOptions">
      By default, the intent client will fire custom events for [Navattic](https://www.navattic.com/) product demos.
      This option can be used to customize which Navattic demo events will result in Unify events being fired or disable this behavior entirely.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField type="number">
  Length in minutes that user sessions will persist when no activities are tracked. Activities include `page`, `identify,` and `track` activities.
</ParamField>

## Cookies

<Note>
  This section only applies to intent client versions `1.4.0` and up. If you install the intent client with the website tag, you automatically get access to the latest client version. Versions older than this use obfuscated cookie names.
</Note>

When the intent client mounts, it places two values in the user's cookies:

* `unify_visitor_id` - A randomly generated UUID which uniquely identifies the user. This persists across sessions.
* `unify_session_id` - A randomly generated UUID which uniquely identifies the user's current session. Sessions will persist as long as a new `page`, `identify`, or `track` event is fired at least once every 30 minutes. This duration be customized with the `sessionDurationMinutes` option on the `UnifyIntentClientConfig`.

These cookies are *first-party cookies* and associated with the top-level domain where the intent client is running.

<Callout icon="lightbulb">
  **Example**

  If the intent client is running on [https://www.unifygtm.com](https://www.unifygtm.com) then the cookies will be associated with `.unifygtm.com`. This means that they are accessible and reused across all subdomains of the top-level domain.

  In this example, if the intent client were also running on [https://app.unifygtm.com](https://app.unifygtm.com) then a visitor ID stored while on the `www` subdomain would be reused on `app` subdomain.
</Callout>

These cookies are stored for the maximum permitted time by Google Chrome of 400 days and updated every time the visitor visits your site. In other words, as long as the same visitor visits your site at least once every 400 days and does not clear their browser cookies, their visitor ID will be reused across sessions. Note that some browsers have default limits lower than 400 days. In these cases, the maximum allowed limit by the browser will be used.


# Website tag
Source: https://docs.unifygtm.com/developers/intent-client/website-tag

Set up the Unify Intent client on a marketing website.

## Installation

You can automatically load and install the client by placing a `<script>` tag in the `<head>`
or `<body>` of your website's HTML. The minified script can be found [here](https://app.unifygtm.com/dashboard/settings/integrations/unify-intent-client)
in Unify.

```html index.html theme={null}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <!-- Your Unify JavaScript tag here -->
  </head>
  <body>
    <!-- Or here... -->
  </body>
</html>
```

<Warning>
  Be sure to only initialize the client one time on your website.
</Warning>

Once added, it will start collecting page visits automatically. Often, no
further setup is required unless you wish to track visitor interactions
manually. For more details, see [Usage](#usage) below.

### Content Security Policy

If your site has a content security policy defined, you will need to modify
two of the policy's directives to permit the Unify client to load and function:

* Add `https://tag.unifyintent.com` to the `script-src` directive
  * This allows your site to load and execute the script which installs the Unify client
* Add `https://api.unifyintent.com` to the `connect-src` directive
  * This allows the Unify client to make requests to the Unify API

Here is an example content security policy definition. Yours will likely contain additional
values beyond the ones defined here:

```http theme={null}
Content-Security-Policy:
  default-src 'self';
  script-src 'self' https://tag.unifyintent.com;
  connect-src 'self' https://api.unifyintent.com;
```

### Additional instructions

If you're using one of the tools below, you can follow the provider-specific
instructions for that tool to install the website tag.

<AccordionGroup>
  <Accordion title="Google Tag Manager">
    Follow these steps to install the website tag using Google Tag Manager:

    1. Log in to your Google Tag Manager account.
    2. Select the container associated with your website.
    3. Click **Tags** in the left sidebar, then click **New**.
    4. Click **Tag Configuration** and select **Custom HTML**.
    5. Copy the website tag script from the Unify [settings page](https://app.unifygtm.com/dashboard/settings/integrations/unify-intent-client)
       and paste the website tag snippet into the HTML field.

    <Frame>
      <img />
    </Frame>

    6. Under **Triggering**, select **All Pages**.
    7. Save the tag.
    8. Click **Submit** to publish the container.
    9. Visit your website and confirm the tag is firing correctly.

    Lastly, be sure to enable support for `document.write` in the tag settings.
    This is required for the website tag to work correctly.

    For more information, see the official Google Tag Manager support docs
    [here](https://support.google.com/tagmanager/answer/6107167).
  </Accordion>

  <Accordion title="HubSpot CMS">
    Follow these steps to install the website tag on a site hosted with HubSpot CMS:

    1. Log in to your HubSpot account.

    2. Navigate to **Settings → Website → Pages**.

    3. Open the **Templates** or **Pages** tab (depending on your setup).

    4. Choose one of the following approaches:

       * **Global install (recommended):**

         1. Open **Website → Pages → Templates**.
         2. Edit your main site template.
         3. Paste the website tag snippet inside the `<head>` section.

       * **Per-page install:**

         1. Open a specific page.
         2. Go to **Advanced Settings**.
         3. Paste the snippet into the **HTML Head** field.

    5. Save and publish your changes.

    6. Visit your site and confirm the tag is running.

    <Note>
      A global template install is recommended to ensure full site coverage.
    </Note>
  </Accordion>

  <Accordion title="Shopify">
    Follow these steps to install the website tag on a Shopify store:

    1. Log in to your Shopify admin.
    2. In the left sidebar, go to **Online Store → Themes**.
    3. Find your active theme and click **⋯ → Edit code**.
    4. Under the **Layout** section, open `theme.liquid`.
    5. Locate the closing `</head>` tag.
    6. Paste the website tag snippet **immediately before** the closing `</head>` tag.
    7. Click **Save**.
    8. Visit your storefront and confirm the tag loads correctly.

    <Note>
      Installing the tag in `theme.liquid` ensures it runs on all pages of your site.
    </Note>
  </Accordion>

  <Accordion title="Squarespace">
    Follow these steps to install the website tag on a Squarespace site:

    1. Log in to your Squarespace account.
    2. Open the site you want to install the tag on.
    3. Go to **Settings → Advanced → Code Injection**.
    4. In the **Header** field, paste the website tag snippet.
    5. Click **Save**.
    6. Publish your site if it is not already live.
    7. Visit your site and verify that the tag is loading.

    <Note>
      Adding the script to the Header ensures it loads on every page.
    </Note>
  </Accordion>

  <Accordion title="Static hosts (e.g., Netlify, Vercel, Cloudflare Pages)">
    Use these steps if your site is deployed as a static site or via a modern framework:

    1. Open your project’s source code locally.

    2. Identify the file that controls your global HTML layout, such as:

       * `index.html`
       * `_document.tsx` (Next.js)
       * `app.html` (SvelteKit)
       * A shared layout or template file

    3. Paste the website tag snippet inside the `<head>` section of that file.

    4. Save your changes.

    5. Commit and push the changes to your Git repository.

    6. Deploy the site using your hosting provider (Netlify, Vercel, Cloudflare Pages, etc.)

    7. Once the deployment completes, visit the live site and verify the tag loads correctly.

    <Note>
      Ensure the script runs on all pages and is not conditionally excluded during build or runtime.
    </Note>
  </Accordion>

  <Accordion title="Webflow">
    Follow these steps to install the website tag on a Webflow site:

    1. Log in to your Webflow account.
    2. Open the project you want to install the tag on.
    3. Go to **Project Settings**.
    4. Select the **Custom Code** tab.
    5. Paste the website tag snippet into the **Head code** field.

    <Frame>
      <img />
    </Frame>

    6. Click **Save Changes**.
    7. Publish the site to apply the changes.
    8. Visit your site and verify the tag is loading.

    <Note>
      The tag will run on all published pages of the site.
    </Note>
  </Accordion>
</AccordionGroup>

## Usage

Once the website tag is installed, the Unify Intent client will automatically
start collecting events on your website. Often, there is nothing else you need
to do.

If you'd like to manually trigger events in specific places on your website, you
can do so by calling the client directly. When you include the tag in your HTML,
you will immediately be able to access the client at `window.unify` (or simply
`unify` since `window` is global).

```js Console theme={null}
// Trigger a "page" event
unify.page();

// Trigger a custom event
unify.track("See More Button Clicked");

// Trigger an "identify" event
unify.identify("user@email.com");

// You can also pass standard Person/Company fields as a second argument
unify.identify("jane@unifygtm.com", {
  firstName: "Jane",
  lastName: "Doe",
  company: { name: "Unify", domain: "unifygtm.com" },
});
```

<Tip>
  As demonstrated above, you can pass standard Person & Company fields as a second argument to the
  `identify` method. See [Field Mappings](/reference/integrations/salesforce/field-mappings#available-fields)
  for all available fields.
</Tip>

For details on how this works and the available options, see the full [Usage guide](/developers/intent-client/usage-guide).


# Unify for Developers
Source: https://docs.unifygtm.com/developers/introduction

Build on top of Unify's powerful data platform and best-in-class APIs.

## Overview

Unify is a system of action that empowers sales, marketing, and growth teams to
drive revenue growth. At its core, the Unify platform is built to be open and
developer-friendly.

## Getting started

If you have a specific use case in mind, you can jump straight to the developer
guides:

<CardGroup>
  <Card title="Connect website traffic" href="/developers/guides/website-traffic/introduction" icon="browser">
    Send website visitors, sessions, and events into Unify.
  </Card>

  <Card title="Connect product usage data" href="/developers/guides/product-usage-data/introduction" icon="computer-mouse-button-left">
    Send web application and software usage data into Unify.
  </Card>

  <Card title="Connect data systems" href="/developers/guides/data-systems/overview" icon="database">
    For data in a database, data warehouse, or data lake.
  </Card>

  <Card title="Send data via API" href="/developers/guides/send-data/overview" icon="webhook">
    For data that can be sent via webhooks or APIs.
  </Card>

  <Card title="Request data via API" href="/developers/guides/request-data/bulk-api" icon="download">
    For large datasets that need to be requested from Unify.
  </Card>
</CardGroup>

See [Connecting your data](/developers/connecting-data) for an overview of how
data can be sent into Unify. You can also explore the API reference guides and
Bulk API guide below to get a sense of the available capabilities and features.

## Developer APIs

The Unify developer interface provides APIs for event collection, object data,
and large Sequence data requests:

* [Analytics API](/developers/api/analytics/overview): Exposes public-facing
  endpoints for collecting either client-side or server-side events from
  websites, web apps, and custom software.
* [Data API](/developers/api/data/overview): Provides deep access to the data
  platform that powers Unify, including the ability to manage objects and send
  records.
* [Bulk API](/developers/guides/request-data/bulk-api): Provides asynchronous
  query jobs for requesting large Sequence enrollment and enrollment-step
  datasets.

Official SDKs are also available in the following languages:

<CardGroup>
  <Card title="Python library" href="/developers/sdks/python-library" icon="python">
    Install and use the official Unify Python library.
  </Card>

  <Card title="TypeScript library" href="/developers/sdks/typescript-library" icon="js">
    Install and use the official Unify TypeScript library.
  </Card>
</CardGroup>

In addition, integrations with third-party analytics and reverse ETL tools
simplify the process of connecting external data systems. Unify provides a
flexible and scalable data layer built to support nearly any type of data.


# Getting started with Unify MCP
Source: https://docs.unifygtm.com/developers/mcp/getting-started

Connect Unify to Claude, Cursor, or any MCP-compatible AI assistant.

<Note>
  Unify MCP is in early access and under active development. Available
  tools and behavior may change before general availability.
</Note>

Unify MCP lets you connect Unify to Claude, Cursor, or any other
MCP-compatible AI assistant. Once connected, your assistant can research
companies, build lists, write sequences, update your CRM, and more, all
from a normal conversation, using the same Agent that powers Unify Chat.

## What is MCP?

[MCP](https://modelcontextprotocol.io) (Model Context Protocol) is an open
standard that lets AI assistants like Claude or Cursor securely connect to
outside tools and data. Instead of copying information back and forth
between Unify and your AI assistant, you connect once. From there, your
assistant can call Unify directly, on your behalf, whenever it's useful.

## What you can do with Unify MCP

Because Unify MCP runs the exact same Agent as Unify Chat, anything you can
ask Unify Chat to do, you can ask your connected assistant to do too:

<AccordionGroup>
  <Accordion title="Research">
    "Research acme.com and tell me if they look like a good fit for our ICP."
  </Accordion>

  <Accordion title="Prospecting and creating sequences">
    "Find VP of Sales at Series B SaaS companies in the Bay Area, then
    create a 4-step sequence and enroll them."
  </Accordion>

  <Accordion title="List building">
    "Build me a list of Series B fintech companies in the US with 50-200
    employees."
  </Accordion>

  <Accordion title="CRM updates">
    "Update these accounts in Salesforce with our latest ICP tier."
  </Accordion>

  <Accordion title="Sequence performance">
    "Which of my active sequences have the highest reply rate this month?"
  </Accordion>

  <Accordion title="Rep activity and performance">
    "How many touches has each rep logged this week, and who's below
    pace?"
  </Accordion>

  <Accordion title="Recurring / scheduled work">
    "Every Monday at 9am, find companies that raised funding in the last
    week and send me the list."
  </Accordion>
</AccordionGroup>

Your assistant can also pull in supporting context as needed, like a
results table from a previous run, your outbound email voice profile, or
your company's business context, to make its answers more accurate.

If you have other MCP connectors set up too, like a call recording tool,
your assistant can combine that context with Unify in the same
conversation. For example, it can pull insights from a recent discovery
call and use them to help draft a more personalized sequence in Unify.

## Getting started

Pick your client below. Claude (Desktop / claude.ai) is the most common
starting point. For Claude Code, Cursor, and Codex, the recommended path is
installing [Unify's official plugin](https://github.com/unifygtm/agent-plugins),
which bundles the Unify skills and MCP configuration.

<Tabs>
  <Tab title="Claude (Desktop / claude.ai)">
    If your company is on a Claude **Team or Enterprise** plan, an admin
    usually needs to add Unify as a connector for the workspace first, since
    most people can't add a custom connector themselves on those plans.

    1. As a Claude workspace **admin**, go to **Settings → Connectors** (or
       **Integrations**, depending on your plan) and click **Add custom
       connector**.
    2. Enter:

       * **Name:** `Unify`
       * **Remote MCP server URL:** `https://mcp.unifygtm.com/mcp`

       <Warning>
         You must also enter this **OAuth Client ID**. The connector will
         fail to connect without it:

         ```
         WlCPDTjIzXkpsvxi5TwnkBQECGTL3dGE
         ```
       </Warning>
    3. Save. Unify now shows up as an available connector for everyone in
       the workspace.

    <Info>
      This Client ID identifies the Claude Desktop app to Unify. It's the
      same value for every organization and isn't specific to your
      company. Each person still logs in with their own Unify account, and
      only ever sees their own company's data.
    </Info>

    Once that's done, each person connects individually:

    4. Go to **Settings → Connectors** and search for **Unify**.
    5. Click **Connect**, then log in with your Unify account when
       prompted.
    6. Go to **Settings → Plugins** and click **Add marketplace**.
    7. Enter: `https://github.com/unifygtm/agent-plugins`
    8. Click **Sync**.
    9. Click **Install**.

    You're now connected, with Unify's skills and MCP tools available.
  </Tab>

  <Tab title="Claude Code">
    Add the Unify plugin marketplace, then install the plugin at user scope:

    ```bash theme={null}
    claude plugin marketplace add unifygtm/agent-plugins --scope user
    claude plugin install unify@unify-plugins --scope user
    ```

    Fully restart Claude Code, then run `/mcp` and complete the Unify login
    when prompted.
  </Tab>

  <Tab title="Cursor">
    Cursor does not currently provide CLI commands for adding a marketplace
    and installing a plugin. If your organization uses team marketplaces:

    1. Ask a Cursor administrator to add `unifygtm/agent-plugins` as a team
       marketplace.
    2. Open **Settings → Plugins**, find **Unify**, and install it.
    3. Fully restart Cursor, then enable and sign in to Unify from **Settings
       → Plugins**.

    For an individual local installation, run the official setup script:

    ```bash theme={null}
    curl -fsSL https://raw.githubusercontent.com/unifygtm/agent-plugins/main/scripts/setup.sh | bash -s -- cursor
    ```

    If Unify does not appear after restarting, ask a Cursor administrator to
    allow user-local plugin imports.
  </Tab>

  <Tab title="Codex">
    Add the Unify plugin marketplace, then install the plugin:

    ```bash theme={null}
    codex plugin marketplace add unifygtm/agent-plugins
    codex plugin add unify@unify-plugins
    ```

    Fully restart Codex, then sign in to Unify:

    ```bash theme={null}
    codex mcp login unify
    ```
  </Tab>

  <Tab title="ChatGPT">
    <Note>
      Support for ChatGPT is still being finalized. Check with your Unify
      contact for current setup steps.
    </Note>
  </Tab>
</Tabs>

### Custom or other clients

If your client isn't listed above, or you'd rather authenticate with an API
key instead of logging in, connect manually with this configuration:

```json theme={null}
{
  "mcpServers": {
    "unify": {
      "url": "https://mcp.unifygtm.com/mcp",
      "headers": {
        "x-api-key": "<your-api-key>"
      }
    }
  }
}
```

Generate an API key from **Settings → Developers** in the Unify app. Every
action taken this way is scoped to whichever Unify user the key belongs to.

## Usage and credits

Unify MCP runs on the same Agent, and consumes the same usage/credits, as
messages sent directly in Unify Chat. There's no separate cost for
connecting through MCP.

## Best practices

**Use Unify's own terms when you prompt.** Your assistant understands
requests best when you use the same words Unify does, like "sequence,"
"enrich," "prospect," "play," and "audience," instead of a generic word
like "campaign" or "segment." That makes it far more likely your assistant
maps what you're asking for to the right Unify action.

It also helps to say so explicitly when you want something run as a
background Agent task you can check on later:

> "Start an Agent run to prospect a new list, and give me a link to check
> on it."

## FAQ

<AccordionGroup>
  <Accordion title="Is this the same AI as Unify Chat?">
    Yes. Unify MCP runs the exact same Agent. Nothing is different except
    how you're talking to it.
  </Accordion>

  <Accordion title="Does this cost extra?">
    No. It uses your existing Unify Chat credits/usage.
  </Accordion>

  <Accordion title="Is my data isolated from other users?">
    Yes. Every request is tied to the specific Unify user who connected, so
    your assistant only ever sees what that user can see in Unify.
  </Accordion>

  <Accordion title="Can I schedule recurring tasks?">
    Yes. Ask your assistant to set up a recurring prompt (a "scheduled
    chat"), and it'll run automatically on the schedule you give it.
  </Accordion>

  <Accordion title="Which AI clients are supported?">
    The official Unify plugin supports Claude Code, Cursor, and Codex. Claude
    Desktop/claude.ai and ChatGPT can connect without the plugin. Any other
    MCP-compatible client that supports remote/HTTP servers can use the custom
    configuration above.
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup>
  <Card title="Tools reference" href="/developers/mcp/tools" icon="wrench">
    The complete, technical tool-by-tool reference.
  </Card>
</CardGroup>


# Tools
Source: https://docs.unifygtm.com/developers/mcp/tools

Reference for every tool exposed by Unify MCP.

Unify MCP exposes 71 tools. Six manage the Agent lifecycle, four load identity
or Unify data for context, and 61 provide direct access to Unify's public APIs.

Every tool call is scoped to the Unify user and tenant that authenticated the
connection. A tool can only read or act on data that user can already see in
Unify.

## Agent tools

Use `run_agent` to start work, then use the other Agent tools to monitor,
continue, cancel, and read runs.

### run\_agent

Starts Unify's general-purpose Agent on a natural-language task. This is the
same Agent behind [Unify Chat](https://app.unifygtm.com), so `run_agent`
supports anything Unify Chat does: research, building a list of companies or
people, enrolling records in a Sequence, running a Play, writing updates back
to your CRM, and similar work. Returns a run ID immediately; the Agent
continues running in the background.

<ParamField type="string">
  The natural-language task for the Agent to perform.
</ParamField>

| Output field | Type            | Description                                                                                    |
| :----------- | :-------------- | :--------------------------------------------------------------------------------------------- |
| `runId`      | `string` (UUID) | ID of the started run. Pass this to `poll_agent`, `answer_question`, and `read_agent_results`. |

<Warning>
  Starting a run requires the workspace to have chat funding/credits
  available, and is subject to per-user rate limiting. Both conditions
  surface as a tool error rather than a silent failure.
</Warning>

```json Example call theme={null}
{
  "prompt": "Research acme.com and tell me if they're a good fit for our ICP: B2B SaaS, 50-500 employees, uses Salesforce."
}
```

```json Example response theme={null}
{
  "runId": "b0fdcba7-a8e5-4fa3-abb0-26ee20f5ba47"
}
```

### poll\_agent

Checks the status of a run started by `run_agent`. Keep calling this while
the run is `PENDING`.

<ParamField type="string">
  The `runId` returned by `run_agent`.
</ParamField>

| Output field | Type            | Description                                                                                                            |
| :----------- | :-------------- | :--------------------------------------------------------------------------------------------------------------------- |
| `runId`      | `string` (UUID) | The run being polled.                                                                                                  |
| `status`     | `string`        | One of `PENDING`, `CLARIFICATION_NEEDED`, `READY`, `ERROR`, or `NOT_FOUND`.                                            |
| `questions`  | `array \| null` | Present when `status` is `CLARIFICATION_NEEDED`: the questions the Agent needs answered to continue. `null` otherwise. |

**Status values:**

| Status                 | Meaning                                                                                              |
| :--------------------- | :--------------------------------------------------------------------------------------------------- |
| `PENDING`              | Still running. Keep polling.                                                                         |
| `CLARIFICATION_NEEDED` | The Agent needs input before it can continue. Answer every returned question with `answer_question`. |
| `READY`                | The run finished successfully. Call `read_agent_results`.                                            |
| `ERROR`                | The run failed or was canceled. Call `read_agent_results` for the error message.                     |
| `NOT_FOUND`            | No run exists with that `runId` for this user.                                                       |

```json Example response (still running) theme={null}
{
  "runId": "b0fdcba7-a8e5-4fa3-abb0-26ee20f5ba47",
  "status": "PENDING",
  "questions": null
}
```

### answer\_question

Answers every question from a `CLARIFICATION_NEEDED` run and resumes it.
Pass the questions back exactly as `poll_agent` returned them. The tool
validates that the submitted answers line up with the pending questions
before resuming the run.

<ParamField type="string">
  The `runId` of the run awaiting clarification.
</ParamField>

<ParamField type="array">
  One answer for every question `poll_agent` returned, in the same order.

  <Expandable title="answers[]">
    <ParamField type="string">
      The exact question text as returned by `poll_agent`.
    </ParamField>

    <ParamField type="string">
      The answer to that question.
    </ParamField>
  </Expandable>
</ParamField>

| Output field      | Type            | Description                                                                                                   |
| :---------------- | :-------------- | :------------------------------------------------------------------------------------------------------------ |
| `runId`           | `string` (UUID) | The run that was resumed.                                                                                     |
| `alreadyResuming` | `boolean`       | `true` if another request had already started resuming this run. Informational only; keep polling either way. |

```json Example call theme={null}
{
  "runId": "b0fdcba7-a8e5-4fa3-abb0-26ee20f5ba47",
  "answers": [
    { "question": "Which region should I focus the search on?", "answer": "North America" }
  ]
}
```

### read\_agent\_results

Reads the final answer or error from a terminal run (`READY` or `ERROR`).
Call `poll_agent` first. This tool errors if the run hasn't reached a
terminal status yet.

<ParamField type="string">
  The `runId` of the run to read.
</ParamField>

| Output field   | Type             | Description                                                                                      |
| :------------- | :--------------- | :----------------------------------------------------------------------------------------------- |
| `status`       | `string`         | `READY` or `ERROR`.                                                                              |
| `finalAnswer`  | `string \| null` | The Agent's final answer text, when `status` is `READY`.                                         |
| `content`      | `array`          | Structured content items produced by the run (for example, tables or lists the Agent generated). |
| `errorMessage` | `string \| null` | The failure reason, when `status` is `ERROR`.                                                    |

```json Example response theme={null}
{
  "status": "READY",
  "finalAnswer": "Acme Corp looks like a strong fit: 220 employees, B2B SaaS, and their careers page lists a Salesforce Administrator role.",
  "content": [],
  "errorMessage": null
}
```

### cancel\_agent

Stops an in-flight run started by `run_agent`. It is safe to call after a run
has already finished.

<ParamField type="string">
  The `runId` returned by `run_agent`.
</ParamField>

| Output field | Type            | Description                              |
| :----------- | :-------------- | :--------------------------------------- |
| `runId`      | `string` (UUID) | The run targeted for cancellation.       |
| `outcome`    | `string`        | Either `CANCELED` or `ALREADY_TERMINAL`. |

### list\_agent\_runs

Lists Agent runs started through `run_agent` for the current user, newest
first.

<ParamField type="string">
  Exact run status to return. Omit to return all statuses.
</ParamField>

<ParamField type="number">
  Maximum runs to return per page. Cannot exceed 100.
</ParamField>

<ParamField type="string">
  The opaque `nextCursor` returned by the previous page.
</ParamField>

| Output field | Type             | Description                                                                 |
| :----------- | :--------------- | :-------------------------------------------------------------------------- |
| `runs`       | `array`          | Runs with their IDs, Unify links, titles, statuses, and start times.        |
| `nextCursor` | `string \| null` | Pass as `cursor` to load the next page; `null` when there are no more runs. |

## Context and identity tools

### get\_me

Returns the authenticated Unify user's profile and workspace identity. This
tool does not require any input.

| Output field | Type     | Description                                                                             |
| :----------- | :------- | :-------------------------------------------------------------------------------------- |
| `user`       | `object` | The current user's profile, including their ID, name, email, role, and contact details. |
| `workspace`  | `object` | The current workspace's ID, name, and domain.                                           |

### load\_datatable

Loads a Unify DataTable the calling user owns, including its metadata,
columns, and a cursor-paginated page of rows.

<ParamField type="string">
  The ID of the DataTable to load.
</ParamField>

<ParamField type="number">
  Maximum rows to return per page.
</ParamField>

<ParamField type="string">
  The opaque `nextCursor` returned by a previous call, used to load the next
  page.
</ParamField>

| Output field | Type             | Description                                                                                                                                                                               |
| :----------- | :--------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `metadata`   | `object`         | Table metadata, including `hasActiveJob` and `activeJobKinds`. If `hasActiveJob` is `true`, the table is still being populated and calling the tool again later will return updated rows. |
| `columns`    | `array`          | The table's column definitions.                                                                                                                                                           |
| `rows`       | `array`          | The current page of rows.                                                                                                                                                                 |
| `nextCursor` | `string \| null` | Pass as `cursor` to load the next page; `null` when there are no more rows.                                                                                                               |

<Info>
  Only DataTables owned by the authenticated user are accessible. This tool
  can't load another user's tables even within the same tenant.
</Info>

### load\_mailbox\_voice\_profile

Loads the writing voice profile for a specific connected mailbox, the same
profile Unify uses to personalize outbound copy in that mailbox's voice.

<ParamField type="string">
  The ID of the connected mailbox to load the voice profile for.
</ParamField>

| Output field   | Type     | Description                                                          |
| :------------- | :------- | :------------------------------------------------------------------- |
| `voiceProfile` | `object` | The mailbox's voice profile. Shape is currently unstructured/opaque. |

<Info>
  The mailbox must be connected and owned by the authenticated user, and must
  already have an analyzed voice profile, otherwise the call errors.
</Info>

### load\_general\_context

Loads a specific version of the calling user's general business context:
the same information (business description, ICP, products, pricing, and so
on) used to ground Unify's Agents.

<ParamField type="string">
  The ID of the user general context to load.
</ParamField>

<ParamField type="string">
  The specific version of that context to load.
</ParamField>

| Output field | Type     | Description                                                                                                                                                                                                                                            |
| :----------- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `context`    | `object` | Business context, including fields such as `companyName`, `businessDescription`, `industry`, `icp`, `targetBuyerPersonas`, `products`, `pricing`, `customers`, `valueProposition`, `size`, `stage`, `legalStructure`, `location`, and `versionNumber`. |

## Public API tools

These tools expose public API operations directly through MCP. Their input and
output schemas are included in the MCP tool definitions, so your client can
inspect the required fields before calling them.

### Objects and records

| Tool                                  | Purpose                                                  |
| :------------------------------------ | :------------------------------------------------------- |
| `list_objects`                        | List standard and custom objects.                        |
| `get_object`                          | Get an object definition by API name.                    |
| `create_object`                       | Create a custom object.                                  |
| `update_object`                       | Update an object's display name or description.          |
| `delete_object`                       | Delete an object.                                        |
| `list_object_attributes`              | List the attributes defined on an object.                |
| `get_object_attribute`                | Get an attribute by API name.                            |
| `create_object_attribute`             | Add an attribute to an object.                           |
| `update_object_attribute`             | Update an attribute's mutable fields.                    |
| `delete_object_attribute`             | Delete an attribute from an object.                      |
| `list_object_attribute_options`       | List options for a select attribute.                     |
| `get_object_attribute_option`         | Get one option for a select attribute.                   |
| `create_object_attribute_option`      | Add an option to a select attribute.                     |
| `update_object_attribute_option`      | Update a select option's display name.                   |
| `delete_object_attribute_option`      | Delete an option from a select attribute.                |
| `get_object_record`                   | Get a record by ID.                                      |
| `find_unique_object_record`           | Find one record using unique attribute values.           |
| `create_object_record`                | Create a record.                                         |
| `update_object_record`                | Update a record by ID.                                   |
| `upsert_object_record`                | Create or update a record using unique attribute values. |
| `delete_object_record`                | Delete a record by ID.                                   |
| `create_object_record_query_job`      | Start an asynchronous record export.                     |
| `list_object_record_query_jobs`       | List record query jobs for an object.                    |
| `get_object_record_query_job`         | Get a record query job's status.                         |
| `get_object_record_query_job_results` | Retrieve pages of record query job results.              |

### Sequences and enrollments

| Tool                                             | Purpose                                              |
| :----------------------------------------------- | :--------------------------------------------------- |
| `list_sequences`                                 | List Sequences.                                      |
| `retrieve_sequence`                              | Get a Sequence by ID.                                |
| `pause_sequence`                                 | Pause a Sequence and its enrollments.                |
| `resume_sequence`                                | Resume a paused Sequence.                            |
| `delete_sequence`                                | Delete a Sequence.                                   |
| `list_sequence_steps`                            | List a Sequence's steps.                             |
| `retrieve_sequence_step`                         | Get one Sequence step by ID.                         |
| `list_sequence_enrollments`                      | List Sequence enrollments.                           |
| `get_sequence_enrollment`                        | Get an enrollment by ID.                             |
| `create_sequence_enrollment`                     | Enroll a person in a Sequence.                       |
| `pause_sequence_enrollment`                      | Pause one enrollment.                                |
| `resume_sequence_enrollment`                     | Resume one enrollment.                               |
| `delete_sequence_enrollment`                     | Cancel one enrollment.                               |
| `create_sequence_enrollment_query_job`           | Start an asynchronous enrollment export.             |
| `list_sequence_enrollment_query_jobs`            | List enrollment query jobs.                          |
| `get_sequence_enrollment_query_job`              | Get an enrollment query job's status.                |
| `get_sequence_enrollment_query_job_results`      | Retrieve pages of enrollment query job results.      |
| `create_sequence_enrollment_step_query_job`      | Start an asynchronous enrollment-step export.        |
| `list_sequence_enrollment_step_query_jobs`       | List enrollment-step query jobs.                     |
| `get_sequence_enrollment_step_query_job`         | Get an enrollment-step query job's status.           |
| `get_sequence_enrollment_step_query_job_results` | Retrieve pages of enrollment-step query job results. |
| `cancel_sequence_enrollment_step_query_job`      | Cancel an in-progress enrollment-step query job.     |

### Tasks

| Tool                         | Purpose                                          |
| :--------------------------- | :----------------------------------------------- |
| `list_tasks`                 | List outreach and action-item tasks.             |
| `retrieve_task`              | Get a task by ID.                                |
| `create_task`                | Create a task for a person.                      |
| `update_task`                | Update a task's assignee, priority, or due date. |
| `complete_task`              | Mark a task as completed.                        |
| `delete_task`                | Delete a task.                                   |
| `create_task_query_job`      | Start an asynchronous task export.               |
| `list_task_query_jobs`       | List task query jobs.                            |
| `get_task_query_job`         | Get a task query job's status.                   |
| `get_task_query_job_results` | Retrieve pages of task query job results.        |

### Events

| Tool                          | Purpose                                       |
| :---------------------------- | :-------------------------------------------- |
| `create_event_query_job`      | Start an asynchronous analytics event export. |
| `list_event_query_jobs`       | List event query jobs.                        |
| `get_event_query_job`         | Get an event query job's status.              |
| `get_event_query_job_results` | Retrieve pages of event query job results.    |


# Unify Python library
Source: https://docs.unifygtm.com/developers/sdks/python-library

Install and use the official Unify Python library.

## Overview

Unify provides an official Python library that makes it easy to interact with
the Unify API from your code. The library handles authentication, request
formatting, and response parsing so you can focus on building your integration.

<Info>
  The Python library source code is [available on GitHub](https://github.com/unifygtm/sdk-python).
</Info>

## Quick start

You can install the Unify Python library with your preferred package manager:

<CodeGroup>
  ```shell pip theme={null}
  pip install unifygtm-sdk
  ```

  ```shell uv theme={null}
  uv add unifygtm-sdk
  ```

  ```shell poetry theme={null}
  poetry add unifygtm-sdk
  ```
</CodeGroup>

Generate an API key in [Settings → Developers](https://app.unifygtm.com/dashboard/settings/integrations/api-keys)
and then initialize the client:

<CodeGroup>
  ```python Sync theme={null}
  import os
  from unify import Unify

  client = Unify(
      # This is the default and can be omitted
      api_key=os.environ.get("UNIFY_API_KEY"),
  )

  objects = client.data.objects.list()
  print(objects.data)
  ```

  ```python Async theme={null}
  import os
  import asyncio
  from unify import AsyncUnify

  client = AsyncUnify(
      # This is the default and can be omitted
      api_key=os.environ.get("UNIFY_API_KEY"),
  )

  async def main() -> None:
      objects = await client.data.objects.list()
      print(objects.data)

  asyncio.run(main())
  ```
</CodeGroup>

<Note>
  The Python library reads the `UNIFY_API_KEY` environment variable by default.
  If the variable is set, you can omit the `api_key` parameter when
  initializing the client.
</Note>

## Usage

<AccordionGroup>
  <Accordion title="List objects">
    Retrieve all objects in your Unify workspace to see what's available:

    ```python Python theme={null}
    from unify import Unify

    client = Unify()

    objects = client.data.objects.list()

    for obj in objects.data:
        print(f"{obj.api_name} ({obj.display_name})")
    ```

    ```text theme={null}
    company (Company)
    person (Person)
    opportunity (Opportunity)
    ...
    ```
  </Accordion>

  <Accordion title="List attributes on an object">
    Retrieve the attributes defined on a specific object to understand its schema:

    ```python Python theme={null}
    attributes = client.data.attributes.list("person")

    for attr in attributes.data:
        print(f"{attr.api_name} — {attr.type} (required: {attr.is_required})")
    ```

    ```text theme={null}
    email — Text (required: True)
    first_name — Text (required: False)
    last_name — Text (required: False)
    title — Text (required: False)
    company — Reference (required: False)
    ...
    ```
  </Accordion>

  <Accordion title="Upsert a person record">
    Use the upsert endpoint to create a new record or update an existing one based
    on a unique attribute. This is the recommended approach for syncing data into
    Unify because it handles deduplication automatically.

    ```python Python theme={null}
    record = client.data.records.upsert(
        object_name="person",
        match={
            "email": "jane@acme.com",
        },
        create_or_update={
            "email": "jane@acme.com",
            "first_name": "Jane",
            "last_name": "Smith",
            "title": "Head of Growth",
            "company": {
                "match": {
                    "domain": "acme.com",
                },
                "create_or_update_if_empty": {
                    "domain": "acme.com",
                    "name": "Acme Corp",
                },
            },
        },
    )

    print(f"Record ID: {record.data.id}")
    print(f"Created at: {record.data.created_at}")
    print(f"Updated at: {record.data.updated_at}")
    ```

    ```text theme={null}
    Record ID: b0fdcba7-a8e5-4fa3-abb0-26ee20f5ba47
    Created at: 2025-04-15T14:30:00Z
    Updated at: 2025-04-15T14:30:00Z
    ```

    Running this again with updated attributes (for example, a new title) will
    update the existing record rather than creating a duplicate, because `email` is
    used as the match key.
  </Accordion>

  <Accordion title="Find a record by unique attribute">
    If you know the value of a unique attribute (like an email address), you can
    look up the record directly without needing the record ID:

    ```python Python theme={null}
    record = client.data.records.find_unique(
        object_name="person",
        match={
            "email": "jane@acme.com",
        },
    )

    print(f"Record ID: {record.data.id}")
    print(f"Name: {record.data.attributes.first_name} {record.data.attributes.last_name}")
    print(f"Title: {record.data.attributes.title}")
    ```

    ```text theme={null}
    Record ID: b0fdcba7-a8e5-4fa3-abb0-26ee20f5ba47
    Name: Jane Smith
    Title: Head of Growth
    ```
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup>
  <Card title="Send records via API" href="/developers/guides/send-data/overview" icon="rocket">
    Send data from external tools and systems via API.
  </Card>

  <Card title="Data API reference" href="/developers/api/data/overview" icon="book">
    Explore the full Data API reference.
  </Card>
</CardGroup>


# Unify TypeScript library
Source: https://docs.unifygtm.com/developers/sdks/typescript-library

Install and use the official Unify TypeScript library.

## Overview

Unify provides an official TypeScript library that makes it easy to interact
with the Unify API from your code. The library handles authentication, request
formatting, and response parsing so you can focus on building your integration.

<Info>
  The TypeScript library source code is [available on GitHub](https://github.com/unifygtm/sdk-typescript).
</Info>

## Quick start

<Warning>
  The Unify TypeScript SDK provides **server-side** access to the Unify API. For
  client-side integrations or environments where the API key is exposed, use the
  [Intent Client](/developers/intent-client/overview) instead.
</Warning>

You can install the Unify TypeScript library with your preferred package
manager:

<CodeGroup>
  ```shell npm theme={null}
  npm install @unifygtm/sdk
  ```

  ```shell yarn theme={null}
  yarn add @unifygtm/sdk
  ```

  ```shell pnpm theme={null}
  pnpm add @unifygtm/sdk
  ```

  ```shell bun theme={null}
  bun add @unifygtm/sdk
  ```
</CodeGroup>

Generate an API key in [Settings → Developers](https://app.unifygtm.com/dashboard/settings/integrations/api-keys)
and then initialize the client:

```typescript theme={null}
import Unify from '@unifygtm/sdk';

const client = new Unify({
  // This is the default and can be omitted
  apiKey: process.env['UNIFY_API_KEY'],
});

const objects = await client.data.objects.list();
console.log(objects.data);
```

<Note>
  The TypeScript library reads the `UNIFY_API_KEY` environment variable by
  default. If the variable is set, you can omit the `apiKey` parameter when
  initializing the client.
</Note>

## Usage

<AccordionGroup>
  <Accordion title="List objects">
    Retrieve all objects in your Unify workspace to see what's available:

    ```typescript TypeScript theme={null}
    import Unify from '@unifygtm/sdk';

    const client = new Unify();

    const objects = await client.data.objects.list();

    for (const obj of objects.data) {
      console.log(`${obj.api_name} (${obj.display_name})`);
    }
    ```

    ```text theme={null}
    company (Company)
    person (Person)
    opportunity (Opportunity)
    ...
    ```
  </Accordion>

  <Accordion title="List attributes on an object">
    Retrieve the attributes defined on a specific object to understand its schema:

    ```typescript TypeScript theme={null}
    const attributes = await client.data.attributes.list('person');

    for (const attr of attributes.data) {
      console.log(`${attr.api_name} — ${attr.type} (required: ${attr.is_required})`);
    }
    ```

    ```text theme={null}
    email — Text (required: true)
    first_name — Text (required: false)
    last_name — Text (required: false)
    title — Text (required: false)
    company — Reference (required: false)
    ...
    ```
  </Accordion>

  <Accordion title="Upsert a person record">
    Use the upsert endpoint to create a new record or update an existing one based
    on a unique attribute. This is the recommended approach for syncing data into
    Unify because it handles deduplication automatically.

    ```typescript TypeScript theme={null}
    const record = await client.data.records.upsert('person', {
      match: {
        email: 'jane@acme.com',
      },
      create_or_update: {
        email: 'jane@acme.com',
        first_name: 'Jane',
        last_name: 'Smith',
        title: 'Head of Growth',
        company: {
          match: {
            domain: 'acme.com',
          },
          create_or_update_if_empty: {
            domain: 'acme.com',
            name: 'Acme Corp',
          },
        },
      },
    });

    console.log(`Record ID: ${record.data.id}`);
    console.log(`Created at: ${record.data.created_at}`);
    console.log(`Updated at: ${record.data.updated_at}`);
    ```

    ```text theme={null}
    Record ID: b0fdcba7-a8e5-4fa3-abb0-26ee20f5ba47
    Created at: 2025-04-15T14:30:00Z
    Updated at: 2025-04-15T14:30:00Z
    ```

    Running this again with updated attributes (for example, a new title) will
    update the existing record rather than creating a duplicate, because `email` is
    used as the match key.
  </Accordion>

  <Accordion title="Find a record by unique attribute">
    If you know the value of a unique attribute (like an email address), you can
    look up the record directly without needing the record ID:

    ```typescript TypeScript theme={null}
    const record = await client.data.records.findUnique('person', {
      match: {
        email: 'jane@acme.com',
      },
    });

    console.log(`Record ID: ${record.data.id}`);
    console.log(`Name: ${record.data.attributes.first_name} ${record.data.attributes.last_name}`);
    console.log(`Title: ${record.data.attributes.title}`);
    ```

    ```text theme={null}
    Record ID: b0fdcba7-a8e5-4fa3-abb0-26ee20f5ba47
    Name: Jane Smith
    Title: Head of Growth
    ```
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup>
  <Card title="Send records via API" href="/developers/guides/send-data/overview" icon="rocket">
    Send data from external tools and systems via API.
  </Card>

  <Card title="Data API reference" href="/developers/api/data/overview" icon="book">
    Explore the full Data API reference.
  </Card>
</CardGroup>


# Setup guide
Source: https://docs.unifygtm.com/getting-started/setup-guide

Complete a few recommended steps to get Unify up and running.

<Steps>
  <Step title="Connect your CRM">
    If you have a CRM, you'll want to integrate it with Unify so that you can
    build exclusions, track champions, and run plays on your existing contacts
    and acccounts.

    <CardGroup>
      <Card title="Salesforce" href="/reference/integrations/salesforce/overview" icon={<SalesforceLogo />}>
        Connect your Salesforce instance.
      </Card>

      <Card title="HubSpot" href="/reference/integrations/hubspot/overview" icon={<HubspotLogo />}>
        Connect your HubSpot CRM.
      </Card>
    </CardGroup>
  </Step>

  <Step title="Integrate your website">
    One of the most popular ways to start using Unify is to identify
    which companies are visiting your marketing website and reach out to them
    with a <SequenceTooltip>Sequence</SequenceTooltip>. Unify provides
    everything you need to get started—all you need to do is connect your
    website.

    <CardGroup>
      <Card title="Understanding intent data" href="/tutorials/website-product-intent/understanding-intent-data" icon="browser">
        Learn how website and product intent data powers smarter outbound in Unify.
      </Card>

      <Card title="Getting intent data into Unify" href="/tutorials/website-product-intent/getting-intent-data-into-unify" icon="computer-mouse-button-left">
        Send web application and software usage data into Unify.
      </Card>
    </CardGroup>

    You can also connect product usage data to identify and engage with users.
    If you already use Posthog or Segment, all you need to do is configure Unify
    as a destination.
  </Step>

  <Step title="Create exclusions">
    Before you start running Plays, it's a good idea to set up some exclusions
    to prevent Unify from taking action on specific companies or people. Unify
    provides templates for common exclusions, such as existing customers and
    competitors.

    <Card title="Create an Exclusion" icon={<ExclusionsIcon />} href="/tutorials/how-to-create-an-exclusion">
      Prevent Unify from actioning on specific companies or people.
    </Card>
  </Step>

  <Step title="Start exploring">
    To keep learning, check out some of our recommended resources—you'll
    be an expert in no time.

    <CardGroup>
      <Card title="Unify University (Recommended)" href="https://www.unifygtm.com/university" icon="camera-movie">
        Extensive video library of courses, tutorials, and best practices.
      </Card>
    </CardGroup>

    <CardGroup>
      <Card title="Reference Guide" icon="book" href="/reference/overview">
        Explore the full range of features available in Unify.
      </Card>

      <Card title="Tutorials" icon="rocket-launch" href="/tutorials/how-to-create-a-play">
        Hands-on guides that cover essential features and strategies.
      </Card>
    </CardGroup>
  </Step>
</Steps>


# Welcome
Source: https://docs.unifygtm.com/index

Unify is the all-in-one solution for sales and go-to-market teams.

<div />

## Explore the platform

Become an expert and learn how to get the most out of Unify.

<CardGroup>
  <Card title="Reference Guide" icon="book" href="/reference/overview">
    Explore and learn about the features available in Unify.
  </Card>

  <Card title="Tutorials" icon="rocket-launch" href="/tutorials/how-to-create-a-play">
    Hands-on guides that cover the essential features and most popular strategies.
  </Card>

  <Card title="Unify University" icon="camera-movie" href="https://www.unifygtm.com/university">
    An extensive library of video courses covering features and best practices.
  </Card>

  <Card title="Knowledge Base" icon="circle-question" href="https://support.unifygtm.com/">
    Find answers to common questions and troubleshooting tips in our help center.
  </Card>
</CardGroup>

## Sign up

Don't have an account yet? [Try Unify for free](https://app.unifygtm.com/?screen_hint=signup).


# Always-on AI research
Source: https://docs.unifygtm.com/reference/agents/always-on-research

Learn about how AI Research works

## How does AI Research work?

During onboarding, Unify's multi-agent system researches your business to
understand your products, customers, and value proposition. By analyzing this
information, Agents are autonomously able to surface targeted insights to your
reps.

To do this, Agents generate *Observations* about the Companies and People that
flow through Unify. Observations are key pieces of information relevant to
assessing customer fit and buying intent.

<Tip>
  An *observation* is a key piece of information that AI research agents will try
  to find for a Company.
</Tip>

<Frame>
  <img alt="" />
</Frame>

Given a set of Observations, Unify Agents will generate AI Research reports for
your team. These reports surface the most relevant insights for reference when
engaging with prospects.

<Frame>
  <img alt="" />
</Frame>

## Accessing AI research

Reports can be accessed by clicking on the **AI Research** tab on any Task,
Company, or Person details page. AI Research will be automatically generated for
Tasks, and reports for Companies and People can be generated on demand.

<Frame>
  <img alt="" />
</Frame>

## Modifying your observations

Admins have the ability to add, modify, and delete Observations (up to a maximum
of 8). Observations in the **AI Research** settings page can be reordered to
adjust the order in which they appear in reports.

Modifications to the set of Observations will take effect for all future AI
Research reports that are generated. You can also regenerate existing reports
using the **Regenerate** button that appears on historical reports.

<Frame>
  <img alt="" />
</Frame>

## Testing your observations

After configuring Observations, you can run a test to see if the AI Research
Agent retrieves what you are looking for. You can either generate Observations
for specific companies or select a random sample of companies to test on. Use
this to experiment and iterate on the Observation prompts until you are
satisfied with the results.

<Tip>
  To get effective Observations, ensure that your prompt explains all of the context that is needed to retrieve the information that you are looking for.
</Tip>

<Frame>
  <img alt="" />
</Frame>


# Building an agent
Source: https://docs.unifygtm.com/reference/agents/building-an-agent

Create powerful research agents in minutes.

## Agent configuration

Every Agent is configured with three settings:

1. **Record Type**: Specify whether this agent will run on Company records or Person records.
2. **Questions**: Define research questions for the agent to answer.
3. **Guidance** (optional): Provide additional context or advice to the agent to improve the results.

Once you've configured your Agent, test it by running it on example Companies or People.

<Frame>
  <img />
</Frame>

### Record type

Agents can run on Companies or People. Data from Unify for the underlying records will be made
available to the Agent as it performs research to answer your questions.

For example, an agent intended to perform account qualification will run on Company records.
On the other hand, an agent that researches individual people for lead qualification will run on Person records.

<Warning>Once you save an Agent, you cannot change its record type.</Warning>

### Questions

Define a set of questions that the Agent will answer for you. Every question has
an expected response type. The available response types are:

<AccordionGroup>
  <Accordion title="True / False">
    Agents will respond with either `True` or `False` to a question of this type. This is best for simple questions:

    * *Does this company have an office in San Francisco?*
    * *Is there a pricing page on this company's website?*
  </Accordion>

  <Accordion title="Number">
    Agents will respond with a number to a question of this type. This is best for questions that require a numerical answer:

    * *What was the revenue for this company last year?*
    * *How many years of full-time experience does this person have?*
  </Accordion>

  <Accordion title="Select">
    Agents will respond with a *single* option from a list that you specify.
    This is best for multiple-choice questions:

    * *Is this company B2B, B2C, or B2G?*
      * Options: `B2B`, `B2C`, `B2G`
      * Answer: `B2B`

    In some cases, you may want the Agent to respond with *multiple* options from the list you provided.
    Click the `Allow multiple options` checkbox to enable this.
    When enabled, the Agent will respond with zero, one, or multiple options.

    * *Which of the following funding rounds has this company completed?*
      * Options: `Seed`, `Series A`, `Series B`, `Series C`, `Series D`, `Series E`
      * Answer: `Seed`, `Series A`
  </Accordion>
</AccordionGroup>

Try to keep your questions straightforward and concise. Longer explanations or
instructions are best suited for the [guidance prompt](#guidance-prompt).

### Guidance prompt

Optionally, you may provide a prompt to help guide your Agent's thought process.
If there is any context the Agent needs to answer your question, this is the place to include it.

Providing guidance for the Agent is usually not necessary.
The Agent already knows that it will be answering questions about a company or person,
so you do not need to include that information in the prompt.

Examples of things to include in a guidance prompt:

* What your company does
* Where to find specific information about the Person or Company to research
* Definitions for specialized terms and concepts

<Tip>
  Unify provides deep customization of and visibility into Agents' thought processes.
  You can take advantage of this to tweak questions or guidance and dial in the accuracy.
</Tip>

## Testing your agent

Unify gives you best-in-class visibility into an AI's chain-of-thought.
Leverage this to test your Agent, diagnose any issues, and iterate on your
questions and guidance prompts.

Upon providing a valid Agent configuration, an extension will appear and prompt
you to test your Agent. Use the search bar to find a specific Company or Person to test your Agent on,
or use the shuffle button to randomly select a Company or Person. The Agent will run,
explain its reasoning, and provide responses to your questions.

<Tip>
  Generate multiple examples simultaneously to speed up your workflow.
  Navigate through these examples using the arrows at the top of the screen.
</Tip>

<Frame>
  <video />
</Frame>


# Agents in Unify
Source: https://docs.unifygtm.com/reference/agents/overview

Learn what Unify Agents are and how to use them.

## What are Agents?

Agents are AI systems that perform research and take actions. In Unify, agents
run constantly in the background to study your business, observe changing data,
and provide deep insights. You can also build your own agents to for research or
copy generation.

Unify agents run on the [latest LLM technology](https://www.unifygtm.com/blog/gpt-5)
and are [carefully optimized and evaluated](https://www.unifygtm.com/blog/how-we-build-evals-for-ai-agents)
for accuracy across diverse use cases and domains. They have access to a wide
range of tools and data sources to answer questions about companies and people.

<Frame>
  <img />
</Frame>

You can create your own Agents in Unify by defining questions they should
answer. They can then be called in [Plays](/reference/plays/overview) and
[Sequences](/reference/sequences/overview) to orchestrate sophisticated growth
and outbound strategies.

Agents perform research by gathering information from a variety of sources,
including public websites and specialized APIs and data sources, If the answer
to your questions exist on the internet, Unify Agents will find them.

## Use cases

Agents are natively integrated into Unify and can be used for a wide range of
use cases:

* **Account qualification**: Agents can be [used in Plays](/reference/plays/actions#ai-qualification)
  to research companies and determine whether they match your customer profile.
* **Lead scoring**: Agents can answer complex questions about People that [run through Plays](/reference/plays/actions#ai-qualification)
  to determine whether they are the right person to reach out to.
* **Personalization**: Agents research can be used alongside [smart snippets](/reference/sequences/personalization/smart-snippets)
  to generate personalized outreach at scale.

<Tip>Check out the [Agent qualification action](/reference/plays/actions#agent-qualification) to use Agents in your Plays.</Tip>


# HubSpot
Source: https://docs.unifygtm.com/reference/browser-extension/hubspot

Run the Unify Chrome extension in HubSpot.

While viewing Companies and Contacts in HubSpot, the extension will
automatically surface the corresponding Companies and People in Unify.

## HubSpot company page

From this view, you can view People in your Unify instance who work at this Company (and add
them to a Sequence) or instantly add this Company to a Play of your choosing.

## HubSpot contact page

From this view, you can check if this Person is currently enrolled in a Unify Sequence.
If they are not already enrolled, you can enroll them from here using any mailbox or
mailbox group in Unify. Additionally, you can instantly add this Person to any of the
Plays you’ve built. See more info on building Plays in Unify [here](/reference/plays/overview).


# Introduction
Source: https://docs.unifygtm.com/reference/browser-extension/installation

Get started with the Unify Chrome extension.

<img />

Unify offers a native Chrome extension.
Some notable features of the extension include the ability to:

* View details about any Company or Person in your Unify instance
* Enroll People into Sequences
* Add Companies and People to Plays
* Add People to Unify through enrichment
* Manually add new Companies and People to Unify

## Installation

<Card title="Install Unify on the Chrome Web Store" icon={<ChromeLogo />} href="https://chromewebstore.google.com/detail/unify/badmdkkfomlfkcbjegcfjaoeegifdbmm" />

## Usage

The extension can be used anywhere on the web. Let's explore a few examples:

<CardGroup>
  <Card title="The web" icon="globe" href="/reference/browser-extension/web">
    Lookup Companies in Unify and add them to Plays as soon as you discover them
    on the web.
  </Card>

  <Card title="Salesforce" icon={<SalesforceLogo />} href="/reference/browser-extension/salesforce">
    Surface the corresponding Company or Person in Unify for Accounts, Contacts,
    & Leads in Salesforce.
  </Card>

  <Card title="HubSpot" icon={<HubspotLogo />} href="/reference/browser-extension/hubspot">
    Surface the corresponding Company or Person in Unify for Companies &
    Contacts in HubSpot.
  </Card>
</CardGroup>


# Salesforce
Source: https://docs.unifygtm.com/reference/browser-extension/salesforce

Run the Unify Chrome extension in Salesforce.

While viewing Accounts, Contacts & Leads in Salesforce, the extension will
automatically surface the corresponding Companies and People in Unify.

## Salesforce account page

From this view, you can view People in your Unify instance who work at this Company (and add
them to a Sequence) or instantly add this Company to a Play of your choosing.

<Frame>
  <img />
</Frame>

## Salesforce contact & lead pages

From this view, you can check if this Person is currently enrolled in a Unify Sequence.
If they are not already enrolled, you can enroll them from here using any mailbox or
mailbox group in Unify. Additionally, you can instantly add this Person to any of the
Plays you’ve built. See more info on building Plays in Unify [here](/reference/plays/overview).

<Frame>
  <img />
</Frame>


# Browsing the Web
Source: https://docs.unifygtm.com/reference/browser-extension/web

Run the Unify Chrome extension on other websites.

The extension can surface relevant information while browsing the web on
other sites, too. When you view a website with a domain that matches one
of the Companies in your Unify instance, the extension will automatically
surface details about that Company.

<Frame>
  <img />
</Frame>

<br />

<Frame>
  <img />
</Frame>


# Domain Configuration
Source: https://docs.unifygtm.com/reference/deliverability/domain-configuration

Set up domain names for Unify-managed mailboxes.

## Overview

In order to send emails with Unify managed deliverability, you need to add one or more sending domain to
the platform. We recommend adding multiple sending domains in order to distribute volume and create redundancy.

## What domains can I use?

* **YES** — Secondary domains: The reputation of these secondary domains are isolated from your primary domain. You want to follow best practices when naming these secondary domains to ensure they don't get flagged as spam.
* **NO** — Domains installed on other ESPs: The product cannot be used with domains that are used on e.g. Google Workspace because MX records can only be installed for one ESP at a time. You would need to remove certain existing DNS records to ensure we can register the domain succesfully on Unify.
* **NO** — Primary domains: We do not recommend using your primary domain for high-volume sending. The reason for this is to ensure your primary domain reputation is always kept pristine.

## How should I name my domain?

We generally recommend aiming for a .com or .io name and avoiding hyphens if possible. Common naming conventions include mybusiness.io, trymybusiness.com, getmybusiness.com.

We do not recommend using misspelt variations of your domain like mybuziness.com, even if these domain names are only a few letters off from your primary domain or company name. Your email provder will potentially show spam warnings on these emails because they look like phishing attempts.

## Best practices

* `SPF`, `DKIM`, `DMARC` - Unify enforces and monitors email authentication to ensure that your emails pass the tests conducted by the ESPs.
* `Branded links` - Unify will automatically generate branded links with your domain. E.g. links.mybusiness.io. These are used for unsubscribe links and open tracking.
* `Primary Domain Forwarding` - Secondary domains and subdomains should forward the user to the primary domain. This improves deliverability as users can investigate the secondary domain and as it creates a link between your primary domain and secondary domain.
* `WHOIS` - WHOIS information should be provided on the domain.
  Privacy Policy - The primary domain should have an easily accessible privacy policy.
* `Domain monitoring` - Unify will continuously monitor your domain health. For example by monitoring domain blocklists. If there is a problem you will be notified and sending can be paused.

## Purchasing a domain

The first step is to purchase a domain. This can be done through domain providers like CloudFlare, Google Domains, Squarespace, GoDaddy or Namecheap.

## Registering the domain in Unify

Navigate to the [domain settings page](https://app.unifygtm.com/dashboard/settings/deliverability/domains) and press "Add domain". Type in your domain name in the text box and press register. This process can take a few seconds, please wait for the registration to finish.

## DNS record overview

The screen will refresh showing you 7 DNS records to add. Below is an explanation of why we require each record:

<Frame>
  <img alt="domain-details-unverified" />
</Frame>

* `SPF` - The SPF record authorizes Unify to send emails on your behalf. The SPF record must be exclusive to Unify as no other email providers can be used in conjunction.,
* `DKIM` - The DKIM record allows Unify to digitally sign your emails, enabling recipients to verify their authenticity and integrity.,
* `DMARC` - The DMARC record instructs recipient mail servers on how to handle emails from your domain that fail SPF or DKIM checks, enhancing your email security.,
* `MX` - Use priority 10. The MX record allows Unify to receive email messages on your behalf. The MX records must be exclusive to Unify as no other email providers can be used in conjunction. There are two MX records to create redundancy.
* `CNAME` - There are two CNAME records. The first CNAME record is an alias to Unify servers which allows branded links to be used for unsubscribes and open tracking. The second CNAME record is a validation record which authorizes Unify to accept HTTPS requests for the branded links.

## Adding the DNS records

1. Go to your domain provider (e.g. Squarespace or GoDaddy).
2. Navigate to the DNS settings.
3. Copy paste the DNS records. In order for the DNS records to propagate quickly you can use a TTL of 600 seconds.
4. Certain providers will ask you not to include the domain in the host name field. For example, `mybusiness.io` becomes `@` or sometimes just an empty string and `links.mybusiness.io` becomes just `links`.
5. It can take multiple minutes if not hours for the DNS records to propagate. You can use the refresh button in Unify to refresh the status.
6. Once the records are verified they will light up green with the text "Verified".

## Domain activation

Once the domain is verified we will automatically activate the domain which will enable you to register mailboxes under it. This process can take up to an hour.

<Frame>
  <img alt="domain-details-active" />
</Frame>


# Mailbox Configuration
Source: https://docs.unifygtm.com/reference/deliverability/mailbox-configuration

Provision Unify-managed mailboxes for your team to send from.

## Mailbox registration and ownership

Once your domain is verified and activated, you can start setting up mailboxes
in Unify. When setting up a mailbox, provide the names of your senders to your
CSM or create mailboxes from the mailbox settings page if that workflow is
enabled for your workspace. Unify will then create email mailboxes for you (for
example, `jane@mybusiness.io`).

#### Sending emails

Through the Unify Sequencing product, you can send emails using your
Unify-managed mailboxes. The email signature and display name are pulled from
the assigned user. Unify automatically schedules emails and manages sending
volume across your mailboxes.

#### Receiving emails

Replies to [`jane@mybusiness.io`](mailto:jane@mybusiness.io) will be forwarded
to the assigned user. For example, email replies sent to the Unify-managed
mailbox [`jane@mybusiness.io`](mailto:jane@mybusiness.io) will be forwarded to
`Jane Doe's` primary email [`jane@mybusiness.com`](mailto:jane@mybusiness.com).

## Mailbox warmup

When a mailbox is created, Unify automatically starts warming the mailbox to
protect deliverability. Warming works by automatically sending emails to
addresses in a warming network. These emails are automatically opened and
replied to. If warming emails land in spam, they are taken out of spam, which is
called spam rescue. This tells email service providers that your emails are
high-quality and helps improve deliverability.

Unify continuously monitors the warmup process. After about 3 weeks, warmup will
complete and your mailboxes will be ready to send. Once your mailboxes are
warmed, they can send up to the configured mailbox send limit. Unify recommends
25 emails per mailbox per day by default. By default, send times are set to 9 AM - 4 PM PT on business days.

## Secondary forward

There are situations, such as vacation coverage, where you need a second user to
monitor replies for another user. You can set a secondary forwarding user on a
Unify-managed mailbox. This user receives a copy of replies sent to the mailbox.
For example, if `John Doe` is helping `Jane Doe` during her vacation, replies to
[`jane@mybusiness.io`](mailto:jane@mybusiness.io) can also be forwarded to
[`john@mybusiness.com`](mailto:john@mybusiness.com), John's primary email.

For more operational guidance, see
[Mailbox operations](/reference/deliverability/mailbox-operations).


# Mailbox operations
Source: https://docs.unifygtm.com/reference/deliverability/mailbox-operations

Manage mailbox owners, reply forwarding, send limits, warmup, backlog, and recipient eligibility.

## Overview

Mailboxes determine who sends Sequence emails, where replies are routed, and how
quickly queued emails can leave Unify. Most mailbox controls live in
[Settings → Deliverability → Mailboxes](https://app.unifygtm.com/dashboard/settings/deliverability/mailboxes)
and organization-level sending controls live in
[Settings → Organization → Sequences](https://app.unifygtm.com/dashboard/settings/organization/sequences).

Some controls apply only to Unify-managed mailboxes. Connected Gmail mailboxes
can have different authorization and forwarding behavior because they are tied
to the connected Google account.

## Assigned user and mailbox ownership

Each mailbox has an assigned user. For Unify-managed mailboxes, the assigned
user is the person represented by the mailbox:

* The sender display name and email signature come from the assigned user.
* Replies to the mailbox are forwarded to the assigned user's primary email.
* Sequence tasks and routing can use the assigned user, depending on your
  Sequence ruleset settings.

Admins with permission to manage email integrations can change the assigned user
from the mailbox details page. If the assigned-user field is disabled, contact a
workspace admin. If the mailbox is managed by Unify and the change is not
available in your workspace, contact Unify support or your CSM.

## Reply routing and forwarding

When a recipient replies to a Sequence email, they reply to the sending mailbox
address. For example, replies to `jane@mybusiness.io` are received by that
mailbox and forwarded to the assigned user's primary email.

Unify-managed mailboxes can also have a secondary forwarding user. Secondary
forwarding sends a copy of replies to another user, such as a teammate covering
for the assigned user. It does not change the sender address that the recipient
sees.

In mailbox details, the **Forwarding Email** field shows the current forwarding
destination when Unify can read it from the provider. If forwarding looks wrong
or is missing, check the mailbox details page and the mailbox provider before
changing Sequence routing.

## Warmup and ramp-up

New Unify-managed mailboxes warm before they are used for normal Sequence
sending. During warmup, Unify sends warmup emails through a warmup network,
monitors engagement, and helps build mailbox reputation. The existing mailbox
configuration guide describes the standard warmup process.

A mailbox can show these operational states:

| State            | What it means                                                                          |
| ---------------- | -------------------------------------------------------------------------------------- |
| **Warming**      | The mailbox is still building reputation and is not ready for normal Sequence sending. |
| **Warm**         | The mailbox is warmed and can be used for Plays and Sequences.                         |
| **Paused**       | The mailbox is intentionally paused and will not send until it is unpaused.            |
| **Unauthorized** | The mailbox needs to be reauthorized before Unify can send from it.                    |

Mailbox ramp-up starts at 0 for new mailboxes or at the previous daily send
limit for existing mailboxes. When enabled, it increases the daily send limit
until it reaches the configured maximum.

## Send limits and scheduling

Unify uses send limits and schedules to protect deliverability.

At the organization level, admins can set the maximum number of sends per
mailbox per 24 hours. A mailbox can also override the organization limit from
the mailbox details page. Unify recommends 25 emails per mailbox per day by
default.

By default, Sequence emails are sent on business days between 9 AM and 4 PM
Pacific time. Sends are staggered throughout the day, with the default spacing
fluctuating between roughly 2 and 6 minutes to emulate natural sending patterns.

Use [custom send schedules](/reference/sequences/send-schedules/overview) to
customize the send window, time zone, holiday behavior, or excluded date set for
Sequences.

## Backlog and queued emails

Queued Sequence emails wait in the outbox until the selected mailbox has send
capacity during an allowed send window. A mailbox with a large backlog may have
valid queued emails that are simply waiting for capacity.

When a specific Sequence email is delayed, check:

* The enrollment status and step status.
* The mailbox status: warm, ramping, paused, or unauthorized.
* The mailbox daily send limit and current daily send limit.
* The Sequence send schedule and allowed send days.
* Whether other pending outbox messages are already using that mailbox's daily
  capacity.

If volume drops unexpectedly across a workspace, compare the number of active
mailboxes, their send limits, warmup/ramp-up state, paused or unauthorized
mailboxes, and the number of blocked or bounce-stopped enrollments.

## Recipient eligibility and bounce safeguards

Unify checks email verification before sending Sequence email. Admins can
configure which verification statuses are eligible for sending in Sequence
deliverability settings.

| Verification status | Default behavior                                                                                                                                                      |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Valid**           | Eligible for sending.                                                                                                                                                 |
| **Catch-all**       | Eligible by default. Catch-all domains accept mail for many addresses, so validity can only be confirmed after sending and bounce risk is less predictable.           |
| **Unverified**      | Eligible by default. Delivery may succeed, but reliability is uncertain.                                                                                              |
| **Role-based**      | Not eligible by default. These are shared inboxes such as `info@`, `support@`, or `sales@`; they are valid but often have lower engagement and higher filtering risk. |
| **Invalid**         | Not eligible and cannot be enabled for sending. These addresses are confirmed undeliverable.                                                                          |

If Unify identifies a high bounce risk or invalid email before sending, the
Sequence enrollment can stop with **Bounce stopped** instead of sending the
email. Review the Person's email address before enrolling them again.

## Troubleshooting

<AccordionGroup>
  <Accordion title="Replies are going to the wrong person">
    Check the mailbox assigned user and secondary forwarding user. For
    Unify-managed mailboxes, replies forward to the assigned user's primary
    email and any secondary forwarding user.
  </Accordion>

  <Accordion title="A mailbox is not available for Plays or Sequences">
    Check whether the mailbox is still warming, paused, unauthorized, deleted,
    or not assigned to an active user.
  </Accordion>

  <Accordion title="Queued emails are not sending">
    Check the mailbox send limit, current ramp-up limit, send schedule, allowed
    send days, mailbox backlog, and whether the enrollment is blocked.
  </Accordion>

  <Accordion title="Send volume is lower than expected">
    Check warmup/ramp-up, daily send limits, paused or unauthorized mailboxes,
    Sequence send windows, and whether too many enrollments are assigned to a
    small number of mailboxes.
  </Accordion>

  <Accordion title="A Person was stopped before sending">
    Check recipient eligibility settings and the Person's email verification
    status. Invalid emails are not sent, and high-risk emails may result in a
    "Bounce stopped" outcome.
  </Accordion>

  <Accordion title="DNS records are not verified">
    Review the domain records in [Domain configuration](/reference/deliverability/domain-configuration),
    especially SPF, DKIM, DMARC, MX, and CNAME records.
  </Accordion>
</AccordionGroup>


# Managed Deliverability
Source: https://docs.unifygtm.com/reference/deliverability/overview

Safeguard your deliverability while sending emails at scale.

## Overview

Unify's suite of deliverability features enable you to send large volumes of
emails without needing to manage your own infrastructure.

Maintaining high deliverability typically requires continuous, tedious work,
such as mailbox warming, IP rotation, and engagement monitoring. Unify takes
care of that for you by provisioning and managing mailboxes on your behalf.

Unify's deliverability capabilities integrate with Unify sequences and the rest
of the Unify product. Unify will automatically adjust sending patterns and
limits as needed.

## Setup

To get started, you'll first need to configure your domain and mailboxes. See
the next sections for more information.

<CardGroup>
  <Card title="Domain Configuration" icon={<WebsiteIcon />} href="/reference/deliverability/domain-configuration">
    Add domains to use for Unify-managed mailboxes.
  </Card>

  <Card title="Mailbox Configuration" icon={<MailboxesIcon />} href="/reference/deliverability/mailbox-configuration">
    Provision Unify-managed mailboxes for your team to send emails from.
  </Card>

  <Card title="Mailbox Operations" icon={<MailboxesIcon />} href="/reference/deliverability/mailbox-operations">
    Manage mailbox owners, forwarding, warmup, send limits, and backlog.
  </Card>
</CardGroup>


# Call recording
Source: https://docs.unifygtm.com/reference/dialer/call-recording

How call recording and transcription work, and where to manage recording settings.

Unify transcribes and records calls based on your recording settings. You
control recording behavior for your organization, so it matches how your team
wants to operate.

<Warning>
  **You are responsible for your own compliance.** It is your responsibility to
  ensure that your use of call recording and dialing complies with all laws and
  regulations that apply to you and the people you call, including any consent or
  notification requirements. Unify does not provide legal advice. If you are
  unsure of your obligations, consult your legal team before recording calls. Use
  the recording settings in
  [**Settings → Dialer**](https://app.unifygtm.com/dashboard/settings/features/dialer)
  to configure recording to meet your requirements.
</Warning>

## Recording settings

Call recording is controlled by your organization's recording settings. Admins
manage how recording behaves and can turn it on or off in
[**Settings → Dialer**](https://app.unifygtm.com/dashboard/settings/features/dialer).
Recording follows those settings on every call, so there is nothing for reps to
toggle mid-call.

An in-call **recording badge** shows whether the current call is being recorded,
so reps always know the state of the call in real time.

<Note>
  Unify does not play an automated announcement telling the person on the other
  end that the call is being recorded.
</Note>

## What gets saved

Calls are transcribed and recorded based on your recording settings. When a call
is recorded, the recording is attached to the call alongside the transcript.
Both are visible in Unify and [sync to your CRM](/reference/dialer/crm-sync)
with the logged call.

## Calling hours

For calls placed outside 8am to 9pm in the prospect's local time, Unify shows a
warning before the call connects. Unify does not block after-hours calls, so the
rep can proceed or cancel.

## Frequently asked questions

<AccordionGroup>
  <Accordion title="Are calls recorded?">
    Recording follows your organization's recording settings. Admins manage
    recording behavior in **Settings → Dialer**.
  </Accordion>

  <Accordion title="How do I change what gets recorded?">
    Admins manage recording in **Settings → Dialer**. Update the settings there
    to match how your team wants to record calls.
  </Accordion>

  <Accordion title="Does Unify announce that the call is being recorded?">
    No. Unify does not play a recording announcement. An in-call badge shows
    whether the current call is being recorded.
  </Accordion>
</AccordionGroup>


# Syncing calls to your CRM
Source: https://docs.unifygtm.com/reference/dialer/crm-sync

How calls, dispositions, recordings, and transcripts write back to your CRM.

One of the biggest reasons to call from inside Unify is that every call logs
itself. When a rep hangs up and logs a disposition, Unify writes the call back
to the person record and syncs it to your CRM automatically.

## What syncs

Each call syncs to Salesforce or HubSpot as an activity on the matched person,
including:

* The **call** itself, with its time and duration.
* The **disposition** the rep logged, such as Meeting booked or Not interested.
* The **notes** the rep logged on the call.
* The **transcript** of the call.
* The **recording**, when
  [recording was on](/reference/dialer/call-recording) for that call.

Inbound callbacks are logged too, so both sides of the conversation show up in
your CRM and reporting.

## How calls are matched

Calls sync to the person record they were placed from, so the activity lands on
the right contact or lead in your CRM without manual matching. The write-back
uses your existing CRM connection and field mappings.

## Supported CRMs

<CardGroup>
  <Card title="Salesforce" icon={<SalesforceLogo />} href="/reference/integrations/salesforce/overview">
    Calls sync as activities on the matched person in Salesforce.
  </Card>

  <Card title="HubSpot" icon={<HubspotLogo />} href="/reference/integrations/hubspot/overview">
    Calls sync as activities on the matched person in HubSpot.
  </Card>
</CardGroup>

<Note>
  Call sync uses the same CRM connection as the rest of Unify. If calls aren't
  appearing in your CRM, confirm your
  [Salesforce](/reference/integrations/salesforce/overview) or
  [HubSpot](/reference/integrations/hubspot/overview) integration is connected
  and syncing.
</Note>


# Making calls
Source: https://docs.unifygtm.com/reference/dialer/making-calls

Place calls from tasks, Sequences, or a person record and log the outcome.

Once the [dialer is set up](/reference/dialer/setup), a rep can call any person
with a phone number by clicking that number in Unify. The call connects in the
browser, and the rep logs the outcome when the call ends. This page covers where
calls start, what the in-call experience looks like, and how to log a call.

## Where calls start

<CardGroup>
  <Card title="From a task" icon={<PhoneCallIcon />} href="#calling-from-a-task">
    Work a queue of call tasks and dial each one in turn.
  </Card>

  <Card title="From a Sequence" icon={<PhoneCallIcon />} href="#calling-from-a-sequence">
    Dial when a Sequence reaches a phone-call step.
  </Card>

  <Card title="Ad-hoc" icon={<PhoneCallIcon />} href="#ad-hoc-calls">
    Click a number on any person record to call right away.
  </Card>
</CardGroup>

### Calling from a task

Call tasks are the most common way reps dial. Working a list of call tasks
(often built from intent or engagement signals), a rep clicks to dial each one,
talks, logs a disposition, and moves to the next without leaving the queue.

Call tasks can be created individually or generated by a
[phone-call step in a Sequence](/reference/sequences/sequence-step-types#phone-call).

### Calling from a Sequence

When a Sequence reaches a phone-call step, Unify creates a call task for the
assigned rep. The rep dials the prospect from inside the Sequence, and the call
writes back to the CRM on its own. See
[Sequence step types](/reference/sequences/sequence-step-types#phone-call) for
how phone-call steps are configured.

### Ad-hoc calls

No task is required to call someone. Click the phone number on any person record
and Unify dials it immediately.

If the person has no phone number, enrich them on the spot and Unify will find
a number to dial.

## The in-call experience

When a call connects, the rep stays inside Unify with the person's full context
on screen: account activity, research, notes, and signals. Reps can navigate
Unify freely during the call to inform the conversation.

An in-call **recording badge** shows whether the current call is being recorded.
See [Call recording](/reference/dialer/call-recording).

If a call falls outside 8am to 9pm in the prospect's local time, Unify shows a
warning before the call connects. Unify does not block the call, so the rep can
proceed or cancel.

<Tip>
  Prompt Chat with who you're calling before you dial and it will produce
  research, insights, or a full call script to prep with.
</Tip>

## Logging a call

When the rep hangs up, they log a disposition in one click. The preset
dispositions are:

| Disposition        | Use it when                                        |
| ------------------ | -------------------------------------------------- |
| **No answer**      | The call rang out with no answer.                  |
| **Left voicemail** | You reached voicemail and left a message.          |
| **Busy signal**    | The line was busy.                                 |
| **Bad number**     | The number was wrong or disconnected.              |
| **Gatekeeper**     | You reached a gatekeeper rather than the prospect. |
| **Referral**       | You were referred to a different contact.          |
| **Call later**     | The prospect asked you to call back another time.  |
| **Not interested** | The prospect was not interested.                   |
| **Interested**     | The prospect was interested.                       |
| **Meeting booked** | The call resulted in a booked meeting.             |

The disposition, along with any notes, the call recording, and the transcript,
is written back to the person record and
[synced to your CRM](/reference/dialer/crm-sync).

## Redial and repeat calls

After a call, reps can redial the same prospect directly from the call view.

To protect prospects and your numbers' reputation, Unify warns you before a
third call to the same person in one day and soft-blocks additional calls beyond
that.

## Frequently asked questions

<AccordionGroup>
  <Accordion title="Do I need a task to place a call?">
    No. You can click the number on any person record and it dials, with or
    without an existing task.
  </Accordion>

  <Accordion title="Can I call someone without a phone number on file?">
    Yes. Enrich the person on the spot and Unify will find a number to dial.
  </Accordion>

  <Accordion title="Can Chat prepare call notes before I dial?">
    Yes. Tell Chat who you're calling and it will generate research, insights,
    or a full call script. Starting the dial itself from Chat is on the roadmap.
  </Accordion>

  <Accordion title="Is there a limit on how many times I can call someone in a day?">
    Unify warns you before a third call to the same person in one day and
    soft-blocks additional calls beyond that.
  </Accordion>
</AccordionGroup>


# Unify Dialer
Source: https://docs.unifygtm.com/reference/dialer/overview

Call prospects directly from Unify and log every call automatically.

## What is the dialer?

The Unify dialer lets reps call prospects straight from Unify, with no separate
dialer tab to juggle. A rep clicks a phone number anywhere it appears, the call
connects in the browser, and the rep logs the outcome on hang-up. Every call,
disposition, recording, and transcript logs itself back to the record and syncs
to your CRM, so reps stop copy-pasting numbers and hand-logging notes.

Because the dialer lives where reps already research accounts, review signals,
and run Sequences, every call happens with full context and each touch is
captured automatically.

<Note>
  The dialer places outbound calls to the United States and Canada. Support for
  additional countries is on the roadmap.
</Note>

## How it works

When a rep clicks a phone number in Unify, the browser opens a call session and
places the outbound call through our telephony provider. From there:

1. Unify selects which of your numbers to call from.
2. The call connects in the browser and the rep talks to the prospect.
3. The call is transcribed and recorded based on your recording settings (see
   [Call recording](/reference/dialer/call-recording)).
4. On hang-up, the rep logs a disposition in one click.
5. The call, disposition, recording, and transcript
   [sync to your CRM](/reference/dialer/crm-sync) as an activity on the matched
   person.

## Where you can call from

Calls can start from three places in Unify. Whichever you use, the in-call
experience and logging are the same.

<CardGroup>
  <Card title="Call tasks" icon={<PhoneCallIcon />} href="/reference/dialer/making-calls#calling-from-a-task">
    Work a list of call tasks and dial each one without leaving the queue.
  </Card>

  <Card title="Sequence steps" icon={<PhoneCallIcon />} href="/reference/dialer/making-calls#calling-from-a-sequence">
    Dial the prospect when a Sequence reaches a phone-call step.
  </Card>

  <Card title="Person records" icon={<PhoneCallIcon />} href="/reference/dialer/making-calls#ad-hoc-calls">
    Click a number on any person record to place an ad-hoc call.
  </Card>
</CardGroup>

## What you can do

* Place outbound calls to United States and Canada numbers from inside Unify.
* Record and transcribe calls based on your recording settings.
* Log a call outcome in one click and add notes.
* [Sync](/reference/dialer/crm-sync) the call, disposition, notes, recording, and
  transcript back to Salesforce or HubSpot automatically.
* Route prospect callbacks to your own phone with a
  [forwarding number](/reference/dialer/setup#set-a-forwarding-number).
* Use Chat to prep before a call with research, talk tracks, and full call
  scripts on demand.

## Get started

<CardGroup>
  <Card title="Set up the dialer" icon={<SettingsIcon />} href="/reference/dialer/setup">
    Activate the dialer, then buy and assign phone numbers.
  </Card>

  <Card title="Make your first call" icon={<PhoneCallIcon />} href="/reference/dialer/making-calls">
    Dial from a task, a Sequence step, or a person record.
  </Card>
</CardGroup>

## Frequently asked questions

<AccordionGroup>
  <Accordion title="Which countries does the dialer support?">
    The United States and Canada. International calling beyond the US and Canada
    is on the roadmap.
  </Accordion>

  <Accordion title="What does the dialer cost?">
    Calling is included for Unify customers with no separate seat fee. Each rep
    gets free phone numbers based on your plan, and call time is billed in
    credits per minute once the prospect picks up. See
    [Pricing](/reference/dialer/pricing) for details.
  </Accordion>

  <Accordion title="Does it power-dial through a list automatically?">
    Not yet. Today the dialer is a single-call loop: click, talk, log. Power
    dialing is on the roadmap.
  </Accordion>

  <Accordion title="Can I dial from Chat?">
    Not yet. Today you can use Chat to prep for a call (research, a talk track,
    or a full script), but starting the dial itself from Chat is on the roadmap.
  </Accordion>

  <Accordion title="Can I call someone who doesn't have a phone number yet?">
    Yes. If a person has no number, enrich them on the spot and Unify will find
    one to dial.
  </Accordion>

  <Accordion title="What happens when a prospect calls back?">
    Callbacks route to the forwarding number you set in **Settings → Dialer**,
    such as your mobile. If you don't pick up, the call goes to that phone's
    voicemail. Inbound calls are logged to the activity log and reporting.
    Answering callbacks directly in Unify is on the roadmap. See
    [Set a forwarding number](/reference/dialer/setup#set-a-forwarding-number).
  </Accordion>
</AccordionGroup>


# Dialer pricing
Source: https://docs.unifygtm.com/reference/dialer/pricing

How phone numbers and call usage are billed for the dialer.

Two things drive dialer cost: the phone numbers your reps hold and the call time
they use. Calling is included for Unify customers, with no separate seat fee to
turn the dialer on.

## Phone numbers

Each rep gets a set of free phone numbers based on your plan. Reps can hold more
than the free allowance, and additional numbers cost 100 credits per number per
month.

| Plan                         | Free numbers per rep | Maximum numbers per rep |
| ---------------------------- | -------------------- | ----------------------- |
| Self-serve customers         | 1                    | 5                       |
| Customers on a business plan | 5                    | 10                      |

Add or assign numbers in [**Settings → Dialer**](https://app.unifygtm.com). See
[Setup](/reference/dialer/setup#add-and-assign-phone-numbers) for the steps.

## Call usage

Call time is billed at 2 credits per minute. Billing starts when the prospect
answers or voicemail recording begins, and minutes are rounded up to the nearest
full minute.

If your team runs out of credits, calling pauses until you top up your balance
from the in-product prompt.

<Note>
  For how credits work across Unify, see the
  [credit system](/reference/management/credit-system).
</Note>


# Setting up the dialer
Source: https://docs.unifygtm.com/reference/dialer/setup

Activate the dialer, buy phone numbers, and set a forwarding number.

Getting a team ready to call takes three things: activating the dialer for your
organization, giving reps phone numbers to call from, and setting a forwarding
number so callbacks reach you. Activation is an admin task; setting a forwarding
number is done per rep.

## Activate the dialer

An admin turns the dialer on for your organization in
[**Settings → Dialer**](https://app.unifygtm.com/dashboard/settings/features/dialer).
Once it is enabled, the dialer is available to your team.

<Note>
  If you don't see the dialer, make sure an admin has enabled it in
  Settings → Dialer and that phone numbers have been added.
</Note>

## Add and assign phone numbers

Reps call from numbers your organization provisions in Unify. How many free
numbers each rep gets depends on your plan, and admins can add more beyond the
free allowance for a monthly fee per number. See
[Pricing](/reference/dialer/pricing) for the details.

<Steps>
  <Step title="Open dialer settings">
    Go to
    [**Settings → Dialer**](https://app.unifygtm.com/dashboard/settings/features/dialer)
    and click **+ Add Phone Number**.
  </Step>

  <Step title="Buy a number">
    Choose a number to provision. Unify assigns United States local numbers.
  </Step>

  <Step title="Assign it to a rep">
    Assign the number to the rep who will call from it. How many numbers a rep
    can hold depends on your plan. See [Pricing](/reference/dialer/pricing) for
    the free allowance and limits.
  </Step>
</Steps>

## Set a forwarding number

A forwarding number is where prospect callbacks are sent, typically a rep's
mobile. Setting one means a prospect who calls back reaches the rep instead of
dead-ending.

<Steps>
  <Step title="Open dialer settings">
    Go to
    [**Settings → Dialer**](https://app.unifygtm.com/dashboard/settings/features/dialer).
  </Step>

  <Step title="Add a forwarding number">
    Enter the phone number where callbacks should ring, such as your mobile, and
    save.
  </Step>
</Steps>

If a rep doesn't pick up a callback, it lands in that phone's voicemail. Inbound
calls are logged to the activity log and reporting.

<Note>
  Forwarding numbers are for receiving callbacks only. Outbound calls always
  use the provisioned numbers assigned to a rep, never a personal number.
</Note>

## Start calling

Once the dialer is active and reps have numbers, they can place their first
call from a task, a Sequence step, or any person record. See
[Making calls](/reference/dialer/making-calls).


# Glossary
Source: https://docs.unifygtm.com/reference/glossary

Figure out what terms mean and where to learn more about them.

## Company

A *company* represents a business or organization in Unify. Companies are one of
the primary record types you'll work with. You can view them in the [Companies tab](https://app.unifygtm.com/dashboard/companies),
build exclusions to prevent engaging with certain companies, create audiences
and Plays to target specific companies, and more.

Companies come from many different integrations and data sources. Unify can
identify companies from website visitors (using visitor identification), CRM
syncs, CSV uploads, integrations into third-party tools, and even data you send
in through the [developer APIs](/developers/api/data/overview).

Companies can be linked to People, CRM records (like Salesforce Accounts or
HubSpot Companies), and any custom data you bring into Unify.

## CRM

A *CRM* (short for "customer relationship management") is a system for managing
customer interactions and data throughout the customer lifecycle. The most
established CRM software products are Salesforce and HubSpot.

<AccordionGroup>
  <Accordion title="Does everyone need a CRM?">
    Most businesses need a CRM once they reach a certain size or level of
    maturity in terms of customer count or number of customer interactions.

    However, many earlier teams and small businesses do not need a CRM and
    instead track customer relationships in a different way, such as using
    spreadsheets.

    In addition, not all customers are tracked in CRMs. Many teams track their
    self-serve or product-led growth customers using different tools, such as
    a data warehouse.
  </Accordion>

  <Accordion title="What CRMs does Unify integrate with?">
    Unify has dedicated integrations for both Salesforce and HubSpot.

    <CardGroup>
      <Card title="Salesforce" href="/reference/integrations/salesforce/overview" icon={<SalesforceLogo />}>
        Connect your Salesforce instance.
      </Card>

      <Card title="HubSpot" href="/reference/integrations/hubspot/overview" icon={<HubspotLogo />}>
        Connect your HubSpot CRM.
      </Card>
    </CardGroup>
  </Accordion>
</AccordionGroup>

## Custom event

A *custom event* captures a user interaction on a website, web application, or
other software. Examples include form fills, button clicks, sign-ups, and more.

Custom events are collected using the [Unify Intent client](/developers/intent-client/overview)
or similar tools. Once in Unify, they are linked to Companies and People. They
can be seen in the activity feed for specific companies and people and can be
used to trigger Plays.

For more information, see the following guides:

<CardGroup>
  <Card title="Connect website traffic" href="/developers/guides/website-traffic/introduction" icon="browser">
    Send website visitors, sessions, and events into Unify.
  </Card>

  <Card title="Connect product usage data" href="/developers/guides/product-usage-data/introduction" icon="computer-mouse-button-left">
    Send web application and software usage data into Unify.
  </Card>
</CardGroup>

## Data lake

A *data lake* is a centralized repository that allows you to store all your
structured and unstructured data at any scale. You can store your data as-is,
without having to first structure the data, and then use and analyze it with
specialized tools that can connect to data lake data.

Unify supports syncing data from external data lakes into Unify and then using
that data to power features. The easiest way to connect a data lake to Unify is
via a reverse ETL tool like Hightouch or Census. If you're looking for more
flexibility, you can also create custom processes that send data to the [Data API](/developers/api/data/overview)
directly.

For more information, see [Connect data systems to Unify](/developers/guides/data-systems/overview).

## Data system

A *data system* is any external system that stores data outside of Unify. This
term is used to refer broadly to databases, data warehouses, data lakes, and
more.

Unify supports syncing data from external data systems into Unify and then using
that data to power features. You can build Exclusions, Plays, Sequences, and
more based on data that lives in external data systems.

For more information, see [Connect data systems to Unify](/developers/guides/data-systems/overview).

## Data warehouse

A *data warehouse* is a centralized repository that allows you to store all your
structured data at any scale. Snowflake, BigQuery, Redshift, and Databricks are
some of the most popular data warehouse products.

Unify supports syncing data from external data warehouses into Unify and then
using that data to power features. The easiest way to connect a data warehouse
to Unify is via a reverse ETL tool like Hightouch or Census. If you're looking
for more flexibility, you can also create custom processes that send data to the
[Data API](/developers/api/data/overview).

For more information, see [Connect data systems to Unify](/developers/guides/data-systems/overview).

## Database

A *database* is tool for storing and managing data in a structured way. Often,
databases are the source of truth for operational or product data. PostgreSQL,
MySQL, and MongoDB are some of the most popular database products.

Unify supports syncing data from external databases into Unify and then using
that data to power features. The easiest way to connect a database to Unify is
via a reverse ETL tool like Hightouch or Census. If you're looking for more
flexibility, you can also create custom processes that send data to the [Data API](/developers/api/data/overview)
directly.

For more information, see [Connect data systems to Unify](/developers/guides/data-systems/overview).

## Event

An *event* captures something that happened at a specific moment—a page visit, a
button click, a form submission, a login, or any other action on your website or
product.

Unify supports three kinds of events:

* **Page events** record when someone visits a page on your website or app.
* **Identify events** indicate who a visitor is (usually by providing an email
  address), which links all of their activity to a known Person or Company.
* **Custom events** capture specific actions you define, like "Demo Requested"
  or "Paywall Hit." These are the events you'll typically use to trigger [Plays](#play).

Events are collected by integrating with your website, web application, or other
software. For more information, see [Getting intent data into Unify](/tutorials/website-product-intent/getting-intent-data-into-unify).

## Person

A *person* represents an individual contact within Unify. People are linked to
Companies and can be enrolled in Sequences, actioned on by Plays, and viewed in
the [People tab](https://app.unifygtm.com/dashboard/people).

People can enter Unify through many paths: CRM syncs, prospecting, enrichment,
form fills, Identify events from your website or product, and data you send via
API.

When a website visitor or product user is identified (for example, by logging in
or submitting a form), Unify links their activity history to a Person record.
This is what makes it possible to see a Person's full engagement—website visits,
product usage, email interactions—in one place.

## Play

Plays are automated workflows that let you build and execute repeatable
strategies. Unify manages the logistics of coordinating and scaling all the
details.

For more information, see [Unify Plays](/reference/plays/overview) or [How to Create a Play](/tutorials/how-to-create-a-play).

## Sequence

A sequence is a series of automated or manual steps that let you reach out to
buyers and run sophisticated outbound at scale. Sequences are purpose-built for
modern outbound sales with native AI capabilities and deep integration with the
Unify platform.

For more information, see [Unify Sequences](/reference/sequences/overview).


# 6sense integration guide
Source: https://docs.unifygtm.com/reference/integrations/6sense

Use your existing subscription to identify website visitors.

## Overview

Unify integrates with 6sense in two ways:

* If you already have a 6sense subscription, you can connect it to Unify by
  providing your API key to identify website visitors.
* [Unify Intent](https://app.unifygtm.com/dashboard/settings/integrations/unify-intent)
  identifies website visitors out of the box and is powered by 6sense as well as
  other providers.

Unify uses 6sense along with various other providers to identify website
visitors. If you already have a 6sense subscription, you can connect it to Unify
by providing your API key.

## Setup

To connect your existing 6sense subscription to Unify, simply navigate to
[Settings → Integrations → 6sense](https://app.unifygtm.com/dashboard/settings/integrations/6sense)
and enter your API key. Unify will start using your 6sense account to identify
website visitors.

<Note>
  Some customers do not have their 6sense API token enabled by default. If you
  don't see website visitors being identified soon after entering your API key and
  setting up the website tag, this might be the case for you.

  You can reach out to [support@6sense.com](mailto:support@6sense.com) or your dedicated CSM with the following
  message:

  > Hi there,
  >
  > We need an API token to hit the reveal ([https://epsilon.6sense.com/v3/company/details](https://epsilon.6sense.com/v3/company/details)) API in a server to server (not from the browser) mode.
  >
  > Could you please provide the API key?
  >
  > Thanks,

  They should be able to enable access for you.
</Note>


# Clearbit integration guide
Source: https://docs.unifygtm.com/reference/integrations/clearbit

Use your existing subscription to identify website visitors.

## Overview

Unify integrates with Clearbit in two ways:

* If you already have a Clearbit subscription, you can connect it to Unify by
  providing your API key to identify website visitors.
* [Unify Intent](https://app.unifygtm.com/dashboard/settings/integrations/unify-intent)
  identifies website visitors out of the box and is powered by Clearbit as well
  as other providers.

Unify uses Clearbit along with various other providers to identify website
visitors. If you already have a Clearbit subscription, you can connect it to
Unify by providing your API key.

## Setup

To connect your existing Clearbit subscription to Unify, simply navigate to
[Settings → Integrations → Clearbit](https://app.unifygtm.com/dashboard/settings/integrations/clearbit)
and enter your API key. Unify will start using your Clearbit account to identify
website visitors.


# Demandbase integration guide
Source: https://docs.unifygtm.com/reference/integrations/demandbase

Identify website visitors with Demandbase and other providers.

## Overview

Unify provides out-of-the-box website visitor identification Demandbase and
other providers. To get started, simply enable [Unify Intent](https://app.unifygtm.com/dashboard/settings/integrations/unify-intent)
in your settings.

Once connected, Unify will automatically begin identifying website visitors
using Demandbase and other data sources for maximum coverage. Be sure to set up
the Unify Intent client on your website to start receiving visitors to identify.


# G2 integration guide
Source: https://docs.unifygtm.com/reference/integrations/g2

Revealing anonymous visitors on your G2 profile.

## Overview

You can connect your G2 account to Unify to reveal anonymous visitors on your G2
profile, comparison pages, and more. These visitors can then be used to create
Audiences and Plays.

## Setup

To connect your existing G2 subscription to Unify, simply navigate to
[Settings → Integrations → G2](https://app.unifygtm.com/dashboard/settings/integrations/g2)
and enter your API token. Your API token can be found [here](https://my.g2.com/)
in the G2 dashboard. Once this is done, Unify will start using your G2 account
to identify visitors.


# Gmail integration guide
Source: https://docs.unifygtm.com/reference/integrations/gmail

This guide outlines how start sending and receiving emails via Gmail in Unify.

## Overview

Unify integrates with Gmail to send and receive emails in sequences. Once your mailbox is connected, you can start enrolling people in sequences and sending outbound emails.

## Connecting to Gmail

1. Go to [Settings → Mailboxes](https://app.unifygtm.com/dashboard/settings/deliverability/mailboxes)
   in Unify and select **New Mailbox**

2. After being redirected to Gmail's authorization page, select the mailbox you
   want to connect and choose **Allow** to proceed

<Frame>
  <img alt="gmail-integration-step-2" />
</Frame>

3. You will be redirected back to the mailbox settings page, where you can see
   the status of your newly connected mailbox


# Google Tag Manager integration guide
Source: https://docs.unifygtm.com/reference/integrations/google-tag-manager

This guide outlines how to install the Unify website tag using Google Tag Manager.

## Overview

Unify provides several different ways to start collecting intent data from your
website. The quickest way to get started is by installing the Unify website tag
directly on your website.

If you're using Google Tag Manager, you can add the website tag as a custom HTML
tag. This allows you to manage all your scripts in one place and easily control
when and where they are loaded.

## Installation

For instructions, see the [Website tag](/developers/intent-client/website-tag)
installation guide.


# How bidirectional syncs work
Source: https://docs.unifygtm.com/reference/integrations/hubspot/bidirectional-syncs

An in-depth explanation of how syncs work between HubSpot and Unify.

## Overview

Unify can create and update HubSpot records in response to Play runs and
Sequence enrollments. This page summarizes the rules used to determine when and
how to create or update records in HubSpot.

## Sync timing

HubSpot read syncs are scheduled approximately every 15 minutes. HubSpot
association syncs run on a separate daily schedule to refresh relationships
between records. When a large number of records change quickly in HubSpot, the
next scheduled sync may take longer to complete, which can temporarily delay
the appearance of new or updated records in Unify.

When a HubSpot field mapping changes, Unify starts a background job to reprocess
all records for the affected object. This does not interfere with the regular
sync schedule, but it does mean that field mapping updates can take some time to
be fully reflected in Unify.

## Overwriting data

Unify takes a very conservative approach to overwriting existing HubSpot data in
order to make data loss impossible. This approach is based around only a few
simple rules:

* **Creating new records:** When Unify is creating a new HubSpot record, it will
  fill in all properties that are enabled for writing in the field mapping or
  default values.

* **Updating existing records:** Unify will inspect whether the field is empty
  or not. If the field is empty, it will be updated with the new value. If the
  field already has a value, it will only be updated if it is a Unify-specific
  field. These fields are prefixed with "Unify" and can be found
  [here](/reference/integrations/hubspot/field-mappings#available-fields).

These rules apply regardless of how the record was originally created (e.g., by
Unify or externally). If you're looking for more fine-grained control, you can
also limit the permissions granted to the Unify integration user in HubSpot.

## Duplicate prevention

Duplicates are strictly prevented within Unify. When creating new HubSpot
records, Unify will only ever create one record. If there is already an existing
HubSpot record of the same type, Unify will always update it rather than
creating a new one.

However, duplicates are a common problem in HubSpot and may already exist in
your HubSpot instance. In addition, users or other integrations may accidentally
create new duplicates over time.

In order to accommodate this reality, Unify follows specific rules to ensure
predictable behavior when updating duplicated HubSpot records. While Unify
cannot de-duplicate your HubSpot, it will *never* make the problem worse, and
in some situations may be able to help clarify the “source of truth” record.

## Supported objects

<AccordionGroup>
  <Accordion title="Contacts">
    If there is an existing contact that matches the Unify person being written, it
    will be updated. Matches are determined based on email address. If there are no
    matches, a new contact will be created.

    If there are multiple contacts that match the Unify person, only one will be
    updated. Specifically, the contact that was most recently modified within
    HubSpot is the one that will be updated.
  </Accordion>

  <Accordion title="Companies">
    HubSpot companies are written by Unify whenever a contact is created or updated.
    They are also written if a HubSpot sync action runs within a Play that is
    running on companies.

    If there is an existing company that matches the Unify company being written, it
    will be updated. Matches are determined based on the domain of the company
    website. Domains are normalized, so URLs that redirect to different domains will
    not result in duplicates. If there are no matches, a new company will be
    created.

    If there are multiple companies that match the Unify company, only one will be
    updated. Specifically, the company that was most recently modified within
    HubSpot will be updated.
  </Accordion>

  <Accordion title="Email messages">
    Unify does not update existing email messages in HubSpot; only emails sent
    through Unify or received in response to those emails will be written to
    HubSpot.

    Email messages are written to HubSpot for emails sent as a part of Unify
    Sequences and for replies to those emails. The corresponding person must already
    exist in HubSpot as a contact, or a Play action must sync the person to HubSpot
    before the email activity is written.
  </Accordion>

  <Accordion title="Tasks">
    Unify writes eligible Unify tasks to HubSpot as HubSpot tasks. This includes
    ready or completed non-email tasks, such as phone-call and action-item tasks,
    and completed email or reply tasks. Unify does not write email tasks to
    HubSpot before they are complete because completing an email task in HubSpot
    can imply that the email has been sent, while email sending is controlled in
    Unify.

    HubSpot tasks are associated with the corresponding HubSpot contact. If the
    corresponding person does not already exist as a HubSpot contact, Unify must
    sync the person to HubSpot before the task can be written.

    Task sync uses HubSpot's standard task properties instead of custom field
    mappings. Unify writes values such as the task subject, body, task type,
    status, priority, timestamp, and owner. When a task is deleted in Unify,
    Unify archives the matching task in HubSpot.

    HubSpot-to-Unify task sync is limited to completion updates. When a
    non-email HubSpot task that was written by Unify is marked complete in
    HubSpot, Unify marks the corresponding task complete in Unify. Email tasks
    are excluded from this completion sync.
  </Accordion>

  <Accordion title="Deals">
    HubSpot deals are read into Unify as opportunity records. They can be associated
    with companies and people when the HubSpot deal has the corresponding company or
    contact association.

    Deal data is primarily CRM-owned. Unify uses it for record context, filters, and
    exclusions, such as excluding companies with open opportunities from outbound
    Plays. Unify does not create or update HubSpot deals itself.
  </Accordion>
</AccordionGroup>


# Configure default values
Source: https://docs.unifygtm.com/reference/integrations/hubspot/default-values

Learn how to set default values writing to HubSpot.

## Overview

When Unify creates or updates records in HubSpot, it will populate each HubSpot
property using the value in the corresponding Unify field. However, you can also
specify *default values* to be used as a fallback. This can useful in a few
different scenarios:

1. You may have custom fields in HubSpot that require a value
2. You may want to write a custom value to a field that is not available in the
   field mappings
3. You may want to dynamically set a value in different Plays or Play actions

You can set global default values from [Settings → Integrations → HubSpot](https://app.unifygtm.com/dashboard/settings/integrations/hubspot).
These will be used for all writes to HubSpot unless overridden in a Play or by a
field mapping.

<Frame>
  <img />
</Frame>

To learn how to set default values at the Play level instead, see the [Sync to HubSpot](/reference/plays/actions#sync-to-hubspot)
action reference.


# Field mappings
Source: https://docs.unifygtm.com/reference/integrations/hubspot/field-mappings

Understand how to configure and use HubSpot field mappings in Unify.

## Overview

Unify can sync data between HubSpot objects and Unify objects. However, the
exact fields in HubSpot differ from Unify, so Unify needs to understand how to
sync data between the two systems. This is done using *field mappings*.

## Setup

### Change field mappings

When you first connect your HubSpot instance, Unify will automatically prepare
the field mappings for you. If you use any custom properties in place of
default HubSpot properties, you may want to update the mappings before Unify
starts syncing data.

In the [HubSpot integration settings](https://app.unifygtm.com/dashboard/settings/integrations/hubspot),
look for the **Company** and **Person** field mappings at
the bottom of the page. Select one to view and edit the field configuration.

<Frame>
  <img />
</Frame>

You can return to update these mappings any time in the future, so you don't
need to worry about getting them perfect right off the bat!

### (Optional) Create custom properties

You can write values to default properties and custom properties. To write to
custom properties, they must already exist in HubSpot.

While some of the fields Unify can write exist as standard properties in
HubSpot, many of them do not. In particular, Unify-specific fields (like the
name of the Sequence a person was enrolled in) do not exist in HubSpot by
default. To write these values to HubSpot, you will need to create custom
properties before mapping them.

<Note>
  Here's what the process looks like for adding **Contact** properties. First, in
  HubSpot, navigate to **CRM → Contacts**.

  <Frame>
    <img alt="HubSpot Home" />
  </Frame>

  Select **Actions → Edit properties**.

  <Frame>
    <img alt="HubSpot Contacts" />
  </Frame>

  Navigate to **Groups → Create group**.

  <Frame>
    <img alt="HubSpot Contact Property Groups" />
  </Frame>

  Type in the name of the group (recommended title "Unify information") and click
  **Create**.

  <Frame>
    <img alt="HubSpot Contact Create Property Group" />
  </Frame>

  Navigate to **Properties → Create property**.

  <Frame>
    <img alt="HubSpot Contact Properties" />
  </Frame>

  When editing the property details, make sure the **Object type** is set properly
  (in this case, to **Contact**) and the **Group** is set to the group you
  created earlier. You can fill in the **Label** and **Description** as desired.

  <Frame>
    <img alt="HubSpot Contact Create Property" />
  </Frame>

  Lastly, select the **Field type** and click **Create**.

  <Frame>
    <img alt="HubSpot Contact Select Property Type" />
  </Frame>

  This is what your **Contact** properties filtered to your new group might look
  like after you've added them:

  <Frame>
    <img alt="HubSpot Contact New Properties" />
  </Frame>

  You can then repeat this process for **Company** properties as well.
</Note>

## Available fields

Below is a full list of the values that can be configured in the field mappings
for each object type. Some of these are standard properties, while others
provide Unify-specific information, such as the name of the Sequence that a
person was enrolled in.

<AccordionGroup>
  <Accordion title="Companies">
    | Field                                  | Description                                                                                                                                                       |
    | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | **Company Name**<br />*Text*           | Name of the company.                                                                                                                                              |
    | **Domain**<br />*Text*                 | Web domain of the company.                                                                                                                                        |
    | **Address**<br />*Text*                | Physical address of the company.                                                                                                                                  |
    | **State or Province**<br />*Text*      | State, province, region, or territory the company is located in.                                                                                                  |
    | **Country**<br />*Country*             | Country the address is located in.                                                                                                                                |
    | **City**<br />*Text*                   | City, town, or village the company is located in.                                                                                                                 |
    | **Postal Code**<br />*Text*            | Postal code for the company.                                                                                                                                      |
    | **Time Zone**<br />*Text*              | Time zone the company is located in.                                                                                                                              |
    | **Corporate Phone**<br />*Text*        | Corporate phone number for the company.                                                                                                                           |
    | **Status**<br />*Text*                 | Status of the company in the sales lifecycle.                                                                                                                     |
    | **LinkedIn URL**<br />*Text*           | URL to the company's LinkedIn page.                                                                                                                               |
    | **Description**<br />*Text*            | Description of the company.                                                                                                                                       |
    | **Do Not Contact**<br />*Boolean*      | Flag indicating that the company should not be contacted.                                                                                                         |
    | **Founded**<br />*Date*                | Date the company was founded.                                                                                                                                     |
    | **Industry**<br />*Text*               | Industry the company is in.                                                                                                                                       |
    | **Employee Count**<br />*Number*       | Approximate number of employees at the company.                                                                                                                   |
    | **Revenue**<br />*Number*              | Estimated annual revenue of the company.                                                                                                                          |
    | **Revenue Currency**<br />*Text*       | Three-letter ISO 4217 code indicating the revenue value currency type.                                                                                            |
    | **Account Source**<br />*Text*         | Channel this Company record was sourced from.                                                                                                                     |
    | **Unify Metadata**<br />*Text*         | A unique identifier useful for tracking records that Unify writes to.                                                                                             |
    | **Unify Created At**<br />*Date*       | Date and time the record was created by Unify. This will only be populated if Unify created the record; otherwise, it will remain empty.                          |
    | **Unify Updated At**<br />*Date*       | Date and time the record was last updated by Unify.                                                                                                               |
    | **Unify First Written At**<br />*Date* | Date and time the record was first written to by Unify. This will be populated when Unify first creates or updates the record, and it will not change after that. |
    | **Unify Initial Play**<br />*Text*     | Name of the first Unify Play that ran on this record.                                                                                                             |
    | **Unify Initial Play At**<br />*Date*  | Date and time the first Unify Play ran on this record.                                                                                                            |
    | **Unify Most Recent Play**<br />*Text* | Name of the most recent Unify Play that ran on this record.                                                                                                       |
    | **Unify Intent Level**<br />*Text*     | Intent level of the company (either **High**, **Medium**, **Low**, or **None**).                                                                                  |
  </Accordion>

  <Accordion title="People">
    | Field                                                  | Description                                                                                                                                                       |
    | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | **Email**<br />*Text*                                  | Contact email address.                                                                                                                                            |
    | **Address**<br />*Text*                                | Physical address of the person.                                                                                                                                   |
    | **Country**<br />*Country*                             | Country the address is located in.                                                                                                                                |
    | **Postal Code**<br />*Text*                            | Postal code for the person.                                                                                                                                       |
    | **Email Opt Out**<br />*Boolean*                       | Indicates whether the person has opted out of receiving emails.                                                                                                   |
    | **Status**<br />*Text*                                 | Status of the person in the sales lifecycle.                                                                                                                      |
    | **First Name**<br />*Text*                             | First name of the contact.                                                                                                                                        |
    | **First Name Suffix**<br />*Text*                      | Suffix of the first name of the contact.                                                                                                                          |
    | **Last Name**<br />*Text*                              | Last name of the contact.                                                                                                                                         |
    | **Title**<br />*Text*                                  | Job title or position of the contact.                                                                                                                             |
    | **Mobile Phone**<br />*Text*                           | Mobile phone number of the contact.                                                                                                                               |
    | **Work Phone**<br />*Text*                             | Work phone number of the contact.                                                                                                                                 |
    | **Corporate Phone**<br />*Text*                        | Corporate phone number of the contact.                                                                                                                            |
    | **LinkedIn URL**<br />*Text*                           | LinkedIn profile URL of the contact.                                                                                                                              |
    | **Do Not Call**<br />*Boolean*                         | Indicates whether the contact should receive phone calls or not.                                                                                                  |
    | **Do Not Email**<br />*Boolean*                        | Indicates whether the contact should receive emails or not.                                                                                                       |
    | **EU Resident**<br />*Boolean*                         | Indicates whether the contact is a resident of the European Union.                                                                                                |
    | **Lead Source**<br />*Text*                            | Channel this Person record was sourced from.                                                                                                                      |
    | **Last Activity Date**<br />*Date*                     | Date of the last activity or engagement with the contact.                                                                                                         |
    | **Unify Metadata**<br />*Text*                         | A unique identifier useful for tracking records that Unify writes to.                                                                                             |
    | **Unify Created At**<br />*Date*                       | Date and time the record was created by Unify. This will only be populated if Unify created the record; otherwise, it will remain empty.                          |
    | **Unify Updated At**<br />*Date*                       | Date and time the record was last updated by Unify.                                                                                                               |
    | **Unify First Written At**<br />*Date*                 | Date and time the record was first written to by Unify. This will be populated when Unify first creates or updates the record, and it will not change after that. |
    | **Unify Initial Play**<br />*Text*                     | Name of the first Unify Play that ran on this record.                                                                                                             |
    | **Unify Initial Play At**<br />*Date*                  | Date and time the first Unify Play ran on this record.                                                                                                            |
    | **Unify Most Recent Play**<br />*Text*                 | Name of the most recent Unify Play that ran on this record.                                                                                                       |
    | **Unify Most Recent Play At**<br />*Date*              | Date and time the most recent Unify Play ran on this record.                                                                                                      |
    | **Unify Initial Sequence**<br />*Text*                 | Name of the first Unify Sequence this person was enrolled in.                                                                                                     |
    | **Unify Initial Sequence At**<br />*Date*              | Date and time this person was first enrolled in a Unify Sequence.                                                                                                 |
    | **Unify Initial Sequence Step At**<br />*Date*         | Date and time this person first completed a step in a Unify Sequence.                                                                                             |
    | **Unify Most Recent Sequence**<br />*Text*             | Name of the most recent Unify Sequence this person was enrolled in.                                                                                               |
    | **Unify Most Recent Sequence At**<br />*Date*          | Date and time this person was most recently enrolled in a Unify Sequence.                                                                                         |
    | **Unify Most Recent Sequence Step At**<br />*Date*     | Date and time this person most recently completed a step in a Unify Sequence.                                                                                     |
    | **Unify Most Recent Sequence Status**<br />*Text*      | Status of the most recent enrollment for this person. The statuses shown on enrollments in Unify are the same values that will be written to HubSpot.             |
    | **Unify Initial Reply Classification**<br />*Text*     | High-level classification of the initial reply received from a person. It will be either "Positive", "Objection", "Neutral", "Automated", or "Negative".          |
    | **Unify Most Recent Reply Classification**<br />*Text* | High-level classification of the most recent reply received from a person. It will be either "Positive", "Objection", "Neutral", "Automated", or "Negative".      |
    | **Unify Initial Reply Tags**<br />*Text*               | Comma-separated list of classification tags of the initial reply received from a person. For example, "Willing to Meet, Needs More Info".                         |
    | **Unify Most Recent Reply Tags**<br />*Text*           | Comma-separated list of classification tags of the most recent reply received from a person. For example, "Willing to Meet, Needs More Info".                     |
  </Accordion>
</AccordionGroup>


# HubSpot integration guide
Source: https://docs.unifygtm.com/reference/integrations/hubspot/overview

This guide outlines how to connect your HubSpot CRM to Unify.

## Overview

In just a few steps, you can connect your HubSpot CRM to Unify and start syncing
data bidirectionally. This unlocks a few key benefits when using Unify:

1. HubSpot records can be used to [construct exclusions](/tutorials/how-to-create-an-exclusion)
   that prevent Unify from engaging with specific people or companies. For
   example, you can create an exclusion for all current customers or deals in
   progress.
2. You can create Plays that are triggered by HubSpot records. This allows you
   to run a Play based on a specific event or criteria captured within HubSpot.
3. Unify can write data back to HubSpot so that you can maintain a source of
   truth in your CRM and respect rules of engagement in other tools or business
   processes.

Unify's integration with HubSpot is designed from the ground up to prevent many
common pitfalls, including overwriting existing data or creating duplicate
records. For an in-depth description of how Unify does this, see [How Bidirectional Syncs Work](/reference/integrations/hubspot/bidirectional-syncs).

## Setup

<Steps>
  <Step title="Connect HubSpot instance">
    Navigate to [Settings → HubSpot](https://app.unifygtm.com/dashboard/settings/integrations/hubspot)
    and select **Connect**. You will be redirected to the HubSpot authentication
    page where you can sign in and authorize Unify to access HubSpot data.

    <Frame>
      <img />
    </Frame>

    <Frame>
      <img />
    </Frame>
  </Step>

  <Step title="Create field mappings">
    Unify provides granular control over which HubSpot properties map to which
    Unify fields. For each object, select **Create Mapping** and update any
    fields you wish to customize.

    In most cases, the default options will be a good starting point. You can
    always return to change these mappings in the future.

    <Frame>
      <img />
    </Frame>

    See [Field mappings](/reference/integrations/hubspot/field-mappings) for details on
    how field mappings work and the available options.
  </Step>

  <Step title="Enable syncs">
    Once you're satisfied with your integration settings and field mappings, you
    can begin syncing data into Unify by selecting **Resume**. If at any point
    you want to pause syncs again, you can return to this page and select
    **Pause**.

    To enable Unify to write data back to HubSpot, activate the toggle next to
    **Enable writing to HubSpot**. This will allow Unify to sync records back to
    HubSpot.

    <Frame>
      <img />
    </Frame>
  </Step>
</Steps>

## Additional HubSpot resources

<CardGroup>
  <Card icon="arrow-right-arrow-left" title="Field Mappings" href="/reference/integrations/hubspot/field-mappings">
    Configure mappings between Unify fields and HubSpot properties.
  </Card>

  <Card icon="pen-to-square" title="Configure Default Values" href="/reference/integrations/hubspot/default-values">
    Specify default values that should be used when writing to HubSpot.
  </Card>
</CardGroup>


# Property options
Source: https://docs.unifygtm.com/reference/integrations/hubspot/property-options

Find the options for a property in HubSpot.

## Explanation

Properties in HubSpot have a different name displayed in the UI than the value
used at the API level. For most properties, the dropdown options you see in the
UI will be the same as the values you see in Unify.

However, certain properties in HubSpot have options which Unify cannot access.
At the moment, this is a known HubSpot limitation. The steps outlined here can
help to work around the issue.

## Workaround

To support using these options for filtering in audiences and exclusions, you
can perform the following steps. This article uses the **Lifecycle Stage**
property on **Company** as an example, but the same steps should work for other
properties and objects.

In HubSpot, navigate to **CRM → Companies** and select **Actions → Edit properties**.

<Frame>
  <img alt="Properties" />
</Frame>

Search for the property by its name (in this case, **Lifecycle Stage**) and
select the property.

<Frame>
  <img alt="Properties" />
</Frame>

<Frame>
  <img alt="Lifecycle Stage" />
</Frame>

Navigate to **Field type**. You will see a list of options, with **LABEL** and
**INTERNAL NAME** values alongside the number of records that have that value.
You may want to copy these values to a secure separate location for easy future
reference. If you wish to filter records in Unify to a specific **LABEL** value,
you can do so by using the corresponding **INTERNAL NAME** value.

<Frame>
  <img alt="Property Options" />
</Frame>

Here's what that looks like in Unify for the **LABEL** value "Lead" and
therefore **INTERNAL NAME** value "lead":

<Frame>
  <img alt="Filtering in Unify" />
</Frame>


# Running Call Campaigns with Nooks
Source: https://docs.unifygtm.com/reference/integrations/nooks/call-campaigns

Launch and manage effective call campaigns using Nooks with your CRM integration.

## Prerequisites

Before starting your call campaign, ensure you have:

* Completed your CRM setup ([HubSpot](/reference/integrations/nooks/hubspot-setup) or [Salesforce](/reference/integrations/nooks/salesforce-setup))

## Setting up Your call campaign

### 1. Create your Sequence

Create a Unify Sequence that includes phone call steps. This will generate the call tasks that sync to your CRM and feed into Nooks. Learn more in our [Sequences guide](/reference/sequences/sequence-step-types#phone-call).

### 2. Monitor the sync

Sequence enrollments will appear in your CRM within 30 minutes of being created in Unify. These tasks will automatically be available in Nooks when you reset your call list.

### 3. Set up your call session

In Nooks, follow these steps to prepare your calling session:

1. Login to Nooks

2. Select your call sequence

### 4. Start calling

Begin your call campaign! As you complete calls, results will automatically sync back to both your CRM and Unify, keeping all your systems up to date.

<Note>
  Need additional help? Contact our support team or visit the [Nooks documentation](https://support.devrev.ai/nooks/directories) for more detailed troubleshooting guides.
</Note>

***

That's it! By following these steps, your team will run faster, more productive call campaigns with seamless integration between your CRM, Unify, and Nooks.


# Nooks HubSpot Setup
Source: https://docs.unifygtm.com/reference/integrations/nooks/hubspot-setup

Configure Nooks integration with HubSpot for seamless call task management.

## Overview

This guide walks you through how to set up the Nooks integration with HubSpot to synchronize call tasks.

## Prerequisites

Before you begin, make sure you have:

* Admin access to your HubSpot account
* An active Nooks subscription

## Setup steps

1. **Admin**: Map users to their Hubspot profiles. Make sure your team has the proper permissions in your Hubspot to be able to create sequences, tasks or lists for themselves (If managers/admins are creating sequences and lists, this can be disregarded)
2. Create or Edit your Call Outcomes
3. Set up automation rules and/or filters to ensure proper hygiene and activities against your contacts.

For detailed step-by-step instructions, see [setup guide](https://support.devrev.ai/nooks/article/ART-120-getting-started-with-hubspot).

## Next steps

With your HubSpot integration configured and Nooks connected, you're ready to [launch your first call campaign](/reference/integrations/nooks/call-campaigns)!


# Nooks integration overview
Source: https://docs.unifygtm.com/reference/integrations/nooks/overview

Learn how to integrate Nooks with your CRM for seamless call campaign management.

## What you'll need

Before setting up the Nooks integration, ensure you have:

* Admin access to your CRM (HubSpot or Salesforce)
* An active Nooks account

## Integration options

Choose your CRM to get started:

<Card title="HubSpot Setup" icon="hubspot" href="/reference/integrations/nooks/hubspot-setup">
  Configure Nooks with HubSpot for call task synchronization
</Card>

<Card title="Salesforce Setup" icon="salesforce" href="/reference/integrations/nooks/salesforce-setup">
  Set up call reports and connect Nooks with Salesforce
</Card>

## Getting started

1. **Choose your CRM**: Follow the setup guide for either HubSpot or Salesforce
2. **Configure Integration**: Setup call tasks to sync to CRM
3. **Launch Campaigns**: Start running organized, efficient call campaigns

Ready to get started? Select your CRM platform above to begin the setup process.


# Nooks Salesforce setup
Source: https://docs.unifygtm.com/reference/integrations/nooks/salesforce-setup

Configure Nooks integration with Salesforce for call task synchronization.

## Overview

This guide walks you through the steps required to set up call tasks in Salesforce and configure the Nooks integration for seamless call campaign management.

## Overview

You can bidirectionally sync your call tasks between Unify and Nooks using a Salesforce report. The instructions below will help you build a report to successfully set up the sync.

## Salesforce report setup

### Call report setup in Salesforce

To create call tasks in Salesforce, set up a new report with the following criteria:

1. Navigate to your Salesforce Reports tab
2. Click **New Report**
3. Configure the report with these settings:
   * **Category**: Activities (Activities with Contacts)
   * **Show Me**: All activities
   * **Date**: All Time
   * **Show**: Open Activities
   * **Show**: Tasks
   * **Assigned**: equals \$USER
   * **Task Subtype**: equals Call

<Note>
  These report filters ensure that each user in Nooks only sees their own open call tasks
</Note>

<Frame>
  <img alt="salesforce-report-filters.png" />
</Frame>

### Best practices for report columns

We recommend including the following columns in your report for better visibility and alignment with Unify Sequences:

1. Click **Customize** on your report
2. Add the following columns:
   * Subject
   * First Name
   * Last Name
   * Unify Sequence

<Frame>
  <img alt="salesforce-column-setup.png" />
</Frame>

## Nooks integration setup

<Info>
  **Sep 2025 Update: Installing Nooks as a Trusted App in Salesforce**

  In September 2025, Salesforce made security changes regarding which apps can be connected to Salesforce (via OAuth) by individual reps. This can impact Nooks users who are connecting to Salesforce for the first time, or reconnecting Salesforce. They might see an "OAuth Error" like this:

  <Frame>
    <img alt="salesforce-oauth-error.png" />
  </Frame>

  Your Salesforce administrator will need to install Nooks as a trusted app in your Salesforce org. For more information, see: [Installing Nooks as a Trusted App in SFDC](https://support.devrev.ai/nooks/article/ART-115-getting-started-with-salesforce-sfdc#Sep%202025%20Update%3A%20Installing%20Nooks%20as%20a%20Trusted%20App%20in%20SFDC).
</Info>

Once your Salesforce report is ready, connect Nooks to Salesforce:

1. Navigate to **Settings** in Nooks
2. Select **Integrations**
3. Select **Connect Salesforce** and authorize the connection
4. Install Nooks as an OAuth app. Nooks should appear as an app in the Salesforce Setup settings in the "Connected Apps OAuth Usage" section. Click **Install**.
5. \[Recommended] Configure field mappings to optimize your call tasks:
   * Navigate to **Settings** > **Salesforce** > **Field Mappings**
   * Add your specific SFDC fields such as:
     * Current Unify Sequence
     * Current Unify Play
     * Relevant prospect information for call tasks

<Note>
  You will need admin access to Salesforce to authorize this connection. For more information, see: [Nooks admin setup](https://support.devrev.ai/nooks/article/ART-115-getting-started-with-salesforce-sfdc) or reach our to your CSM.
</Note>

## Next steps

With your Salesforce integration configured and Nooks connected, you're ready to [launch your first call campaign](/reference/integrations/orum/call-campaigns)!


# Running Call Campaigns with Orum
Source: https://docs.unifygtm.com/reference/integrations/orum/call-campaigns

Launch and manage effective call campaigns using Orum with your CRM integration.

## Prerequisites

Before starting your call campaign, ensure you have:

* Completed your CRM setup ([HubSpot](/reference/integrations/orum/hubspot-setup) or [Salesforce](/reference/integrations/orum/salesforce-setup))

## Setting up your call campaign

### 1. Create Your Sequence

Create a Unify Sequence that includes phone call steps. This will generate the call tasks that sync to your CRM and feed into Orum. Learn more in our [Sequences guide](/reference/sequences/sequence-step-types#phone-call).

### 2. Monitor the sync

Sequence enrollments will appear in your CRM within 30 minutes of being created in Unify. These tasks will automatically be available in Orum when you reset your call list.

### 3. Set up your call session

In Orum, follow these steps to prepare your calling session:

1. **Login with your CRM** to ensure Orum can access your phone call tasks

2. **Select your call list** from the available CRM reports:

<Frame>
  <img alt="list-selection.png" />
</Frame>

3. **Reset your tasks** by clicking the reset button to pull the latest call tasks:

<Frame>
  <img alt="reset-button.png" />
</Frame>

4. **Configure filters** (optional): If you have multiple call tasks for the same person, deselect the "Skip duplicate numbers" filter to include all tasks:

<Frame>
  <img alt="skip-duplicate-numbers.png" />
</Frame>

### 4. Start calling

Begin your call campaign! As you complete calls, results will automatically sync back to both your CRM and Unify, keeping all your systems up to date.

<Note>
  Need additional help? Contact our support team or visit the [Orum documentation](https://support.orum.com) for more detailed troubleshooting guides.
</Note>

***

That's it! By following these steps, your team will run faster, more productive call campaigns with seamless integration between your CRM, Unify, and Orum.


# Orum HubSpot Setup
Source: https://docs.unifygtm.com/reference/integrations/orum/hubspot-setup

Configure Orum integration with HubSpot for seamless call task management.

## Overview

This guide walks you through how to set up the Orum integration with HubSpot to synchronize call tasks.

## Prerequisites

Before you begin, make sure you have:

* Admin access to your HubSpot account
* An active Orum subscription

## Setup steps

1. **Admin Authorization**: Have a HubSpot admin authorize the Orum connection in your HubSpot account
2. **Login**: Login with your HubSpot credentials in Orum to complete the integration

For detailed step-by-step instructions, follow our [interactive setup guide](https://app.tango.us/app/workflow/Connecting-Orum-to-HubSpot-899a4dfbc33b40a9bf6faef1fdb60761).

## Next steps

With your HubSpot integration configured and Orum connected, you're ready to [launch your first call campaign](/reference/integrations/orum/call-campaigns)!

<Note>
  Need help with the setup? Contact our support team or refer to [Orum's HubSpot documentation](https://support.orum.com/orum/article/ART-449-getting-started-with-hubspot) for additional assistance.
</Note>


# Orum integration overview
Source: https://docs.unifygtm.com/reference/integrations/orum/overview

Learn how to integrate Orum with your CRM for seamless call campaign management.

## What You'll Need

Before setting up the Orum integration, ensure you have:

* Admin access to your CRM (HubSpot or Salesforce)
* An active Orum account

## Integration Options

Choose your CRM to get started:

<Card title="HubSpot Setup" icon="hubspot" href="/reference/integrations/orum/hubspot-setup">
  Configure Orum with HubSpot for call task synchronization
</Card>

<Card title="Salesforce Setup" icon="salesforce" href="/reference/integrations/orum/salesforce-setup">
  Set up call reports and connect Orum with Salesforce
</Card>

## Getting Started

1. **Choose your CRM**: Follow the setup guide for either HubSpot or Salesforce
2. **Configure Integration**: Setup call tasks to sync to CRM
3. **Launch Campaigns**: Start running organized, efficient call campaigns

Ready to get started? Select your CRM platform above to begin the setup process.


# Orum Salesforce Setup
Source: https://docs.unifygtm.com/reference/integrations/orum/salesforce-setup

Configure Orum integration with Salesforce for call task synchronization.

## Overview

This guide walks you through the steps required to set up call tasks in Salesforce and configure the Orum integration for seamless call campaign management.

## Overview

You can bidirectionally sync your call tasks between Unify and Orum using a Salesforce report. The instructions below will help you build a report to successfully set up the sync.

## Salesforce report setup

### Call report setup in Salesforce

To create call tasks in Salesforce, set up a new report with the following criteria:

1. Navigate to your Salesforce Reports tab
2. Click **New Report**
3. Configure the report with these settings:
   * **Category**: Activities (Activities with Contacts)
   * **Show Me**: All activities
   * **Date**: All Time
   * **Show**: Open Activities
   * **Show**: Tasks
   * **Assigned**: equals \$USER
   * **Task Subtype**: equals Call

<Note>
  These report filters ensure that each user in Orum only sees their own open call tasks
</Note>

<Frame>
  <img alt="salesforce-report-filters.png" />
</Frame>

### Best practices for report columns

We recommend including the following columns in your report for better visibility and alignment with Unify Sequences:

1. Click **Customize** on your report
2. Add the following columns:
   * Subject
   * First Name
   * Last Name
   * Unify Sequence

<Frame>
  <img alt="salesforce-column-setup.png" />
</Frame>

## Orum integration setup

Once your Salesforce report is ready, connect Orum to Salesforce:

1. Navigate to **Settings** in Orum
2. Select **Integrations**
3. Choose **Salesforce** and authorize the connection

<Note>
  You will need admin access to Salesforce to authorize this connection. For more information, see: [Orum admin setup](https://support.orum.com/orum/article/ART-441).
</Note>

## Next steps

With your Salesforce integration configured and Orum connected, you're ready to [launch your first call campaign](/reference/integrations/orum/call-campaigns)!

<Note>
  Need help with the setup? Contact our support team or refer to [Orum's Salesforce documentation](https://support.orum.com/orum/article/ART-410-getting-started-with-salesforce) for additional assistance.
</Note>


# Integration guides
Source: https://docs.unifygtm.com/reference/integrations/overview

Explore the external tools and systems Unify integrates natively with.

<CardGroup>
  <Card title="Salesforce" href="/reference/integrations/salesforce/overview" icon={<SalesforceLogo />}>
    Connect your Salesforce instance to seamlessly keep your CRM in sync.
  </Card>

  <Card title="HubSpot" href="/reference/integrations/hubspot/overview" icon={<HubspotLogo />}>
    Connect your HubSpot instance to seamlessly keep your CRM in sync.
  </Card>

  <Card
    title="6sense"
    href="/reference/integrations/6sense"
    icon={
  <>
    <SixsenseLogoDark />
    <SixsenseLogoLight />
  </>
}
  >
    Use your existing 6sense subscription to identify visitors.
  </Card>

  <Card title="Clearbit" href="/reference/integrations/clearbit" icon={<ClearbitLogo />}>
    Connect your existing Clearbit subscription to identify visitors.
  </Card>

  <Card title="Demandbase" href="/reference/integrations/demandbase" icon={<DemandbaseLogo />}>
    Identify website visitors with Unify's native Demandbase integration.
  </Card>

  <Card title="G2" href="/reference/integrations/g2" icon={<G2Logo />}>
    Identify anonymous visitors on G2 and use them as an intent source.
  </Card>

  <Card title="Gmail" href="/reference/integrations/gmail" icon={<GoogleWorkspaceLogo />}>
    Send emails from your existing Google Workspace mailbox.
  </Card>

  <Card title="Google Tag Manager" href="/reference/integrations/google-tag-manager" icon={<GoogleTagManagerLogo />}>
    Install the Unify website tag using Google Tag Manager.
  </Card>

  <Card title="Nooks" href="/reference/integrations/nooks/overview" icon={<NooksLogo />}>
    Connect your Nooks dialer to streamline call workflows and sync call tasks.
  </Card>

  <Card title="Orum" href="/reference/integrations/orum/overview" icon={<OrumLogo />}>
    Connect your Orum dialer to streamline call workflows and sync call tasks.
  </Card>

  <Card
    title="Posthog"
    href="/reference/integrations/posthog"
    icon={
  <>
    <PosthogLogoDark />
    <PosthogLogoLight />
  </>
}
  >
    Send PostHog events into Unify.
  </Card>

  <Card title="Segment" href="/reference/integrations/segment" icon={<SegmentIcon />}>
    Send Segment events into Unify.
  </Card>

  <Card title="Slack" href="/reference/integrations/slack" icon={<SlackLogo />}>
    Send Slack notifications and messages from Unify Plays.
  </Card>
</CardGroup>


# PostHog integration guide
Source: https://docs.unifygtm.com/reference/integrations/posthog

Send PostHog events into Unify.

## Overview

PostHog is a product analytics tool that allows you to capture and monitor key
events taking place. By pulling this data into Unify, you're able to run
product-led outbound for use cases like:

* **Free plan conversions** — Identify free plan users who are actively using key features and send them targeted upgrade campaigns.
* **Upsells and cross-sells** — Identify existing customers who are using specific features and send them relevant upsell or cross-sell offers.
* **Enterprise expansion** — Identify individual users at companies, reach out to other contacts at those companies, and target them with enterprise offers.

You can forward PostHog events into Unify by configuring a PostHog destination
to send events directly to the Unify [Analytics API](/developers/api/analytics/overview).

This integration can create new Unify People and Companies and update existing Unify
People and Companies with event data from your PostHog instance.

<Note>
  If you’re also using the Unify Tag, ensure it isn’t running on the same pages as PostHog. Otherwise, events may be double counted.
</Note>

## Prerequisites

* A working PostHog setup capturing events
* Your Unify **Write Key** ([Unify → Settings → Integrations → PostHog](https://app.unifygtm.com/dashboard/settings/integrations/posthog))

## Recommended setup

Create a PostHog destination. You can filter out any event that you do not wish
to forward into Unify.

<Steps>
  <Step title="Create a Unify destination">
    In PostHog, go to **Data → Destinations → Create a new destination**.
    Search for **Unify** and click **Create**.
  </Step>

  <Step title="Filter events to send to Unify">
    Add an **event matcher** to send the events you want to Unify. We recommend
    sending **Pageview** and **Identify** events in addition to any custom events
    of your choice.

    <Frame>
      <img alt="event-filtering.png" />
    </Frame>

    In the example above, `survey dismissed` is a custom event.
  </Step>

  <Step title="Configure your destination">
    1. Paste your write key under **Unify Write Key**
    2. Ensure your Unify Person attributes are correctly mapped to your PostHog
       properties
       <Tip>Not sure what attributes are or why this mapping matters? See our [FAQ](#faq) for more details.</Tip>
       <Frame>
         <img alt="person-attribute-mapping.png" />
       </Frame>
    3. Ensure your Unify Company attributes are correctly mapped to your PostHog
       properties
       <Tip>Not sure what attributes are or why this mapping matters? See our [FAQ](#faq) for more details.</Tip>
       <Frame>
         <img alt="company-attribute-mapping.png" />
       </Frame>
  </Step>

  <Step title="Test and create your destination">
    To test whether the integration is working, you can send a test event from PostHog.
    Select **Start testing** and **Test function** to send a test event to Unify.

    <Frame>
      <img alt="testing.png" />
    </Frame>

    Events may take up to 5 minutes to show up in the [Unify event console](https://app.unifygtm.com/dashboard/settings/data/web-intent?webEventsTab=Events)

    Once you've verified that the correct data has been sent, select **Create and enable**
    to activate the destination.
  </Step>
</Steps>

## FAQ

<AccordionGroup>
  <Accordion title="What is an attribute mapping and why does it matter?">
    The PostHog integration has the ability to create and update People and
    Companies in your Unify instance. An attribute mapping describes how
    PostHog should convert data into a format Unify understands. If this
    mapping is not correctly configured, some data may be missing when the
    Person or Company is created in Unify.
  </Accordion>

  <Accordion title="How do I know when an attribute mapping is correct?">
    Consider the example attribute mapping below:

    | Unify attribute | PostHog property             |
    | --------------- | ---------------------------- |
    | email           | "\{person.properties.email}" |

    There are three things to verify when checking that an attribute mapping is correct.

    1. Check that the left side of the mapping is the Unify property you
       want to populate with event data. In this case, we want to populate the `email`
       property of the Unify Person who will be associated with this event.
    2. Check that the right side of the mapping is the correct location of the data in
       the PostHog. If you have PostHog Person data that looks like
       ```json theme={null}
       {
         "person": {
           "properties": {
             "email": "person@acme.com"
           }
         }
       }
       ```
       then the value of this field in the data sent to Unify will be `person@acme.com`.
       If you have PostHog Person data that looks like
       ```json theme={null}
       {
         "person": {
           "properties": {
             "email_address": "person@acme.com"
           }
         }
       }
       ```
       on the other hand, then the value of this field in the data sent to Unify will be
       `undefined` since there is no `email_address` key. In this case, you would have to
       change the right side of the attribute mapping to `{person.properties.email_address}`
       to correct the mapping.
    3. Check that the format of the event data corresponds with the attribute's
       [value type](/reference/objects/value-types). The `Email address` value type is a
       text field and `person@acme.com` is a valid email address, so the attribute mapping
       is correct here.
  </Accordion>

  <Accordion title="Company data is not being sent over. Why?">
    PostHog does not natively have the concept of a Company. To support this, we strongly recommend using PostHog's
    [group analytics](https://posthog.com/docs/product-analytics/group-analytics) feature. Please ensure a `company`
    group is a defined group type in your PostHog instance.

    Following that, please check your Company attribute mapping in your Unify destination is correct and that a
    `domain` is being sent.
  </Accordion>

  <Accordion title="Does this integration support updating custom attributes?">
    Yes. In PostHog, navigate to your Unify destination and add a new entry to the `Person` or `Company` mapping.
    Add your custom attribute name on the left side and the corresponding field in PostHog on the right side.
  </Accordion>

  <Accordion title="Will PostHog data overwrite any existing data on my Unify People or Companies?">
    No, only fields that are missing on an existing Person or Company will be updated with PostHog event data.
    For example, if the Company `acme.com` does not have an existing `Corporate Phone Number` in Unify and
    a PostHog event is sent with that data, then the `Corporate Phone Number` will be updated. If it has an
    existing `Corporate Phone Number`, however, it will not be updated.
  </Accordion>

  <Accordion title="I don't want this integration to update Person or Company data in Unify. How can I disable it?">
    We strongly recommend sending at least Person data with event data from PostHog since this can save credits
    if you have reveal enabled in Unify. However, if you still want to stop sending Person or Company data from PostHog
    to Unify, then go to PostHog, navigate to your Unify destination and remove all attribute mappings.
  </Accordion>
</AccordionGroup>


# How bidirectional syncs work
Source: https://docs.unifygtm.com/reference/integrations/salesforce/bidirectional-syncs

An in-depth explanation of how syncs work between Salesforce and Unify.

## Overview

Unify can create and update Salesforce records in response to Play runs and
Sequence enrollments. This page summarizes the rules used to determine when and
how to create or update records in Salesforce.

## Sync timing

Salesforce read syncs are scheduled approximately every 15 minutes. When a large
number of records change quickly in Salesforce, the next scheduled sync may take
longer to complete, which can temporarily delay the appearance of new or updated
records in Unify.

When a Salesforce field mapping changes, Unify starts a background job to
reprocess all records for the affected object. This does not interfere with the
regular sync schedule, but it does mean that field mapping updates can take some
time to be fully reflected in Unify.

## Overwriting data

Unify takes a very conservative approach to overwriting existing Salesforce data
to make data loss impossible. This approach is based around only a few simple
rules:

* **Creating new records:** When Unify is creating a new Salesforce record, it
  will fill in all fields that are enabled for writing in the field mapping or
  default values.

* **Updating existing records:** Unify will inspect whether the field is empty
  or not. If the field is empty, it will be updated with the new value. If the
  field already has a value, it will only be updated if it is a Unify-specific
  field. These fields are prefixed with "Unify" and can be found [here](/reference/integrations/salesforce/field-mappings#available-fields).

These rules apply regardless of how the record was originally created (e.g., by
Unify or externally). If you're looking for more fine-grained control, you can
also limit the permissions granted to the Unify integration user in Salesforce.

## Duplicate prevention

Duplicates are strictly prevented within Unify. When creating new Salesforce
records, Unify will only ever create one record. If there is already an existing
Salesforce record of the same type, Unify will always update it rather than
creating a new one.

However, duplicates are a common problem in Salesforce and may already exist in
your Salesforce instance. In addition, users or other integrations may
accidentally create new duplicates over time.

To accommodate this reality, Unify follows specific rules to ensure predictable
behavior when updating duplicated Salesforce records. While Unify cannot
de-duplicate your Salesforce, it will *never* make the problem worse, and in
some situations may be able to help clarify the “source of truth” record.

## Supported objects

<AccordionGroup>
  <Accordion title="Accounts">
    Salesforce accounts are written by Unify whenever a contact is created or
    updated. They are also written if a Salesforce sync action runs within a Play
    that is running on companies.

    If there is an existing account that matches the Unify company being written, it
    will be updated. Matches are determined based on the domain of the company
    website. Domains are normalized, so URLs that redirect to different domains will
    not result in duplicates. If there are no matches, a new account will be
    created.

    If there are multiple accounts that match the Unify company, only one will be
    updated. Specifically, the account that was most recently modified within
    Salesforce will be updated.
  </Accordion>

  <Accordion title="Contacts">
    Salesforce contacts are written by Unify if **Create new records as Contacts & Accounts**
    is selected. In addition, contacts are sometimes created in place of leads if
    the person being written to Salesforce *already exists* as a contact. Unify
    cannot create a lead in this situation due to Salesforce’s
    [contact duplicate rules](https://help.salesforce.com/s/articleView?language=en_US\&id=sf.duplicate_rules_standard_contact_rule.htm\&type=5).

    In both situations, if there is an existing contact that matches the Unify
    person being written, it will be updated. Matches are determined based on email
    address. If there are no matches, a new contact will be created.

    If there are multiple contacts that match the Unify person, only one will be
    updated. Specifically, the contact that was most recently modified within
    Salesforce is the one that will be updated.
  </Accordion>

  <Accordion title="Leads">
    Salesforce leads are written by Unify when **Create new records as Leads** is
    selected.

    If there is an existing lead that matches the Unify person being written, it
    will be updated. Matches are determined based on email address. If there are no
    matches, a new lead will be created.

    If there are multiple leads that match the Unify person, only one will be
    updated. Specifically, the lead that was most recently modified within
    Salesforce is the one that will be updated.
  </Accordion>

  <Accordion title="Email messages">
    Unify writes to the email message object in Salesforce, which is the recommended
    approach for syncing email data to Salesforce. To write records of this object
    type, the *Enhanced Email* feature must be enabled in Salesforce. This is
    typically enabled by default.

    Unify does not update existing email messages in Salesforce. Only emails sent
    through Unify or received in response to those emails will be written to
    Salesforce. Unify uses the standard **Universal Message ID** to deduplicate
    email messages if they are simultaneously being written by another integration.

    Email messages are written to Salesforce for emails sent as a part of Unify
    Sequences and for replies to those emails. The corresponding person must already
    exist in Salesforce as a contact or lead, or a Play action must sync the person
    to Salesforce before the email activity is written.

    Email messages can include mapped email activity fields such as subject,
    content, sent time, bounce status, click count, open timestamps, spam status,
    opt-out status, the enrolling Play, and Sequence name. These values are written
    only when the relevant event exists and the mapped Salesforce field is writable
    by the integration user.
  </Accordion>

  <Accordion title="Tasks">
    Unify writes eligible Unify tasks to the Salesforce Task object. This
    includes ready or completed non-email tasks, such as phone-call and
    action-item tasks, and completed email or reply tasks. Unify does not write
    email tasks to Salesforce before they are complete because email sending is
    controlled in Unify.

    Salesforce tasks are related to the corresponding Salesforce contact or
    lead. If the person does not already exist in Salesforce, Unify must sync
    the person to Salesforce before the task can be written. When there is an
    associated company and the person is a contact, Unify can also relate the
    task to the Salesforce account. When the person is a lead, Salesforce does
    not support the same account relationship on the task.

    Task sync uses Unify's standard Salesforce Task mapping rather than the
    company, person, or email message field mapping tables. Unify writes values
    such as subject, description, status, priority, task subtype, due date,
    owner, contact/lead relationship, and account relationship when available.
    When a task is deleted in Unify, Unify deletes the matching Salesforce task.

    Salesforce-to-Unify task sync is limited to completion updates. When a
    non-email Salesforce task that was written by Unify is marked **Completed**
    in Salesforce, Unify marks the corresponding task complete in Unify.

    Completed Salesforce phone-call tasks created by supported dialer
    integrations can also complete the matching open Unify phone-call task when
    Unify can identify a single matching task for the same person. Email tasks
    are excluded from this completion sync.
  </Accordion>

  <Accordion title="Opportunities">
    Salesforce opportunities are read into Unify as opportunity records. They can be
    associated with companies and people when the Salesforce opportunity has the
    corresponding account or contact relationship.

    Opportunity data is primarily CRM-owned. Unify uses it for record context,
    filters, and exclusions, such as excluding companies with open
    opportunities from outbound Plays. Unify does not create or update Salesforce
    opportunities itself.
  </Accordion>
</AccordionGroup>


# Bulk update records
Source: https://docs.unifygtm.com/reference/integrations/salesforce/bulk-update-records

Use Salesforce reports to quickly update many records in Salesforce.

## Explanation

If you need to update many records in Salesforce, you can use Salesforce reports to simplify the process. A common use case is updating the value of a field across all records created by a Play. However, these steps are generally applicable to any set of Salesforce records.

## Steps

### Export the records

1. Navigate to the **Reports** page.

<Tip>
  In the top-right corner of the screen, if you click the menu icon and search for “reports”, you should see a link to get there.

  <Frame>
    <img alt="export-the-records-step-1" />
  </Frame>
</Tip>

2. In the top-right corner of the screen, select **New Report**
3. Choose a report type based on which type of records you need to update, and then click **Start Report** on the right

<Frame>
  <img alt="export-the-records-step-3" />
</Frame>

4. Be sure to add the `Id` column to your report in the sidebar, which is typically named after the record type you are selecting (e.g., `Account ID`, `Contact ID`, etc.)

<Frame>
  <img alt="export-the-records-step-4" />
</Frame>

5. Also add any additional columns that you wish to edit on the records
6. Add any filters or sorting options needed to narrow down the records you want to update

<Frame>
  <img alt="export-the-records-step-6" />
</Frame>

7. When ready, click **Save** in the top-right corner, enter a name, and then click **Save** again

<Frame>
  <img alt="export-the-records-step-7" />
</Frame>

8. Click **Run** in the top-right corner and verify these are the records you want to update
9. Click the dropdown arrow next to **Edit** in the top-right corner and select **Export**
10. Choose **Details Only** and **Comma Delimited .csv** as the format and then click **Export**

<Frame>
  <img alt="export-the-records-step-10" />
</Frame>

### Make changes

1. Open the downloaded file and make any desired updates to the values
2. Save the changes as a new file so that the original is available as a backup

### Upload the changed records

1. Navigate to the **Setup** page in Salesforce

2. In the sidebar on the left, search for "data import wizard" and select the **Data Import Wizard** integration

3. Follow the on-screen instructions to update existing records and be sure to choose the option to match records by `Salesforce.com ID`

<Frame>
  <img alt="upload-the-changed-records-step-3" />
</Frame>

4. Ensure the mapping looks correct and that the ID column is mapped to `Salesforce.com ID`

<Frame>
  <img alt="upload-the-changed-records-step-4" />
</Frame>

5. Verify the details on the last page and then click **Start Import**

<Frame>
  <img alt="upload-the-changed-records-step-5" />
</Frame>

6. Once this bulk import is complete you’re all finished!


# Configure default values
Source: https://docs.unifygtm.com/reference/integrations/salesforce/default-values

Learn how to set default values writing to Salesforce.

## Overview

When Unify creates or updates records in Salesforce, it will populate each
Salesforce field using the value in the corresponding Unify field. However, you
can also specify *default values* to be used as a fallback. This can useful in a
few different scenarios:

1. You may have custom fields in Salesforce that require a value
2. You may want to write a custom value to a field that is not available in the
   field mappings
3. You may want to dynamically set a value in different Plays or Play actions

You can set global default values from [Settings → Integrations → Salesforce](https://app.unifygtm.com/dashboard/settings/integrations/salesforce).
These will be used for all writes to Salesforce unless overridden in a Play or
by a field mapping.

<Frame>
  <img />
</Frame>

To learn how to set default values at the Play level instead, see the [Sync to Salesforce](/reference/plays/actions#sync-to-salesforce)
action reference.


# Field mappings
Source: https://docs.unifygtm.com/reference/integrations/salesforce/field-mappings

Understand how to configure and use Salesforce field mappings in Unify.

## Overview

Unify can sync data between Salesforce objects and Unify objects. However, the
exact objects and fields in Salesforce differ from Unify, so Unify needs to
understand how to sync data between the two systems. This is done using *field
mappings*.

## Setup

### Change field mappings

When you first connect your Salesforce instance, Unify will automatically
prepare the field mappings for you. If you use any custom fields in place of
standard Salesforce fields, you may want to update the mappings before Unify
starts syncing data.

In the [Salesforce integration settings](https://app.unifygtm.com/dashboard/settings/integrations/salesforce),
look for the **Company**, **Person**, and **Email Message** field mappings at
the bottom of the page. Select one to view and edit the field configuration.

<Frame>
  <img />
</Frame>

You can return to update these mappings any time in the future, so you don't
need to worry about getting them perfect right off the bat!

### (Optional) Create custom fields

You can write values to standard fields and custom fields. To write to custom
fields, they must already exist in Salesforce. See [this guide](https://help.salesforce.com/s/articleView?id=platform.adding_fields.htm\&type=5)
for instructions on creating custom fields in Salesforce.

While some of the fields Unify can write exist as standard fields in Salesforce,
many of them do not. In particular, Unify-specific fields (like the name of the
Sequence a person was enrolled in) do not exist in Salesforce by default. In
order to write these values to Salesforce, you will need to create custom fields
before mapping them.

## Available fields

Below is a full list of the values that can be configured in the field mappings
for each object type. Some of these are standard fields, while others provide
Unify-specific information, such as the name of the Sequence that a person was
enrolled in.

<AccordionGroup>
  <Accordion title="Companies">
    | Field                                  | Description                                                                                                                                                       |
    | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | **Company Name**<br />*Text*           | Name of the company.                                                                                                                                              |
    | **Domain**<br />*Text*                 | Web domain of the company.                                                                                                                                        |
    | **Address**<br />*Text*                | Physical address of the company.                                                                                                                                  |
    | **State or Province**<br />*Text*      | State, province, region, or territory the company is located in.                                                                                                  |
    | **Country**<br />*Country*             | Country the address is located in.                                                                                                                                |
    | **City**<br />*Text*                   | City, town, or village the company is located in.                                                                                                                 |
    | **Postal Code**<br />*Text*            | Postal code for the company.                                                                                                                                      |
    | **Time Zone**<br />*Text*              | Time zone the company is located in.                                                                                                                              |
    | **Corporate Phone**<br />*Text*        | Corporate phone number for the company.                                                                                                                           |
    | **Status**<br />*Text*                 | Status of the company in the sales lifecycle.                                                                                                                     |
    | **LinkedIn URL**<br />*Text*           | URL to the company's LinkedIn page.                                                                                                                               |
    | **Description**<br />*Text*            | Description of the company.                                                                                                                                       |
    | **Do Not Contact**<br />*Boolean*      | Flag indicating that the company should not be contacted.                                                                                                         |
    | **Founded**<br />*Date*                | Date the company was founded.                                                                                                                                     |
    | **Industry**<br />*Text*               | Industry the company is in.                                                                                                                                       |
    | **Employee Count**<br />*Number*       | Approximate number of employees at the company.                                                                                                                   |
    | **Revenue**<br />*Number*              | Estimated annual revenue of the company.                                                                                                                          |
    | **Revenue Currency**<br />*Text*       | Three-letter ISO 4217 code indicating the revenue value currency type.                                                                                            |
    | **Account Source**<br />*Text*         | Channel this Company record was sourced from.                                                                                                                     |
    | **Unify Metadata**<br />*Text*         | A unique identifier useful for tracking records that Unify writes to.                                                                                             |
    | **Unify Created At**<br />*Date*       | Date and time the record was created by Unify. This will only be populated if Unify created the record; otherwise, it will remain empty.                          |
    | **Unify Updated At**<br />*Date*       | Date and time the record was last updated by Unify.                                                                                                               |
    | **Unify First Written At**<br />*Date* | Date and time the record was first written to by Unify. This will be populated when Unify first creates or updates the record, and it will not change after that. |
    | **Unify Initial Play**<br />*Text*     | Name of the first Unify Play that ran on this record.                                                                                                             |
    | **Unify Initial Play At**<br />*Date*  | Date and time the first Unify Play ran on this record.                                                                                                            |
    | **Unify Most Recent Play**<br />*Text* | Name of the most recent Unify Play that ran on this record.                                                                                                       |
    | **Unify Intent Level**<br />*Text*     | Intent level of the company (either **High**, **Medium**, **Low**, or **None**).                                                                                  |
  </Accordion>

  <Accordion title="People">
    | Field                                                  | Description                                                                                                                                                       |
    | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | **Email**<br />*Text*                                  | Contact email address.                                                                                                                                            |
    | **Address**<br />*Text*                                | Physical address of the person.                                                                                                                                   |
    | **Country**<br />*Country*                             | Country the address is located in.                                                                                                                                |
    | **Postal Code**<br />*Text*                            | Postal code for the person.                                                                                                                                       |
    | **Email Opt Out**<br />*Boolean*                       | Indicates whether the person has opted out of receiving emails.                                                                                                   |
    | **Status**<br />*Text*                                 | Status of the person in the sales lifecycle.                                                                                                                      |
    | **First Name**<br />*Text*                             | First name of the contact.                                                                                                                                        |
    | **First Name Suffix**<br />*Text*                      | Suffix of the first name of the contact.                                                                                                                          |
    | **Last Name**<br />*Text*                              | Last name of the contact.                                                                                                                                         |
    | **Title**<br />*Text*                                  | Job title or position of the contact.                                                                                                                             |
    | **Mobile Phone**<br />*Text*                           | Mobile phone number of the contact.                                                                                                                               |
    | **Work Phone**<br />*Text*                             | Work phone number of the contact.                                                                                                                                 |
    | **Corporate Phone**<br />*Text*                        | Corporate phone number of the contact.                                                                                                                            |
    | **LinkedIn URL**<br />*Text*                           | LinkedIn profile URL of the contact.                                                                                                                              |
    | **Do Not Call**<br />*Boolean*                         | Indicates whether the contact should receive phone calls or not.                                                                                                  |
    | **Do Not Email**<br />*Boolean*                        | Indicates whether the contact should receive emails or not.                                                                                                       |
    | **EU Resident**<br />*Boolean*                         | Indicates whether the contact is a resident of the European Union.                                                                                                |
    | **Lead Source**<br />*Text*                            | Channel this Person record was sourced from.                                                                                                                      |
    | **Last Activity Date**<br />*Date*                     | Date of the last activity or engagement with the contact.                                                                                                         |
    | **Unify Metadata**<br />*Text*                         | A unique identifier useful for tracking records that Unify writes to.                                                                                             |
    | **Unify Created At**<br />*Date*                       | Date and time the record was created by Unify. This will only be populated if Unify created the record; otherwise, it will remain empty.                          |
    | **Unify Updated At**<br />*Date*                       | Date and time the record was last updated by Unify.                                                                                                               |
    | **Unify First Written At**<br />*Date*                 | Date and time the record was first written to by Unify. This will be populated when Unify first creates or updates the record, and it will not change after that. |
    | **Unify Initial Play**<br />*Text*                     | Name of the first Unify Play that ran on this record.                                                                                                             |
    | **Unify Initial Play At**<br />*Date*                  | Date and time the first Unify Play ran on this record.                                                                                                            |
    | **Unify Most Recent Play**<br />*Text*                 | Name of the most recent Unify Play that ran on this record.                                                                                                       |
    | **Unify Most Recent Play At**<br />*Date*              | Date and time the most recent Unify Play ran on this record.                                                                                                      |
    | **Unify Initial Sequence**<br />*Text*                 | Name of the first Unify Sequence this person was enrolled in.                                                                                                     |
    | **Unify Initial Sequence At**<br />*Date*              | Date and time this person was first enrolled in a Unify Sequence.                                                                                                 |
    | **Unify Initial Sequence Step At**<br />*Date*         | Date and time this person first completed a step in a Unify Sequence.                                                                                             |
    | **Unify Most Recent Sequence**<br />*Text*             | Name of the most recent Unify Sequence this person was enrolled in.                                                                                               |
    | **Unify Most Recent Sequence At**<br />*Date*          | Date and time this person was most recently enrolled in a Unify Sequence.                                                                                         |
    | **Unify Most Recent Sequence Step At**<br />*Date*     | Date and time this person most recently completed a step in a Unify Sequence.                                                                                     |
    | **Unify Most Recent Sequence Status**<br />*Text*      | Status of the most recent enrollment for this person. The statuses shown on enrollments in Unify are the same values that will be written to Salesforce.          |
    | **Unify Initial Reply Classification**<br />*Text*     | High-level classification of the initial reply received from a person. It will be either "Positive", "Objection", "Neutral", "Automated", or "Negative".          |
    | **Unify Most Recent Reply Classification**<br />*Text* | High-level classification of the most recent reply received from a person. It will be either "Positive", "Objection", "Neutral", "Automated", or "Negative".      |
    | **Unify Initial Reply Tags**<br />*Text*               | Comma-separated list of classification tags of the initial reply received from a person. For example, "Willing to Meet, Needs More Info".                         |
    | **Unify Most Recent Reply Tags**<br />*Text*           | Comma-separated list of classification tags of the most recent reply received from a person. For example, "Willing to Meet, Needs More Info".                     |
  </Accordion>

  <Accordion title="Email Messages">
    | Field                                | Description                                                                                                    |
    | ------------------------------------ | -------------------------------------------------------------------------------------------------------------- |
    | **Universal Message ID**<br />*Text* | Globally unique identifier that exists for all email messages.                                                 |
    | **Sender**<br />*Text*               | Reference to the user, contact, or lead who sent the email.                                                    |
    | **Recipients**<br />*Text\[]*        | List of users, contacts, or leads who received the email.                                                      |
    | **Subject**<br />*Text*              | Subject of the email.                                                                                          |
    | **Content**<br />*Text*              | Body of the email.                                                                                             |
    | **Sent At**<br />*Date*              | Date and time the email was sent.                                                                              |
    | **Is Bounced**<br />*Boolean*        | Indicates whether the email bounced.                                                                           |
    | **Bounced At**<br />*Date*           | Date and time the email bounced.                                                                               |
    | **Click Count**<br />*Number*        | Number of times a link in the email was clicked. Only links to sites with the Unify intent client are tracked. |
    | **Clicked At**<br />*Date*           | Date and time a link in the email was first clicked.                                                           |
    | **Is Marked as Spam**<br />*Boolean* | Indicates whether the email was marked as spam by a recipient.                                                 |
    | **Marked As Spam At**<br />*Date*    | Date and time the email was marked as spam by a recipient.                                                     |
    | **Is Opened**<br />*Boolean*         | Indicates whether the email was opened by a recipient.                                                         |
    | **First Opened At**<br />*Date*      | Date and time the email was first opened by a recipient.                                                       |
    | **Last Opened At**<br />*Date*       | Date and time the email was last opened by a recipient.                                                        |
    | **Track Opens**<br />*Boolean*       | Indicates whether open tracking was enabled for the email.                                                     |
    | **Is Opted Out**<br />*Boolean*      | Indicates whether the recipient opted out of receiving emails.                                                 |
    | **Opted Out At**<br />*Date*         | Date and time the recipient opted out of receiving emails.                                                     |
    | **Enrolled By Play**<br />*Text*     | Name of the Play that enrolled the recipient in the sequence.                                                  |
    | **Sequence Name**<br />*Text*        | Name of the sequence linked to the email.                                                                      |
  </Accordion>
</AccordionGroup>


# Toggle lead assignment rules in Salesforce
Source: https://docs.unifygtm.com/reference/integrations/salesforce/lead-assignment-rules

Troubleshoot a common bug in Salesforce related to lead assignment rules.

## Explanation

Salesforce allows you to create "lead assignment rules" that automatically assign different owners to leads depending on custom criteria. However, sometimes these rules don’t work right off the bat due to a specific bug in Salesforce. The steps outlined here should resolve the issue.

## Steps

### Ensure you have an active lead assignment rule

Navigate to the **Setup** page in Salesforce by clicking the settings icon in the top-right corner of any Salesforce page.

<Frame>
  <img alt="active-lead-assignment-rule-step-1" />
</Frame>

Search for **Lead Assignment Rules** in the sidebar.

<Frame>
  <img alt="active-lead-assignment-rule-step-2" />
</Frame>

You should see at least one rule with a checkmark under the **Active** column.

<Frame>
  <img alt="active-lead-assignment-rule-step-3" />
</Frame>

### Toggle the rule off and on

In the **Lead Assignment Rules** page from the previous step, click on the name of your rule and then select **Edit**. Deselect the checkbox next to **Active** to temporarily deactivate the rule.

<Frame>
  <img alt="toggle-rule-off-on-step-2" />
</Frame>

Click **Save**. Then click **Edit** again, re-check the checkbox next to **Active**, and then choose **Save**.

### Test that leads are assigned correctly in the UI

Navigate to the **Leads** page in Salesforce. You can get there via the app launcher.

<Frame>
  <img alt="test-leads-correctly-assigned-step-1" />
</Frame>

In the top-right corner of the screen, select **New** to create a new lead.

<Frame>
  <img alt="test-leads-correctly-assigned-step-2" />
</Frame>

Check the **Assign using active assignment rule** checkbox in the lower-left corner.

<Frame>
  <img alt="test-leads-correctly-assigned-step-3" />
</Frame>

Fill out the required lead fields with values that should trigger the lead assignment rule you created and then click **Save** in the bottom-right corner.

Lastly, verify that the lead was assigned to the correct owner.


# Salesforce integration guide
Source: https://docs.unifygtm.com/reference/integrations/salesforce/overview

This guide outlines how to connect your Salesforce instance to Unify.

## Overview

In just a few steps, you can connect your Salesforce instance to Unify and start
syncing data bidirectionally. This unlocks a few key benefits when using Unify:

1. Salesforce records can be used to [construct exclusions](/tutorials/how-to-create-an-exclusion)
   that prevent Unify from engaging with specific people or companies. For
   example, you can create an exclusion for all current customers or deals in
   progress.
2. You can create Plays that are triggered by Salesforce records. This allows
   you to run a Play based on a specific event or criteria captured within
   Salesforce.
3. Unify can write data back to Salesforce so that you can maintain a source of
   truth in your CRM and respect rules of engagement in other tools or business
   processes.

Unify's integration with Salesforce is designed from the ground up to prevent
many common pitfalls, including overwriting existing data or creating duplicate
records. For an in-depth description of how Unify does this, see [How bidirectional syncs work](/reference/integrations/salesforce/bidirectional-syncs).

## Prerequisites

* **Salesforce Subscription:** Unify requires API access to your Salesforce
  instance. This is typically included with most Salesforce plans, but some
  plans may require an upgrade.

  * If you're unsure, follow [these instructions](https://help.salesforce.com/s/articleView?id=000386929\&type=1)
    to determine your plan and then check [here](https://help.salesforce.com/s/articleView?id=000385436\&language=en_US\&type=1)
    to see if API access is included.

* **Administrative Access:** To assign the correct permissions to the
  integration user, a Salesforce admin may be needed to complete these steps.

## Setup

<Note>
  If you are using a Salesforce sandbox instance, let our support team know in
  advance and we will create a dedicated testing login for you.
</Note>

<Steps>
  <Step title="Choose an integration user strategy">
    Decide which integration user Unify should use to connect to Salesforce.
    Unify supports multiple approaches:

    | Setup                                                      | Pros                                                                                                                                                                         | Cons                                                                                                                                                                 |
    | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | **Dedicated integration user**                             | This is best practice and our recommended option. The user is granted specific limited permissions and all updates made within Salesforce are clearly attributable to Unify. | This requires the purchase or use of a dedicated Salesforce user license, which may require time to set up at your company.                                          |
    | **Shared integration user with other connected apps**      | This might be a better choice, because you may already use an integration user with other connected apps. You don't need to provision a new user.                            | Unify must share the permissions and limits of the shared integration user. If this user's access is shut down, all connected apps will be impacted.                 |
    | **Existing individual user with system admin permissions** | This is typically the fastest and most affordable option because you use an individual user that already exists in your Salesforce. There's no need to create anything new.  | Unify is given full system access and edits made within Salesforce are attributed to the individual user. If the user leaves the company, the connection will break. |

    If you choose to create a dedicated integration user, you can follow [this guide](https://help.salesforce.com/s/articleView?id=platform.integration_user.htm\&type=5)
    for step-by-step instructions.
  </Step>

  <Step title="Connect Salesforce instance">
    Navigate to [Settings → Salesforce](https://app.unifygtm.com/dashboard/settings/integrations/salesforce)
    and select **Connect**. You will be redirected to the Salesforce authentication
    page where you can sign in using the desired Salesforce integration user that
    Unify will use.

    <Frame>
      <img />
    </Frame>

    <Frame>
      <img />
    </Frame>

    <Tip>
      If you are unable to connect your Salesforce instance, you may need to install and unblock the Unify
      Connected App. Navigate to **Setup → Connected Apps → Connected Apps OAuth Usage**, look for "Unify", and ensure it
      is installed and unblocked.
    </Tip>
  </Step>

  <Step title="Assign required permissions">
    Unify requires specific permissions to access the Salesforce API and read
    and write data. If any permissions are missing, they will be shown on the
    settings page.

    <Frame>
      <img />
    </Frame>

    See [Required Permissions and Settings](/reference/integrations/salesforce/required-permissions)
    for details on fixing any issues.
  </Step>

  <Step title="Choose which objects to create">
    Salesforce has two different ways of representing companies and people:

    1. **Contacts and Accounts**: Every person has a Contact record, and Contacts are associated with Accounts.
    2. **Leads**: Every person has a Lead record which contains information about both the person and their company.

    Unify supports both options, and you can choose which approach you want to
    use on the integration settings page. This can be changed at any time.

    <Tip>
      Pick the option that best aligns with how your team uses Salesforce today.
      If you're unsure, Unify recommends **Contacts and Accounts** as a best
      practice.
    </Tip>
  </Step>

  <Step title="Create field mappings">
    Unify provides granular control over which Salesforce fields map to which
    Unify fields. For each object, select **Create Mapping** and update any
    fields you wish to customize.

    In most cases, the default options will be a good starting point. You can
    always return to change these mappings in the future.

    <Frame>
      <img />
    </Frame>

    See [Field mappings](/reference/integrations/salesforce/field-mappings) for details on
    how field mappings work and the available options.
  </Step>

  <Step title="Enable syncs">
    Once you're satisfied with your integration settings and field mappings, you
    can begin syncing data into Unify by selecting **Resume**. If at any point
    you want to pause syncs again, you can return to this page and select
    **Pause**.

    To enable Unify to write data back to Salesforce, activate the toggle next to
    **Enable writing to Salesforce**. This will allow Unify to sync records back
    to Salesforce.

    <Frame>
      <img />
    </Frame>
  </Step>
</Steps>

## Additional Salesforce resources

<CardGroup>
  <Card icon="shield-check" title="Required Permissions" href="/reference/integrations/salesforce/required-permissions">
    Ensure your Salesforce user has the correct permissions and settings enabled
    for Unify.
  </Card>

  <Card icon="arrow-right-arrow-left" title="Field Mappings" href="/reference/integrations/salesforce/field-mappings">
    Configure mappings between Unify fields and Salesforce fields.
  </Card>

  <Card icon="pen-to-square" title="Configure Default Values" href="/reference/integrations/salesforce/default-values">
    Specify default values that should be used when writing to Salesforce.
  </Card>

  <Card icon="arrows-rotate" title="How Bidirectional Syncs Work" href="/reference/integrations/salesforce/bidirectional-syncs">
    Learn how Unify's bidirectional syncs work and how to avoid common pitfalls.
  </Card>
</CardGroup>


# Required permissions and settings
Source: https://docs.unifygtm.com/reference/integrations/salesforce/required-permissions

Ensure your Salesforce user has the required permissions for Unify.

## Overview

The permissions that Unify requires fall into two categories:

1. **System Permissions**: These are permissions that apply to the entire
   Salesforce instance and are required for Unify to function properly.
2. **Object Permissions**: These are permissions that apply to specific objects
   (e.g., Account, Contact, etc.) and are required for Unify to read and write
   data.

The exact permissions that Unify needs are detailed below along with
instructions on assigning these permissions to your integration user.

## Required permissions

<Info>
  Access can be restricted as desired for sensitive records or fields that you
  do not want Unify to access. However, Unify needs access to any records or
  fields that you want to use for exclusions.

  For example, to prevent Unify from engaging with current customers, Unify will
  require access to the records that indicate current customers to evaluate the
  exclusion rule.
</Info>

<Tabs>
  <Tab title="System Permissions">
    | Permission                       | Reason                                                      |
    | -------------------------------- | ----------------------------------------------------------- |
    | **API Enabled**                  | Allows Unify to communicate with Salesforce via the API     |
    | **View All Users**               | Enables Unify to link Salesforce users to Unify users       |
    | **View Setup and Configuration** | Enables Unify to provide details about missing permissions  |
    | **Edit Tasks**                   | Enables Unify to create and update tasks and email messages |
  </Tab>

  <Tab title="Object Permissions">
    | Object            | Permissions          | Reason                                                     |
    | ----------------- | -------------------- | ---------------------------------------------------------- |
    | **Account**       | *Read, Create, Edit* | Enables Unify to sync companies bidirectionally            |
    | **Contact**       | *Read, Create, Edit* | Enables Unify to sync people bidirectionally               |
    | **Lead**          | *Read, Create, Edit* | Enables Unify to sync companies and people bidirectionally |
    | **Opportunity**   | *Read*               | Enables Unify to use and filter based on opportunities     |
    | **Email Message** | *Read, Create, Edit* | Enables Unify to write outbound emails and replies         |
  </Tab>
</Tabs>

## Setup

### Assign required permissions

Depending on whether you are using profiles or permission sets, the steps to
assign the required permissions will differ slightly. Follow the instructions
below based on your setup.

<Tabs>
  <Tab title="Profiles">
    If you're using a **Profile** to manage permissions, follow these steps:

    1. Navigate to the **Setup** page in Salesforce by clicking the gear icon in
       the top-right corner.

    2. Go to **Users > Profiles**.

    3. Choose the Profile assigned to your integration user.

    4. Click **Edit**.

    5. In the **Administrative Permissions** section, enable the following
       options:

       * **API Enabled**
       * **View All Users**
       * **View Setup and Configuration**

    6. In the **General User Permissions** section, enable the following
       options:

       * **Access Activities**

    7. In the **Standard Object Permissions** section, enable the following
       options for each object:

       * **Account**: Read, Create, Edit
       * **Contact**: Read, Create, Edit
       * **Lead**: Read, Create, Edit
       * **Opportunity**: Read
       * **Email Message**: Read, Create, Edit

    8. Click **Save**.
  </Tab>

  <Tab title="Permission Sets">
    If you're using a **Permission Set** to manage permissions, follow these steps:

    1. Navigate to **Setup > Permission Sets**.

    2. Create a new permission set (or modify an existing one).

    3. Assign the permission set to your integration user.

    4. Under **System Permissions**, enable the following options:

       * **API Enabled**
       * **View All Users**
       * **View Setup and Configuration**

    5. Under **App Permissions**, enable the following options:

       * **Access Activities**

    6. Under **Object Settings**, select each object and enable the following
       options:

       * **Account**: Read, Create, Edit
       * **Contact**: Read, Create, Edit
       * **Lead**: Read, Create, Edit
       * **Opportunity**: Read
       * **Email Message**: Read, Create, Edit

    7. Click **Save**.

    8. If you created a new permission set, assign it to your integration user.
  </Tab>
</Tabs>

Once you've assigned these permissions, you can verify they are correctly set up
by checking the **Permissions** widget in Unify. Navigate to
[Settings → Integrations → Salesforce](https://app.unifygtm.com/dashboard/settings/integrations/salesforce)
and look for the **Permissions** widget.

<Frame>
  <img />
</Frame>

<Frame>
  <img />
</Frame>

### Enable enhanced emails

To ensure Unify can write emails to Salesforce, the **Enhanced Email** feature
must be enabled. This allows Unify to write sent emails using the **Email Message**
object.

In most Salesforce instances, Enhanced Email is enabled by default. If you don’t
see the **Email Message** object, review the following guide to enable it.

<Card icon="envelope" title="Set Up Enhanced Email" href="https://help.salesforce.com/s/articleView?id=sf.enable_enhanced_email.htm&type=5">
  Salesforce support article explaining how to enable Enhanced Email.
</Card>

For more information:

* [Use Enhanced Email for More Email Functionality](https://help.salesforce.com/s/articleView?id=sf.emailadmin_enhanced_email_overview.htm\&type=5)
* [Considerations for Using Enhanced Email](https://help.salesforce.com/s/articleView?id=sf.emailadmin_enhanced_email_considerations.htm\&type=5)


# Segment integration guide
Source: https://docs.unifygtm.com/reference/integrations/segment

Send Segment events into Unify.

## Overview

If you use Segment to collect website analytics, Unify can be connected to your
Segment workspace as a destination to reveal web traffic data. This will also
let you build audiences and Plays using Segment analytics data.

## Steps

<Note>
  If you’re also using the Unify Tag, ensure it isn’t running on the same
  pages as Segment. Otherwise, events may be double counted.
</Note>

### Generate a key in Unify

1. Log in to Unify

2. Navigate to [Settings → Integrations → Segment](https://app.unifygtm.com/dashboard/settings/integrations/segment) and click **Setup**

   <Frame>
     <img alt="Setup.png" />
   </Frame>

3. Click the **Copy** button to copy the write key to your clipboard

   <Frame>
     <img alt="Write Key.png" />
   </Frame>

### Add Segment destination

1. Log in to Segment and click on the **Destinations** tab in the sidebar

   <Frame>
     <img alt="Screenshot 2023-08-23 at 8.02.29 PM.png" />
   </Frame>

2. Click **Add destination** in the top right corner

   <Frame>
     <img alt="Screenshot 2023-08-23 at 7.02.47 PM.png" />
   </Frame>

3. Search for “webhook” and select the **Webhook (actions)** destination

   <Frame>
     <img alt="Screenshot 2023-08-23 at 7.03.49 PM.png" />
   </Frame>

4. Click **Add destination** again in the top right corner

   <Frame>
     <img alt="Screenshot 2023-08-23 at 7.05.58 PM.png" />
   </Frame>

5. Select website source whose data you want to send to Unify and then click **Next**

   <Frame>
     <img alt="Screenshot 2023-08-23 at 7.08.02 PM.png" />
   </Frame>

6. Give this destination a name, make sure **Fill in settings manually** is selected, and click **Create destination**

   <Frame>
     <img alt="Screenshot 2023-08-23 at 7.13.50 PM.png" />
   </Frame>

7. Click on the **Mappings** tab on the top and then select **New Mapping**

   <Frame>
     <img alt="Screenshot 2023-08-23 at 7.18.04 PM.png" />
   </Frame>

8. Choose the **Send** option

   <Frame>
     <img alt="send-option.png" />
   </Frame>

9. Fill in the following mapping values…
   1. Under **Section 2**:

      1. Unify currently supports Page, Track, and Identify event types. You should select **Add Condition** for each event type
         and select **any**.
      2. If there are specific event types that you know you do not want to forward to Unify, you can omit them.

      <Frame>
        <img alt="event-trigger.png" />
      </Frame>

      3. Click **Generate sample event** to populate the box with an example Segment event

      <Frame>
        <img alt="generate-sample-event.png" />
      </Frame>

   2. Under **Section 4**:

      1. Next to **URL**, fill in the following value:

         ```
         https://analytics.unifygtm.com/api/v1/webhooks/segment
         ```

      2. List two values under **Headers** (click **Add Mapping Field** to add more boxes):
         1. `<YOUR WRITE KEY` → `X-Write-Key`
         2. `application-json` → `Content-Type`

      3. Be sure to replace `<YOUR WRITE KEY>` with the key you copied earlier

      <Frame>
        <img alt="map-fields.png" />
      </Frame>

   3. Under **Section 5**:

      1. Send a test event to verify that it’s working

      <Frame>
        <img alt="Screenshot 2023-08-23 at 7.44.09 PM.png" />
      </Frame>

That’s it! If you see **Test event successfully received by destination.**, you’re all set. Traffic should now be flowing into Unify.


# Slack integration guide
Source: https://docs.unifygtm.com/reference/integrations/slack

This guide details the process of integrating Unify with your Slack workspace.

<Note>
  To add an app to your Slack workspace, you need the necessary permissions as
  per your organization's policy. Refer to [Slack's roles and
  permissions](https://slack.com/help/articles/201314026-Permissions-by-role-in-Slack)
  or consult with a workspace owner or admin.
</Note>

## Connect to Slack

Go to [Settings → Integrations → Slack](https://app.unifygtm.com/dashboard/settings/integrations/slack) in Unify and press the **Connect** button.

<Frame>
  <img alt="" />
</Frame>

You will be redirected to Slack's authorization page. Click **Allow** to proceed.

<Frame>
  <img alt="" />
</Frame>

You will be redirected back to the Slack settings page, where you can view the status of your connection.

<Frame>
  <img alt="" />
</Frame>


# Authentication options
Source: https://docs.unifygtm.com/reference/management/authentication

Learn about the login methods available for your organization in Unify.

## Overview

Unify supports the following forms of authentication:

1. **Username and Password**: Users can log in with an email address and password managed by Unify.

2. **Google Workspace**: Users can log in using a Google account associated with your organization's Google Workspace.

3. **Single Sign-On (SSO) via SAML 2.0**: Unify supports SSO through the SAML 2.0 protocol. This allows your organization to use your existing identity provider (IdP), such as Okta or Azure AD, to authenticate your users.

All methods are powered by Auth0, the leading industry standard for secure authentication.

### Single sign-on (SSO)

<Info>
  SSO is available for an additional fee, which is a direct passthrough cost from our provider.
</Info>

Our team will work directly with you to integrate Unify with your identify provider. Below are the steps and information we'll cover during this process.

#### Supported identity providers (IdPs)

* Okta
* Azure Active Directory (AD)
* Any SAML 2.0 compliant IdP

#### Information required for SSO setup

* **Sign In URL**: The URL where SAML authentication requests are sent. This is also called the single sign-on (SSO) endpoint.
* **Sign Out URL**: The URL where SAML logout requests are sent. This is also called the single logout (SLO) endpoint.
* **X.509 Certificate**: A certificate used to verify the SAML response.


# Unify credit system
Source: https://docs.unifygtm.com/reference/management/credit-system

Learn how credits work in Unify.

## Overview

Unify operates on a flexible, usage-based credit system that scales with your
needs. Credits are consumed by various activities such as prospecting,
enrichment, AI Agent runs, and certain intent signals.

## How credits work

Here are the key points to know about the credit system:

* **Credit Value**: Each Unify Credit represents a unit of platform usage.

* **Consumption**: Credits are deducted in real-time as features are used.

* **Replenishment**: Credits reset monthly or annually based on your plan. Add
  credits at anytime on the [Usage](https://app.unifygtm.com/dashboard/settings/organization/usage)
  page or upgrade your plan on the [Plans & Billing](https://app.unifygtm.com/dashboard/settings/billing)
  page.

You can monitor your credit consumption on the [Usage](https://app.unifygtm.com/dashboard/settings/organization/usage)
page.

## Credit consumption

Different features consume credits at different rates. Here's a breakdown of the
credit consumption of each feature:

| Feature                        | Unify Credits | Unit                              | Description                                                                                                                  |
| ------------------------------ | ------------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| Website Reveals                | 0.1           | Per website visitor revealed      | Website reveals are triggered by adding our website tag and turning on Unify Intent.                                         |
| Person Enriched (B2B Email)    | 2             | Per person enriched               | People that are uploaded via CSV without emails or prospected via the prospecting step are enriched when run through a Play. |
| Person Enriched (Phone Number) | 4             | Per person enriched               | Phone number enrichment can be turned on in the prospecting node in Unify.                                                   |
| New Hire Tracking              | 5             | Per new hire found                | A new hire is returned when someone within the customer defined specifications that has moved jobs in the last 90 days.      |
| Champion Tracking              | 1             | Per champion track attempt        | Champions are set up by users and are tracked on a monthly basis.                                                            |
| AI Agent                       | 0.1           | Per question answered per company | Agents can be configured to answer various per each company or person they are run on.                                       |

## Best practices

* **Use Prospecting Limits**: Set limits on the number of people you want to prospect for at each company, especially when targeting only a couple personas.

* **Create Specific Personas**: Be as specific as possible when listing titles to include or exclude in your buyer persona to make sure you aren't prospecting for unqualified contacts.

* **Set Global Exclusions**: Exclusions are a helpful way to make sure that you are not prospecting, enriching, or tracking people who don't fit your ICP.

## Need help?

* Contact [billing@unifygtm.com](mailto:billing@unifygtm.com) for credit-related questions

* Visit our [reference center](/reference/overview) for detailed guides on each feature


# Organization settings
Source: https://docs.unifygtm.com/reference/management/organization-settings

Configure your organization within Unify.

Users with sufficient permission can configure their organization settings within Unify. There are a variety of available configuration options, including:

* **Company name**: The name of your organization.
* **Managed signature**: A standardized email signature to be included in all outbound emails sent by Unify users. This is a template that will dynamically construct each signature based on the user's profile information.
* **Custom user fields**: Additional fields that can be set for each user profile. These values can then be used with other Unify features, such as email signatures and snippets.

You will find these options within [Settings](https://app.unifygtm.com/dashboard/settings/organization/general).

<Frame>
  <img />
</Frame>


# User management
Source: https://docs.unifygtm.com/reference/management/user-management

Invite users and set their roles directly in Unify.

Your teammates can be assigned two different roles in Unify:

* **Admin** — Designed for users who need access to all core Unify capabilities and settings in the organization.

* **Rep** — Designed for users who are primarily focused on creating and managing Sequences in Unify, and who don’t need access to edit Plays or manage organization settings.

<Frame>
  <img />
</Frame>

## Role detail

Each role has a granular set of permissions available to them:

| Permission                                    |    Admin    |           Rep          |
| --------------------------------------------- | :---------: | :--------------------: |
| Invite users and set roles                    |      ✅      |            ❌           |
| Edit Organization settings, including Billing |      ✅      |            ❌           |
| Edit Exclusion settings                       |      ✅      |            ❌           |
| Create and edit Plays                         |      ✅      |            ❌           |
| View Plays                                    |      ✅      |            ✅           |
| Create and edit Sequences                     |      ✅      |            ✅           |
| Create and edit Audiences                     |      ✅      |            ✅           |
| Viewable tasks on Tasks dashboard             | *All tasks* | *Tasks assigned to me* |
| Edit settings to make task skippable          |      ✅      |            ❌           |

## Inviting a new user

To invite a new user, click the **+ Invite** button, and set their role. You can invite multiple users at one time.

You can always change this role after they accept the invite.

<Frame>
  <img />
</Frame>


# Notifications in Unify
Source: https://docs.unifygtm.com/reference/notifications/overview

Stay on top of important updates with multi-channel notifications.

## Overview

Notifications help you stay on top of important updates—from positive replies to Sequences to ensuring no tasks slip through the cracks.

Notifications are available both in-app and through Slack, giving teams visibility wherever they work.

## Notification types

<CardGroup>
  <Card title="Replies to Sequences" icon={<ReplyIcon />}>
    Receive a notification when prospects reply to your Sequences. Admins can customize which reply classifications trigger notifications. Slack notifications can be sent to shared channels to increase team visibility.
  </Card>

  <Card title="New Tasks" icon={<TasksIcon />}>
    Get notified when new tasks are assigned to you. Reps receive task notifications as soon as they are assigned. Admins can choose to be notified of all new tasks or only those assigned to them.
  </Card>
</CardGroup>

## Notification channels

Unify supports notifications across multiple channels so you can stay informed wherever you work.

### In-app notifications

Access all your notifications directly within Unify through the notification feed in the left sidebar. The notification icon displays a badge with your unread count, making it easy to see when new updates arrive.

<Frame>
  <img />
</Frame>

In-app notifications provide quick access to relevant context and allow you to take immediate action—like viewing a reply or opening a task—with a single click.

### Slack notifications

Connect your Slack workspace to receive notifications directly in Slack. Admins can configure notifications to be sent to shared channels for team-wide visibility, or individuals can receive personal notifications through the Unify Slack app.

<Frame>
  <img />
</Frame>

Slack notifications include all the essential details and provide a direct link back to Unify to take action.

### Email notifications

<Info>
  Email notifications are coming soon.
</Info>

## Learn more

<Tip>
  Watch [this Loom](https://www.loom.com/share/473d5ba223a94a049fba94312bc3e442?sid=53c24cbf-a1ee-4b57-99a2-b0cb283bc6b9) for a quick overview of how notifications appear in Unify and Slack, and how to update your preferences.
</Tip>


# Notification preferences
Source: https://docs.unifygtm.com/reference/notifications/preferences

Set how you want to be notified for updates and activities on Unify.

Notification preferences allow you to control how and when you receive alerts for replies, tasks, and updates.
Preferences are divided into two categories: **Workspace notifications** (team-level notifications available for admins) and
**my notifications** (personal notifications available for all users).

## Workspace Notifications

<Note>
  Workspace notifications are only available to users with the **Admin** role.
</Note>

Workspace notifications allow admins to have visibility into any notification for any team member, ensuring admins stay informed about important updates
across the team.

### Workspace Replies

Receive notifications when prospects reply to any Sequence. Admins can customize which reply classifications trigger notifications and choose where to receive them.

<Frame>
  <img />
</Frame>

#### Reply Classifications

By default, the following reply classifications can be configured.

* <PositiveToneIcon />**Positive** — The email response shows enthusiasm, agreement, or active engagement with the sender's offer, indicating a genuine interest in moving forward
* <WillingToMeetIcon />**Willing to meet** — The recipient's email indicates their openness to schedule a meeting, specifically about the offer mentioned in the initial outreach
* <NeedsMoreInfoIcon />**Needs more info** — The recipient requests additional details or expresses uncertainty about the offer
* <NeutralToneIcon />**Neutral** — The email is objective, factual, respectful, unemotional, and polite yet concise

You can add additional classifications if you want to receive notifications for other types of replies. For example, if you want to be notified
about <OutOfOfficeIcon />**Out of Office** replies, you can add that classification in your settings.

<Tip>
  See [Reply classifications](/reference/sequences/replies#reply-classifications) for detailed definitions of all classification types.
</Tip>

<Frame>
  <img />
</Frame>

#### Excluding Classifications

Some replies can have multiple classifications. You can exclude specific classifications from triggering notifications. **If a reply has any excluded classification, no notification will be sent**, even if it also has other classifications that would normally trigger an alert.

Common exclusions include:

* <OutOfOfficeIcon />**OOO** (Out of Office) — Automated away messages
* <AutomatedIcon />**Automated** — Auto responders and system-generated replies

<Frame>
  <img />
</Frame>

### Workspace Tasks and Updates

Receive notifications for all tasks and updates created for anyone on your team. This allows admins to stay informed about task assignments and progress across the organization.

<Frame>
  <img />
</Frame>

## My Notifications

Personal notifications are available to all users (both Admins and Reps) and allow you to manage alerts specific to you.

<Frame>
  <img />
</Frame>

### Connecting Your Slack Account

To receive Slack notifications, you need to connect your personal Slack profile to Unify.

<Steps>
  <Step title="Connect to your Slack Organization">
    Admins must configure their tenant's connection to Slack before users can select their profiles.
  </Step>

  <Step title="Select your Slack profile">
    Click on the Slack profile selector to connect your account. Slack notifications will be sent directly to your Unify Slack app.
  </Step>
</Steps>

<Tip>
  If you don't see your Slack profile in the dropdown, or if the options are disabled,
  make sure the Unify Slack app is installed in your workspace and you've been added to it.
</Tip>

### My Tasks and Updates

Receive notifications for tasks assigned to you and updates on those tasks.

**Notification channels:**

* **Slack** — Direct messages in Slack (requires Slack profile connection)
* **In app** — Notifications in the Unify notification feed

## Notification Channels

Unify supports two notification channels:

| Channel    | Description                                       | Requirements                                         |
| ---------- | ------------------------------------------------- | ---------------------------------------------------- |
| **Slack**  | Receive notifications as direct messages in Slack | Must connect your Slack Organization / Slack profile |
| **In app** | View notifications in the Unify notification feed | No setup required                                    |

You can enable either or both channels for each notification type.

## Default Settings

All new users are configured with default notification preferences upon onboarding.
You can customize these settings at any time from the notification preferences page.


# Reference guide
Source: https://docs.unifygtm.com/reference/overview

Bring your most creative go-to-market ideas to life with Unify.

<CardGroup>
  <Card title="Plays" icon={<PlaysIcon />} href="/reference/plays/overview">
    Orchestrate outbound workflows that bridge data and action.
  </Card>

  <Card title="Agents" icon="sparkle" href="/reference/agents/overview">
    Use AI to research leads and personalize messaging at scale.
  </Card>

  <Card title="Sequences" icon={<SequencesIcon />} href="/reference/sequences/overview">
    Personalize your outreach at scale with dynamic multi-channel outbound.
  </Card>

  <Card title="Dialer" icon={<PhoneCallIcon />} href="/reference/dialer/overview">
    Call prospects from inside Unify and log every call automatically.
  </Card>

  <Card title="Signals" icon={<SignalsIcon />} href="/reference/signals/overview">
    Identify and engage your target accounts with real-time buying signals.
  </Card>

  <Card title="Integrations" icon={<SettingsIcon />} href="/reference/integrations/overview">
    Connect and orchestrate your full stack end-to-end in minutes, not months.
  </Card>

  <Card title="Notifications" icon="bell" href="/reference/notifications/overview">
    Stay on top of important updates with multi-channel notifications.
  </Card>

  <Card title="Management" icon={<UserIcon />} href="/reference/management/user-management">
    Add or remove users, control organization settings, and set up
    authentication.
  </Card>

  <Card title="Chrome extension" icon="chrome" href="/reference/browser-extension/installation">
    Access Unify records from your CRM or across the web.
  </Card>
</CardGroup>


# Play actions
Source: https://docs.unifygtm.com/reference/plays/actions

Actions are the building blocks of Unify Plays.

## Overview

Plays chain together actions to perform anything from simple automations to
complex and dynamic outbound campaigns. Below are the actions you can choose
from when creating a Play.

## Core actions

### AI Agent qualification

AI Agents are powerful tools for researching companies or people and answering
questions about them. In Plays, the answers provided by an Agent can be used to
determine whether a company or person is qualified or not.

When you select the Agent qualification action, you will be able to choose an
existing Agent or create a new one. Every Agent has a set of questions that it
will answer about the given record. In the action configuration panel, you can
select which answers are required for the record to be considered qualified.

<Frame>
  <img />
</Frame>

### Assign owner

The owner assignment action allows you to assign a record to a specific owner in
Unify. Every company and person record in Unify has an owner, and this action
allows you to set or change the owner of a record.

<Frame>
  <img />
</Frame>

When you connect a CRM to Unify, the owner of the corresponding records in the
CRM will be synced into Unify. For records that don't yet have an owner or don't
yet exist in the CRM, you can use this action to assign an owner. You can also
choose to update the owner if desired.

### Prospect

One of the most common use cases for Plays is to find new people to reach out
to. The prospecting action takes a company record as input and returns a list of
people at that company matching specific personas and criteria.

When you select the prospecting action, you can specify one or more personas to
search for. The personas are considered in order, so the first persona will be
preferred over the second, then each subsequent persona.

<Frame>
  <img />
</Frame>

You can also specify a limit on the number of people to find per company. The
limit must be between 1 and 10.

#### Prospecting methods

The prospecting method determines whether Unify should use people that already
exist in Unify or your CRM, pull fresh contact data, or do both.

| Method                          | Behavior                                                                                                                                | Credit usage                                                                                 |
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| **Prioritize existing records** | Adds matching existing people first, then uses Unify prospecting data to find additional people until the per-company limit is reached. | Credits are charged only for new people found from Unify prospecting.                        |
| **Find the best matches**       | Uses Unify prospecting data for every person so Unify can return the freshest matching records.                                         | Credits are charged for every person added, even if they already exist in Unify or your CRM. |
| **Find new people only**        | Excludes existing people and only returns net-new people.                                                                               | Credits are charged for every person added.                                                  |

Unify prospecting uses 2 credits per person. If credits are exhausted, the
action cannot find net-new people. If **Prioritize existing records** is
selected, the action can still return matching existing people.

#### Persona order and filters

Personas are matched in the order shown in the action. Drag personas to set the
preferred order. You can select up to five personas in one Prospect action.

Optional filters refine the search:

* **Phone enrichment** attempts to enrich phone numbers for returned people.
* **Keywords** search information associated with prospects and rank matching prospects higher.
* **Countries** only return people located in selected countries.

The Prospect action returns a list of people. To enroll those people in
Sequences, connect the Prospect action to a **Sequence** action and configure
persona routing there.

### Sequence

The sequence enrollment action makes building automated outbound campaigns
easier than ever. You can choose which sequences to send people to based on
which personas they match.

<Frame>
  <img />
</Frame>

The routing configuration provides a way to specify which mailboxes and
Sequences should be used for people this action runs on. You can route by
persona, send everyone to one Sequence, or add an **Everyone else** route for
people who do not match a configured persona.

<Frame>
  <img />
</Frame>

#### Persona routing

For persona routes, Unify compares the person's title to each configured
persona in order. The first matching persona determines which Sequence and
mailbox route is used. If **Route all personas together** is enabled, every
configured persona uses the same Sequence and mailbox route.

If the Play has an upstream Prospect action, Unify can detect prospect personas
that are not yet routed and offer **Add prospect personas** in the Sequence
configuration.

The optional **Everyone else** route catches people who do not match any
configured persona. If there is no matching persona route and no **Everyone
else** route, the action skips that person because there is no routing target.

#### Mailbox routing

For each route, choose how Unify should select the sending mailbox:

| Routing option                | Behavior                                                      |
| ----------------------------- | ------------------------------------------------------------- |
| **Manually select mailboxes** | Select specific mailboxes or mailbox groups for that route.   |
| **Use Person record owner**   | Use a mailbox assigned to the Person's Unify owner.           |
| **Use Company record owner**  | Use a mailbox assigned to the Person's Company's Unify owner. |

When owner-based routing is selected, you must also select fallback mailboxes.
Unify uses the fallback mailboxes if the record is unowned or if the owner does
not have an eligible mailbox.

Only eligible mailboxes are used. A mailbox must be assigned to an active user,
not deleted, not paused, and eligible to send. Unify Email Delivery mailboxes
must be warm or explicitly marked warm; Gmail mailboxes do not require Unify
warmup.

#### Enrollment limits and skips

You also have the option to set **Max. enrollments per Company**, which is
generally recommended to avoid over-targeting a single company. This limit
checks active Sequence enrollments for people at the same company across all
Plays in Unify. If the company already has that many active enrollments, the
action skips additional people from that company.

The Sequence action can also skip a person when:

* The person is already enrolled in a Sequence that prevents another enrollment.
* The selected Sequence has been deleted or has no published version.
* No route matches the person and there is no **Everyone else** route.
* No eligible mailbox can be selected for the route.

See [Sequence enrollments](/reference/sequences/enrollments) for more detail on
enrollment lifecycle and eligibility.

### Slack alert

The Slack alert action allows you to send a customized Slack message at any
point in a Play. You can send messages to any public channels or DM any users in
your workspace.

<Frame>
  <img />
</Frame>

The contents of the messages can be customized with template variables, so you
can include information about the record that triggered the action.

<Note>
  If the value for a template variable is missing, the message will still be sent,
  but the variable will be replaced with `Unknown`.
</Note>

You may optionally tag the owner of the account (e.g. `@John Doe`), so they can
be easily notified of the alert. You can also include intent signal information
containing recent website visitors, G2 page views, and more.

This action is available when Slack connected to Unify. See the [Slack integration guide](/reference/integrations/slack)
for information on integrating Slack with Unify.

### Sync to HubSpot

The HubSpot sync action allows you to create or update a record in HubSpot based
on a company or person record in Unify. This action will use the settings you've
configured for HubSpot in the Unify settings.

You also have the option to specify additional default field values. These will
be written to HubSpot unless a different Unify field is already mapped to the
HubSpot field.

<Frame>
  <img />
</Frame>

### Sync to Salesforce

The Salesforce sync action allows you to create or update a record in Salesforce
based on a company or person record in Unify. This action will use the settings
you've configured for Salesforce in the Unify settings.

You also have the option to specify additional default field values. These will
be written to Salesforce unless a different Unify field is already mapped to the
Salesforce field.

<Frame>
  <img />
</Frame>

### Webhook

The webhook action allows you to send an HTTP request to any URL with
configurable options and a custom payload. This can be used to integrate with
any tool that accepts webhooks, such as Zapier, n8n, or internal tooling.

Here are the available configuration options:

| Option             | Description                                                                         |
| ------------------ | ----------------------------------------------------------------------------------- |
| **URL**            | The URL to send the request to.                                                     |
| **Method**         | The HTTP method to use (e.g. GET, POST, etc.).                                      |
| **Authentication** | The authentication method to use, if any (e.g. Basic Auth, Bearer Token, etc.).     |
| **Headers**        | Any custom headers to include in the request.                                       |
| **Query params**   | Any custom query parameters to include in the request URL.                          |
| **Body**           | The body of the request, which can be customized with template variables.           |
| **Retry policy**   | The number of retries to attempt if the request fails and the time between retries. |

<Frame>
  <img />
</Frame>

## Utility actions

### A/B test

The A/B test action allows you to route records down a specific path based on a
set probability. This is useful for testing different sequences or actions.

<Frame>
  <img />
</Frame>

### Delay

The Delay action waits for a specified amount of time before continuing to the
next action in a Play. This can be useful for spacing out actions in a Play and
ensuring that actions are performed at the right time.

<Frame>
  <img />
</Frame>

This action is particularly useful when combined with if-else actions. For
example, when a person visits your website, it can be useful to wait a few
minutes before taking action to see which pages they visit or whether they fill
out a form.

### Get Company

If you have a person record, you can use this action to fetch the company that
the person works at. If the person does not have a company associated with them,
this action will not return any result.

### Get People

If you have a company record, you can use this action to fetch people that work
at the company. Unlike the **Prospect for new People** action, this action only
looks for people that already exist in Unify rather than prospecting for new
people.

### If / Else

The if-else action creates a branch in a Play, evaluates some conditions for
records, and sends them down a specific path based on the result. This allows
you to perform different actions on different records based on criteria that you
specify.

<Frame>
  <img />
</Frame>

This action enables you to solve a wide variety of more complex use cases using
Plays. For example, you can enroll people into different sequences based on
their company firmographics, exact job title, or custom CRM field values.

## Coming soon

There are lots of additional actions in the works including more powerful AI
features and deep integrations with third-party tools. If you're interested in
an action that isn't available yet, [let us know](mailto:support@unifygtm.com)!
We'll get you in the beta as soon as it's ready.


# Building a Play
Source: https://docs.unifygtm.com/reference/plays/building-a-play

Learn the fundamentals of creating Plays in Unify.

## Actions and triggers

The building blocks of Plays are called *actions*. Each action is a different
step of a Play, each representing a different task that can be automated in
Unify.

Every Play starts with a special type of action called a *trigger*. A trigger is
the starting point which defines when the Play should run and what data should
be provided to it.

<Frame>
  <img />
</Frame>

Here are a few of the triggers you can choose from:

* **Record enters an Audience**: Run a Play once on every company or person that
  "enters" an Audience. Audiences can be reused across multiple Plays.
* **Record matches criteria**: Run a Play once on every company or person that
  matches a set of filters. This trigger is similar to the audience trigger, but
  it doesn't require you to create a separate audience. Useful when you don't
  need to create a reusable audience.
* **Manual**: Only run a Play when it is manually triggered. For example, you
  can send individual companies or people to a Play, or you can send an entire
  audience.

Once the trigger is selected, you can start adding additional actions to the
Play. Each action performs a different task. Actions can be chained together or
perform branching logic based on the results of the previous action.

Here are some commonly used actions:

* **AI Agent qualification**: Perform AI-powered research to answer qualifying
  questions about a company or person.
* **Prospect for new People**: Find new people at a company matching specific
  personas. You can specify a limit on the number of people to find.
* **Sequence enrollment**: Enroll a person in a Sequence. You can route people
  to different mailboxes and Sequences based on their persona.
* **Write to Salesforce or HubSpot**: Sync a company or person to Salesforce or
  HubSpot. This will create or update a record in your CRM.

You can find details about the full set of available triggers and actions in the
reference sections below:

<Card title="Triggers" icon="zap" href="/reference/plays/triggers">
  See the full list of triggers available in Unify and how to use them.
</Card>

<Card title="Actions" icon="play-circle" href="/reference/plays/actions">
  See the full list of actions available in Unify and how to use them.
</Card>

<Card title="Play settings" icon="rotate-right" href="/reference/plays/play-settings">
  Configure play-level settings such as rerun behavior.
</Card>

## Inputs and outputs

Each action receives an input and produces an output. Actions in the Play
Builder have small colored symbols that represent what type of input and output
they expect.

Here's what each symbol represents:

| Symbol |                                       | Value |
| :----: | ------------------------------------- | :---- |
|        | A single person record.               |       |
|        | A list of one or more person records. |       |
|        | A single company record.              |       |

Plays work by connecting each action's output to a matching input on another
action. This is how data flows through the Play and how each action knows what
to do.

## Connecting actions

To connect two actions, click on the output symbol of the first action and drag
the connection to the input symbol of the second action.

<Frame>
  <video />

  <video />
</Frame>

When adding a new action to the Play Builder, you can drag it on top of another
action to automatically connect them.

<Frame>
  <video />

  <video />
</Frame>

Another shortcut for connecting actions is to move any action near to another
action. Once the input and output symbols are close enough, they will
automatically be connected.

<Frame>
  <video />

  <video />
</Frame>

To delete a connection, click on the connection line and press the **Backspace**
or **Delete** key.

<Frame>
  <video />

  <video />
</Frame>

## Save and publish

When you first create a Play, it is automatically saved as a draft. You can
leave and return later to finish building the Play without losing your progress.

Once you're ready to start running the Play, you can publish it. Published Plays
will run automatically based on the trigger you've selected. To publish a Play,
click the **Publish** button in the top right corner of the Play Builder.

<Frame>
  <img />
</Frame>

After publishing a Play, you can still make changes to it. Any changes you make
will be saved as a new draft. You can publish the new draft at any time by
clicking the **Publish** button again. You can also discard the draft and revert
to the last published version.

If you want to temporarily stop a Play from running, you can pause it by
toggling the pause button to the left of the **Publish** button. Pausing a Play
will prevent it from running until you resume it.

## View logs

Once a Play starts running, you can view the logs to see which companies and
people the Play has run on. In the top left corner of the Play Builder, click
on **Logs** to see the full history of Play executions.

<Frame>
  <img />
</Frame>

Within the logs view, you can see the status of each Play execution, including
in-progress, completed, and failed executions. You can click on any row of the
logs table to see more details about that specific execution.

<Frame>
  <img />
</Frame>

The exact path this record took through the Play is highlighted on the right
side of the details view. You can see exactly which actions ran and what the
results were at each step.

## View metrics

You can view metrics for each Play to see how it's performing over time. In the
top left corner of the Play Builder, click on **Metrics** to see overview
metrics and charts for the Play and its actions.

<Frame>
  <img />
</Frame>

You can click on any action to see detailed information about how it's
performing. For example, clicking on an Agent qualification action will let you
measure how many records are being qualified over time and why.

<Frame>
  <img />
</Frame>

The action-specific metrics pages will also show you the records that have
passed through that action and their results.


# Unify Plays
Source: https://docs.unifygtm.com/reference/plays/overview

Learn what Unify Plays are and how to use them.

## What are Plays?

Plays are automated workflows that let you build and execute repeatable
strategies. Unify manages the logistics of coordinating and scaling all the
details.

<Frame>
  <img />
</Frame>

Building scalable and effective sales, marketing, and GTM strategies requires
successfully coordinating two key components:

* **Data**: Countless data sources go into building scalable automations. This
  data is traditionally scattered across tools and databases, but Unify
  centralizes it in one place.
* **Actions**: Researching companies, identifying decision-makers, executing
  multi-channel outreach, and more. Taking the right action at the right time
  is crucial to success.

Unify is a purpose-built system of action that solves this problem. Plays let
you define a series of actions that will be taken on companies or people at
exactly the right moment.

## Use cases

Plays are a versatile tool that can be used to build out anything from standard,
reliable outbound strategies to complex and innovative growth campaigns. Here
are some of the most popular use cases for Plays:

* **Warm Outbound**: Find prospects at companies matching intent signals and
  reach out to them with personalized messaging at just the right time.
* **Champion tracking**: Keep tabs on champions of your business and reach out
  to them when they take a role at a new company.
* **List building**: Take a list of companies and turn it into high-quality
  leads by enriching the data and finding new contacts in relevant roles.

These are just a few of the most common ways Plays are used. Plays provide the
flexibility to build arbitrarily complex automations tailored to your goals.

<Tip>Check out the tutorial [How to create a Play](/tutorials/how-to-create-a-play) for a hands-on introduction to Plays!</Tip>


# Play settings
Source: https://docs.unifygtm.com/reference/plays/play-settings

Configure individual Plays with settings and options.

## Overview

Play settings control behavior that applies to the overall Play, even if the
trigger or actions are modified. These settings currently include controls that
determine when the same record can run through the Play multiple times.

## Rerun settings

By default, an automated Play runs once per matching record. When a company or
person has already started a Play execution, Unify prevents that same record
from future automated runs of the same Play.

You can change this behavior by enabling reruns and setting a cooldown period.
The available options are outlined below.

| Setting                                                | Behavior                                                                                                                                                                                                                        |
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Allow Play to rerun on the same record**             | Controls whether a company or person can run through the same Play more than once. When off, a record is suppressed after it starts a Play execution. When on, a record can run again after the configured cooldown has passed. |
| **Only allow Plays to rerun on the same record after** | Sets the cooldown period before the same record can run through the same Play again. In-progress executions are still suppressed.                                                                                               |

For example, if a record match Play has a 30 day cooldown, a company that
matches today can run today, will be suppressed for the next 30 days, and can
run again later if it still matches the trigger criteria.

<Note>
  Rerun settings are not shown for every trigger type. For example, lookalike
  company triggers currently do not support the same rerun setting.
</Note>


# Play triggers
Source: https://docs.unifygtm.com/reference/plays/triggers

Triggers represent the events and data sources that a Play runs on.

## Overview

Plays run on individual records, such as companies or people. Triggers define
when a Play should run and what data should be provided to it. Below are the
triggers you can choose from when creating a Play.

## How triggers run

### Timing

Most automated triggers run on a recurring schedule. When the schedule runs,
Unify checks which records currently match the trigger, removes records that
have already run through the Play, and starts new Play executions for the
remaining records.

For **Record matches criteria** and **Record enters an Audience** triggers, this
means a record can run when it already matches at publish time or when it starts
matching later. By default, the same record will not run through the same Play
again after it has already started a Play execution. To allow the same record to
run again after a waiting period, configure [Play settings](/reference/plays/play-settings).

Automated trigger schedules are managed by Unify. Record match and Audience
triggers are evaluated about every 15 minutes. Lookalike company triggers are
evaluated about every 30 minutes.

### Outputs

The record type you choose in the trigger determines the output of the trigger
and which actions can connect directly to it:

| Trigger output | Common next actions                                                 |
| -------------- | ------------------------------------------------------------------- |
| Company        | Prospect, Get People, Assign owner, CRM sync, Slack alert, Webhook  |
| Person         | Sequence, Get Company, Assign owner, CRM sync, Slack alert, Webhook |

If a company-triggered Play needs to enroll people in a Sequence, add a
**Prospect** or **Get People** action first. **Prospect** can find net-new or
existing people, while **Get People** only returns people that already exist in
Unify.

## Available triggers

### Champions

This trigger is a shortcut for running a Play on champions that Unify has
tracked for your business. Once selected, you can customize the matching
criteria similar to the record match trigger. This trigger always returns
People.

<Frame>
  <img />
</Frame>

In order to use this trigger, you must have enabled and configured champion
tracking in your settings. For more information, see [Champion tracking](/reference/signals/champions).

### Find lookalike companies

This trigger runs a Play on companies that are similar to a set of companies
you specify. This is useful for finding new companies that are similar to your
existing customers or ideal customer profile.

<Frame>
  <img />
</Frame>

Once you've defined the criteria that specifies which companies to find
lookalikes for, you can define some additional options for the trigger, such as
additional filters to apply or exclusions to enable and disable.

<Frame>
  <img />
</Frame>

This trigger is powered by [Ocean.io](https://www.ocean.io/). The integration is
fully managed by Unify and included in your plan, so no additional subscription
or setup is required.

### Record enters an Audience

This trigger runs a Play on companies or people that are in an Audience and have
not already run through the Play. A record enters an Audience when it meets the
Audience criteria for the first time.

<Frame>
  <img />
</Frame>

When you select an audience trigger, you will be prompted to select an audience
from the list of audiences you have created. Audiences are reusable in Unify,
which means you can use the same audience in multiple Plays.

You also have the choice to run the Play on either companies that enter the
audience or people that enter the audience. If you select companies, the output
of this trigger will be a company record. Otherwise, the output will be a person
record.

### Record matches criteria

This trigger runs a Play on companies or people that match a set of filters and
have not already run through the Play. This trigger behaves the same as the
Audience trigger, but it doesn't require that you already have an Audience
created. Instead, you can define the filters directly in the Play.

<Frame>
  <img />
</Frame>

When you select a criteria trigger, you will be prompted to add filters to
select the companies or people that the Play should run on. Just like building
Audiences, you can add as many filters as you like and preview the records that
match the filters before saving the trigger.

As with audience triggers, you can choose to run the Play on either companies or
people. This will determine what type of record the trigger outputs.

### Website visitors

This trigger is a shortcut for running a Play on companies that visit your
website. Once selected, you can customize the matching criteria similar to the
record match trigger. This trigger always returns companies.

<Frame>
  <img />
</Frame>

### Record manually added

This trigger runs a Play on a company or person that is manually added by a user.
Unlike automated triggers, this trigger does not run on its own. It only fires
when someone explicitly sends a record to the Play.

<Frame>
  <img />
</Frame>

When you select a manual trigger, you will be prompted to choose whether the
Play should accept companies or people. This determines the type of record that
the trigger outputs.

Once the Play is active, you can manually add records to it from anywhere in
Unify where you can select companies or people. This is useful when you want
full control over which records enter a Play, rather than relying on automated
signals or filter criteria.

## Coming soon

There are lots of additional triggers in the works including webhooks, third-party
events, schedules, and more. If you're interested in one that isn't available
yet, [let us know](mailto:support@unifygtm.com)! We'll get you in the beta as
soon as it's ready.

## FAQ

<AccordionGroup>
  <Accordion title="Should I use an Audience trigger or a record match trigger?">
    Audience triggers and record match triggers can both be used to accomplish
    the same goal. The main difference is that Audience triggers require you to
    create an Audience ahead of time, while record match triggers allow you to
    define the filters directly in the Play.

    Audiences can be reused in multiple Plays, which is useful if you have a set
    of filters that you use frequently. Audiences can also be viewed, edited,
    and exported from the **Audiences** tab.

    Record match triggers are a great option for quickly iterating on a Play or
    if you don't want to create an Audience for a one-off Play. You can always
    come back later, convert the filters into an Audience, and then swap the
    trigger out for an Audience trigger.
  </Accordion>

  <Accordion title="Is an Audience trigger the same as sending an Audience to a manual trigger?">
    Audiences are dynamic lists of companies and people that can change over
    time according to the filters you specify. For example, an Audience might
    capture all companies that have visited your website in the last 30 days.

    When you send an Audience to a manual trigger, you are sending the current
    list of companies or people that are in the Audience at that moment. This
    is useful if you want to run a Play on a snapshot of the audience but not on
    a recurring basis.

    By contrast, an Audience trigger will keep checking the Audience over time
    and run the Play for matching companies or people that have not already run
    through that Play. This is useful if you want the Play to run on records that
    match now and records that match in the future.
  </Accordion>

  <Accordion title="Can I make an automated trigger run only on future matches?">
    Automated triggers evaluate matching records when the Play is published and
    on future scheduled checks. If you only want future matches, add a time-based
    condition to the trigger or Audience, such as a recent activity date, created
    date, or signal timestamp that represents the future window you want to
    target.

    If you need a one-time snapshot instead, use a manual trigger and send the
    selected records to the Play manually.
  </Accordion>
</AccordionGroup>


# Sequence enrollments
Source: https://docs.unifygtm.com/reference/sequences/enrollments

Understand how Sequence enrollments work.

## Overview

A Sequence enrollment is the record of a person moving through a Sequence.
Enrollments track which Sequence the person is in, which mailbox is sending,
which steps have run, and why the enrollment is active, blocked, or finished.

People can enter a Sequence in a few ways:

* A [Play](/reference/plays/overview) enrolls the person automatically with a
  Sequence action
* A user manually adds the person to a Sequence, such as from the person details
  screen, a list, or the browser extension

Each enrollment uses a sending mailbox or mailbox group. If Unify cannot safely
continue the enrollment, it will stop or block the enrollment instead of sending
an incomplete or risky message.

## Manually add a person to a Sequence

To manually add a person to a Sequence, follow these steps:

1. Open the person in Unify.
2. Click **Sequence**.
3. Select the Sequence to enroll the person into.
4. Select the mailbox or mailbox group that should send the emails.
5. Click **Add to Sequence**.

If the person is already in an active Sequence, you will need to unenroll them
first before you can add them to a different Sequence. A person with a recent
enrollment may also be blocked from enrollment depending on your re-enrollment
settings.

Certain conditions may prohibit enrollment. If the person meets any exclusion
criteria that apply to Sequences, you will see a warning and need to confirm
before enrolling them. Lastly, if the person has opted out of emails or has a
"Do Not Email" status, new enrollments will be prohibited.

## Unenroll a person from a Sequence

A person who is actively enrolled in a Sequence can be removed by *unenrolling*
them. This stops the active enrollment but preserves the historical enrollment
information so you can still see what happened.

After removal, the enrollment appears as either **Canceled** or as a completed
enrollment with an unenrolled reason, depending on where the person was in the
Sequence when they were removed.

## Re-enrollment rules

Unify prevents a person from being in multiple active Sequences at the same
time. A previous enrollment can also prevent a new enrollment, depending on your
organization's Sequence re-enrollment settings.

If re-enrollment is not enabled, a person who completed at least one step in a
previous Sequence cannot be enrolled again. If re-enrollment is enabled, admins
can configure whether people can be re-enrolled into Sequences after a waiting
period and whether they can be re-enrolled into the same Sequence.

When an enrollment fails because the person was already enrolled or recently
enrolled, review the active or previous enrollment before changing the
re-enrollment setting. The earlier enrollment may explain whether the person
already replied, opted out, bounced, or was removed.

## Enrollment statuses

Sequence enrollment statuses are user-facing labels that appear in Sequence
analytics, enrollment tables, person timelines, and related CRM sync fields.

| Status             | What it means                                                                                                                                                                       |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **In progress**    | A summary status for enrollments that are still active. Active enrollments can also appear as Queued, Started, Blocked, or Paused.                                                  |
| **Queued**         | The enrollment has been accepted, but no step has completed yet. It may be waiting for the first step, a send window, or mailbox capacity.                                          |
| **Started**        | At least one step has completed successfully and the Sequence may still have additional steps to run.                                                                               |
| **Blocked**        | The enrollment cannot continue until a user fixes an issue. Common causes include missing or invalid template variables, a paused mailbox, or a mailbox that needs reauthorization. |
| **Paused**         | The enrollment is paused and will not continue until it is resumed.                                                                                                                 |
| **Finished**       | The enrollment has ended and no more Sequence steps will run. This is a broad finished status used when a more specific finished reason is not shown.                               |
| **Completed**      | The Sequence has completed after at least one step ran. The enrollment details may show additional context, such as Replied, Opt-out, Canceled, or Excluded.                        |
| **Bounced**        | An email sent by the Sequence bounced.                                                                                                                                              |
| **Bounce stopped** | Unify automatically stopped the enrollment because the email address had a high bounce risk or was identified as invalid before sending.                                            |
| **Canceled**       | A user removed or unenrolled the person from the Sequence before it completed.                                                                                                      |
| **Excluded**       | The person matched exclusion criteria that apply to Sequences, so Unify stopped the enrollment.                                                                                     |

## Blocked enrollments

Blocked enrollments are still active, but Unify will not continue them until the
blocking issue is fixed. This prevents Unify from sending an email with missing
personalization, an invalid value, or a mailbox problem.

Common blocked reasons include:

* **Missing variables**: the email uses a template variable that has no value for
  the person or company.
* **Invalid variables**: a variable exists but cannot be used in the email as
  written.
* **Mailbox paused**: the selected mailbox is paused.
* **Mailbox unauthorized**: the mailbox needs to be reauthorized.
* **Other mailbox issues**: Unify cannot currently send from the selected
  mailbox.

To resolve a blocked enrollment, open the enrollment details. If the issue is a
missing or invalid variable, edit the email, replace the highlighted value, and
save. If the issue is a paused or unauthorized mailbox, go to mailbox settings
and unpause or reauthorize the mailbox. Once the issue is fixed, Unify
automatically unblocks and reschedules the step.

For more detail on missing personalization, see
[Template variables](/reference/sequences/personalization/template-variables#enrollment-blocking).

## Enrollment failure reasons

<AccordionGroup>
  <Accordion title="This person is already enrolled in an active Sequence.">
    A person can only have one active Sequence enrollment at a time. Remove the active enrollment or wait for it to finish before enrolling the person again.
  </Accordion>

  <Accordion title="This person is already enrolled in another Sequence.">
    The person has an existing Sequence enrollment that blocks this enrollment. Open the person record to inspect the current Sequence.
  </Accordion>

  <Accordion title="This person is already enrolled in this Sequence.">
    Re-enrollment in the same Sequence is not allowed for this person under the current re-enrollment settings. Review the previous enrollment and the re-enrollment rules.
  </Accordion>

  <Accordion title="This person was recently enrolled in a Sequence.">
    Your re-enrollment waiting period has not elapsed. Wait until the configured period passes or update the Sequence re-enrollment settings if the person should be eligible sooner.
  </Accordion>

  <Accordion title="This person meets the exclusion criteria for the Sequence.">
    The person or their company matches an exclusion that applies to Sequences. Review the relevant exclusion before enrolling them.
  </Accordion>

  <Accordion title="This person has opted out of emails.">
    The person cannot be enrolled in email outreach while opted out. Review the person's consent and email preference data.
  </Accordion>

  <Accordion title="This person is not allowed to receive emails.">
    The person is marked *Do Not Email* or otherwise blocked from email outreach. Update the source data only if that status is incorrect.
  </Accordion>

  <Accordion title="Sequence is not published.">
    Publish the Sequence before enrolling people into it.
  </Accordion>

  <Accordion title="Mailbox not found.">
    Choose a valid mailbox or mailbox group. If the mailbox was removed or disconnected, select another sender.
  </Accordion>

  <Accordion title="Missing variables or Invalid variables">
    Open the blocked enrollment, edit the email, replace the highlighted values, and save.
  </Accordion>

  <Accordion title="Mailbox paused">
    Unpause the mailbox from mailbox settings. The enrollment resumes automatically after the mailbox can send.
  </Accordion>

  <Accordion title="Mailbox unauthorized">
    Reauthorize the mailbox from mailbox settings. The enrollment resumes automatically after authorization succeeds.
  </Accordion>

  <Accordion title="Email failed validation or Bounce stopped">
    Review or replace the person's email address before trying to enroll them again.
  </Accordion>

  <Accordion title="Previous enrollment is still ending">
    Wait a moment and try again. Unify may still be finishing the previous unenrollment process.
  </Accordion>
</AccordionGroup>


# Unify Sequences
Source: https://docs.unifygtm.com/reference/sequences/overview

Learn what Unify Sequences are and how to use them.

## What are Sequences?

A sequence is a series of automated or manual steps that let you reach out to
buyers and run sophisticated outbound at scale. Sequences are purpose-built for
modern outbound sales with native AI capabilities and deep integration with the
Unify platform.

Once you've created a sequence, you can enroll people in it to automate your
outreach. Sequence enrollments can be performed automatically from Plays, but
you can also enroll people manually. Enrollments can then be monitored from the
sequence details page to track their progress.

Each [enrollment](/reference/sequences/enrollments) tracks a Person's lifecycle
through the Sequence, including the mailbox used for sending, the step currently
scheduled or completed, and the reason the enrollment is queued, started,
blocked, paused, completed, bounced, or stopped.

<Frame>
  <img />
</Frame>

## What can a Sequence do?

Sequences can combine automated emails with manual work that should happen
between emails, such as calls or action items. Emails can be personalized using
[template variables](/reference/sequences/personalization/template-variables)
or [smart snippets](/reference/sequences/personalization/smart-snippets),
and reply detection automatically ends enrollments when someone replies.

Unify Sequences come equipped with comprehensive analytics that let you measure
their effectiveness and compare performance across different sequences with
ease. Unify also provides an unparalleled suite of features for maintaining high
deliverability and ensuring your domain reputation is being handled with care.


# Sequence personalization
Source: https://docs.unifygtm.com/reference/sequences/personalization/overview

Learn how to personalize Sequence emails and tasks.

## Overview

Sequence personalization lets you tailor outreach and task instructions for each
person, company, and sender. Personalization can be used in automatic emails,
manual email tasks, phone call notes, and action item notes.

Use personalization when the content should change based on who the person is,
where they work, why they matched a Play or Audience, or what the assigned user
should do next.

## Personalization tools

| Tool                                                                          | Use it for                                                                                           |
| ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| [Template variables](/reference/sequences/personalization/template-variables) | Inserting known values, such as a person's name, company, title, or other fields available in Unify. |
| [Snippets](/reference/sequences/personalization/template-variables#snippets)  | Reusing blocks of copy and defining fallback text when a variable is missing.                        |
| [Smart snippets](/reference/sequences/personalization/smart-snippets)         | Generating short, recipient-specific copy with AI from a prompt and available data.                  |
| Manual edits                                                                  | Letting a user review and adjust a manual email before sending it.                                   |
| Task notes                                                                    | Giving reps customized instructions for phone call and action item tasks.                            |

## Where personalization appears

Automatic email steps send personalized content automatically after Unify fills
in the required values. Manual email steps create a task so a user can review
and edit the personalized email before sending.

Phone call and action item steps can also use personalized notes. These notes do
not send to the recipient; they give the assigned user context and instructions
for completing the task.

## Missing data

Unify will not send an email with missing required personalization. If a
template variable or snippet cannot be resolved and there is no fallback, the
enrollment is blocked so a user can fix the message before it sends.

Use snippet fallbacks and focused smart snippets to reduce blocked enrollments.
For details, see
[Template variables](/reference/sequences/personalization/template-variables#handling-missing-data).

## Best practices

* Use template variables for straightforward facts that already exist in Unify.
* Use snippets for reusable copy that should stay consistent across Sequences.
* Use smart snippets for small sections of copy that benefit from AI-generated
  context, such as an opening line or reason for outreach.
* Add fallbacks whenever missing data should not block the enrollment.
* Keep task notes specific enough that the assigned user knows what action to
  take.


# Smart snippets
Source: https://docs.unifygtm.com/reference/sequences/personalization/smart-snippets

Personalize your outreach with AI-powered email copy generation.

## Overview

Smart snippets allow you to personalize messages with AI-generated copy that's
unique to each recipient. You can use smart snippets to enhance your messaging,
improve deliverability, and increase engagement.

Smart snippets are concise, self-contained pieces of text that serve a clear
communicative purpose. Each snippet should be laser-focused on the parts of your
outbound message that change the most to fit each recipient differently.

## Creating a smart snippet

Navigate to the [Snippets](https://app.unifygtm.com/dashboard/snippets) tab in
the sidebar, select **New snippet** in the top right corner, and choose
**Smart snippet**. You will see the smart snippet creation screen.

<Frame>
  <img />
</Frame>

To define a smart snippet, you provide a prompt that describes the content you
want to generate. The prompt should include template variables for any data you
want the model to use when writing the snippet. You can click on the quick
prompts to see example prompts for inspiration.

After you've entered your prompt, click **Generate examples** to see what the
smart snippet will generate for a sample of real people from your data. You can
edit the prompt and regenerate examples to iteratively refine your snippet.

<Frame>
  <img />
</Frame>

Just like regular snippets, you should define a fallback value in case any
template variables in the prompt are missing data. This will prevent enrollments
from being blocked by the missing data.

When you're satisfied with your prompt, click **Create** to save it. You will
now be able to use the snippet in your Sequences.

## Recommendations

Here are a few practices we recommend to get the most out of smart snippets:

1. Always include at least one template variable for the model to use to
   personalize the snippet. For example, include some details about the sender,
   the recipient, or their company. This helps the model write more precise and
   personalized copy.
2. Include 2-3 example outputs to guide the model. Examples help the model
   understand the tone and structure you're trying to achieve. The model will
   often pick up on vocabulary and stylistic choices from your examples.
3. Start small. Pick a specific part of the email, such as the salutation or
   hook, and focus on personalizing that part. Smart snippets are most effective
   when they're used to personalize small sections of your email. Remember that
   you can use as many snippets in an email as you want!


# Template variables
Source: https://docs.unifygtm.com/reference/sequences/personalization/template-variables

Use template variables to personalize your emails.

## Overview

Template variables are key to personalizing messages sent through Unify. You can
use template variables to insert dynamic values into your emails, such as a
person's name, company, or job title.

## Inserting variables

You can insert template variables into emails you write when creating Sequences
in Unify. To open the template variable dropdown, click the template variable
button in the Sequence Builder.

<Frame>
  <img alt="template-var-1" />
</Frame>

You can also press **`{`** on your keyboard to open the template variable dropdown. Once open, you can select a variable and insert it into your email.

<Frame>
  <img alt="template-var-2" />
</Frame>

<Frame>
  <img alt="template-var-3" />
</Frame>

When a Person is enrolled in this Sequence, this value will be filled in
dynamically.

## Handling missing data

### Enrollment blocking

Sometimes, Unify won’t have data to populate variables used in a Sequence email.
In these cases, Unify will never send an email with a placeholder or missing
value. Instead, Unify will *block* the Sequence enrollment.

<Frame>
  <img alt="template-var-4" />
</Frame>

Blocked enrollments can be seen on the Sequence details page. Click a blocked
enrollment to edit the message and manually fill in any missing values.

<Frame>
  <img alt="template-var-5" />
</Frame>

The template variables with missing values will appear highlighted in orange.
Once you’ve replaced the missing values, click **Save** and the blocked status
will disappear.

<Frame>
  <img alt="template-var-6" />
</Frame>

The step will then be rescheduled and sent automatically as part of the
Sequence.

<Info>
  For other enrollment statuses and blocked-enrollment troubleshooting, see
  [Sequence enrollments](/reference/sequences/enrollments).
</Info>

### Snippets

To avoid having to manually unblock enrollments that are missing a value, it's
highly recommended that you take advantage of *snippets*.

Snippets are reusable blocks of copy that can be inserted into messages the same
as template variables. However, snippets also allow you to define fallback text
which is used if any template variables are missing values.

<Frame>
  <img />
</Frame>

You can access snippets by navigating to the [Snippets](https://app.unifygtm.com/dashboard/snippets)
tab in the sidebar. When defining a snippet, you can use template variables or
even other snippets in the copy. Underneath the snippet text area, there is a
second text area where you can define a fallback.

<Frame>
  <img />
</Frame>

The fallback will be used if any of the variables used in the copy are missing.
If you use snippets within snippets (which is called *snippet-ception*), the
fallback for the nested snippet will be used in the top-level snippet.


# Sequence replies
Source: https://docs.unifygtm.com/reference/sequences/replies

View and manage replies from prospects in your Sequences.

## Overview

When prospects reply to your Sequence emails, Unify automatically captures and classifies those replies. All replies are accessible directly within the Unify app.

<Frame>
  <img />
</Frame>

## Out-of-thread replies

In addition to direct replies to Sequence emails, Unify also captures **out-of-thread replies** from your prospects.

An out-of-thread reply is an email from a sequence enrollee that doesn't directly reply to a sequence email. This includes new email threads initiated by the prospect or separate conversations sent to your mailbox while they're engaged with your sequence.

## Reply classifications

Unify automatically classifies replies using AI to help you prioritize your responses. Each reply receives one or more classification tags that indicate the prospect's intent or sentiment.

* <PositiveToneIcon />**Positive** — The email response shows enthusiasm, agreement, or active engagement with the sender's offer, indicating a genuine interest in moving forward. This is not an automated reply.
* <WillingToMeetIcon />**Willing to meet** — The recipient's email indicates their openness to schedule a meeting, specifically about the offer mentioned in the initial outreach.
* <NeedsMoreInfoIcon />**Needs more info** — The recipient requests additional details or expresses uncertainty about the offer. Providing clarification may result in a positive outcome.
* <BadTimingIcon />**Bad Timing** — The email conveys interest but explains that current budget constraints or timing prevent immediate action. Future actions may be possible if a time frame is mentioned.
* <HasSolutionIcon />**Has solution** — The recipient mentions that they are already using a different product or service to meet their needs.
* <NeutralToneIcon />**Neutral** — The email is objective, factual, respectful, unemotional, and polite yet concise.
* <LeftJobIcon />**Left Job** — The email indicates the sender is no longer employed at their previous role or company.
* <UpdatedContactInfoIcon />**Updated contact info** — The email notifies the sender of a new or updated email address for further communication.
* <ReferralIcon />**Referral** — The email includes a suggestion to contact another person, and provides the referral's contact information.
* <NegativeToneIcon />**Negative** — The email contains hostile, emotional, or adversarial language, such as anger or frustration.
* <NsfwIcon />**NSFW** — The email includes content that is offensive or inappropriate.
* <OptOutIcon />**Opt out** — The recipient explicitly requests to unsubscribe, threatens to block communication, or mentions reporting the sender.
* <OutOfOfficeIcon />**OOO** — The recipient's email indicates they are out of office or currently unable to provide a complete response.
* <SoftBounceIcon />**Soft Bounce** — The email indicates a temporary delivery failure, meaning the message might eventually be delivered.
* <HardBounceIcon />**Hard Bounce** — The email indicates a permanent delivery failure, suggesting the recipient's email address is invalid or no longer in use.
* <AutomatedIcon />**Automated** — The email appears to have been generated by an automated system, rather than sent by a person.

<Note>
  Reply classifications can be configured to trigger [notifications](/reference/notifications/preferences) so you're alerted when important replies come in.
</Note>


# Creating a custom send schedule
Source: https://docs.unifygtm.com/reference/sequences/send-schedules/creating-send-schedules

Learn how to configure Custom Send Schedules for Sequences.

## Navigation

You can access the Custom Send Schedules page by navigating to:
**Settings → Organization → Sequences → Send Schedules**.

Once you are on this page, click the **+ New Schedule** button to create a new Custom Send Schedule.

<Frame>
  <img />
</Frame>

## Configuring a new custom send schedule

After clicking the **+ New Schedule** button, a configuration drawer will open, allowing you to define the parameters of your new Custom Send Schedule.

### General

Under the **General** section, you can configure the basic information for your Custom Send Schedule.

* **Name** — Provide a clear, descriptive name for your Custom Send Schedule (e.g., *North America Weekdays* or *APAC Morning Outreach*).
* **Time Zone** — Select the time zone in which the schedule will operate. This ensures that all send windows and skip dates align to the correct local time. (e.g., America/Los Angeles, Europe/London, Asia/Singapore)

<Frame>
  <img />
</Frame>

> 💡 **Tip:** If your team operates globally, create separate Custom Send Schedules for each region to ensure messages are sent during local business hours.

***

### Windows

The **Windows** section defines when Unify is allowed to send automated messages through Sequences during the week.

For each day of the week, you can:

* Enable or disable sending (for example, enable Monday–Friday and disable Saturday–Sunday).
* Specify one or more **time windows** when messages can be sent (e.g., 9 AM to 12 PM, 1 PM to 5 PM).

<Frame>
  <img />
</Frame>

**Example:**
If you want outreach to happen only during typical working hours, you might configure:

* Monday–Friday: 9:00 AM to 4:30 PM
* Saturday & Sunday: Disabled

> **Note:** Messages queued outside of active windows will automatically be held until the next available send window.

***

### Skip dates

Skip Dates allow you to automatically **pause sending on holidays or custom dates**.
This helps maintain deliverability and professionalism by avoiding sends on non-working days.

There are two ways to configure Skip Dates:

1. **U.S. Holidays** — Toggle this option to automatically skip sending on major U.S. federal holidays (e.g., New Year’s Day, Independence Day, Thanksgiving).
2. **Custom Dates** — Add specific dates or recurring dates (such as company off-sites, local holidays, or yearly breaks).

You can specify whether custom dates repeat **annually** or occur **once**.

<Frame>
  <img />
</Frame>

> 💡 **Tip:** Use Skip Dates to prevent outreach from occurring during out-of-office periods or industry-wide holidays that may impact engagement.

***

### Saving the custom send schedule

Once you’ve configured the General settings, Windows, and Skip Dates, click **Create** to save your Custom Send Schedule.
It will now appear in the **Custom Send Schedules** list view, where you can edit, duplicate, or delete it at any time.

Your new Custom Send Schedule is now ready to use!


# Custom send schedules overview
Source: https://docs.unifygtm.com/reference/sequences/send-schedules/overview

Learn what Custom Send Schedules are and how they control automated email sending within Sequences in Unify.

Custom Send Schedules help teams coordinate outreach across time zones, avoid weekends or holidays, and ensure emails are delivered during ideal business hours for recipients.

## What are custom send schedules?

Custom Send Schedules define the specific days and time windows when Unify is allowed to send automated email messages through Sequences.

Each schedule can be customized with:

* **Time zones** — Align delivery windows with your target audience or team region (e.g., America/Los Angeles, Europe/London, Asia/Singapore).

* **Active days** — Choose which weekdays are enabled for sending (e.g., Monday–Friday).

* **Time windows** — Define the daily sending hours to control when messages are delivered within each active day (e.g., 9 AM to 2 PM, 3 PM to 6 PM).

* **Skip dates** — Exclude U.S. holidays or add custom recurring dates to pause sending automatically.

<Frame>
  <img />
</Frame>


# Using a custom send schedule
Source: https://docs.unifygtm.com/reference/sequences/send-schedules/using-send-schedules

Learn how to view and apply Custom Send Schedules for Sequences.

Custom Send Schedules define when automated emails in a Sequence are allowed to send. Once you’ve configured your Custom Send Schedule, you can assign them to individual Sequences.

***

## Accessing sequence settings

To view or edit the Custom Send Schedule assigned to a Sequence:

1. Open any Sequence from your **Sequences** list.
2. Click the **⚙️ cog icon** in the top-right corner to open **Sequence Settings**.
3. In the settings drawer, you’ll see a section labeled **Send schedule**, displaying the currently linked schedule and its details.

<Frame>
  <img />
</Frame>

***

## Selecting a custom send schedule

To change which Custom Send Schedule a Sequence uses:

1. Click **Edit** in the top-right corner of the Sequence Settings drawer.
2. Open the **Send schedule** dropdown.
3. Choose the desired schedule from the list. You’ll see details including:
   * Schedule name
   * Timezone
   * Days enabled for sending
   * Sending windows per day
   * Skip dates

<Frame>
  <img />
</Frame>

After you’ve selected a schedule, click **Save** to apply it.

***

## Important notes

<Note>
  When linking a new Custom Send Schedule to an active Sequence, **Unify will
  immediately reschedule all pending emails for that Sequence** according to the
  new Custom Send Schedule configurations.
</Note>

> 💡 **Tip:** If you’re running outreach across multiple regions, use different Custom Send Schedules for each region’s Sequences to optimize timing and engagement.

***


# Sequence step types
Source: https://docs.unifygtm.com/reference/sequences/sequence-step-types

Learn what each Sequence step type does and when to use it.

Sequence steps define what should happen after a Person is enrolled in a
Sequence. Steps can send emails automatically or create tasks for a user, such
as manual emails or phone calls.

## Adding steps to Sequences

When drafting or editing a Sequence, click **+** in the Sequence Builder to add
a new step.

<CardGroup>
  <Card title="Automatic email" icon="envelope" href="#automatic-email">
    Send a personalized email automatically when the step is scheduled.
  </Card>

  <Card title="Manual email" icon={<ManualEmailIcon />} href="#manual-email">
    Create an email task that a user reviews and sends from Unify.
  </Card>

  <Card title="Phone call" icon={<PhoneCallIcon />} href="#phone-call">
    Create a task to call the Person.
  </Card>

  <Card title="Action item" icon={<ActionItemIcon />} href="#action-item">
    Create a generic task with custom instructions.
  </Card>
</CardGroup>

Every manual step type creates a task for the person and assigns it to a user.

## Automatic email

Automatic email steps send without requiring a user to review the message first.
Use them for outreach that can be safely sent once Unify has hydrated the
recipient-specific content and the mailbox has capacity during an allowed send
window.

Automatic emails can use
[template variables](/reference/sequences/personalization/template-variables),
[snippets](/reference/sequences/personalization/template-variables#snippets),
and [smart snippets](/reference/sequences/personalization/smart-snippets). If
required personalization data is missing or invalid, Unify blocks the enrollment
instead of sending an incomplete email.

## Manual email

Just like automated emails, manual email steps can be composed using
[template variables](/reference/sequences/personalization/template-variables),
[snippets](/reference/sequences/personalization/template-variables#snippets),
or [smart snippets](/reference/sequences/personalization/smart-snippets). When a
Person reaches the step, Unify creates a manual email task instead of sending
the email immediately.

Use manual email steps when a user should review, edit, or tailor the message
before it goes out. You can set the task priority and choose who the task should
be assigned to.

<Frame>
  <img />
</Frame>

## Phone call

Phone call steps create a phone call task for the assigned user. Use them when a
rep should call the Person before the Sequence continues.

Phone call steps can include notes that appear on the call task once created.
[Template variables](/reference/sequences/personalization/template-variables),
[snippets](/reference/sequences/personalization/template-variables#snippets),
and [smart snippets](/reference/sequences/personalization/smart-snippets) can
customize those notes for each Person.

<Frame>
  <img />
</Frame>

## Action item

Action item steps create a general task for the assigned user. Use them for
manual work that is not specifically an email or call, such as reviewing an
account, checking CRM data, preparing for a meeting, or taking a custom follow-up
action.

Action item steps can include notes that appear on the task once created. These
notes can provide instructions or context about the Person or Company.
[Template variables](/reference/sequences/personalization/template-variables),
[snippets](/reference/sequences/personalization/template-variables#snippets),
and [smart snippets](/reference/sequences/personalization/smart-snippets) can
customize those notes for each task.

<Frame>
  <img />
</Frame>

## Step timing and delays

Sequence timing is controlled separately from the step type. When adding or
editing steps, configure the delay or condition that determines when the next
step should run. Delays can be set in seconds, minutes, hours, days, or weeks.


# Champion tracking
Source: https://docs.unifygtm.com/reference/signals/champions

Automatically track your champions and take action on them.

## What is a champion?

Your companies' champions are customers who have used and advocated for the adoption of your product or services.

## What is champion tracking?

With Champion Tracking, you can define filters to select your company's champions and automatically follow when they change jobs.
A champion who has changed jobs is often an opportunity with a high likelihood to convert into a new customer.

When enabled, the job statuses of each of your champions will be checked once per month
and their new contact information will be found when they change jobs. This information is extremely
valuable for breaking into new accounts and performing retargeting campaigns.

Unify will automatically create an exclusion for the old contact records of your champions who have changed jobs.
This means that the old records won't appear in audiences nor be sequenced.

You will be charged one credit per champion tracked per month regardless of whether a job change was detected.
You can view the `Tracking` tab in the Champion Tracking Settings page to see who is being tracked.

### set up champion tracking

Define who your champions are.

#### Enabling

1. In the Unify app, go to [Settings → Track → Champions](https://app.unifygtm.com/dashboard/settings/champion-tracking).

<Frame>
  <img alt="" />
</Frame>

2. Click the toggle at the top of the page to open the Champion Tracking Settings modal.

<Frame>
  <img alt="" />
</Frame>

3. Define filters to identify your champions to track. For example, users commonly filter down to companies with Closed Won opportunities.

<Frame>
  <img alt="" />
</Frame>

4. Click `Enable Champion Tracking`.  Unify will track your champions once per month starting from the moment you enable Champion Tracking.

#### Disabling

1. In the Unify app, go to [Settings → Track → Champions](https://app.unifygtm.com/dashboard/settings/champion-tracking).

2. Click the toggle and click `Disable` to disable Champion Tracking. You will still be able to view job changes Unify has already detected throughout the app, but people will stop being tracked monthly.

<Frame>
  <img alt="" />
</Frame>

### Take action on champion job changes

Take action when Unify detects a champion job change.

#### Champion tracking audience filters

In the audience builder, you can add filters for champion job changes.
Connect these audiences to Plays, sequences, and Slack alerts to automate workflows triggered by these changes.

Here is an example of audience filters that includes champions who have changed jobs in the past 12 months:

<Frame>
  <img alt="" />
</Frame>

### Frequently asked questions

#### How can I be notified in Slack whenever a champion changes jobs?

Create an audience containing champions who have changed jobs and enable Slack alerts on the audience.


# Lookalike companies
Source: https://docs.unifygtm.com/reference/signals/lookalike-companies

Find companies similar to your most successful customers.

## Overview

We’ve partnered with [Ocean.io](https://www.ocean.io/)—a leading Lookalike data provider—so you can run automated Plays that target lookalikes of your most successful customers.

The integration is fully managed by Unify and included in your plan, so no additional subscription or setup is required.

## Setup

### Build a new Play

Start by setting up a new Play using the Find Lookalike Companies trigger. You can also get started with our [pre-built template](https://app.unifygtm.com/dashboard/plays?templateType=SEQUENCE_LOOKALIKE_COMPANIES).

<Frame>
  <img />
</Frame>

### Configure the trigger

First, configure the seed companies you want to find lookalike companies for. You can do this by adding filters to select companies that meet your criteria,
just like building audiences.

<Frame>
  <img />
</Frame>

Next, configure the lookalike companies you want to find for each seed company.
You can set the number of lookalike companies per seed company, minimum relevance score, and more.

The previews on the right will show you a sample of the lookalike companies that will be found based on your configuration.

<Frame>
  <img />
</Frame>

Build the rest of your Play as you need, then click Publish to begin finding lookalike companies and running them through your Play.
Learn more about building Plays [here](/reference/plays/overview).

## Frequently asked questions

<AccordionGroup>
  <Accordion title="How do I see what seed company a lookalike company was based on?">
    Find your lookalike company in the Play Logs.

    <Frame>
      <img />
    </Frame>

    Click the Trigger node to see details like the seed company and the relevance score.

    <Frame>
      <img />
    </Frame>
  </Accordion>

  <Accordion title="How long does it take for Play Logs to appear for my lookalike companies?">
    Depending on the number of seed companies the Play is running on, it can take up to several hours for Play Logs to appear.
  </Accordion>

  <Accordion title="Do I get charged credits if a lookalike company falls under my exclusion rules?">
    Nope! Lookalike companies that fall under your exclusion rules will not run through the Play, and you will not be charged for them.
  </Accordion>
</AccordionGroup>


# New hire tracking
Source: https://docs.unifygtm.com/reference/signals/new-hires

Automatically track new hires at companies and take action.

## What is new hire tracking?

A new hire is someone who has recently started a job at a new company within the past 90 days.

New Hire Tracking helps you identify and monitor individuals who have recently joined companies that align with your target profile. These new hires often play pivotal roles in shaping change within their organizations, making them valuable opportunities for outreach.

These are not people in your current Unify instance, they are net new prospects, meaning that they have not already been sourced through CRM integration, website intent, or uploaded manually.

By using New Hire Tracking, you can apply specific filters to define your target companies and personas, automatically keeping track of new hires at these organizations.

### Why is this a valuable signal?

New hires signify organizational shifts and often catalyze new purchasing decisions, presenting valuable opportunities for strategic outreach.

### How does new hire tracking work?

Once activated, Unify scans for new hires that match your selected personas at your target companies, delivering their contact details to you daily. Your target personas and companies can be customized to include or exclude specific job titles, industries, company size, and location. This enables you to build a dynamic, up-to-date list of key contacts for your team to engage through Audiences.

New hires will not track existing contacts synced over from your CRM today. If enabled, Champion Tracking will be tracking when contacts from existing customers change jobs. For more information, see the [Champion Tracking section](/reference/signals/champions).

Each tracked new hire costs two credits, regardless of whether the lead has been routed or engaged.

To view tracked new hires, navigate to the “New Hires” tab in the New Hire Tracking Settings.

### Setting up new hire tracking

Define the personas and companies you want to track, then follow the steps below to get started.

#### How to enable

1. In the Unify app, go to [Settings → Track → New Hires](https://app.unifygtm.com/dashboard/settings/new-hire-tracking).

<Frame>
  <img alt="" />
</Frame>

2. Click the toggle at the top of the page to open the New Hire Tracking Settings.

<Frame>
  <img alt="" />
</Frame>

3. Apply filters to fine-tune your new hire tracking. For best results, use all available filters to narrow down the most relevant target companies and personas.

<Frame>
  <img alt="" />
</Frame>

4. Click `Enable New Hire Tracking`. Unify will begin tracking new hires daily from this point forward.

<Frame>
  <img alt="" />
</Frame>

#### How to disable

1. In the Unify app, go to [Settings → Track → New Hires](https://app.unifygtm.com/dashboard/settings/new-hire-tracking).

2. Click the toggle and select `Disable` to stop tracking new hires. Previously detected job changes will remain visible, but new hires will no longer be tracked.

<Frame>
  <img alt="" />
</Frame>

### Acting on new hires

When Unify identifies a new hire, you can immediately add these contacts to audiences and run Plays on them. Similar to setting up Plays to capture website intent or retarget CRM opportunities as they’re added, you can create Plays that consistently capture and engage with new hires added by Unify!

<Frame>
  <img alt="" />
</Frame>

#### New hire tracking in Audience filters

In the Audience Builder, you can add filters to focus on new hires.

These audiences can be linked to Plays, sequences, or Slack alerts, allowing you to automate workflows based on new hire data.

Here’s an example of filters used to track new hires in the past 12 months:

<Frame>
  <img alt="" />
</Frame>

### Frequently asked questions

#### How can I get Slack notifications for new hires?

Create an audience for new hires, then enable Slack alerts for that audience to receive real-time notifications.

#### How do I stop tracking new hires?

Click the toggle to disable new hire tracking. Previously detected job changes will remain visible, but new hires will no longer be tracked.

#### Can I track new hires in a specific industry?

Yes, you can filter new hires by industry.

#### Can I track new hires by country?

At the moment, you can track new hires based on the location of their company. We’re actively working on expanding this feature to allow tracking new hires based on their individual country of residence.

#### How are you selecting the new contacts added to Unify?

We identify ideal new hire prospects who have changed roles within the last 90 days, using a combination of job title, company size, and industry. These prospects are then selected through a randomized process.


# Signals in Unify
Source: https://docs.unifygtm.com/reference/signals/overview

Learn what data signals are and how to use them.

## What are signals?

Signals are data sources that provide insights into companies and people that
are demonstrating buying intent. Unify brings a multitude of real-time signals
together to help you identify and engage with warm prospects at exactly the
right time.

<Frame>
  <img />
</Frame>

Unify doesn't just bring the data. Unify is a system of action that provides the
framework and the tools to act on that data in the most effective way possible.

## What signals are available?

Unify provides a wide range of signals, from real-time website visits to
continuous champion tracking. Here are some of the most popular signals
available in Unify:

<CardGroup>
  <Card title="Website Visitors" icon={<WebsiteIcon />} href="/reference/signals/website-visitors">
    Identify the companies and people visiting your website in real-time.
  </Card>

  <Card title="Champions" icon={<ChampionsIcon />} href="/reference/signals/champions">
    Keep track of champions for your business moving to new companies.
  </Card>

  <Card title="New Hires" icon={<NewHiresIcon />} href="/reference/signals/new-hires">
    Find out when key decision-makers join a company you're targeting.
  </Card>

  <Card title="Lookalikes" icon={<OceanioLogo />} href="/reference/signals/lookalike-companies">
    Find companies similar to your most successful customers.
  </Card>
</CardGroup>


# Website visitor intent
Source: https://docs.unifygtm.com/reference/signals/website-visitors

Start revealing the companies and people visiting your website.

## Overview

By integrating with your website, Unify can reveal the companies and people
visiting your website in real time. Beyond identifying these visitors, Unify
enables you to take action based on which pages they view, what they click,
where they visit from, which campaigns brought them there, and how many
sessions they have had.

Website visitor activity comes from page views, identify events, and custom
events sent through the Unify Intent Client, Segment, or PostHog. Unify uses
this activity to power website visitor lists, intent filters, and Play triggers.

## How to get started

### Step 1: Integrate Unify with your website

The first step is to integrate Unify with your website using the Unify Intent
Client or a third-party analytics provider like Segment or PostHog.

If you're not already using Segment, we recommend starting with the official
Unify Intent Client. You can find the installation instructions [here](/developers/intent-client/overview).
For customers already using Segment, you can find the instructions for setting
up the official Segment integration [here](/reference/integrations/segment).

### Step 2: Turn on anonymous visitor reveal

Once events are flowing into Unify, you can enable anonymous visitor reveal to
identify the companies visiting your website. Navigate to
[Settings → Web & product data → Settings](https://app.unifygtm.com/dashboard/settings/data/web-intent?webEventsTab=Settings)
to configure reveal and event sources.

If you already have a subscription to 6sense, Demandbase, or Clearbit Reveal,
you can also bring your own API key.

### Step 3: Identify people when possible

Company reveal identifies the company behind anonymous traffic. To identify the
specific person, send an identify event when a visitor submits a form, signs in,
or otherwise provides an email address. If a visitor is identified later, Unify
can connect earlier activity from the same visitor/session identity to that
person.

## Common filters

Once website activity is flowing into Unify, you can filter visitors and trigger
Plays using signals such as:

* Pages viewed, URL patterns, and page view counts
* Custom events such as form submissions, button clicks, demo interactions, or
  product usage actions
* Custom event properties such as selected plan, product area, or form answer
* UTM Source, UTM Medium, UTM Campaign, UTM Term, and UTM Content
* Referrer, visitor location, session count, and last website activity

UTM and referrer data is captured when the browser or event source provides it.
Referrer data can be missing because of browser privacy settings, redirects, or
referrer policies on the referring site.


# How to create a Play
Source: https://docs.unifygtm.com/tutorials/how-to-create-a-play

Learn the fundamentals and build a Unify Play from start to finish.

## Overview

Plays are automated workflows that let you build and execute repeatable
strategies. In this guide, you'll learn the basics of how Plays work and create
one from scratch.

### What are Plays?

Building scalable and effective sales, marketing, and GTM strategies requires
successfully coordinating two key components:

* **Data**: Countless data sources go into building scalable automations. This
  data is traditionally scattered across tools and databases, but Unify
  centralizes it in one place.
* **Actions**: Researching companies, identifying decision-makers, executing
  multi-channel outreach, and more. Taking the right action at the right time
  is crucial to success.

Unify is a purpose-built system of action that solves this problem. Plays let
you define a series of actions that will be taken on companies or people at
exactly the right moment.

<Frame>
  <img />
</Frame>

### Tutorial preview

One of the most popular use cases for Plays is to find prospects at companies
that are visiting your website and enroll them in outbound sequences. This is a
great example of a *warm outbound* campaign that targets key decision-makers
at companies showing buying intent.

In this guide, you'll create a Unify Play that runs on companies visiting your
website and performs the following actions:

1. **Prospect**: Find new people at the company that match your buyer personas.
2. **Sequence**: Enroll the new prospects in a sequence to send them emails.
3. **Sync to CRM**: Sync newly found people to Salesforce or HubSpot.

This standard Play is a great starting point to understand how Plays work and
kickstart your outbound strategy.

## Walkthrough

### Step 1: Create a new Play

Look for the [Plays](https://app.unifygtm.com/dashboard/plays) tab in the
sidebar and click on it. This is where you will create and manage all your
team's Plays. To create a new Play, click the **New Play** button.

<Frame>
  <img />
</Frame>

<Frame>
  <img />
</Frame>

<Frame>
  <img />
</Frame>

### Step 2: Choose a trigger

Once you've created a new Play, you will see the Play Builder. The first step
when building any Play is to choose a *trigger*. The trigger lets you specify
exactly when the Play should run and which companies or people it should run on.

In the center of the builder, you will see an action that says **Select a trigger**.
Click on it to show the trigger configuration panel. For this Play, choose the
**Website visitors** template.

<Frame>
  <img />
</Frame>

<Frame>
  <img />
</Frame>

Here you have the option to further filter and refine the companies that this
Play will run on. For example, if you only want to run this Play on companies
with more than 100 employees, you can add a filter on **Employee Count**.

You can learn more about the available filters and how to use them in the tutorial
[How to create an Audience](/tutorials/how-to-create-an-audience). You can always
return later to add or modify filters. Click **Done** to finish configuring the
trigger.

### Step 3: Add actions

Now that the trigger has been selected, it's time to start adding actions. There
are many actions to choose from, and you can configure them in countless ways.
For this Play, we're going to start simple and add three actions.

#### Prospect for people

Start by adding a prospecting action. This action will take the company coming
from the trigger and search for relevant prospects. Drag the **Prospect for People**
action from the action list and drop it into the builder.

<Tip>
  If you drag and drop a new action on top of an existing action, it will
  automatically be connected to it.
</Tip>

<Frame>
  <img />
</Frame>

Once added, you will see the prospecting options shown in the configuration
panel on the left. Here are the most important selections to make:

* **Max. prospects per company**: This is how many prospects you want to find at
  each company. We recommend starting with 2-4 prospects per company.
* **Personas**: These are the personas to search for. You can select from
  existing personas or create new ones. Unify will find people matching these
  personas in order, so list them in order of preference.

If you haven't defined any personas yet, you can learn how to do so in the
tutorial [How to create Personas](/tutorials/how-to-use-personas).

#### Loop

Next, add a **Loop** action. The prospecting action will return a list of people
found at the company, and the loop will run subsequent actions once for each
person in the list.

<Frame>
  <img />
</Frame>

Each action receives an input and produces an output. Actions in the Play
Builder have small colored symbols that represent what type of input and output
they expect.

Here's what each symbol represents:

| Symbol |                                       | Value |
| :----: | ------------------------------------- | :---- |
|        | A single person record.               |       |
|        | A list of one or more person records. |       |
|        | A single company record.              |       |

Plays work by connecting each action's output to a matching input on another
action. This is how data flows through the Play and how each action knows what
to do.

Most actions run on one record at a time. The **Loop** action is how you take a
list of records and run actions on them one by one.

#### Sequence enrollment

Now place a **Sequence** action inside the loop. This will enroll each person
into a Unify Sequence.

<Tip>
  Once you've dropped the action into the loop, you can drag it near the loop
  action to automatically connect them. You can also manually draw connections
  between the colored icons that represent action inputs and outputs.
</Tip>

Once added, you can configure the sequence enrollment action by routing personas
to the desired sequences and mailboxes. To speed up the process, click the
**Add prospect personas** button to automatically reuse all the personas you
selected in the prospecting action.

<Frame>
  <img />
</Frame>

<Frame>
  <img />
</Frame>

#### Sync to CRM

Finally, add an action to sync each new person to your CRM. Depending on which
CRM you've connected in Unify, you will see either a **Sync to Salesforce** or
**Sync to HubSpot** action.

<Frame>
  <img />
</Frame>

### Step 4: Publish and view logs

Once your Play is ready, click the **Publish** button in the top right corner of
the Play Builder. This will activate the Play and start running it on companies
that match the trigger criteria you defined earlier.

<Frame>
  <img />
</Frame>

As the Play starts to run on companies, you will see them appear in the logs.
Click on the **Logs** tab at the top of the Play Builder to view the logs.

<Frame>
  <img />
</Frame>

Click on any company to view the details of its run, including the exact actions
that were taken and the results of each action. Click on any action to view the
precise inputs, outputs, and result of that action.

<Frame>
  <img />
</Frame>

<Frame>
  <img />
</Frame>

<Frame>
  <img />
</Frame>

## Conclusion

Congratulations on creating a Play! Combining website intent, prospecting, and
sequences into a single automated flow is a popular Play and an excellent
starting point.

For a comprehensive overview of Unify Plays, check out the reference guide:

<Card title="Plays Reference" icon="arrow-progress" href="/reference/plays/overview">
  Detailed reference guide that covers the fundamentals of plays, the actions
  and triggers available to use, and more.
</Card>


# How to create an audience
Source: https://docs.unifygtm.com/tutorials/how-to-create-an-audience

Create dynamic lists of companies and people to view and act on.

## What are Audiences?

In Unify, audiences are dynamic lists of companies and people that are generated
based on powerful filter criteria that you specify. Once defined, you can view and take
action on these companies and people in Unify.

<Frame>
  <img />
</Frame>

Here are just a few examples of the
types of audiences you can define:

* Companies that have clicked on your pricing page in the past week
* People who have opened an email you sent them in the past month at least twice
  without replying yet
* Champions for your business that have joined a new company matching your ICP

Typically, either sales leaders, revenue operations, or sales operations will
create the audiences to be used by sellers for building plays and taking action.

## Build a new audience

Access audiences by clicking on [Audiences](https://app.unifygtm.com/dashboard/audiences)
in the sidebar. You can view and edit existing audiences or create a new one by
selecting **New audience**.

Audience support a wide variety of filters. One of the most commonly used
options is to filter by fields in your CRM. To get started, click **Add condition**
and search for the field you want to filter by.

<Frame>
  <img />
</Frame>

Another popular filter is website activity. You can filter by page views,
sessions, and visitors to your website. This is a great way to identify which
companies are showing interest in your business.

<Frame>
  <img />
</Frame>

You can combine multiple filter criteria with **And** and **Or** groups to
build more complex audiences. For example, you might want to capture companies
that have visited your pricing page or that have filled out an inbound form.

<Frame>
  <img />
</Frame>

The best way to learn about the available filter options is to explore! As
you add and remove filters, the audience preview will update in real-time to
show the companies and people that match your criteria.

## Exclusions

Exclusions are a mechanism to prevent Unify from taking action on specific
companies or people. Common use cases for exclusions include preventing current
customers or competitors from appearing in your audiences or Plays.

Once you've defined exclusions, they will be automatically applied to all
audiences by default. Sometimes, you may want to disable an exclusion for a
specific audience. This can be done from the audience configuration page under
the **Advanced** section.

<Frame>
  <img />
</Frame>

For more information on creating exclusions, see [How to create an Exclusion](/tutorials/how-to-create-an-exclusion).

## What's next?

Audiences can be used for a variety of purposes, including building plays and
subscribing to Slack alerts. For more information, check out these tutorials:

<Card icon="link" title="How to Create a Play" href="/tutorials/how-to-create-a-play">
  Create a Play that runs on companies or people in an audience.
</Card>

<Card icon="link" title="How to Receive Slack Alerts" href="/tutorials/how-to-receive-slack-alerts">
  Receive Slack alerts when a new company or person enters an audience.
</Card>


# How to create an exclusion
Source: https://docs.unifygtm.com/tutorials/how-to-create-an-exclusion

Prevent Unify from taking action on specific companies or people.

## What are exclusions?

Exclusions are dynamic lists of companies or people that you want to prevent
Unify from taking action on. Common use cases includes:

1. Exclude current customers
2. Exclude in-flight deals
3. Exclude competitors

Exclusions match companies and people based on configurable *filters*. This
means you don't need to maintain static lists of companies or people to exclude.
Instead, you can set up rules that automatically exclude companies or people
that meet certain criteria.

## Walkthrough

<Steps>
  <Step title="Create a new exclusion">
    Go to [Settings > Exclusions](https://app.unifygtm.com/dashboard/settings/features/exclusions) and select **New exclusion**.

    <Frame>
      <img />
    </Frame>
  </Step>

  <Step title="Add filters">
    The exclusion builder allows you to define filters that select which
    companies or people should be matched and excluded.

    <Tip>
      You can select whether this exclusion applies to companies or people. When
      applied to companies, any person that is associated with a matched company
      will also be excluded.
    </Tip>

    <Frame>
      <img />
    </Frame>

    You can add as many filters as you'd like, and nearly any data within Unify
    can be used to create filters. This includes CRM records and custom objects.

    <Frame>
      <img />
    </Frame>
  </Step>

  <Step title="Save and apply">
    Once you save the exclusion, any company or person that matches the filters
    you defined will automatically be excluded from targeting in Unify. You can
    edit the exclusion at any time to adjust the filters and update which
    companies or people are excluded.

    <Frame>
      <img />
    </Frame>
  </Step>
</Steps>


# How to receive Slack alerts
Source: https://docs.unifygtm.com/tutorials/how-to-receive-slack-alerts

Receive real-time Slack alerts when companies or people enter an audience.

## Audience entry alerts

When a new entry is added to the audience, a notification will be sent to the selected Slack channel.

### Enabling

1. Go to the audience page and click on `Enable alert`.

<Frame>
  <img alt="" />
</Frame>

2. Choose a channel from the dropdown menu.

<Frame>
  <img alt="" />
</Frame>

<p />

<Frame>
  <img alt="" />
</Frame>

3. After selecting a channel, click on `Enable`.

<Frame>
  <img alt="" />
</Frame>

### Disabling

1. Go to the audience page and click on `Enabled`.

<Frame>
  <img alt="" />
</Frame>

2. Click on `Disconnect`.

<Frame>
  <img alt="" />
</Frame>


# How to define personas
Source: https://docs.unifygtm.com/tutorials/how-to-use-personas

Create personas to prospect and reach out to your ideal buyers.

## Overview

Personas are collections of job titles that you want to target. Each persona
consists of a list of titles that you want to include and exclude. Personas can
be used throughout Unify, such as when prospecting or routing people to
different sequences.

## Create a persona

Navigate to the [Personas](https://app.unifygtm.com/dashboard/settings/personas) tab in
the sidebar and select **New persona**. Here you can add job titles that you
wish to include or exclude when matching people against this persona.

<Frame>
  <img />
</Frame>

You can also take advantage of AI-powered persona generation to automatically
find and add similar job titles to your persona. This lets you quickly define
comprehensive personas that match different variations of a job title.

<Frame>
  <img />
</Frame>

Once you've added all the titles you want to include or exclude, click **Create
persona** to save your changes. This persona will now be available for use
throughout Unify.

## Title matching behavior

When evaluating whether a person's job title matches a persona, Unify adheres to
the following rules and heuristics:

* **Ignore capitalization**: For example, "RevOps Lead" and "Revops lead" are
  considered equivalent.
* **Ignore punctuation**: For example, "Enterprise Sales, Lead" and "Enterprise
  Sales Lead" are considered equivalent.
* **Ignore word order**: For example, "Lead Sales Engineer" and "Sales Engineer,
  Lead" are considered equivalent.
* **Ignore extraneous words**: For example, "CEO" and "CEO and Founder" are
  considered equivalent.

That means that you don't need to exhaustively list every possible variation of
a job title in your persona. Instead, you can focus on the most common keywords
and let Unify handle the details.


# Getting intent data into Unify
Source: https://docs.unifygtm.com/tutorials/website-product-intent/getting-intent-data-into-unify

Connect your website or product to send visitor intent data into Unify.

## Quick overview

Before you can build Plays on website visitors or product usage events, you need
to get that data flowing into Unify. This guide walks you through the options to
help you pick the right approach for your setup.

Unify can collect page views, identify events, and custom events from your
website or product. After events are collected, Unify links them to companies
and people when possible so you can see and use that activity throughout Unify.

| What you're connecting    | Effort       | Who does it                      |
| :------------------------ | :----------- | :------------------------------- |
| Marketing website traffic | \~15 minutes | You (or a developer)             |
| Product usage data        | 1–2 hours    | A developer, with input from you |

Most teams start with **marketing website traffic** because it's the fastest
path to value—you can be running Plays on website visitors within minutes.
Product usage data typically comes next, once you've seen the value of
intent-driven outbound and want to expand into PLG or upsell motions.

<Columns>
  <Card title="Marketing website traffic" icon="globe-pointer" href="#connect-your-marketing-website">
    Forward existing PostHog or Segment events to Unify, or install the website
    tag to start capturing visitor data.
  </Card>

  <Card title="Product usage events" icon="user-magnifying-glass" href="#connecting-product-usage-data">
    Forward existing PostHog or Segment events to Unify, or set up the Unify
    SDK to capture in-app signals.
  </Card>
</Columns>

## Connect your marketing website

Getting website traffic into Unify is the fastest way to start identifying
companies visiting your site and running Plays on them. In many cases, you can
do this yourself without involving a developer.

### If you don't already have an analytics tool on your website

Install the **Unify Intent Client**, a Unify-provided JavaScript library that
will automatically capture website visits and basic form fills.

<Card
  title="Unify Intent Client"
  icon={
<>
  <UnifyLogoDark />
  <UnifyLogoLight />
</>
}
  href="https://app.unifygtm.com/dashboard/settings/data/web-intent?webEventsTab=Settings"
>
  Install the Unify website tag, React library, or JavaScript library on your
  website.
</Card>

The simplest way to install the client is using the *website tag* approach.
Simply copy a snippet of code from Unify and paste it into your site's HTML (or
through a tag manager). This is a one-time setup that takes about 15 minutes.

If you have a more sophisticated website setup (such as single-page application),
the Unify Intent Client is also available as a React library and a JavaScript
library. This may require developer involvement to set up.

### If you prefer to use Segment or PostHog events

You can forward events from your existing tool directly to Unify—no additional
tag or script needed. This reuses your existing setup and avoids adding another
piece of code to your site.

<CardGroup>
  <Card title="Segment" icon={<SegmentIcon />} href="/reference/integrations/segment">
    Send Segment events into Unify.
  </Card>

  <Card
    title="PostHog"
    icon={
  <>
    <PosthogLogoDark />
    <PosthogLogoLight />
  </>
}
    href="/reference/integrations/posthog"
  >
    Send PostHog events into Unify.
  </Card>
</CardGroup>

These integrations are typically configured by a developer or someone with
access to your Segment or PostHog account. The setup takes about 10–15 minutes.

<Warning>
  **Don't install both.** If you forward events from Segment or PostHog, do not
  also install the Unify Intent Client on the same site. Running two event
  sources on the same site will produce duplicate data.
</Warning>

### How to decide

If you're unsure of which approach to use, here's our recommendation:

* **Looking for the simplest setup?** Install the Unify Website Tag.
* **Already have Segment or PostHog on your marketing site?** Forward events from there.
* **Don't have either?** Install the Unify Intent Client.

This decision is easy to change later if you want to switch approaches.

## Connecting product usage data

Product usage data captures what users do inside your product—logins, feature
usage, paywall hits, and more. This is what powers upsell Plays, expansion
motions, and PLG-driven outbound.

Setting this up often requires developer involvement. This section helps you
decide on an approach and coordinate with your engineering team to get data
flowing into Unify.

### Decide which user actions to track

Before involving a developer, think about the product signals that would trigger
outreach from your team. You don't need to track everything—start with the 3–5
actions that are most likely to indicate buying intent or expansion readiness.

**Here are some common starting points:**

| Signal                     | Why it matters                                                  |
| :------------------------- | :-------------------------------------------------------------- |
| User logs in               | Establishes identity—links all activity to a known person       |
| Paywall or usage limit hit | Strongest upgrade signal—user wants more than their plan allows |
| Key feature activated      | Shows the user is getting value and may be ready to go deeper   |
| Team member invited        | Team growth signals expansion readiness                         |
| Upgrade CTA clicked        | Direct purchase intent                                          |

### If you already use Segment or PostHog in your product

You can forward events from your existing tool directly to Unify—no new code
needed in the product itself. This is the simplest path if you already have
analytics instrumentation in place.

<CardGroup>
  <Card title="Segment" icon={<SegmentIcon />} href="/reference/integrations/segment">
    Send Segment events into Unify.
  </Card>

  <Card
    title="PostHog"
    icon={
  <>
    <PosthogLogoDark />
    <PosthogLogoLight />
  </>
}
    href="/reference/integrations/posthog"
  >
    Send PostHog events into Unify.
  </Card>
</CardGroup>

Your developer may still need to add instrumentation for the specific actions
you identified above if they aren't already being tracked in Segment or PostHog.

### If you don't have an existing analytics tool

Install the **Unify Intent Client** JavaScript or React library directly in your
product. This gives you functions in your product to send user identity and
actions to Unify.

<Card
  title="Unify Intent Client"
  icon={
<>
  <UnifyLogoDark />
  <UnifyLogoLight />
</>
}
  href="/developers/guides/product-usage-data/unify-intent-client"
>
  Install the JavaScript or React SDK in your web application.
</Card>

This requires a developer to add code to your product. The [Product usage data guide](/developers/guides/product-usage-data/introduction)
includes code examples, setup walkthroughs, and guidance on the available
options.

<Warning>
  **Don't install both.** If you forward events from Segment or PostHog, do not
  also install the Unify Intent Client in the same app. Running two event
  sources in the same app will produce duplicate data.
</Warning>

### How to decide

* **Already have Segment or PostHog in your product?** Forward events from
  there. Ask your developer if the actions you want to track are already
  instrumented—if not, they'll need to add them.
* **Don't have either?** Install the Unify Intent Client.
* **Use a different analytics tool (e.g., RudderStack, Amplitude)?** Check if it
  supports sending events to a webhook destination. If so, your developer can
  configure it to send events to Unify. If not, install the Unify Intent Client
  alongside it.


# Understanding intent data
Source: https://docs.unifygtm.com/tutorials/website-product-intent/understanding-intent-data

Learn how website and product intent data powers smarter outbound in Unify.

## Overview

The best outreach reaches the right person, at the right time, with the right
context. Intent data is how you make that happen—it tells you who is interested
in your product *right now* based on their actual behavior.

Unify captures intent data from your marketing website and your product, links
it to real-world companies and people, and takes action on them in real time at
scale.

## Two types of intent data

### Website intent: early interest signals

Website intent captures what's happening on your marketing site, docs, blog,
and other public-facing pages. When someone visits your pricing page, reads a
case study, or comes back to your site multiple times, they're signaling early
interest.

A few examples:

* A visitor from a target account visits your pricing page three times this week
* An unknown visitor from a Fortune 500 company reads two case studies in your
  industry
* Someone clicks through from a marketing email and browses your features page

Most website visitors are anonymous. Unify automatically identifies the
**company** they're from using IP-based matching. When a visitor fills out a
form or clicks a tracked email link, Unify can also identify the **person**.

Website activity includes page views, identify events, and custom events such as
form submissions or button clicks. Unify can also use UTM parameters, referrer,
sessions, location, and last website activity to help you filter visitors and
trigger Plays.

### Product intent: deep interest signals

Product intent captures what users are doing *inside* your product—logins,
feature usage, hitting paywalls, inviting teammates, and other in-app actions.
These signals tell you who is getting real value and who is ready for an
upgrade or expansion conversation.

A few examples:

* A free plan user hits a usage limit multiple times in a week
* A user tries to access an enterprise-only feature
* A new team member is invited to a customer's account
* A user who's been inactive for 30 days logs back in

Product intent is often the highest-quality signal available because it
reflects actual usage, not just browsing.

### How they work together

Website intent finds **new** opportunities—companies showing early interest.
Product intent finds **expansion** opportunities—existing users ready to buy
more. Many teams start with one and add the other over time.

## The big picture

Here's the core loop that makes this work:

1. **Data flows in** from your website, product, CRM, and more
2. **Unify links it** to the companies and people in your pipeline
3. **You build Plays** that act on specific signals automatically
4. **Outreach goes out** by prospecting, automated sequences, rep tasks, and more

This data-action loop is what powers smart, agentic outbound at scale. Scaling
a complex sales process is only possible with the right data and automation
working together.