> ## Documentation Index
> Fetch the complete documentation index at: https://docs.assistable.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Assistant and CRM variable reference

> Every built-in assistant variable, with exact syntax, account availability, examples, and missing-value behavior.

Use variables to put a contact's details, business information, or conversation context into an assistant prompt or a tool field. Copy the complete placeholder, including double braces: `{{contact.first_name}}`.

This reference lists the built-in GHL and Direct variable sets, including keys that are absent from the picker. Your account can also have its own custom fields and custom values, so those names vary by account. Flow Builder has a separate [flow variable reference](/v3/guides/flows/variables).

## Choose the right context

| Context | Where values come from | What to expect |
| - | - | - |
| **GHL** | The linked GHL contact, location, assigned user, custom fields, and custom values, plus assistant/session context | A CRM connection and the relevant records are needed. Voice sessions do not always fetch assigned-user details. |
| **Direct** | The native Assistable contact and client account's business profile | Uses the Direct columns below. GHL user fields, GHL custom values, and most session identifiers are not built-in Direct values. |
| **Flow Builder** | Flow settings, nodes, session state, and initialization data | Uses its own names and refresh rules. See the [flow reference](/v3/guides/flows/variables). |

A listed key is not a guarantee that its value is populated. Test in the channel and account type where you intend to use it. Variable names are case-sensitive; dots are part of the exact key. `{{contact.first_name}}` and `{{contact.firstName}}` are different keys.

## Session variables

Unless marked **Both**, these are built-in GHL-context keys. A calling integration can add more values, but do not assume that makes them available in Direct chat.

| Placeholder | Meaning | Availability or missing value |
| - | - | - |
| `{{location_id}}` | GHL location ID. | GHL; empty if unavailable. |
| `{{account}}` | Assistable client account ID; not a business name or workspace slug. | GHL; `-` if unavailable. |
| `{{account_id}}` | Assistable client account ID. | GHL; `-` if unavailable. |
| `{{workspace_id}}` | Parent workspace ID. | GHL; empty if unavailable. |
| `{{assistant_id}}` | Assistant handling the interaction. | GHL; empty if unavailable. |
| `{{contact_id}}` | Linked GHL contact ID. | GHL; `-` if unavailable. |
| `{{calendar_id}}` | Calendar configured for this assistant/context. | GHL; empty if none is supplied. |
| `{{channel}}` | Channel label supplied by the conversation or calling route. | Both; labels vary by route, such as `VOICE`, `SMS`, or `phone call`. Do not treat the picker hint as a fixed enum. |
| `{{direction}}` | Interaction direction, such as `inbound` or `outbound`. | Both; Direct chat replies use `outbound`, even when answering an incoming message. |
| `{{to}}` | Destination address for this interaction. | GHL; `-` if unavailable. Usually a phone number for calls. |
| `{{from}}` | Source address for this interaction. | GHL; `-` if unavailable. |
| `{{user_target}}` | The customer endpoint: normally `from` on inbound calls and `to` on outbound calls. | GHL; `-` if unavailable; an integration can supply the resolved endpoint. |
| `{{assistant_target}}` | The assistant endpoint: normally `to` on inbound calls and `from` on outbound calls. | GHL; `-` if unavailable. |
| `{{phone_id}}` | Phone record ID supplied for the current interaction. | GHL; empty if not supplied. Not a phone number. |
| `{{outbound_phone_id}}` | Assistant outbound phone record ID. | GHL; `-` if unavailable. |
| `{{inbound_phone_id}}` | Assistant inbound phone record ID. | GHL; `-` if unavailable. |
| `{{messaging_profile_id}}` | Configured messaging profile ID. | GHL; `-` if unavailable. |
| `{{transfer_caller_id}}` | A dialable caller ID candidate for a transfer. | GHL; checks the customer endpoint, assistant endpoint, then configured assistant numbers; empty if none is a valid E.164 candidate. This does not select the transfer caller-ID mode. |
| `{{greeting}}` | Configured greeting after variable replacement. | GHL; can be empty. Not necessarily the opening line actually spoken. |
| `{{assistant_greeting}}` | Resolved opening message for the assistant. | GHL; can be configured, generated, or a fallback. `-` can mean the contact should speak first; do not read it aloud. |
| `{{current_date}}` | Current date, for example `10/20/2026`. | Both; display format is `M/D/YYYY`, not ISO. |
| `{{current_time}}` | Current time, for example `3:05 PM`. | Both; 12-hour display with AM/PM. |
| `{{timezone}}` | Resolved IANA timezone, for example `America/New_York`. | Both; see timezone priority below. |
| `{{contact_notes}}` | Alias of the GHL contact notes text. | GHL; empty if unavailable. |
| `{{memory}}` | Reserved placeholder. | GHL; initialized to an empty string. Not a persistent memory feature. |
| `{{soul}}` | Reserved placeholder. | GHL; initialized to an empty string. Not a stored persona field. |

For the business name, use `{{location.name}}`. Identifiers such as `{{account}}` are intended for integrations, not spoken introductions. Use the [transfer guide](/v3/guides/voice/transfer-calls) to configure caller-ID behavior rather than changing a placeholder alone.

## Contact variables

**Both** means the key is supplied in GHL and Direct contexts when the underlying contact data is available. Known missing fields normally become empty text.

| Placeholder | Meaning or example | Context |
| - | - | - |
| `{{contact.id}}` | Contact record ID; the ID belongs to the account type in use. | Both |
| `{{contact.first_name}}` | First name, for example `Jordan`. | Both |
| `{{contact.last_name}}` | Last name, for example `Lee`. | Both |
| `{{contact.full_name}}` | Full name. GHL combines first and last names; Direct prefers the stored full name. | Both |
| `{{contact.name}}` | Alias of the full name. | Direct only; not a built-in GHL key, despite appearing in the picker. |
| `{{contact.email}}` | Stored email address. | Both |
| `{{contact.phone}}` | Stored phone number, preserving its source formatting. | Both |
| `{{contact.phone_raw}}` | GHL: digits only, with the `+` removed. Direct: stored phone text unchanged. | Both; do not assume E.164 formatting. |
| `{{contact.timezone}}` | Contact timezone. | GHL: the contact field itself. Direct: contact → account → `America/New_York` fallback. |
| `{{contact.address1}}` | Street address from GHL. | GHL |
| `{{contact.address}}` | Street address from the native contact. | Direct |
| `{{contact.city}}` | City. | Both |
| `{{contact.state}}` | State or region. | Both |
| `{{contact.postal_code}}` | Postal/ZIP code. | Both |
| `{{contact.country}}` | Stored country. | Direct only; not a built-in GHL key, despite appearing in the picker. |
| `{{contact.website}}` | Contact website. | Both |
| `{{contact.date_of_birth}}` | Stored date-of-birth text; no display-format conversion is applied. | Both |
| `{{contact.source}}` | Contact source. | GHL |
| `{{contact.tags}}` | Contact tags joined with a comma and space. | GHL |
| `{{contact.notes}}` | Contact notes as text. | GHL |

GHL first and last names equal to “Guest” are treated as missing. Direct uses the stored name as-is. If the contact has not been identified, a name or email may be empty even though the conversation is active.

`{{contact.company_name}}` appears in the picker but is not populated by either built-in set. Use a verified custom field key if you need a company name; do not assume this placeholder will resolve.

## Location variables

These describe the business/location, not the customer. In Direct, they come from the native client account's business profile.

| Placeholder | Meaning | Context |
| - | - | - |
| `{{location.id}}` | GHL location ID, or Direct client account ID. | Both |
| `{{location.name}}` | Business/account name. | Both |
| `{{location.address}}` | Street address. | Both |
| `{{location.city}}` | City. | Both |
| `{{location.state}}` | State or region. | Both |
| `{{location.postal_code}}` | Postal/ZIP code. | Both |
| `{{location.country}}` | Country. | Both |
| `{{location.website}}` | Business website. | Both |
| `{{location.email}}` | Business email. Direct falls back to the account email. | Both |
| `{{location.phone}}` | Stored business phone number. | Both |
| `{{location.phone_raw}}` | GHL: digits only. Direct: stored phone text unchanged. | Both |
| `{{location.timezone}}` | GHL location timezone; Direct resolved contact/account timezone. | Both |
| `{{location.locale}}` | Location locale. | GHL |
| `{{location.domain}}` | Configured domain. | GHL |
| `{{location.first_name}}` | First name on the location profile. | GHL |
| `{{location.last_name}}` | Last name on the location profile. | GHL |
| `{{location.full_name}}` | Location profile first and last names combined. | GHL |
| `{{location.logo_url}}` | Logo URL. | GHL |
| `{{location.currency}}` | Stored currency value. | GHL |
| `{{location.date_added}}` | Location creation date as returned by GHL. | GHL |
| `{{location.brand_id}}` | Brand ID. | GHL |
| `{{location.company_id}}` | Company ID. | GHL |

### Business profile

For GHL, these read the nested business profile. A populated `location.name` does not guarantee `location.business.name` is populated. Direct maps the supported business keys to the native account profile.

| Placeholder | Meaning | Context |
| - | - | - |
| `{{location.business.name}}` | Business name. | Both |
| `{{location.business.address}}` | Street address. | Both |
| `{{location.business.city}}` | City. | Both |
| `{{location.business.state}}` | State or region. | Both |
| `{{location.business.country}}` | Country. | Both |
| `{{location.business.postal_code}}` | Postal/ZIP code. | Both |
| `{{location.business.website}}` | Website. | Both |
| `{{location.business.timezone}}` | Business timezone; Direct uses the resolved timezone. | Both |
| `{{location.business.email}}` | Business email. | Both |
| `{{location.business.logo_url}}` | Business logo URL. | GHL |

### Social profiles

All of these are **GHL only** and require the corresponding location profile value. Missing links stay empty; Assistable does not infer them.

| Placeholder | Meaning |
| - | - |
| `{{location.social.facebook}}` | Facebook profile/page URL. |
| `{{location.social.google_places_id}}` | Google Places ID, not a public profile URL. |
| `{{location.social.linkedin}}` | LinkedIn URL. |
| `{{location.social.instagram}}` | Instagram value. |
| `{{location.social.youtube}}` | YouTube value. |
| `{{location.social.twitter}}` | Twitter/X value. |
| `{{location.social.yelp}}` | Yelp value. |
| `{{location.social.pinterest}}` | Pinterest value. |

## Right now variables

These values are calculated when the context is built; they are not a continuously ticking clock. In the GHL resolver, the timezone priority is **contact → location → supplied account timezone → America/New\_York**. In Direct it is **contact → account → America/New\_York**. Confirm the timezone before interpreting “tomorrow.”

GHL uses the `right_now.` prefix. Direct uses the unprefixed key. The top-level `current_date`, `current_time`, and `timezone` are also available in GHL as listed above.

Flow Builder also uses `right_now.*` names, but some formats differ: its `right_now.current_date` includes the full date, time, and timezone. Use the [flow variable reference](/v3/guides/flows/variables) when working inside a flow.

| GHL placeholder | Direct placeholder | Meaning or example |
| - | - | - |
| `{{right_now.day_name}}` | `{{day_name}}` | Day name, such as `Tuesday`. |
| `{{right_now.day}}` | `{{day}}` | Day of month, such as `20`. |
| `{{right_now.month}}` | `{{month}}` | Full month name, such as `October`. |
| `{{right_now.year}}` | `{{year}}` | Four-digit year, such as `2026`. |
| `{{right_now.hour}}` | `{{hour}}` | 12-hour clock hour, such as `3`. |
| `{{right_now.minute}}` | `{{minute}}` | Two-digit minute, such as `05`. |
| `{{right_now.am_pm}}` | `{{am_pm}}` | `AM` or `PM`. |
| `{{right_now.timezone}}` | `{{timezone}}` | IANA timezone, such as `America/New_York`. |
| `{{right_now.timezone_abbr}}` | `{{timezone_abbr}}` | Timezone abbreviation/display label, such as `EDT`. |
| `{{right_now.current_date}}` | `{{current_date}}` | Today as `M/D/YYYY`, such as `10/20/2026`. |
| `{{right_now.current_time}}` | `{{current_time}}` | Time such as `3:05 PM`. |
| `{{right_now.tomorrow_date}}` | `{{tomorrow_date}}` | Tomorrow as `M/D/YYYY`. |
| `{{right_now.day_after_tomorrow_date}}` | `{{day_after_tomorrow_date}}` | Two days from today as `M/D/YYYY`. |

### Dates for this week and the following two weeks

Weeks run **Monday through Sunday**. A “this week” value can be in the past. For example, on a Friday, `mon_date` is the Monday earlier that week, not the next upcoming Monday. These are date strings, not available booking slots; use the calendar tools to check availability.

| GHL placeholder | Direct placeholder | Date |
| - | - | - |
| `{{right_now.mon_date}}` | `{{mon_date}}` | This week: Monday. |
| `{{right_now.tue_date}}` | `{{tue_date}}` | This week: Tuesday. |
| `{{right_now.wed_date}}` | `{{wed_date}}` | This week: Wednesday. |
| `{{right_now.thu_date}}` | `{{thu_date}}` | This week: Thursday. |
| `{{right_now.fri_date}}` | `{{fri_date}}` | This week: Friday. |
| `{{right_now.sat_date}}` | `{{sat_date}}` | This week: Saturday. |
| `{{right_now.sun_date}}` | `{{sun_date}}` | This week: Sunday. |
| `{{right_now.next_mon_date}}` | `{{next_mon_date}}` | Next week: Monday. |
| `{{right_now.next_tue_date}}` | `{{next_tue_date}}` | Next week: Tuesday. |
| `{{right_now.next_wed_date}}` | `{{next_wed_date}}` | Next week: Wednesday. |
| `{{right_now.next_thu_date}}` | `{{next_thu_date}}` | Next week: Thursday. |
| `{{right_now.next_fri_date}}` | `{{next_fri_date}}` | Next week: Friday. |
| `{{right_now.next_sat_date}}` | `{{next_sat_date}}` | Next week: Saturday. |
| `{{right_now.next_sun_date}}` | `{{next_sun_date}}` | Next week: Sunday. |
| `{{right_now.wk2_mon_date}}` | `{{wk2_mon_date}}` | Two weeks ahead: Monday. |
| `{{right_now.wk2_tue_date}}` | `{{wk2_tue_date}}` | Two weeks ahead: Tuesday. |
| `{{right_now.wk2_wed_date}}` | `{{wk2_wed_date}}` | Two weeks ahead: Wednesday. |
| `{{right_now.wk2_thu_date}}` | `{{wk2_thu_date}}` | Two weeks ahead: Thursday. |
| `{{right_now.wk2_fri_date}}` | `{{wk2_fri_date}}` | Two weeks ahead: Friday. |
| `{{right_now.wk2_sat_date}}` | `{{wk2_sat_date}}` | Two weeks ahead: Saturday. |
| `{{right_now.wk2_sun_date}}` | `{{wk2_sun_date}}` | Two weeks ahead: Sunday. |

## User variables

These are **GHL only**. They describe the CRM user assigned to the contact, not necessarily the person signed into Assistable. They require an assigned user and a context that loads that user's details. Some voice paths skip that lookup, so do not make a voice workflow depend on these fields without testing it.

| Placeholder | Meaning |
| - | - |
| `{{user.id}}` | Assigned user ID. |
| `{{user.name}}` | Stored user name. |
| `{{user.first_name}}` | First name. |
| `{{user.last_name}}` | Last name. |
| `{{user.full_name}}` | First and last names combined; falls back to the stored name. |
| `{{user.email}}` | Email address. |
| `{{user.phone}}` | Stored phone number. |
| `{{user.phone_raw}}` | Phone digits only, without the `+`. |
| `{{user.extension}}` | Phone extension. |
| `{{user.role}}` | GHL role value. |
| `{{user.role_type}}` | GHL role type. |
| `{{user.location_ids}}` | Assigned location IDs joined with a comma and space. |

## Custom values and custom contact fields

Custom names are defined by your GHL account, so there is no universal list to copy. Use the **exact field key**, not the display label. A key such as `custom_values.booking_link` works only when your account defines it and supplies a value.

| Kind | Example placeholder | Where the value comes from |
| - | - | - |
| GHL custom value | `{{custom_values.booking_link}}` | The location's configured custom value. Use this for shared business details such as links and office hours. |
| GHL custom contact field | `{{contact.membership_level}}` | The matching field on the current contact. This example key must exist in your account. |
| Call-supplied value | `{{campaign_name}}` | A value explicitly sent for that call through an integration that supports custom variables. It is not automatically a CRM field. |

In the assistant prompt editor, type `/` and choose **Contact** or **Custom Values** to see the account-specific entries loaded from your connected CRM. Contact entries include standard fields and custom fields whose keys begin with `contact.`. The picker inserts the full placeholder for you.

To check the source list, open the connected GHL location's **Settings → Custom Values** or **Settings → Custom Fields**, copy each exact key, and confirm its value on the intended location/contact. A display label such as “Booking Link” does not itself create `{{booking_link}}`. For contact custom fields, the field definition and the contact's stored value must match. If the picker is empty, check the GHL connection and wait for the field list to load before treating a field as unavailable.

Custom contact-field arrays become comma-separated text; object values become JSON text. Custom values that contain objects or arrays become JSON text. Numbers and booleans become text. The variable is still a string, not a typed object you can query with arbitrary dot paths.

When the CRM cannot be reached, values can be empty, absent, or served from a cached record. Do not rely on an edit being visible immediately in an already-running conversation. Test a new conversation with the intended contact after changing a source value.

### Call-specific custom slots

Calling integrations that expose these five slots can supply them for one call:

| Placeholder | Value |
| - | - |
| `{{custom_one}}` | First custom text value. |
| `{{custom_two}}` | Second custom text value. |
| `{{custom_three}}` | Third custom text value. |
| `{{custom_four}}` | Fourth custom text value. |
| `{{custom_five}}` | Fifth custom text value. |

These are supplied inputs, not automatically populated contact fields. The v3 calls API accepts a `variables` object. Direct calling also accepts this object and merges it after its built-in values, so a matching key can override them for that call. Use distinct names such as `campaign_name` to avoid accidentally replacing a contact or business value. Check the endpoint's current [API Reference](/api-reference/calls/place-an-ai-voice-call) before sending a request.

## Picker differences to know

The picker helps insert names, but runtime support determines whether they resolve.

| Picker item or hint | Use this rule |
| - | - |
| `contact.name` | Use `contact.full_name` for GHL. Both names work in the Direct base context. |
| `contact.country` | Built into Direct, not the GHL base context. Use a verified GHL custom field if you need this information there. |
| `contact.company_name` | Not built into either context. Use an existing custom field key. |
| `account` described as a workspace/account slug | It resolves to an account identifier. Use `location.name` for a business name. |
| ISO-style date or 24-hour time hint | Actual built-in values use `M/D/YYYY` and 12-hour time with AM/PM. |
| `memory` or `soul` | Empty reserved values; neither provides persistent memory/persona content. |

## Examples and missing values

A prompt can use the values while telling the assistant how to handle blanks:

```text theme={null}
You help customers of {{location.name}}.
The contact's first name is {{contact.first_name}}.
Use their name only if it is present. Otherwise ask how they would like to be addressed.
Never invent a missing email, phone number, booking link, or appointment time.
```

For a GHL scheduling prompt:

```text theme={null}
Today is {{right_now.day_name}}, {{right_now.current_date}}, in {{right_now.timezone}}.
Tomorrow is {{right_now.tomorrow_date}}.
Use the calendar tool to verify available times before offering an appointment.
```

For Direct, use `{{day_name}}`, `{{current_date}}`, `{{timezone}}`, and `{{tomorrow_date}}` in that example.

| Result you see | Meaning | What to do |
| - | - | - |
| Empty text | The key exists but its value is empty. | Check the source record; ask the customer for the value if appropriate. |
| `-` | Some session values use a missing-value marker, or the opening-message setting means the contact speaks first. | Treat it as unavailable, not customer-facing text. |
| Literal `{{some_key}}` | The key is unknown or absent in this context. | Check exact spelling, account type, and which integration supplies it. |
| An old value | The context may have been built earlier or loaded from a cache. | Check the source, then start a new test conversation. |

Variable replacement is text substitution. It does not evaluate expressions, add conditional logic, or automatically escape HTML, URLs, or JSON. Let the receiving integration encode values for its destination; keep credentials and secrets out of prompts and conversational variables.

## Test a variable end to end

1. Choose a test contact with a recognizable source value.
2. Insert the exact placeholder into the prompt or tool field where it will be used.
3. Save the configuration; publish before a live voice test.
4. Start a conversation in the intended channel and account type.
5. Verify the rendered answer or the actual request received by your test integration.
6. Repeat with the source value missing and confirm the assistant asks for it or uses your intended fallback.

For a required tool field, check that the actual value is present before sending the request. A populated preview or picker entry alone does not prove the live integration received it.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.