Here’s something exciting — Salesforce shipped the Agentforce Conversation Client (ACC) API, and it lets you programmatically open, close, and prompt your Agentforce agent directly from a Lightning Web Component.
No more relying on users to find and click the agent panel. No more hoping they type the right thing. Your code does it for them.
What Is It?
One import. Three functions. That’s the whole API:
import { open, close, execute } from 'lightning/accApi';
| Function | What It Does |
|---|---|
open(agentId) |
Opens the Agentforce side panel |
close() |
Closes it |
execute(utterance, agentId) |
Sends a message to the agent |
Think of it as a remote control for the Agentforce chat panel — your LWC decides when it appears, what it says, and when it goes away.
Drop a Button, Start a Conversation
The real power here: you can build LWC components with buttons, drop them onto record pages, home pages, app pages — anywhere Lightning App Builder allows — and each button starts a session with a specific agent and an initial prompt tailored to that context.
import { LightningElement, api } from 'lwc';
import { open, execute } from 'lightning/accApi';
export default class AgentforceConversationButton extends LightningElement {
@api agentId; // Set per-component in App Builder
@api initialPrompt; // The message sent automatically on open
async handleStartConversation() {
// Open the panel for THIS specific agent
await open(this.agentId);
// Fire the initial prompt — user doesn't type a thing
if (this.initialPrompt) {
await execute(this.initialPrompt, this.agentId);
}
}
}
An admin drags this component onto a Case record page, sets the agent ID to their Support Agent, and sets the initial prompt to “Summarize this case and suggest a resolution.” Done. Users click one button and the right agent is already working.
Put a different instance on the Opportunity page pointing to a Sales Agent with “What are the next steps to close this deal?” — same component, different config, completely different agent experience.
A Game-Changer for Orgs With Multiple Agents
This is where the ACC API really shines. Most orgs don’t have just one agent — they have several:
- A Sales Agent for pipeline guidance
- A Support Agent for case resolution
- An HR Agent for employee questions
- An Onboarding Agent for new hire workflows
Before the ACC API, users had to manually open the agent panel and hope they were talking to the right one. Now? You wire each button to a specific agent ID. The user never picks the wrong agent because your UI picks for them.
┌─────────────────────────────────────────────────────────┐
│ Opportunity Record Page │
│ │
│ ┌─────────────────────┐ ┌──────────────────────────┐ │
│ │ Ask Sales Agent │ │ Ask Legal for Review │ │
│ │ agentId: 0Xx...1 │ │ agentId: 0Xx...2 │ │
│ └─────────────────────┘ └──────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Get Competitive Intel │ │
│ │ agentId: 0Xx...3 │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
Each button opens a different agent with a different prompt — all from the same reusable LWC component. The admin configures which agent and which prompt in Lightning App Builder. Zero code changes needed per page.
Architecture: How the LWC Talks to the ACC API
Here’s what’s actually happening under the hood when a user clicks that button:
┌──────────────────────────────────────────────────────────────────┐
│ LIGHTNING PAGE │
│ │
│ ┌────────────────────────────────┐ │
│ │ Your LWC Component │ │
│ │ │ │
│ │ ┌──────────────────────────┐ │ │
│ │ │ "Ask Sales Agent" │ │ │
│ │ └───────────┬──────────────┘ │ │
│ │ │ (click) │ │
│ └──────────────┼─────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────┐ │
│ │ lightning/accApi Module │ │
│ │ (ACC API Listener) │ │
│ │ │ │
│ │ • open(agentId) ─────────┐ │ │
│ │ • execute(utterance) ──┐ │ │ │
│ │ • close() │ │ │ │
│ └──────────────────────────┼──┼───┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────────────────────────────────────────────────────┐│
│ │ AGENTFORCE CONVERSATION PANEL ││
│ │ ││
│ │ Agent Session (agentId: 0Xx...1) ││
│ │ ││
│ │ User (via execute): "What are next steps to close?" ││
│ │ Agent: "Based on this opportunity, I recommend..." ││
│ └──────────────────────────────────────────────────────────────┘│
└──────────────────────────────────────────────────────────────────┘
The flow:
- User clicks the button in your LWC component
- Your JS calls
open(agentId)— this hits the ACC API listener built into the Lightning runtime - The listener opens the Agentforce panel and establishes a session with the specified agent
- Your JS calls
execute(utterance, agentId)— the listener routes the message to the active session - The agent receives the prompt and responds in the side panel
- User sees the response — they’re already in a conversation without having typed anything
The ACC API listener acts as the bridge between your component code and the Agentforce runtime. You never deal with session management, authentication to the agent, or panel rendering — lightning/accApi handles all of that. You just say which agent and what to say.
Open the Agent Panel
Want a button that opens your agent? Done:
import { LightningElement } from 'lwc';
import { open } from 'lightning/accApi';
export default class MyAgentButton extends LightningElement {
async handleClick() {
// That's it. One line. Panel slides open.
await open('0Xx000000000001AAA');
}
}
Prompt the Agent Automatically
Send a message to the agent without the user typing anything:
import { open, execute } from 'lightning/accApi';
async startConversation() {
const agentId = '0Xx000000000001AAA';
// Open the panel
await open(agentId);
// Send a prompt — the agent responds as if the user typed it
await execute('Suggest next steps for this record', agentId);
}
The user sees the panel open and the agent already working on an answer. Zero effort on their part.
Close the Panel
When the conversation is done or you want to clean up the UI:
import { close } from 'lightning/accApi';
async handleClose() {
await close();
}
Real Example: Auto-Open on Record Pages
Here’s a component that fires the moment a user lands on a record page. The agent opens itself and immediately asks “Suggest next steps for this record”:
import { LightningElement, wire, api } from 'lwc';
import { open, execute } from 'lightning/accApi';
import getAgentConfiguration from '@salesforce/apex/AgentforceConversationController.getAgentConfiguration';
export default class AgentforceRecordAssistant extends LightningElement {
@api recordId;
@api defaultUtterance = 'Suggest next steps for this record';
hasAutoOpened = false;
@wire(getAgentConfiguration)
wiredConfig({ data }) {
if (data && !this.hasAutoOpened) {
this.hasAutoOpened = true;
this.autoOpen(data.agentId);
}
}
async autoOpen(agentId) {
try {
await open(agentId);
// Small delay lets the panel fully initialize
await new Promise(resolve => setTimeout(resolve, 500));
// Fire the prompt automatically
await execute(this.defaultUtterance, agentId);
} catch (e) {
// Fail silently — auto-actions shouldn't block the user
console.error('Auto-open failed:', e);
}
}
}
What happens from the user’s perspective:
- They navigate to a record
- The AI panel slides open on its own
- The agent is already responding with next-step suggestions
- They didn’t click anything or type anything
A Few Tips
- Guard against double-opens — Wire adapters can fire more than once. Use a boolean flag to prevent opening the panel twice.
- Add a short delay before
execute()— The panel needs ~500ms to initialize afteropen(). - Track panel state yourself — The API doesn’t have an “isOpen” check, so keep a local boolean.
- One component, many configs — Build a single reusable LWC and let admins set the agent ID and prompt per page in App Builder. Don’t hardcode agent IDs.
That’s It
Three functions. One import. You now have full programmatic control over Agentforce from any LWC.
Build buttons that start conversations with the right agent. Auto-open assistants on page load. Give each page its own agent with its own tailored prompt. For orgs running multiple agents, this is the difference between users fumbling to find help and users getting exactly the right AI assistant at exactly the right moment.
Docs: ACC API Reference