Close Menu
    What's Hot

    How to Build a Conversational AI Assistant in Salesforce with Claude

    September 25, 2026

    What Is Salesforce AIforce? What’s Live, What’s Beta, and What It Means for Your Org

    September 23, 2026

    Dreamforce 2026 Admin Keynote Recap: The Announcements Every Admin Should Know

    September 21, 2026

    Subscribe to Updates

    Get the latest creative news from FooBar about art, design and business.

    Facebook X (Twitter) Instagram
    Facebook Instagram LinkedIn WhatsApp Telegram
    Salesforce TrailSalesforce Trail
    • Home
    • Insights & Trends
    • Salesforce News
    • Specialized Career Content
      • Salesforce
      • Administrator
      • Salesforce AI
      • Developer
      • Consultant
      • Architect
      • Designer
    • About Us
    • Contact Us
    Salesforce TrailSalesforce Trail
    Home - Salesforce AI - How to Build a Conversational AI Assistant in Salesforce with Claude
    Salesforce AI

    How to Build a Conversational AI Assistant in Salesforce with Claude

    Muhammad ZohaibBy Muhammad ZohaibSeptember 25, 202612 Mins Read
    Facebook LinkedIn Telegram WhatsApp
    Build a Conversational AI Assistant in Salesforce with Claude
    Share
    Facebook LinkedIn Email Telegram WhatsApp Copy Link Twitter

    Every week I used to get the same two messages. One rep wanted me to pull “all the opportunities closing this month” into a list. Another asked why creating a single Lead took five clicks and three page loads. Neither is a hard problem. Together, they’re the reason I built Orbit.

    Orbit is a chatbot that lives inside Salesforce. You type a question or request in plain English, and it answers, queries, or creates a record for you – across Lead, Contact, Opportunity, Case, and eight other objects. It runs on a Lightning Web Component front end, with Apex doing the actual thinking, Claude AI handling language understanding, and n8n handling writing the record back to Salesforce.

    This walkthrough covers how it’s put together: the Apex routing logic, the Claude API call, the n8n workflow, the security decisions, and a few things I’d do differently starting over. None of it is AI magic. Most of it is ordinary Apex doing ordinary things, with the model called in only where it earns its place.

    Orbit on an Account record
    record - a question gets answered without the user leaving the page they're already on.

    Table of Contents

    Architecture at a glance

    Three parts, each with one job.

    • The LWC is the mouth and ears. It shows messages and captures what the user types. It makes no decisions.
    • Apex is the brain. Every message runs through a routing layer before anything else happens. That routing is deterministic – plain conditional logic, not the model – and it decides whether a message needs Claude at all.
    • Claude and n8n are the specialists. Claude handles language understanding and response formatting. n8n handles the actual record write through Salesforce’s REST API.

    That separation matters more than it first sounds. There’s a clear line between “the AI understood the request” and “the AI is allowed to act on Salesforce data.” Claude proposes. Apex decides. Hold onto that idea, because it shapes every decision that follows.

    Architecture flow diagram
    The LWC captures it, Apex routes it deterministically, and only unmatched messages reach Claude before the result returns to the chat window.

    Setting up the Salesforce side

    Before any Apex runs, two pieces of configuration need to exist in your org.

    Named Credential and External Credential, for calling Claude

    Salesforce reworked how authenticated callouts are configured a while back. Legacy Named Credentials still exist, but they’re deprecated and, per Salesforce’s own documentation, scheduled to be discontinued in a future release. The current model splits the job in two: an External Credential holds the authentication, and a Named Credential points at the endpoint. Here’s the setup that works today.

    First, the External Credential:

    1. Go to Setup, then Named Credentials, then the External Credentials tab, then New.
    2. Give it a label like Claude_Auth and set Authentication Protocol to Custom.
    3. Save, then open it and add a Principal (Identity Type: Named Principal, Sequence Number 1). Under Authentication Parameters, add one named ApiKey and paste your Claude API key as the value.
    4. Add a Custom Header: Name x-api-key, Value {!$Credential.Claude_Auth.ApiKey}.

    Then, the Named Credential:

    1. Back on the Named Credentials tab, click New.
    2. Label it Claude_API and set the URL to https://api.anthropic.com.
    3. Link it to the Claude_Auth External Credential you just made.
    4. Save.

    The last step is access. Add the External Credential to a permission set (via a Principal Access mapping) and assign that permission set to the users who’ll use Orbit. This is the piece people miss – access to the Apex class is not the same as access to the credential, and skipping it produces an authentication error on the very first callout.

    Named Credential Example

    One habit worth stating plainly: the API key lives only in the External Credential. It never touches Apex code, a static resource, a custom setting, or a comment in a class file. If you ever pair with someone or paste code into a chat for help, that’s exactly where a key can accidentally end up. Treat anything pasted outside your org as compromised, and rotate it.

    🔍 Read More: Dreamforce 2026 Admin Keynote Recap: The Announcements Every Admin Should Know

    Talking to Claude: the actual API call

    Once the credential exists, calling Claude from Apex is a fairly ordinary HTTP callout:

    				
    					HttpRequest req = new HttpRequest();
    req.setEndpoint('callout:Claude_API/v1/messages');
    req.setMethod('POST');
    req.setHeader('Content-Type', 'application/json');
    req.setHeader('anthropic-version', '2023-06-01');
    req.setBody(JSON.serialize(new Map<String, Object>{
        'model' => 'claude-haiku-4-5-20251001',
        'max_tokens' => 300,
        'system' => routingSystemPrompt,
        'messages' => conversationHistory
    }));
    HttpResponse res = new Http().send(req);
    				
    			

    A couple of details trip people up here. Claude uses the x-api-key header, not Authorization: Bearer, which is why the header is stored in the External Credential rather than in this code. The anthropic-version header and the max_tokens field are required on every request; omit either, and the call fails. If you want the current version string and the latest model names, consult the Claude API reference rather than trusting a value copied from a blog post.

    The system prompt is where the instruction-following happens. Orbit’s routing prompt tells Claude to return exactly one thing: a small JSON object with a type field, and nothing else. No explanation, no markdown, no extra text. A typical response looks like this:

    				
    					{"type":"SF_QUERY","object":"Opportunity","accountName":"Acme Corp","isCount":false,"filterField":null,"filterValue":null}
    				
    			

    Apex parses that and reads the type field to determine what happens next. SF_QUERY and SF_COUNT execute a SOQL query. SF_HELP and KNOWLEDGE return plain-text answers. WEB_SEARCH calls a search API. CHAT is just conversation. Claude never runs a query itself and never accesses Salesforce data directly. It only tells Apex what kind of request this is, and Apex decides what to do.

    A routing layer that’s predictable, not psychic

    Every incoming message runs through a short checklist in Apex before anything else happens:

    1. Is the conversation midway through capturing a visitor lead, and does this message look like an answer rather than a new question? Continue the lead-capture flow.
    2. Does the message contain a create-style keyword – “create,” “add a,” “new” – next to a recognizable object name, including common typos like “crate” or “creaet”? Start record collection. No AI call happens here at all.
    3. Is the conversation midway through collecting fields for a record? Continue from the state stored in the last message.
    4. Otherwise, send the message to Claude and let the typed JSON response decide.
    				
    					if (mode == 'COLLECTING_LEAD' && !isRealQuestion(input)) {
        return continueLeadCapture(input, history);
    }
    String targetObject = detectCreateIntent(input);
    if (targetObject != null) {
        return startRecordCollection(targetObject);
    }
    if (mode == 'COLLECTING_RECORD') {
        return continueRecordCollection(input, history);
    }
    				
    			

    I used to describe step two as “100% reliable.” An editor pushed back, and they were right to. What’s actually true is narrower and more honest: because the create-intent check is plain keyword matching, not a model making a judgment call, it behaves the same way every time given the same input. That’s what deterministic means here – predictable, not infallible. If someone phrases a request in a way the keyword list doesn’t cover, like “I’d like a new one of these please,” it falls through to Claude instead of silently doing the wrong thing. A soft failure, not a guarantee.

    🔍 Read More: What Is Salesforce AIforce? What’s Live, What’s Beta, and What It Means for Your Org

    Collecting a record, one field at a time

    Once Orbit knows it’s creating a Lead or any supported object, it asks for the required fields first, one small group at a time, and only asks for optional fields once the required ones are filled. A typo in an email address doesn’t restart the conversation. It just re-asks that one field.

    Orbit mid-conversation
    Capturing a lead through plain back-and-forth — name, then email, then phone — instead of a form, re-asking only the field that needs fixing

    The tricky part is state. A Lightning Web Component doesn’t have a natural place to store “we’ve collected the last name and company, still need email.” Orbit handles this by writing a small tag into its own reply:

    				
    					RCSTATE:Lead:Email,City:{"LastName":"Khan","Company":"Acme Retail"}:RCEND
    				
    			

    The JavaScript layer retains the entire message (including the tag) in the conversation history and sends it back to Apex on the next turn, but strips out the tag before displaying anything to the user. Apex reads the bot’s last message, identifies the tag, and resumes the process from where it left off. This approach differs from using a dedicated session object. The advantages of this method are: no custom objects, no cleanup jobs, and no residual state (data) once the conversation ends.

    Once all required fields are populated, Orbit displays a summary in plain language and requests confirmation before writing anything to Salesforce; nothing is created silently.

    Orbit assistant

    Why the write goes through n8n, not straight Apex DML

    This is the question I get asked most, so let me be direct. Apex could absolutely do the insert directly, and for a smaller project I’d probably start there. Orbit routes the final write through n8n instead, for two reasons.

    The first is decoupling. The moment you want to add an update or a delete, send a Slack message when a big Opportunity is created, or write to a second system alongside Salesforce, that logic lives in n8n and doesn’t touch Apex. Apex’s job stays fixed: figure out what the user wants, validate it, hand off a clean payload.

    The second is iteration speed. Changing an n8n workflow doesn’t require an Apex deployment. If I want to add a field mapping or a retry step, I edit the workflow, and it’s live within a minute. That’s a real advantage while a project is still moving fast.

    The tradeoff is honest, too. It’s one more moving part, one more thing that can be temporarily down, one more system to secure. For a simple, stable “just insert this Lead” use case, direct Apex DML is simpler and has fewer places to fail. I’d choose n8n again for Orbit because I knew I wanted update, delete, and multi-system writes down the road. But it isn’t free, and it isn’t the right call for every project.

    Here’s roughly what the n8n workflow looks like, in three nodes:

    1. Webhook – receives the JSON payload from Apex.
    2. HTTP Request – posts to Salesforce’s REST API at /services/data/v59.0/sobjects/{object}, authenticated through a Salesforce OAuth2 credential configured once inside n8n.
    3. Respond to Webhook – sends a success or failure status back to Apex, which Apex turns into a plain message for the user.

    n8n automation workflow

    The payload Apex sends to the webhook looks like this:

    				
    					{
      "object": "Lead",
      "fields": { "LastName": "Khan", "Company": "Acme Retail" },
      "source": "OrbitChatbot",
      "timestamp": "2026-09-15T10:22:00Z"
    }
    
    				
    			

    n8n’s HTTP Request node uses the object name and fields to build the actual Salesforce API call. If the insert fails, whether because a required field is missing or a validation rule on the object catches something Orbit doesn’t know about, that failure comes back through the same path, and Orbit tells the user something went wrong instead of claiming success it can’t back up.

    Security: what actually matters here

    Salesforce permissions. Orbit’s Apex class is declared with sharing, so it runs in the context of the logged-in user. Someone can’t query or create records they don’t already have access to just by asking the bot nicely. It is important to understand what that keyword does: while ‘with sharing’ enforces record-level sharing, it does not automatically enforce field-level security—a point Salesforce clearly states in its Apex sharing documentation. Therefore, ensure that the field-level access is correctly configured in the profiles or permission sets used for the objects to which Orbit writes data. Don’t assume a chatbot is exempt from your existing security model. Test it the way you’d test any other integration user.

    Data sent to Claude. Claude only ever sees the current message and a trimmed slice of conversation history – never a raw SOQL result dumped wholesale, never more Salesforce data than the specific question needs. When Orbit summarizes a list of records, only the fields relevant to that query go into the prompt, not every field on the object.

    Validating AI-generated values. Claude determines the intent, but it cannot write field values ​​directly to Salesforce without verification. Every value: email, phone, date, amount passes through validation before it’s stored. An email needs an @ and a real-looking domain, a phone number needs enough digits and not too many letters, and so on. If a value fails validation, Orbit asks again instead of saving something bad. Treat anything a language model produces as user input, not as trusted system input, even when it’s technically your own AI saying it.

    Conversation state. The state tags described earlier live only in the browser’s memory for that session – not in a Salesforce object, not in a cookie, nowhere durable. Refresh the page, and it’s gone. That’s a deliberate tradeoff: less convenience, since you can’t resume a session tomorrow, in exchange for less to secure and nothing lingering in your org’s data model. If you extend Orbit with persistent memory later, that’s the point to think seriously about data retention and consent – not before.

    API keys, one more time. External Credential only. Never in Apex, never in a debug log, never pasted into a chat thread you don’t fully control.

    Final Thoughts

    You don’t have to build all of this at once – and honestly, you shouldn’t. Start with a single Lightning Web Component, one Apex method, and record creation for one object. Lead is the easiest first target. Get the routing checklist behaving predictably before you add a second object or a second intent type.

    Spin it up in your own dev org this week. Wire up the Named Credential, get one clean callout to Claude returning JSON, and let Apex act on it. Once that loop works, everything else is just more objects and more intent types layered on the same shape. If you land on a better way to handle conversation state or routing, I’d genuinely like to hear about it in the Trailblazer Community.

    Salesforce resources

    • Named Credentials and External Credentials (Salesforce Help)
    • Apex Callouts and Named Credentials (Apex Developer Guide)
    • Enforce Sharing Rules in Apex (Apex Developer Guide)
    • Lightning Web Components Basics (Trailhead)
    Muhammad Zohaib
    Muhammad Zohaib
    Salesforce Developer/Admin

    Muhammad Zohaib is a Salesforce Developer and Admin with 3+ years of experience across Sales Cloud, Service Cloud, and CPQ, building scalable CRM solutions for teams ranging from healthcare providers to B2B sales organizations. He works extensively in Apex, Lightning Web Components, and Flow, and has hands-on experience integrating Salesforce with third-party platforms including Claude AI and n8n.

      This author does not have any more posts.
    AI agents AI Assistant Apex Claude AI n8n salesforce Salesforce AI
    Share. Facebook LinkedIn Email Telegram WhatsApp Copy Link

    Related Posts

    What Is Salesforce AIforce? What’s Live, What’s Beta, and What It Means for Your Org

    September 23, 2026

    Dreamforce 2026 Admin Keynote Recap: The Announcements Every Admin Should Know

    September 21, 2026

    Salesforce AI Context Layer: Stop Re-Explaining Your Org to AI

    September 18, 2026
    Add A Comment
    Leave A Reply Cancel Reply

    Advertise with Salesforce Trail
    Connect with Salesforce Trail Community
    Latest Post

    Salesforce Consultant Career Path: From Junior Consultant to Practice Lead

    March 25, 2026

    How to Hire Salesforce Consultants: Practical Tips Every Business Should Know

    February 19, 2026

    6 Proven Principles to Drive Faster Salesforce CRM Adoption

    November 3, 2025

    Driving Revenue Efficiency with Sales Cloud in Product Companies

    October 30, 2025
    Top Review
    Designer

    Customizing Salesforce: Tailor the CRM to Fit Your Business Needs

    By Vivek KumarAugust 6, 20240

    Salesforce is an adaptable, powerful customer relationship management (CRM) software that businesses can customize, and…

    Sales Professional

    Unlock 10 Powerful Sales Pitches to Boost Your Revenue by 30X

    By Mayank SahuJuly 4, 20240

    Sales is a very competitive arena, and it is followed by one must have a…

    Salesforce Trail
    Facebook X (Twitter) Instagram LinkedIn WhatsApp Telegram
    • Home
    • About Us
    • Write For Us
    • Guest Bloggers
    • Privacy Policy
    • Advertise With Us
    • Contact Us
    © 2026 SalesforceTrail.com All Right Reserved by SalesforceTrail

    Type above and press Enter to search. Press Esc to cancel.