# Contact variables

Typed facts about a contact — which platforms they use, how big their team is — that sequences branch on and emails use.

## Types

Every variable has a key, a label and one of four types:

| Type | Example value | In an email |
| --- | --- | --- |
| Text | `"Shopify"` | Shopify |
| Number | `12` | 12 |
| Yes / No | `true` | yes |
| List | `["figma", "stripe"]` | figma, stripe |

Any variable can also be **unknown** (`null`): it's on the contact, but there's no answer yet — for example while an external API is still researching them. Unknown is different from not set at all, and a condition can check for it.

Keys are lowercase with underscores, like `has_stripe`. If you type a name such as "Has Stripe?", it becomes `has_stripe`.

## Setting and unsetting

- **By hand:** the *Variables* section on a contact (inbox sidebar or contact page). Click a value to edit it, mark it unknown, or remove it.
- **In a sequence:** a *Set variables* step. Leave a value empty to mark it unknown.
- **From your API:** a *Call external API* step stores the `variables` your API returns. See [External API integrations](https://founderdb.co/docs/integrations.md).
- **From an AI agent:** Claude can set them with `set_contact_variables` — see [AI agents (MCP)](https://founderdb.co/docs/mcp.md).

Define variables up front in *Outreach → Settings → Contact variables* to fix their type. A key nobody has defined yet is created the first time it gets a real value, with its type taken from that value (marking it unknown first doesn't fix the type). Values are converted to the variable's type where that makes sense: `"yes"` becomes `true` for a Yes/No variable, `"a, b"` becomes a list, `"12"` a number. Values that can't be converted are skipped. Every change is logged on the contact's timeline with who made it.

## Using variables in emails

In templates and subjects, write `{{var.key}}`. Unknown or missing values render as nothing, so add a fallback after a `|`:

```text
Hi {{firstName | there}},

Saw you're on {{var.platforms | a few tools we integrate with}} —
{{var.pitch_line}}
```

Built-in values work the same way: `{{name}}`, `{{firstName}}`, `{{email}}`, `{{makerName}}`, `{{productName}}`.

### AI emails

An AI email step sees every *known* variable as context ("What we know about this contact"), so an instruction like "mention the integrations they'd benefit from" just works. You can also put `{{var.key}}` in the instruction itself.

## Branching on a variable

A *Branch on variable* step checks one variable and continues on **Yes** or **No**.

| Condition | Yes when |
| --- | --- |
| is known / is unknown | The value is (not) unknown or missing |
| is yes / is no | A Yes/No variable is true / false |
| equals / doesn't equal | Text or number matches, ignoring case |
| contains / doesn't contain | A list has the item, or text contains it |
| is more than / is less than | A number — or a list's length — compared to the value |

> **Note:** An unknown value only matches *is unknown* (and the "doesn't" conditions never match it). Put an *is unknown* branch first if a contact might still be waiting for data.
