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

> ## Agent Instructions
> Use the public API base URL: https://api.teamfollowup.ai/api.
> Authenticate public API requests with Authorization: Bearer YOUR_API_KEY.
> Use product-owned terms: agents, campaigns, projects (GoHighLevel sub-accounts), contacts, calls, outcomes, skills, cadences, phone numbers.
> Scope requests by locationId rather than projectName.
> Read the guide linked from each API reference group before recommending an endpoint.

# Using CRM fields on the call

> Form answers, survey answers and custom fields from HighLevel are context the agent reasons with, not placeholders it reads out. The difference is what stops it saying field names down the phone.

Your contacts arrive carrying answers: what they enquired about, what they said
on the form, what a survey captured. The agent can use all of it.

The whole trick is one distinction.

## Context, not a placeholder

A CRM field is **context the agent reasons with**, not a slot it reads out.

Even when you want the field mentioned in the opening line, you do not write the
token into the spoken line. You put the token in the `# Context` section, and
then write the step as an instruction about behaviour.

<CodeGroup>
  ```text How it works theme={"dark"}
  # Context
  Weight goal from form: {{weight_goal}}

  # Steps to Follow
  If the weight goal from the form is present, reference it conversationally and
  ask them to confirm. If it is missing, ask what result they're hoping for.
  ```

  ```text What not to write theme={"dark"}
  "so your goal is to lose {{weight_goal}}, is that right?"
  "Weight goal: {{weight_goal}}"
  "I see your weight_goal is..."
  "CRM says..."
  ```
</CodeGroup>

The version on the right breaks in two ways. When the field is filled it sounds
like a database being read aloud. When it is empty it is worse: the agent says
the raw token, or says "not on file", to a real person.

The version on the left handles both, because you told it what to do rather than
what to say.

## Missing values

Blank, `(not on file)`, and an unresolved `{{field_name}}` all mean the same
thing: **missing**. Every step that uses a field needs the other branch written.

And when a value is missing, the agent should just ask, the way a person would.
Not "I don't have your weight goal on file", not "the form didn't capture that",
not "the CRM says nothing here". Those phrases tell the lead they are a row in a
database. "What result were you hoping for?" gets the same answer and sounds like
a conversation.

<Tip>
  If you actually want the system named ("I can see from your form that..."),
  that is a fine choice and you can ask for it. It just should not be the
  default, which is why it is written the other way round.
</Tip>

## Custom fields versus custom values

Two different things with confusingly similar names.

| | Custom fields | Custom values |
| - | - | - |
| Scope | Per contact | Per sub account |
| Changes | Every lead | Rarely |
| Example | What they enquired about, their form answers | Office name, a policy line, a booking link |
| Token | `{{field_name}}` | `{{custom_values.name}}` |

Custom values are constants, so use them for stable facts: the office name, a
standing policy, a pricing note, a link. They are not per lead answers and will
be identical on every call.

Take the exact token from the variables list rather than guessing at the spelling,
because a token that does not resolve is a token the agent may say out loud.

When you select a linked project under a master agent, the chatbot reads that
project's CRM fields and custom values. The script remains shared across the
linked projects, so adding a context field changes the shared script. Keep the
missing-value instructions above for projects where that field is unavailable.

## Where this sits

Pulling a person's details into the opening is covered on [What your agent
says](/agents/prompt). This page is about the fields underneath it: choosing
which ones travel with the call, and writing steps that survive an empty one.

## In the API

* [Update agent](/api-reference/agents/update-agent) sets `contextFields`, the CRM fields the agent reasons with
* [Get agent](/api-reference/agents/get-agent) reads the current list
* The field ids come from your CRM; see [CRM resources](/concepts/crm-resources)
