> For the complete documentation index, see [llms.txt](https://doc.autoreach.tech/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://doc.autoreach.tech/outreach-and-sequences/dm-personalization.md).

# DM Personalization

When a DM or Email step executes in a sequence, AutoReach generates a personalized message for each lead. It takes your template with `{{variable}}` placeholders, enriches it with lead data, and uses AI to produce a natural, personalized message.

The variable system documented here applies to **both DMs (X / LinkedIn) and Email steps** (subject and body). Email-specific routing details are covered in [Email Channel](/outreach-and-sequences/email-channel.md).

## When You Need This Page

You don't have to read this whole page to get started. Autopilot generates a working DM template for you, and the defaults are fine for the first run.

Come back here when:

* **Your reply rate is low** and you want to add more relevant references to your messages (a recent post, a specific role, a pain point).
* **You're writing your own template from scratch** and need to know which `{{variables}}` are available.
* **Messages are coming out generic** because you're missing the variables that drive personalization (typically `{{post}}` for X, `{{current_role}}` + `{{company_name}}` for LinkedIn, or a custom `{{pain_point}}` placeholder the AI fills from your offer).
* **A variable isn't substituting** and you need to know whether it's a known variable (direct fill from lead data) or a custom one (AI-inferred from context).

If your first sequence is sending and getting replies, you can skip this page entirely.

## Two modes: prompt-only and template

There are two ways a DM or email step can generate its message:

* **Prompt-only (default, recommended):** leave the message template empty. The AI writes the whole message from your DM generation prompt, the lead's data, and offer context. There are no `{{placeholders}}` to fill; the prompt owns the rules.
* **Template (legacy slot-filling):** provide a message template with `{{variable}}` placeholders. The AI only fills the placeholders, and the prompt becomes style guidance. This path exists for older sequences and for cases where you want strict control over wording.

The variable reference below applies to template mode. In prompt-only mode the same lead data is available to the AI, just without explicit placeholders.

## Personalization Flow (template mode)

When a template is present, message personalization follows three passes:

1. **Direct substitution** - replaces known variables with data from the lead's profile
2. **Post fetch** - fetches `{{post}}`/`{{tweet}}` content if referenced in the template
3. **AI personalization** - fills remaining placeholders using lead profile, enrichment data, offer context, knowledge base content, and tone examples

Messages with unresolved variables are blocked and never sent.

***

## Known Variables (Direct Substitution)

These variables are replaced directly from lead data in the first pass.

### Identity

| Variable         | Source                            |
| ---------------- | --------------------------------- |
| `{{name}}`       | Full name, falls back to username |
| `{{first_name}}` | Extracted from full name          |
| `{{username}}`   | Platform handle                   |
| `{{bio}}`        | Lead bio                          |
| `{{location}}`   | Lead location                     |
| `{{email}}`      | Lead email                        |

### Network

| Variable        | Source          |
| --------------- | --------------- |
| `{{followers}}` | Follower count  |
| `{{following}}` | Following count |

### Profile Links

| Variable            | Source               |
| ------------------- | -------------------- |
| `{{website}}`       | Lead website URL     |
| `{{linkedin_url}}`  | LinkedIn profile URL |
| `{{x_profile_url}}` | X profile URL        |

### Professional Profile

| Variable           | Source                                     |
| ------------------ | ------------------------------------------ |
| `{{headline}}`     | LinkedIn headline, falls back to bio       |
| `{{summary}}`      | Profile summary                            |
| `{{current_role}}` | Current job title from LinkedIn experience |
| `{{skills}}`       | Top skills, comma-separated                |

### Company Data

| Variable               | Source                                      |
| ---------------------- | ------------------------------------------- |
| `{{company_name}}`     | Company name from enrichment or profile     |
| `{{company_size}}`     | Employee count range (e.g., "51-200")       |
| `{{company_industry}}` | Company industry from enrichment or profile |
| `{{funding_stage}}`    | Company funding stage                       |
| `{{tech_stack}}`       | Top technologies, comma-separated           |

### Web Enrichment Insights

| Variable                 | Source                                             |
| ------------------------ | -------------------------------------------------- |
| `{{achievements}}`       | Notable achievements (filtered to current company) |
| `{{speaking}}`           | Speaking engagements                               |
| `{{podcasts}}`           | Podcast appearances                                |
| `{{enrichment_summary}}` | Web enrichment summary                             |

Achievements, speaking engagements, and podcasts are filtered to the lead's current company. Data from previous employers is excluded.

### Sender and Booking

| Variable           | Source                                   |
| ------------------ | ---------------------------------------- |
| `{{user_name}}`    | Your name (sender)                       |
| `{{booking_link}}` | Calendar URL with lead-specific tracking |

***

## Special Variables (Fetched at Send-Time)

These variables trigger data fetching when used in a template.

### `{{post}}` / `{{tweet}}`

Both map to the same logic (`{{tweet}}` is a backwards-compatible alias). Fetches the lead's recent post content using this priority:

1. **Stored content** - if the lead was sourced from a search with original post content
2. **Live fetch** - fetches the latest post from the lead's profile
3. **Bio fallback** - AI uses bio for personalization instead

For commenter-sourced leads, the context includes both the original post and the lead's reply.

### `{{replied_post}}`

References a post that was commented on in a **prior sequence step**. If a comment action executed earlier in the sequence, this variable provides the original post text and your comment text so the DM can reference prior engagement.

If no prior comment happened (step was skipped), the AI uses a generic opener instead.

***

## Custom Variables (AI-Inferred)

Any `{{placeholder}}` that is not in the known variables list is treated as a custom variable. The AI fills it using explicit information from the lead's profile, enrichment data, and offer context. If the information is not available, the placeholder and surrounding text are removed. The AI never invents or guesses information.

Common AI-inferred variables:

| Variable         | What AI looks for                                  |
| ---------------- | -------------------------------------------------- |
| `{{role}}`       | Job title from bio, headline, or enrichment        |
| `{{company}}`    | Company name from bio or enrichment                |
| `{{industry}}`   | Industry from bio or enrichment                    |
| `{{pain_point}}` | Relevant challenge based on offer and lead context |
| `{{question}}`   | Contextual question based on lead and offer        |

You can use any custom placeholder name.

***

## Example Template

```
hey {{first_name}},

saw you're {{current_role}} at {{company_name}} which probably means {{pain_point}}

I help with {{tech_stack}} teams - think {{enrichment_summary}}.

quick 15-min review, no cost.

interested?

{{user_name}}
{{booking_link}}
```

**Pass 1** replaces `{{first_name}}`, `{{current_role}}`, `{{company_name}}`, `{{tech_stack}}`, `{{enrichment_summary}}`, `{{user_name}}`, `{{booking_link}}` with lead data.

**Pass 2** sends `{{pain_point}}` to AI, which infers it from the lead's profile and offer context or removes it with surrounding text.

***

## Booking Link Tracking

The `{{booking_link}}` variable injects your calendar URL with a lead-specific tracking parameter so a resulting booking can be matched back to the lead. The identifier is prefixed by platform (`li:` for LinkedIn, `ig:` for Instagram, bare for X):

| Provider | Parameter     | Notes                                                             |
| -------- | ------------- | ----------------------------------------------------------------- |
| Calendly | `utm_content` | Captured invisibly and returned in the booking webhook            |
| Cal.com  | `username`    | Prefills (and can hide) the username booking question             |
| Custom   | none          | Custom calendar links are passed through without a tracking param |

***

## DM Quality Standards

AutoReach enforces quality standards on generated messages to ensure they read naturally and avoid common spam patterns:

* **Concise and direct** - short messages with simple language
* **Ends with a question** - invites a natural reply
* **No generic openers** - avoids overused phrases
* **Specific personalization** - references actual lead data (company, role, recent post) rather than generic compliments
* **No hype language** - avoids buzzwords and sales jargon

## Custom Prompts

Sequences have two separate prompt fields for DM control:

| Field                | Purpose                                                      |
| -------------------- | ------------------------------------------------------------ |
| DM Generation Prompt | Overrides the system prompt for message personalization only |
| AI Prompt            | Controls AI conversation replies across all stages           |

The DM Generation Prompt is optional. If not provided, the default system prompt is used. It allows DM-specific instructions separate from general conversation AI behavior.

## Template Generation

AutoReach can generate DM templates for you using AI. Provide a campaign name, tone preference (professional/casual/friendly), and length, and the AI creates a template with `{{variable}}` placeholders ready for personalization.

## Negative Content Checking

Before replying to a lead's post, the system checks for sensitive content. If the check cannot be completed, the message proceeds rather than blocking.

**Skipped topics:** Death, obituaries, serious illness, natural disasters, violence, terrorism, suicide, personal tragedies.

**Allowed topics:** Work complaints, business failures, layoffs, market downturns, sarcasm, controversial opinions, career setbacks.

## Multi-Language Support

Message generation can run in any language you set on the offer. The language picker covers the full ISO 639-1 set (English, Italian, Spanish, French, German, Portuguese, and well over a hundred others). For non-English offers, all AI output (keywords, messages, templates) is generated in the selected language.

## Platform Behavior

All known variables work identically on both X and LinkedIn. Platform differences affect the AI's tone and context, not variable availability:

| Aspect           | X                 | LinkedIn                   |
| ---------------- | ----------------- | -------------------------- |
| Username prefix  | `@username`       | `username` (no prefix)     |
| Tone instruction | Casual and direct | Slightly more professional |
| `{{post}}` label | "on X"            | "on LinkedIn"              |

## Next Steps

* [**Simulation and A/B Testing**](/outreach-and-sequences/simulation-and-testing.md): Preview DMs with real leads before sending
* [**Building Sequences**](/outreach-and-sequences/building-sequences.md): Integrate DM steps into multi-step campaigns
* [**Supported Actions**](/outreach-and-sequences/supported-actions.md): When to use DM vs. other engagement types


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://doc.autoreach.tech/outreach-and-sequences/dm-personalization.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
