For AI agents and developers: machine-readable getting-started guide and automated Salesforce org setup (/llms.txt).

Experience Site

Experience Site 45 min

Quick Deploy an Agent to an Experience Site

Outcome

A working chat widget on your Experience Site where visitors can message your Agentforce Service Agent in real-time.

When complete, you'll have:

  • An Experience Cloud site with the Enhanced Chat component
  • A Messaging Channel routed directly to your Service Agent
  • Verified end-to-end message flow from widget to agent

This guide uses SF CLI commands as the primary method. REST API and browser fallbacks are included for each step.

Architecture

When a visitor opens the chat widget on your Experience Site, the message flows through a chain of Salesforce objects:

Click a node to jump to its configuration step.

The key routing link is SessionHandlerId on the MessagingChannel — it points directly to your agent's BotDefinition.Id. When a message arrives, Salesforce routes it to the handler specified by this ID.

Configure Your Variables

Update these variables with your values and they will be substituted in the code blocks below.

Salesforce org alias or username{{ORG_ALIAS}}
Service Agent developer name{{AGENT_NAME}}
Experience Cloud site name{{SITE_NAME}}
Messaging Channel developer name{{CHANNEL_NAME}}
Embedded Service Deployment name{{DEPLOYMENT_NAME}}
Experience Site domain prefix{{DOMAIN_PREFIX}}
Salesforce instance URL{{INSTANCE_URL}}
OAuth access token{{ACCESS_TOKEN}}
OAuth client ID (Consumer Key){{CLIENT_ID}}
OAuth client secret (Consumer Secret){{CLIENT_SECRET}}
Agent API base URL{{AGENT_API_BASE_URL}}
Agent ID{{AGENT_ID}}

1. Verify Your Starting Point

Confirm your agent exists and your org is ready.

Confirm your Service Agent exists and is active

Before building the routing chain, verify your Agentforce Service Agent is deployed and active in the target org.

1
2
3
sf data query \
  --target-org <your-org-alias> \
  --query "SELECT Id, DeveloperName, MasterLabel, AgentType FROM BotDefinition WHERE DeveloperName='Reservation_Agent' AND IsActive=true"

Verify the agent is active:

Expected result: One record returned with a valid Id.

If no record is returned, activate your agent in Agent Builder before proceeding.

The agent must have AgentType = 'Bot' or AgentType = 'ServiceAgent'. Other agent types cannot be routed via Enhanced Chat.

Authenticate and verify org access

Ensure you have admin access to the target org and the CLI is connected.

1
2
sf org login web --alias <your-org-alias> --instance-url https://login.salesforce.com
sf org display --target-org <your-org-alias> --verbose

Verify org access:

Expected result: Org display shows your username and instance URL without errors.

2. Build the Routing Chain

Create the queue, channel, and deployment that route messages to your agent.

Create a messaging queue for fallback routing

The queue handles messages when the agent is unavailable. Even with direct agent routing, a fallback queue is required.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Check if queue exists
sf data query --target-org <your-org-alias> \
  --query "SELECT Id FROM Group WHERE Type='Queue' AND DeveloperName='AgentforceChannel_Queue'"

# If not found, create via Metadata API
cat > queue-metadata.xml << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<Queue xmlns="http://soap.sforce.com/2006/04/metadata">
    <fullName>AgentforceChannel_Queue</fullName>
    <name>AgentforceChannel Queue</name>
    <queueSobject>
        <sobjectType>MessagingSession</sobjectType>
    </queueSobject>
</Queue>
EOF

sf project deploy start --target-org <your-org-alias> --metadata Queue:AgentforceChannel_Queue

Verify queue exists:

Expected result: One queue record returned.

Create a Messaging Channel routed to your agent

The Messaging Channel is the key routing component. Setting SessionHandlerId to your agent's BotDefinition.Id enables direct routing.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Get the Bot ID and Queue ID
BOT_ID=$(sf data query --target-org <your-org-alias> --json \
  --query "SELECT Id FROM BotDefinition WHERE DeveloperName='Reservation_Agent'" \
  | jq -r '.result.records[0].Id')

QUEUE_ID=$(sf data query --target-org <your-org-alias> --json \
  --query "SELECT Id FROM Group WHERE Type='Queue' AND DeveloperName='AgentforceChannel_Queue'" \
  | jq -r '.result.records[0].Id')

# Create or update MessagingChannel via Apex
sf apex run --target-org <your-org-alias> << EOF
MessagingChannel channel = new MessagingChannel();
channel.DeveloperName = 'AgentforceChannel';
channel.MasterLabel = 'AgentforceChannel';
channel.MessageType = 'EmbeddedMessaging';
channel.MessagingPlatformKey = 'AgentforceChannel-' + String.valueOf(Crypto.getRandomLong());
channel.IsActive = true;
channel.SessionHandlerId = '$BOT_ID';
channel.FallbackQueueId = '$QUEUE_ID';
insert channel;
System.debug('Created MessagingChannel: ' + channel.Id);
EOF

Verify channel configuration:

Expected result: One record with IsActive=true and SessionHandlerId matching your BotDefinition.Id.

If SessionHandlerId is not available in your org's API version, you'll need to configure routing through a Flow instead. See the Troubleshooting section.

Create an Embedded Service Deployment

The deployment packages the channel configuration and generates the code snippet for your site.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Create EmbeddedServiceConfig via Tooling API
cat > esd-metadata.json << 'EOF'
{
  "FullName": "AgentforceDeployment",
  "Metadata": {
    "masterLabel": "AgentforceDeployment",
    "deploymentFeature": "EmbeddedMessaging",
    "deploymentType": "Web",
    "isEnabled": true,
    "embeddedServiceMessagingChannel": {
      "isEnabled": true,
      "messagingChannel": "AgentforceChannel"
    }
  }
}
EOF

sf data create record --target-org <your-org-alias> --use-tooling-api \
  --sobject EmbeddedServiceConfig --values "$(cat esd-metadata.json)"

Verify deployment exists:

Expected result: One deployment record returned.

3. Create the Experience Site

Stand up the site and add the chat widget component.

Create an Experience Cloud site

The Experience Site hosts your public-facing pages. We'll use the Customer Service template which includes Enhanced Chat support.

1
2
3
4
5
sf community create \
  --target-org <your-org-alias> \
  --name "AgentforceSite" \
  --template-name "Customer Service" \
  --url-path-prefix "mycompany"

Verify site exists:

Expected result: One site record returned.

Add the Enhanced Chat component to your site

The component renders the chat widget. It connects to your deployment configuration.

1
2
3
4
5
6
7
8
# Retrieve the site bundle
sf project retrieve start \
  --target-org <your-org-alias> \
  --metadata "DigitalExperienceBundle:site/AgentforceSite" \
  --target-metadata-dir ./site-bundle

# The component must be added via Experience Builder (browser)
# See Browser method below

Verify component placement:

Expected result: The Enhanced Chat component appears in Experience Builder on the Home page.

Publish the Experience Site

Publishing makes the site accessible at its public URL.

1
2
3
sf community publish \
  --target-org <your-org-alias> \
  --name "AgentforceSite"

Verify site is published:

Expected result: Status = 'Live'.

4. Deploy & Verify

Test the full flow from widget to agent.

Get your site URL

Find the public URL where your chat widget is live.

1
2
3
sf org display --target-org <your-org-alias> --verbose --json | jq -r '.result.instanceUrl' | \
  sed 's/\.my\.salesforce\./.my.site./'
# Append: /mycompany

Verify site URL:

Expected result: You have a URL like https://yourorg.my.site.com/{{DOMAIN_PREFIX}}.

Test the chat widget

Open your site and verify the widget appears and can send messages.

1
2
# Open the site in your browser
open "https://$(sf org display --target-org <your-org-alias> --json | jq -r '.result.instanceUrl' | sed 's/https:\/\///' | sed 's/\.my\.salesforce\./.my.site./').com/mycompany"

Verify chat functionality:

Expected result: Chat widget visible, message sends successfully, agent responds.

Verify message routing to agent

Confirm messages are being routed to your agent by checking MessagingSession and AgentWork records.

1
2
3
4
5
6
7
# Check recent MessagingSessions
sf data query --target-org <your-org-alias> \
  --query "SELECT Id, Status, AgentType, OwnerId, CreatedDate FROM MessagingSession ORDER BY CreatedDate DESC LIMIT 5"

# Check AgentWork records
sf data query --target-org <your-org-alias> \
  --query "SELECT Id, WorkItemId, BotId, RoutingType, CreatedDate FROM AgentWork ORDER BY CreatedDate DESC LIMIT 5"

Verify messaging session:

Expected result: Recent MessagingSession exists with Status = 'Active' or 'Ended'.

Troubleshooting

Widget doesn't appear on site

  1. Verify the Embedded Service Deployment is published
  2. Check that the Enhanced Chat component is on the Home page
  3. Republish the Experience Site after adding the component
  4. Clear browser cache and try incognito mode

Messages not reaching agent

  1. Verify SessionHandlerId is set on the MessagingChannel
  2. Confirm the agent is Active (not Draft)
  3. Check that the Messaging Channel is Active
  4. Verify the fallback queue is properly configured

SessionHandlerId field not available

Some org configurations don't expose this field via API. Options:

  1. Configure routing via Omni-Channel Flow instead
  2. Use Setup UI to configure direct agent routing
  3. Contact Salesforce support for API access

Site publish fails

  1. Check for unpublished components or missing required fields
  2. Review the publish error in Setup → Digital Experiences
  3. Ensure you have admin permissions

Definition of Done

Definition of Done:

  • Chat widget launcher visible on Experience Site
  • User can open chat and send a message
  • Agent responds to the message
  • MessagingSession record created with correct routing
  • AgentWork record shows message assigned to agent