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

# Configure Your AI Agent

> Complete guide to creating, customizing, and deploying an AI agent that qualifies leads through natural conversations.

An AI agent is the brain behind every lead conversation in Naturalead. It determines how the AI introduces itself, what questions it asks, when it qualifies a lead, and when it escalates to a human. Each agent is defined by four building blocks:

<CardGroup cols={2}>
  <Card title="System Prompt & Instructions" icon="message-bot">
    The personality, tone, and context the AI uses in every message. This is the foundation of how your agent sounds and behaves.
  </Card>

  <Card title="Conversation Stages" icon="list-tree">
    An ordered flow of stages (introduction, discovery, qualification, etc.) that guide the conversation toward a goal.
  </Card>

  <Card title="Guardrails" icon="shield-check">
    Safety limits like max messages, inactivity timeouts, forbidden topics, and escalation triggers that keep conversations on track.
  </Card>

  <Card title="Knowledge Bases" icon="book-open">
    Documents and data the agent can reference via RAG to answer domain-specific questions accurately.
  </Card>
</CardGroup>

## Prerequisites

Before configuring an agent you need:

* A Naturalead account with `agent_config:edit` permission (roles: **owner**, **integrator**, or **ai\_architect**)
* An API key with `agent_config:edit` scope
* Optionally, uploaded knowledge base documents if you want RAG-powered answers

## Step-by-step walkthrough

<Steps>
  ### Start from a template (recommended)

  Templates give you a proven starting point. Fetch the available templates and apply one to pre-populate your agent configuration.

  <CodeGroup>
    ```bash curl theme={null}
    # List available templates
    curl "${API_URL}/api/agent-config/templates" \
      -H "X-API-Key: ${API_KEY}"

    # Apply a template to get a pre-filled config
    curl -X POST "${API_URL}/api/agent-config/apply-template" \
      -H "X-API-Key: ${API_KEY}" \
      -H "Content-Type: application/json" \
      -d '{ "templateId": "sales-qualifier" }'
    ```

    ```python Python theme={null}
    import requests

    headers = {"X-API-Key": API_KEY}

    # List templates
    templates = requests.get(f"{API_URL}/api/agent-config/templates", headers=headers).json()
    print(templates)

    # Apply a template
    config = requests.post(
        f"{API_URL}/api/agent-config/apply-template",
        headers=headers,
        json={"templateId": "sales-qualifier"},
    ).json()
    ```

    ```javascript Node.js theme={null}
    const headers = { "X-API-Key": API_KEY };

    // List templates
    const templates = await fetch(`${API_URL}/api/agent-config/templates`, { headers }).then(r => r.json());
    console.log(templates);

    // Apply a template
    const config = await fetch(`${API_URL}/api/agent-config/apply-template`, {
      method: "POST",
      headers: { ...headers, "Content-Type": "application/json" },
      body: JSON.stringify({ templateId: "sales-qualifier" }),
    }).then(r => r.json());
    ```
  </CodeGroup>

  <Info>
    The `apply-template` endpoint returns a configuration object without saving it. You can modify it before creating the agent.
  </Info>

  ### Create the agent

  Use the template output (or build from scratch) to create a new agent. At minimum you need a `name`, `systemPrompt`, and `goal`.

  <CodeGroup>
    ```bash curl theme={null}
    curl -X POST "${API_URL}/api/agent-config" \
      -H "X-API-Key: ${API_KEY}" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Sales Qualifier",
        "systemPrompt": "You are a friendly sales assistant for Acme Corp. Your job is to understand the prospect'\''s needs, qualify them based on budget and timeline, and schedule a demo if they are a good fit.",
        "goal": "Qualify inbound leads and book demo meetings",
        "language": "English",
        "instructions": "Always greet by name. Ask open-ended questions. Never discuss competitor pricing."
      }'
    ```

    ```python Python theme={null}
    agent = requests.post(
        f"{API_URL}/api/agent-config",
        headers={**headers, "Content-Type": "application/json"},
        json={
            "name": "Sales Qualifier",
            "systemPrompt": "You are a friendly sales assistant for Acme Corp...",
            "goal": "Qualify inbound leads and book demo meetings",
            "language": "English",
            "instructions": "Always greet by name. Ask open-ended questions.",
        },
    ).json()

    agent_id = agent["_id"]
    print(f"Created agent: {agent_id}")
    ```

    ```javascript Node.js theme={null}
    const agent = await fetch(`${API_URL}/api/agent-config`, {
      method: "POST",
      headers: { ...headers, "Content-Type": "application/json" },
      body: JSON.stringify({
        name: "Sales Qualifier",
        systemPrompt: "You are a friendly sales assistant for Acme Corp...",
        goal: "Qualify inbound leads and book demo meetings",
        language: "English",
        instructions: "Always greet by name. Ask open-ended questions.",
      }),
    }).then(r => r.json());

    const agentId = agent._id;
    ```
  </CodeGroup>

  ### Customize the system prompt and instructions

  The **system prompt** is sent to the LLM as the system message for every conversation turn. It defines the agent's persona, context, and behavioral rules. The **instructions** field provides additional guidance that supplements the system prompt.

  Tips for writing effective prompts:

  * Be specific about the agent's role and company context
  * Define the tone (formal, friendly, consultative)
  * List what the agent should and should not discuss
  * Include example phrases if you want a particular style

  <CodeGroup>
    ```bash curl theme={null}
    curl -X PUT "${API_URL}/api/agent-config/${AGENT_ID}" \
      -H "X-API-Key: ${API_KEY}" \
      -H "Content-Type: application/json" \
      -d '{
        "systemPrompt": "You are Alex, a senior sales consultant at Acme Corp. You help prospects understand how our AI platform can save them 10+ hours per week on lead qualification. You are warm, knowledgeable, and concise. Never make up features that do not exist.",
        "instructions": "1. Always use the prospect'\''s first name.\n2. Reference their industry when possible.\n3. If they mention a competitor, acknowledge it positively and pivot to our strengths.\n4. End every message with a question to keep the conversation going."
      }'
    ```

    ```python Python theme={null}
    requests.put(
        f"{API_URL}/api/agent-config/{agent_id}",
        headers={**headers, "Content-Type": "application/json"},
        json={
            "systemPrompt": "You are Alex, a senior sales consultant at Acme Corp...",
            "instructions": "1. Always use the prospect's first name.\n2. Reference their industry when possible.",
        },
    )
    ```

    ```javascript Node.js theme={null}
    await fetch(`${API_URL}/api/agent-config/${agentId}`, {
      method: "PUT",
      headers: { ...headers, "Content-Type": "application/json" },
      body: JSON.stringify({
        systemPrompt: "You are Alex, a senior sales consultant at Acme Corp...",
        instructions: "1. Always use the prospect's first name.\n2. Reference their industry when possible.",
      }),
    });
    ```
  </CodeGroup>

  ### Add conversation stages

  Stages define the flow of the conversation. Each stage has a prompt that guides the LLM, transition criteria that determine when to move on, and optional branching via `nextStages`.

  A typical qualification flow looks like:

  1. **Introduction** -- greet and build rapport
  2. **Discovery** -- understand needs, budget, and timeline
  3. **Qualification** -- evaluate fit against your criteria
  4. **Handoff / Close** -- schedule a meeting or politely disengage

  <CodeGroup>
    ```bash curl theme={null}
    curl -X PUT "${API_URL}/api/agent-config/${AGENT_ID}" \
      -H "X-API-Key: ${API_KEY}" \
      -H "Content-Type: application/json" \
      -d '{
        "stages": [
          {
            "id": "intro",
            "name": "Introduction",
            "order": 0,
            "prompt": "Greet the lead by name and introduce yourself. Explain briefly why you are reaching out.",
            "transitionCriteria": "Lead has responded and acknowledged the conversation.",
            "maxMessages": 3,
            "nextStages": [{ "id": "discovery" }]
          },
          {
            "id": "discovery",
            "name": "Discovery",
            "order": 1,
            "prompt": "Ask about their current process, pain points, team size, and budget range.",
            "transitionCriteria": "You have gathered budget, timeline, and primary pain point.",
            "maxMessages": 8,
            "nextStages": [
              { "id": "qualified", "condition": "Good fit" },
              { "id": "close", "condition": "Not a fit" }
            ]
          },
          {
            "id": "qualified",
            "name": "Qualification",
            "order": 2,
            "prompt": "Confirm the lead is a good fit. Propose a demo meeting and ask for availability.",
            "transitionCriteria": "Meeting is scheduled or lead declines.",
            "maxMessages": 5,
            "nextStages": [{ "id": "close" }]
          },
          {
            "id": "close",
            "name": "Close",
            "order": 3,
            "prompt": "Thank the lead for their time. If qualified, confirm next steps. If not, leave the door open for future contact.",
            "transitionCriteria": "Conversation is complete.",
            "maxMessages": 2
          }
        ]
      }'
    ```

    ```python Python theme={null}
    stages = [
        {
            "id": "intro",
            "name": "Introduction",
            "order": 0,
            "prompt": "Greet the lead by name and introduce yourself.",
            "transitionCriteria": "Lead has responded.",
            "maxMessages": 3,
            "nextStages": [{"id": "discovery"}],
        },
        {
            "id": "discovery",
            "name": "Discovery",
            "order": 1,
            "prompt": "Ask about their process, pain points, and budget.",
            "transitionCriteria": "Budget, timeline, and pain point gathered.",
            "maxMessages": 8,
            "nextStages": [
                {"id": "qualified", "condition": "Good fit"},
                {"id": "close", "condition": "Not a fit"},
            ],
        },
        {
            "id": "qualified",
            "name": "Qualification",
            "order": 2,
            "prompt": "Confirm fit and propose a demo meeting.",
            "transitionCriteria": "Meeting scheduled or declined.",
            "maxMessages": 5,
            "nextStages": [{"id": "close"}],
        },
        {
            "id": "close",
            "name": "Close",
            "order": 3,
            "prompt": "Thank the lead and confirm next steps.",
            "transitionCriteria": "Conversation complete.",
            "maxMessages": 2,
        },
    ]

    requests.put(
        f"{API_URL}/api/agent-config/{agent_id}",
        headers={**headers, "Content-Type": "application/json"},
        json={"stages": stages},
    )
    ```

    ```javascript Node.js theme={null}
    const stages = [
      {
        id: "intro",
        name: "Introduction",
        order: 0,
        prompt: "Greet the lead by name and introduce yourself.",
        transitionCriteria: "Lead has responded.",
        maxMessages: 3,
        nextStages: [{ id: "discovery" }],
      },
      {
        id: "discovery",
        name: "Discovery",
        order: 1,
        prompt: "Ask about their process, pain points, and budget.",
        transitionCriteria: "Budget, timeline, and pain point gathered.",
        maxMessages: 8,
        nextStages: [
          { id: "qualified", condition: "Good fit" },
          { id: "close", condition: "Not a fit" },
        ],
      },
      {
        id: "qualified",
        name: "Qualification",
        order: 2,
        prompt: "Confirm fit and propose a demo meeting.",
        transitionCriteria: "Meeting scheduled or declined.",
        maxMessages: 5,
        nextStages: [{ id: "close" }],
      },
      {
        id: "close",
        name: "Close",
        order: 3,
        prompt: "Thank the lead and confirm next steps.",
        transitionCriteria: "Conversation complete.",
        maxMessages: 2,
      },
    ];

    await fetch(`${API_URL}/api/agent-config/${agentId}`, {
      method: "PUT",
      headers: { ...headers, "Content-Type": "application/json" },
      body: JSON.stringify({ stages }),
    });
    ```
  </CodeGroup>

  ### Set up guardrails

  Guardrails protect your brand and keep conversations safe. Configure them based on your use case:

  | Setting                    | Description                                             | Default    |
  | -------------------------- | ------------------------------------------------------- | ---------- |
  | `maxTotalMessages`         | Hard cap on total messages per conversation             | 40         |
  | `inactivityTimeoutMinutes` | Auto-close after N minutes of silence                   | 1440 (24h) |
  | `forbiddenTopics`          | Comma-separated topics the agent must refuse to discuss | empty      |
  | `escalationTriggers`       | Comma-separated phrases that trigger human handoff      | empty      |

  <CodeGroup>
    ```bash curl theme={null}
    curl -X PUT "${API_URL}/api/agent-config/${AGENT_ID}" \
      -H "X-API-Key: ${API_KEY}" \
      -H "Content-Type: application/json" \
      -d '{
        "guardrails": {
          "maxTotalMessages": 30,
          "inactivityTimeoutMinutes": 720,
          "forbiddenTopics": "competitor pricing, internal roadmap, legal advice",
          "escalationTriggers": "speak to a human, talk to manager, file a complaint"
        }
      }'
    ```

    ```python Python theme={null}
    requests.put(
        f"{API_URL}/api/agent-config/{agent_id}",
        headers={**headers, "Content-Type": "application/json"},
        json={
            "guardrails": {
                "maxTotalMessages": 30,
                "inactivityTimeoutMinutes": 720,
                "forbiddenTopics": "competitor pricing, internal roadmap, legal advice",
                "escalationTriggers": "speak to a human, talk to manager, file a complaint",
            }
        },
    )
    ```

    ```javascript Node.js theme={null}
    await fetch(`${API_URL}/api/agent-config/${agentId}`, {
      method: "PUT",
      headers: { ...headers, "Content-Type": "application/json" },
      body: JSON.stringify({
        guardrails: {
          maxTotalMessages: 30,
          inactivityTimeoutMinutes: 720,
          forbiddenTopics: "competitor pricing, internal roadmap, legal advice",
          escalationTriggers: "speak to a human, talk to manager, file a complaint",
        },
      }),
    });
    ```
  </CodeGroup>

  <Warning>
    Setting `maxTotalMessages` too low (below 10) may prevent the agent from completing the qualification flow. Test with real conversations before deploying to production.
  </Warning>

  ### Attach knowledge bases

  Knowledge bases give your agent access to company-specific information via RAG (Retrieval-Augmented Generation). Upload documents first through the Knowledge Base API, then attach them to your agent.

  <CodeGroup>
    ```bash curl theme={null}
    # List knowledge bases available in your account
    curl "${API_URL}/api/agent-config/knowledge/documents" \
      -H "X-API-Key: ${API_KEY}"

    # Attach a knowledge base to the agent
    curl -X POST "${API_URL}/api/agent-config/${AGENT_ID}/knowledge-bases/${KB_ID}" \
      -H "X-API-Key: ${API_KEY}"

    # Verify attached knowledge bases
    curl "${API_URL}/api/agent-config/${AGENT_ID}/knowledge-bases" \
      -H "X-API-Key: ${API_KEY}"
    ```

    ```python Python theme={null}
    # Attach a knowledge base
    requests.post(
        f"{API_URL}/api/agent-config/{agent_id}/knowledge-bases/{kb_id}",
        headers=headers,
    )

    # List attached knowledge bases
    kbs = requests.get(
        f"{API_URL}/api/agent-config/{agent_id}/knowledge-bases",
        headers=headers,
    ).json()
    print(f"Attached KBs: {len(kbs)}")
    ```

    ```javascript Node.js theme={null}
    // Attach a knowledge base
    await fetch(`${API_URL}/api/agent-config/${agentId}/knowledge-bases/${kbId}`, {
      method: "POST",
      headers,
    });

    // List attached knowledge bases
    const kbs = await fetch(`${API_URL}/api/agent-config/${agentId}/knowledge-bases`, {
      headers,
    }).then(r => r.json());
    console.log(`Attached KBs: ${kbs.length}`);
    ```
  </CodeGroup>

  <Info>
    You can attach multiple knowledge bases to a single agent. The agent searches across all attached bases when retrieving context for a response.
  </Info>

  ### Test with the playground

  Before deploying your agent in a campaign, test it using the built-in playground. Navigate to **Bot > Playground** in the dashboard, select your agent, and simulate a conversation. The playground shows the full LLM input (system prompt + RAG context + conversation history) so you can debug prompt behavior.

  Key things to verify during testing:

  * The agent introduces itself correctly and uses the right tone
  * Stage transitions happen at the right moments
  * Guardrails trigger when expected (try forbidden topics and escalation phrases)
  * Knowledge base answers are accurate and relevant
  * The agent stays on-topic and does not hallucinate
</Steps>

## Monitoring agent performance

Once your agent is live, track its effectiveness using the stats endpoint:

<CodeGroup>
  ```bash curl theme={null}
  curl "${API_URL}/api/agent-config/${AGENT_ID}/stats" \
    -H "X-API-Key: ${API_KEY}"
  ```

  ```python Python theme={null}
  stats = requests.get(
      f"{API_URL}/api/agent-config/{agent_id}/stats",
      headers=headers,
  ).json()

  print(f"Total conversations: {stats['totalConversations']}")
  print(f"Qualification rate: {stats['qualificationRate']}%")
  print(f"Response rate: {stats['responseRate']}%")
  ```

  ```javascript Node.js theme={null}
  const stats = await fetch(`${API_URL}/api/agent-config/${agentId}/stats`, {
    headers,
  }).then(r => r.json());

  console.log(`Total conversations: ${stats.totalConversations}`);
  console.log(`Qualification rate: ${stats.qualificationRate}%`);
  console.log(`Response rate: ${stats.responseRate}%`);
  ```
</CodeGroup>

The stats response includes:

| Field                | Description                                            |
| -------------------- | ------------------------------------------------------ |
| `totalConversations` | Total conversations using this agent                   |
| `qualifiedLeads`     | Number of leads the agent qualified                    |
| `qualificationRate`  | Percentage of conversations resulting in qualification |
| `responseRate`       | Percentage of conversations where the lead replied     |

## Next steps

<CardGroup cols={2}>
  <Card title="Launch a Campaign" icon="rocket" href="/guides/launch-first-campaign">
    Use your configured agent to run automated outreach at scale.
  </Card>

  <Card title="Knowledge Base API" icon="book" href="/api-reference/knowledge-bases/list-knowledge-bases">
    Upload and manage documents for RAG-powered agent responses.
  </Card>

  <Card title="Agent Config API Reference" icon="code" href="/api-reference/agent-config/list-agents">
    Full API reference for all agent configuration endpoints.
  </Card>

  <Card title="Roles & Permissions" icon="lock" href="/roles-permissions">
    Understand which roles can create and edit agent configurations.
  </Card>
</CardGroup>
