Copy skill

Cold email spintax linter

Paste a subject line or email with spintax and the assistant finds every option that will break at send time, explains why, and returns a fixed template with sample renders.

Works with

One Markdown file, free to use and change. It reads only what you paste into the chat.

What it does

What the skill checks

  • Detects double-brace ({{RANDOM|a|b}}) and single-brace ({a|b}) syntax
  • Flags spaces at option edges, which many engines trim, mashing words together
  • Flags empty options, nested single-brace spintax and unbalanced braces
  • Flags merge-variable fallbacks inside single-brace spintax and nested fallbacks
  • Checks every {{variable}} against the columns of your lead file
  • Renders samples with filled and with empty fields, and counts distinct renders

Use it when

  • Before you load a new subject line or sequence into Instantly, Smartlead or another sequencer
  • When a sent email shows mashed words, raw {{tags}} or "Hi ,"
  • When you convert spintax from one tool's syntax to another's

Example

What you paste and what you get back

You
Check this spintax for Instantly:

Subject: {{RANDOM|quick| short}} question, {{firstName|{{companyName|there}}}}
Body: {Hi {{first_name|there}}|Hello},
Assistant, with the skill
ERROR subject "| short": leading space is trimmed at send time, renders "shortquestion" in some engines. Fix: {{RANDOM|quick|short}}.
ERROR subject nested fallback {{firstName|{{companyName|there}}}}: the inner tag ships raw when firstName is empty. Fix: {{firstName|there}}.
ERROR body fallback pipe inside {...}: the | splits the spintax block. Fix: {Hi {{first_name}}|Hello}, and drop leads without a first name.

Fixed subject: {{RANDOM|quick|short}} question, {{firstName|there}}
Renders (filled): quick question, Sarah / short question, Sarah
Renders (empty): quick question, there / short question, there

Install

Install it in your assistant

The same file works everywhere. Claude and Claude Code load it as a skill; the other assistants follow it as instructions.

Claude Code

  1. Run the command below. It saves the skill to your personal skills folder, available in every project. For one project only, use .claude/skills in the project instead.
  2. Start a new Claude Code session. Claude uses the skill when your request matches its description, or when you name it.
Terminal
mkdir -p ~/.claude/skills/cold-email-spintax-linter
curl -fsSL https://outreach2day.com/skills/cold-email-spintax-linter/SKILL.md -o ~/.claude/skills/cold-email-spintax-linter/SKILL.md

Claude (web and desktop)

  1. Download the ZIP file.
  2. In Claude, open Settings, find Skills under Capabilities and upload the ZIP. Skills need code execution to be turned on for your account.
  3. Ask for the task in any chat. Claude loads the skill when the request matches.

ChatGPT

  1. Download SKILL.md.
  2. Paste its text into a Project's instructions or a custom GPT's instructions. For a single chat, attach the file and write: follow the instructions in this file.

Gemini

  1. Download SKILL.md.
  2. Create a Gem and paste the file's text into its instructions, or attach the file to a chat and ask Gemini to follow it.

Grok

  1. Download SKILL.md.
  2. Paste its text into a Project's instructions, or attach the file to a chat and ask Grok to follow it.

Cursor and other coding agents

  1. Save the file as a project rule with the command below. Cursor reads the description to decide when to apply it.
  2. Agents that read AGENTS.md (Codex and others): paste the text into AGENTS.md or reference the file from it.
Terminal, in your project
mkdir -p .cursor/rules
curl -fsSL https://outreach2day.com/skills/cold-email-spintax-linter/SKILL.md -o .cursor/rules/cold-email-spintax-linter.mdc

Source

The full SKILL.md

Read it before you install it. Change the rules to match your own setup.

cold-email-spintax-linter/SKILL.md
---
name: cold-email-spintax-linter
description: Lints cold email spintax and merge variables before a campaign goes live. Catches options that mash words together when the sending tool trims spaces, empty options, broken or nested braces, merge variables with fallbacks placed inside single-brace spintax, nested fallbacks, and templates that break when a lead field is empty. Renders sample emails with filled and empty fields. Use when the user pastes a subject line, email body or sequence with {a|b} or {{RANDOM|a|b}} spintax, or asks to check, validate, fix or preview spintax.
---

# Cold email spintax linter

You check spintax templates for cold email the way a sending engine will render them, report every problem with its exact location, and propose a fixed template. You never ship a template you have not rendered.

## Step 1. Detect the syntax

Ask which sending tool the user uses if it is not obvious. Two syntaxes are common:

| Syntax | Example | Where |
|---|---|---|
| Double-brace | `{{RANDOM\|Hi\|Hello}} {{firstName}}` | Instantly and tools that copy its format |
| Single-brace | `{Hi\|Hello} {{first_name}}` | Most other sequencers and many in-house engines |

Merge variables are `{{name}}` in both. Check the exact variable names against the columns of the user's lead file (case matters: `firstName` and `first_name` are different fields). A variable the engine does not know usually renders as an empty string, silently.

## Step 2. Run the checks

Report each finding as `ERROR` (will break renders) or `WARN` (renders, but risky), with the line and the offending fragment.

ERROR:

1. **Unbalanced braces.** Every `{` or `{{` has a matching close. Count them per line.
2. **Edge whitespace in an option.** Many engines trim leading and trailing spaces from every option at render time. `{{RANDOM| quick| short}} note` renders as `quicknote`. A word join must be literal text between two blocks (`{{RANDOM|quick|short}} note`), never a space at the edge of an option.
3. **Empty option.** `{a||b}` or `{a|}`: some engines drop it, some render nothing and leave double spaces. Offer a shorter complete option instead.
4. **Nested single-brace spintax.** `{Hi {there|all}|Hello}`: single-brace engines usually support one level only. Flatten into complete options: `{Hi there|Hi all|Hello}`.
5. **Fallback pipe inside single-brace spintax.** `{Hi {{first_name|there}}|Hello}`: the `|` of the fallback is read as an option separator and splits the block. Use a bare variable inside spintax (`{Hi {{first_name}}|Hello}`) and handle empty fields at import (see step 4).
6. **Nested fallback.** `{{firstName|{{companyName|there}}}}` does not resolve recursively on most engines; the raw inner tag ships. Use one level: `{{firstName|there}}`.
7. **Unknown variable.** Any `{{var}}` that is not a column in the lead file (or a sender variable the tool documents).

WARN:

8. A variable without a fallback on a double-brace engine (`{{companyName}}` with no `|your team`), when the lead file has empty values in that column.
9. The same variable twice in one sentence, or the company name more than once in the email.
10. An option that changes the meaning of the sentence (e.g. one option asks a question, another states a fact) so some renders read badly.
11. Punctuation that dangles when a field is empty: `Hi ,`, `owner -`, `, at`.
12. A link, URL or bare domain in any option (auto-linked by mail clients; treat as a spam signal in cold email).

## Step 3. Render

Render at least 8 samples in two modes and show them:

- **Filled:** every variable has a realistic value.
- **Empty:** every variable is empty, so only fallbacks and literal text remain.

Then render the same random path with every option trimmed of edge spaces. If the trimmed render differs from the normal render by even one character, that is an ERROR (check 2).

Count the distinct renders (product of option counts per block, ignoring variables) and report it. For subject lines at high volume, more distinct renders is better, but every render must be a subject a person would actually write.

## Step 4. Fix and hand back

Return:

1. A findings table: severity, location, fragment, why it breaks, fix.
2. The corrected template in the user's syntax.
3. The sample renders of the corrected template (filled and empty).
4. Data advice when fallbacks are not supported: remove or suppress leads with empty `first_name` or `company` before import instead of relying on the template.

## Rules

- Do not change the user's wording beyond what a fix needs. If you suggest copy improvements, list them separately.
- Do not claim a template is clean without showing renders.
- The sending tool's own preview or test send is the final check. Tell the user to send one test email per template to a mailbox they own and read the rendered subject and body, because preview screens sometimes show raw spintax in the subject.

## Example

Input:

```
Subject: {{RANDOM|quick| short}} question, {{firstName|{{companyName|there}}}}
Body: {Hi {{first_name|there}}|Hello},
```

Output (abridged):

| Severity | Where | Fragment | Fix |
|---|---|---|---|
| ERROR | subject | `\| short` | remove the leading space: `{{RANDOM\|quick\|short}}` |
| ERROR | subject | `{{firstName\|{{companyName\|there}}}}` | one level: `{{firstName\|there}}` |
| ERROR | body | `{{first_name\|there}}` inside `{...}` | bare variable inside spintax: `{Hi {{first_name}}\|Hello},` and drop leads without a first name |

Fixed subject: `{{RANDOM|quick|short}} question, {{firstName|there}}`

Download SKILL.md · Download ZIP

FAQ

Questions

Why do spaces at the edge of a spintax option break emails?

Some sending tools trim the leading and trailing spaces of every option when they render. If the space between two words sits at the edge of an option, the words join: "quick" and " note" become "quicknote". Keep spaces in the literal text between blocks.

Can I put a merge variable inside spintax?

Usually yes, as a bare variable: {Hi {{first_name}}|Hello}. A variable with a fallback, {{first_name|there}}, inside single-brace spintax is the problem: the fallback's pipe is read as an option separator. Test on your tool with one test email.

Does this skill send anything or connect to my sequencer?

No. It works on the text you paste. The assistant reads the template, renders samples in the chat and returns a fixed version. Nothing leaves the conversation.

Is there a version I can run without an AI assistant?

Yes. The free spintax validator on this site runs the same checks in your browser and shows sample renders.

Mailboxes, warm-up and sending in one place

$2.50 a mailbox a month. DNS records are set for you, and every mailbox shows its warm-up numbers from day one.