# LabBox

A LabBox is a Salesforce org provisioned through Agentforce Labs with every AI feature already enabled. Einstein, Agentforce, Data Cloud, OmniChannel routing, messaging channels, and an Experience Site with a chat widget are all configured and ready to use the moment you sign in.

No manual setup required. If you want to replicate the same configuration in your own org, each section below includes step-by-step instructions.

> **ℹ️ Already have a LabBox?**: You do not need to enable any of these settings yourself. This page documents what is pre-configured so you can understand the capabilities available to you.

## Core Platform

Einstein, Agentforce, and Data Cloud must be turned on before any AI features work. These are the foundational toggles. Everything else depends on them.

| Setting    | Setup Location         | What it does                                                                                                   |
| ---------- | ---------------------- | -------------------------------------------------------------------------------------------------------------- |
| Einstein   | Einstein Setup         | Enables the Einstein AI platform across the org                                                                |
| Agentforce | Einstein Copilot Setup | Enables the Agentforce agent runtime and Copilot features                                                      |
| Data Cloud | Org Provisioning       | Enables the Customer Data Platform for unified data access and grounding. Provisioning can take 30–60 minutes. |

### Enable it yourself

**Choose one of the following methods:**

#### SF CLI

```bash
# Verify Data Cloud is provisioned
sf data query --target-org {{ORG_ALIAS}} \
  --query "SELECT Id, Name, DurableId FROM Organization LIMIT 1"

# Verify Einstein limits are available
sf org display --target-org {{ORG_ALIAS}} --verbose --json | jq '.result'
```

#### REST API

```bash
# Verify Data Cloud
curl -s "{{INSTANCE_URL}}/services/data/v65.0/query?q=SELECT+Id,Name,DurableId+FROM+Organization+LIMIT+1" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}"

# Verify Einstein
curl -s "{{INSTANCE_URL}}/services/data/v65.0/limits" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" | jq '.EinsteinGenAiStandard'
```

#### Browser Agent

```text
1. Setup → Data Cloud Setup Home → verify "Home Org" shows Org Details
2. Setup → Quick Find → "Einstein Setup" → verify "Turn on Einstein" toggle is active
3. Setup → Quick Find → "Agentforce Agents" → click toggle in top-right to ON
4. Refresh page and confirm toggle persists
```

## API Access

| Setting        | Setup Location       | What it does                                                                   |
| -------------- | -------------------- | ------------------------------------------------------------------------------ |
| SOAP API Login | User Interface Setup | Allows programmatic login via SOAP API, used by CLI tools and backend services |

### Enable it yourself

**Choose one of the following methods:**

#### SF CLI

```bash
# No CLI equivalent. Use Browser Agent
echo "SOAP API Login must be enabled via Setup UI"
```

#### REST API

```bash
# No API equivalent. Use Browser Agent
echo "SOAP API Login must be enabled via Setup UI"
```

#### Browser Agent

```text
1. Setup → Quick Find → "User Interface"
2. Find "Enable SOAP API Login" checkbox
3. Check the box
4. Click "Save"
```

## Einstein Trust Layer

| Setting                       | Setup Location       | What it does                                                                                              |
| ----------------------------- | -------------------- | --------------------------------------------------------------------------------------------------------- |
| Large Language Model Data Masking | Einstein Trust Layer | Disabled to allow larger LLM context. Toggle is set to OFF so sensitive data patterns are not masked in prompts. |

### Enable it yourself

**Choose one of the following methods:**

#### SF CLI

```bash
# No CLI equivalent. Use Browser Agent
echo "Data Masking must be disabled via Setup UI"
```

#### REST API

```bash
# No API equivalent. Use Browser Agent
echo "Data Masking must be disabled via Setup UI"
```

#### Browser Agent

```text
1. Setup → Quick Find → "Einstein Trust"
2. Click "Einstein Trust Layer" (under Einstein → Einstein Generative AI)
3. Go to "Data Masking" tab
4. Turn OFF "Large Language Model Data Masking" toggle
5. Confirm if prompted
```

## Identity Verification

| Setting                                       | Setup Location        | What it does                                                                                 |
| --------------------------------------------- | --------------------- | -------------------------------------------------------------------------------------------- |
| Require identity verification for email changes | Identity Verification | Disabled so that org automation can update user email addresses without triggering verification flows. |

### Enable it yourself

**Choose one of the following methods:**

#### SF CLI

```bash
# No CLI equivalent. Use Browser Agent
echo "Identity Verification must be configured via Setup UI"
```

#### REST API

```bash
# No API equivalent. Use Browser Agent
echo "Identity Verification must be configured via Setup UI"
```

#### Browser Agent

```text
1. Setup → Quick Find → "Identity Verification"
2. Scroll to the "General" section at the bottom
3. Uncheck "Require identity verification for email address changes"
4. Click "Save"
```

## Permissions

A custom **AiAdmin** permission set is created with the following system permissions:

| Permission                | What it grants                               |
| ------------------------- | -------------------------------------------- |
| Manage Agentforce Grids   | Create and manage Agentforce Grid worksheets |
| Manage Agentforce Testing | Run Agent Eval Labs tests against agents     |
| Manage AI Agents          | Create, edit, and publish Agentforce agents  |
| API Enabled               | Programmatic API access for CLI tools and integrations |

The following permission sets are assigned to the org user:

| Permission Set                          | Purpose                                     |
| --------------------------------------- | ------------------------------------------- |
| AiAdmin                                 | AI agent management (see above)             |
| Data Cloud User                         | Access to Data Cloud objects and features   |
| Access Agentforce Optimization          | Agent optimization and performance features |
| Tableau Next Admin                      | Tableau analytics administration            |
| Tableau Next Platform Analyst           | Tableau analytics usage and dashboards      |
| Contact Center Admin                    | Contact center administration               |

> **💡 Tip**: The full list of enabled permission sets also includes AI Workbench, Access Agentforce Default Agent, Agent Presence Status Access, Agentforce Default Admin, Agentforce Reference App, Agentforce Service Agent Configuration, Code Builder User, Contact Center Agent, Contact Center Supervisor, Customer Orders, Data Cloud Architect, Einstein Sales Emails, Prompt Template Manager, Prompt Template User, and Tableau Next Consumer.

### Enable it yourself

**Choose one of the following methods:**

#### SF CLI

```bash
# Create AiAdmin permission set
EXISTING=$(sf data query --target-org {{ORG_ALIAS}} --json \
  --query "SELECT Id FROM PermissionSet WHERE Name='AiAdmin'" \
  | jq -r '.result.totalSize')

if [ "$EXISTING" = "0" ]; then
  sf data create record --target-org {{ORG_ALIAS}} \
    --sobject PermissionSet \
    --values "Name='AiAdmin' Label='AiAdmin' Description='Admin permissions for Agentforce'"
fi

# Deploy system permissions via Metadata API
mkdir -p /tmp/aiadmin-deploy/permissionsets
cat > /tmp/aiadmin-deploy/permissionsets/AiAdmin.permissionset-meta.xml << 'XMLEOF'
<?xml version="1.0" encoding="UTF-8"?>
<PermissionSet xmlns="http://soap.sforce.com/2006/04/metadata">
    <label>AiAdmin</label>
    <description>Admin permissions for Agentforce</description>
    <userPermissions>
        <enabled>true</enabled>
        <name>ManageAgentforceGrids</name>
    </userPermissions>
    <userPermissions>
        <enabled>true</enabled>
        <name>ManageAgentforceTesting</name>
    </userPermissions>
    <userPermissions>
        <enabled>true</enabled>
        <name>ManageAiAgents</name>
    </userPermissions>
    <userPermissions>
        <enabled>true</enabled>
        <name>ApiEnabled</name>
    </userPermissions>
</PermissionSet>
XMLEOF
cat > /tmp/aiadmin-deploy/package.xml << 'XMLEOF'
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>AiAdmin</members>
        <name>PermissionSet</name>
    </types>
    <version>65.0</version>
</Package>
XMLEOF
sf project deploy start --target-org {{ORG_ALIAS}} --source-dir /tmp/aiadmin-deploy

# Assign AiAdmin + Data Cloud User to admin
ADMIN_ID=$(sf data query --target-org {{ORG_ALIAS}} --json \
  --query "SELECT Id FROM User WHERE Profile.Name='System Administrator' AND IsActive=true ORDER BY CreatedDate ASC LIMIT 1" \
  | jq -r '.result.records[0].Id')

PS_ID=$(sf data query --target-org {{ORG_ALIAS}} --json \
  --query "SELECT Id FROM PermissionSet WHERE Name='AiAdmin'" \
  | jq -r '.result.records[0].Id')
sf data create record --target-org {{ORG_ALIAS}} \
  --sobject PermissionSetAssignment \
  --values "PermissionSetId='$PS_ID' AssigneeId='$ADMIN_ID'"

DC_PS_ID=$(sf data query --target-org {{ORG_ALIAS}} --json \
  --query "SELECT Id FROM PermissionSet WHERE Label='Data Cloud User' LIMIT 1" \
  | jq -r '.result.records[0].Id')
sf data create record --target-org {{ORG_ALIAS}} \
  --sobject PermissionSetAssignment \
  --values "PermissionSetId='$DC_PS_ID' AssigneeId='$ADMIN_ID'"
```

#### REST API

```bash
# Create AiAdmin permission set
curl -X POST "{{INSTANCE_URL}}/services/data/v65.0/sobjects/PermissionSet" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" \
  -H "Content-Type: application/json" \
  -d '{"Name":"AiAdmin","Label":"AiAdmin","Description":"Admin permissions for Agentforce","IsOwnedByProfile":false}'

# System permissions require Metadata API. Use SF CLI or Browser Agent

# Assign to admin user
ADMIN_ID=$(curl -s "{{INSTANCE_URL}}/services/data/v65.0/query?q=SELECT+Id+FROM+User+WHERE+Profile.Name='System+Administrator'+AND+IsActive=true+ORDER+BY+CreatedDate+ASC+LIMIT+1" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" | jq -r '.records[0].Id')

PS_ID=$(curl -s "{{INSTANCE_URL}}/services/data/v65.0/query?q=SELECT+Id+FROM+PermissionSet+WHERE+Name='AiAdmin'" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" | jq -r '.records[0].Id')

curl -X POST "{{INSTANCE_URL}}/services/data/v65.0/sobjects/PermissionSetAssignment" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" \
  -H "Content-Type: application/json" \
  -d "{\"PermissionSetId\":\"$PS_ID\",\"AssigneeId\":\"$ADMIN_ID\"}"
```

#### Browser Agent

```text
1. Setup → Quick Find → "Permission Sets" → New
2. Label: AiAdmin, API Name: AiAdmin → Save
3. Click "System Permissions" → Edit
4. Check: Manage Agentforce Grids, Manage Agentforce Testing, Manage AI Agents, API Enabled
5. Save (confirm if prompted)
6. Setup → Quick Find → "Users" → click admin user
7. Hover "Permission Set Assignments" → Edit Assignments
8. Add: AiAdmin, Data Cloud User
9. Save
```

> **✅ Success**: **Verify:** `SELECT Id, Assignee.Name, PermissionSet.Name FROM PermissionSetAssignment WHERE PermissionSet.Name='AiAdmin' AND Assignee.Profile.Name='System Administrator'`. This should return one record.

## Observability & Analytics

These settings enable the full observability stack for agents: monitoring, debugging, and optimization.

| Setting                                  | Setup Location                        | What it does                                           |
| ---------------------------------------- | ------------------------------------- | ------------------------------------------------------ |
| Einstein Audit and Feedback              | Einstein Audit Analytics & Monitoring | Audit logging for all Einstein AI interactions         |
| Knowledge / RAG Quality Data and Metrics | Einstein Audit Analytics & Monitoring | Quality metrics for RAG-based knowledge retrieval      |
| Agent Analytics                          | Einstein Audit Analytics & Monitoring | Agent performance dashboards and usage data            |
| Agentforce Session Tracing               | Einstein Audit Analytics & Monitoring | Session-level debugging traces for agent conversations |
| Agent Optimization                       | Einstein Audit Analytics & Monitoring | AI-driven optimization recommendations                 |
| Service Agent Analytics App              | Agent Analytics Setup                 | Pre-built analytics app for service agent performance  |

> **💡 Tip**: The Service Agent Analytics app can take up to 15 minutes to fully install after org provisioning because it depends on Agent Analytics being enabled first.

### Enable it yourself

**Choose one of the following methods:**

#### SF CLI

```bash
# Audit toggles require Setup UI. Use Browser Agent
# After enabling, assign Access Agentforce Optimization:
ADMIN_ID=$(sf data query --target-org {{ORG_ALIAS}} --json \
  --query "SELECT Id FROM User WHERE Profile.Name='System Administrator' AND IsActive=true LIMIT 1" \
  | jq -r '.result.records[0].Id')
OPT_PS_ID=$(sf data query --target-org {{ORG_ALIAS}} --json \
  --query "SELECT Id FROM PermissionSet WHERE Label='Access Agentforce Optimization' LIMIT 1" \
  | jq -r '.result.records[0].Id')
sf data create record --target-org {{ORG_ALIAS}} \
  --sobject PermissionSetAssignment \
  --values "PermissionSetId='$OPT_PS_ID' AssigneeId='$ADMIN_ID'"
```

#### REST API

```bash
# Audit toggles require Setup UI. Use Browser Agent
# After enabling, assign Access Agentforce Optimization:
ADMIN_ID=$(curl -s "{{INSTANCE_URL}}/services/data/v65.0/query?q=SELECT+Id+FROM+User+WHERE+Profile.Name='System+Administrator'+AND+IsActive=true+LIMIT+1" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" | jq -r '.records[0].Id')
OPT_PS_ID=$(curl -s "{{INSTANCE_URL}}/services/data/v65.0/query?q=SELECT+Id+FROM+PermissionSet+WHERE+Label='Access+Agentforce+Optimization'+LIMIT+1" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" | jq -r '.records[0].Id')
curl -X POST "{{INSTANCE_URL}}/services/data/v65.0/sobjects/PermissionSetAssignment" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" \
  -H "Content-Type: application/json" \
  -d "{\"PermissionSetId\":\"$OPT_PS_ID\",\"AssigneeId\":\"$ADMIN_ID\"}"
```

#### Browser Agent

```text
1. Setup → Quick Find → "Audit" → select "Einstein Audit, Analytics, and Monitoring Setup"
2. Enable: Audit and Feedback, Knowledge/RAG Quality Data and Metrics, Agent Analytics, Agentforce Session Tracing
3. Refresh Setup → navigate to Setup → Agent Analytics
4. Wait ~15 minutes if page is blank. Apps need time to appear
5. Once ready: install "Service Agent Analytics" (click down arrow → Install → Data Space: default → Ok)
6. Wait for "Installation Completed Successfully" notification
7. Setup → Users → admin user → Edit Assignments → add "Access Agentforce Optimization" → Save
```

## Digital Experiences

| Setting                    | Setup Location                                     | What it does                                                    |
| -------------------------- | -------------------------------------------------- | --------------------------------------------------------------- |
| Enable Digital Experiences | Feature Settings → Digital Experiences → Settings  | Allows creation of Experience Cloud sites for hosting chat widgets |

### Enable it yourself

**Choose one of the following methods:**

#### SF CLI

```bash
# No CLI equivalent. Use Browser Agent
echo "Digital Experiences must be enabled via Setup UI"
```

#### REST API

```bash
# No API equivalent. Use Browser Agent
echo "Digital Experiences must be enabled via Setup UI"
```

#### Browser Agent

```text
1. Setup → Feature Settings → Digital Experiences → Settings
2. Check "Enable Digital Experiences"
3. Click "Save"
4. A popup will appear asking to enable and register domain. Click "OK"
```

## Routing

OmniChannel routing allows agents to receive and handle conversations.

| Setting                                  | Setup Location       | What it does                                                        |
| ---------------------------------------- | -------------------- | ------------------------------------------------------------------- |
| Skills-Based and Direct-to-Agent Routing | OmniChannel Settings | Routes conversations to agents based on skills or direct assignment |
| Secondary Routing Priority               | OmniChannel Settings | Fallback routing when the primary agent is unavailable              |

A routing configuration and fallback queue are pre-created:

| Resource                          | Name                               | Details                                           |
| --------------------------------- | ---------------------------------- | ------------------------------------------------- |
| Routing Configuration             | Agentforce Service configuration   | Priority 1, Most Available model, capacity 2/3    |
| Queue                             | Agentforce Service Queue           | Supports Messaging Session, linked to routing config |

### Enable it yourself

**Choose one of the following methods:**

#### SF CLI

```bash
# Enable OmniChannel via Browser Agent first, then create routing config:
sf data create record --target-org {{ORG_ALIAS}} \
  --sobject ServiceChannel \
  --values "DeveloperName='Agentforce_Service_configuration' MasterLabel='Agentforce Service configuration' RoutingModel='MostAvailable' SecondaryRoutingPriority=1"

# Create queue via Metadata API
mkdir -p /tmp/queue-deploy/queues
cat > /tmp/queue-deploy/queues/Agentforce_Service_Queue.queue-meta.xml << 'XMLEOF'
<?xml version="1.0" encoding="UTF-8"?>
<Queue xmlns="http://soap.sforce.com/2006/04/metadata">
    <fullName>Agentforce_Service_Queue</fullName>
    <name>Agentforce Service Queue</name>
    <queueSobject>
        <sobjectType>MessagingSession</sobjectType>
    </queueSobject>
</Queue>
XMLEOF
cat > /tmp/queue-deploy/package.xml << 'XMLEOF'
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Agentforce_Service_Queue</members>
        <name>Queue</name>
    </types>
    <version>65.0</version>
</Package>
XMLEOF
sf project deploy start --target-org {{ORG_ALIAS}} --source-dir /tmp/queue-deploy
```

#### REST API

```bash
# Create routing configuration
curl -X POST "{{INSTANCE_URL}}/services/data/v65.0/sobjects/ServiceChannel" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" \
  -H "Content-Type: application/json" \
  -d '{"DeveloperName":"Agentforce_Service_configuration","MasterLabel":"Agentforce Service configuration","RoutingModel":"MostAvailable","SecondaryRoutingPriority":1}'

# Create queue
curl -X POST "{{INSTANCE_URL}}/services/data/v65.0/sobjects/Group" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" \
  -H "Content-Type: application/json" \
  -d '{"Name":"Agentforce Service Queue","DeveloperName":"Agentforce_Service_Queue","Type":"Queue"}'

# Add MessagingSession as supported object
QUEUE_ID=$(curl -s "{{INSTANCE_URL}}/services/data/v65.0/query?q=SELECT+Id+FROM+Group+WHERE+DeveloperName='Agentforce_Service_Queue'+AND+Type='Queue'" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" | jq -r '.records[0].Id')
curl -X POST "{{INSTANCE_URL}}/services/data/v65.0/sobjects/QueueSobject" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" \
  -H "Content-Type: application/json" \
  -d "{\"QueueId\":\"$QUEUE_ID\",\"SobjectType\":\"MessagingSession\"}"
```

#### Browser Agent

```text
1. Setup → Feature Settings → Service → Omni-Channel Settings
2. Check "Enable Skills-Based and Direct-to-Agent Routing" and "Enable Secondary Routing Priority" → Save
3. Setup → Feature Settings → Service → Messaging → Messaging Settings → toggle ON
4. Setup → Quick Find → "Routing Configuration" → New
5. Name: Agentforce Service configuration, Priority: 1, Model: Most Available, Capacity: 2/3 → Save
6. Setup → Quick Find → "Queues" → New
7. Label: Agentforce Service Queue, Supported Objects: Messaging Session, Routing Config: Agentforce Service configuration, Members: add admin → Save
```

> **✅ Success**: **Verify:** `SELECT Id, DeveloperName FROM ServiceChannel WHERE DeveloperName='Agentforce_Service_configuration'` and `SELECT Id, DeveloperName FROM Group WHERE Type='Queue' AND DeveloperName='Agentforce_Service_Queue'`. Both should return one record.

## Messaging

| Setting           | Setup Location                                         | What it does                                                     |
| ----------------- | ------------------------------------------------------ | ---------------------------------------------------------------- |
| Enable Messaging  | Feature Settings → Service → Messaging → Messaging Settings | Enables the Messaging platform for agent chat conversations |

A messaging channel is pre-created:

| Field             | Value                        |
| ----------------- | ---------------------------- |
| Channel Name      | Salesforce Agent Channel     |
| Developer Name    | Salesforce_Agent             |
| Type              | Enhanced Chat                |
| Deployment Type   | Web                          |
| Routing Type      | Agentforce Service Agent     |
| Fallback Queue    | Agentforce Service Queue     |

### Enable it yourself

**Choose one of the following methods:**

#### SF CLI

```bash
BOT_ID=$(sf data query --target-org {{ORG_ALIAS}} --json \
  --query "SELECT Id FROM BotDefinition WHERE DeveloperName='{{AGENT_NAME}}'" \
  | jq -r '.result.records[0].Id')
QUEUE_ID=$(sf data query --target-org {{ORG_ALIAS}} --json \
  --query "SELECT Id FROM Group WHERE Type='Queue' AND DeveloperName='Agentforce_Service_Queue'" \
  | jq -r '.result.records[0].Id')

sf apex run --target-org {{ORG_ALIAS}} << EOF
MessagingChannel channel = new MessagingChannel();
channel.DeveloperName = 'Salesforce_Agent';
channel.MasterLabel = 'Salesforce Agent Channel';
channel.MessageType = 'EmbeddedMessaging';
channel.MessagingPlatformKey = 'Salesforce_Agent-' + String.valueOf(Crypto.getRandomLong());
channel.IsActive = true;
channel.SessionHandlerId = '$BOT_ID';
channel.FallbackQueueId = '$QUEUE_ID';
insert channel;
System.debug('Created MessagingChannel: ' + channel.Id);
EOF
```

#### REST API

```bash
BOT_ID=$(curl -s "{{INSTANCE_URL}}/services/data/v65.0/query?q=SELECT+Id+FROM+BotDefinition+WHERE+DeveloperName='{{AGENT_NAME}}'" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" | jq -r '.records[0].Id')
QUEUE_ID=$(curl -s "{{INSTANCE_URL}}/services/data/v65.0/query?q=SELECT+Id+FROM+Group+WHERE+Type='Queue'+AND+DeveloperName='Agentforce_Service_Queue'" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" | jq -r '.records[0].Id')

curl -X POST "{{INSTANCE_URL}}/services/data/v65.0/sobjects/MessagingChannel" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" \
  -H "Content-Type: application/json" \
  -d "{\"DeveloperName\":\"Salesforce_Agent\",\"MasterLabel\":\"Salesforce Agent Channel\",\"MessageType\":\"EmbeddedMessaging\",\"MessagingPlatformKey\":\"Salesforce_Agent-$(date +%s)\",\"IsActive\":true,\"SessionHandlerId\":\"$BOT_ID\",\"FallbackQueueId\":\"$QUEUE_ID\"}"
```

#### Browser Agent

```text
1. Setup → Feature Settings → Service → Messaging → Messaging Settings
2. Click "New Channel" → Select "Enhanced Chat" → Next
3. Channel Name: Salesforce Agent Channel, Developer Name: Salesforce_Agent
4. Deployment Type: Web, Domain: <your site domain>
5. Routing Type: Agentforce Service Agent, Agent: {{AGENT_NAME}}
6. Fallback Queue: Agentforce Service Queue → Save
```

## Embedded Service Deployment

An Embedded Service Deployment container is pre-created to host the chat widget.

| Field                           | Value                                |
| ------------------------------- | ------------------------------------ |
| Embedded Service Deployment Name | Salesforce Agent Web Deployment     |
| API Name                        | Salesforce_Agent                     |
| Type                            | Enhanced Chat                        |
| Messaging Channel               | Salesforce Agent Channel             |

> **ℹ️ Info**: After creation the deployment is switched to V2 and published so the chat widget is immediately available.

### Enable it yourself

**Choose one of the following methods:**

#### SF CLI

```bash
# Embedded Service Deployments are best created via the Setup UI wizard
echo "Use Browser Agent for Embedded Service Deployment creation"
```

#### REST API

```bash
# Embedded Service Deployments are best created via the Setup UI wizard
echo "Use Browser Agent for Embedded Service Deployment creation"
```

#### Browser Agent

```text
1. Setup → Embedded Service → Embedded Service Deployments → New Deployment
2. Select "Enhanced Chat" → Select "Web"
3. Name: Salesforce Agent Web Deployment, API Name: Salesforce_Agent
4. Domain: <your site domain>, Messaging Channel: Salesforce Agent Channel → Save
5. Click "Switch to V2" (top right)
6. Click "Publish" (top right)
```

## Experience Site

An Experience Cloud site is pre-created with the chat widget embedded.

| Field            | Value                        |
| ---------------- | ---------------------------- |
| Site Name        | Salesforce Agent             |
| Template         | Build Your Own (LWR)         |
| Public Access    | Enabled                      |
| Enhanced Chat | Placed in Footer, linked to Salesforce Agent Web Deployment |

### Enable it yourself

**Choose one of the following methods:**

#### SF CLI

```bash
# Create site
sf community create --target-org {{ORG_ALIAS}} \
  --name "Salesforce Agent" \
  --template-name "Build Your Own (LWR)" \
  --url-path-prefix "salesforceagent"

# After adding Enhanced Chat component via Builder, publish:
sf community publish --target-org {{ORG_ALIAS}} \
  --name "Salesforce Agent"
```

#### REST API

```bash
# Publish via Connect API (after creating site and adding component via Builder)
NETWORK_ID=$(curl -s "{{INSTANCE_URL}}/services/data/v65.0/query?q=SELECT+Id+FROM+Network+WHERE+Name='Salesforce+Agent'" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" | jq -r '.records[0].Id')
curl -X POST "{{INSTANCE_URL}}/services/data/v65.0/connect/communities/$NETWORK_ID/publish" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" \
  -H "Content-Type: application/json"
```

#### Browser Agent

```text
1. Setup → Digital Experiences → All Sites → New
2. Select "Build Your Own (LWR)" → Get Started → Name: Salesforce Agent → Create
3. In Experience Builder: Settings → General → enable "Public Access"
4. Drag "Enhanced Chat" component into Footer → select "Salesforce Agent Web Deployment"
5. Click "Publish" → confirm
```

> **✅ Success**: **Verify:** `SELECT Id, Name, Status FROM Network WHERE Name='Salesforce Agent'`. This should return one record with Status = 'Live'.

## Site Domain & Trusted Domains

The Salesforce Site domain is registered and trusted domains are configured so the chat widget loads without CORS errors.

| Setting                | Setup Location                         | What it does                                                  |
| ---------------------- | -------------------------------------- | ------------------------------------------------------------- |
| Site Domain            | User Interface → Sites & Domains → Sites | Registered so Experience Sites have a public URL             |
| Trusted Domain         | Sites & Domains → Sites                | `*.my.site.com` added to trusted domains for inline frames   |

> **⚠️ Trusted domains are critical**: Without the trusted domain entry, the chat widget will fail silently. No button appears and no errors are shown to the user. This is the most common cause of "chat doesn't work" issues.

### Enable it yourself

**Choose one of the following methods:**

#### SF CLI

```bash
# Register domain (check if already exists)
sf data query --target-org {{ORG_ALIAS}} \
  --query "SELECT Id, Domain FROM Domain WHERE DomainType='DNS' LIMIT 1"

# Add trusted domain
sf data create record --target-org {{ORG_ALIAS}} \
  --sobject CorsWhitelistEntry \
  --values "UrlPattern='https://*.my.site.com'"

# Republish site after adding trusted domain
sf community publish --target-org {{ORG_ALIAS}} \
  --name "Salesforce Agent"
```

#### REST API

```bash
curl -X POST "{{INSTANCE_URL}}/services/data/v65.0/sobjects/CorsWhitelistEntry" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" \
  -H "Content-Type: application/json" \
  -d '{"UrlPattern":"https://*.my.site.com"}'

# Republish site
NETWORK_ID=$(curl -s "{{INSTANCE_URL}}/services/data/v65.0/query?q=SELECT+Id+FROM+Network+WHERE+Name='Salesforce+Agent'" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" | jq -r '.records[0].Id')
curl -X POST "{{INSTANCE_URL}}/services/data/v65.0/connect/communities/$NETWORK_ID/publish" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" \
  -H "Content-Type: application/json"
```

#### Browser Agent

```text
1. Setup → User Interface → Sites and Domains → Sites
2. Accept terms → Click "Register My Salesforce Site Domain" → accept popup
3. Find "ESW_Salesforce_Agent_*" → "Trusted Domains for Inline Frames" → Add Domain: *.my.site.com
4. Republish Experience Site: Setup → Digital Experiences → All Sites → Salesforce Agent → Builder → Publish
```

## Agent Deployment

A default Agentforce Service Agent is deployed, compiled, and activated in the org.

| Step               | What happens                                                      |
| ------------------ | ----------------------------------------------------------------- |
| Metadata Deploy    | Agent bundle deployed via Metadata API                            |
| Script Compilation | AgentScript compiled via SFAP authoring endpoint                  |
| Version Publish    | Agent version published and linked to the org instance            |
| Activation         | Bot version set to Active so the agent can receive conversations  |

### Enable it yourself

**Choose one of the following methods:**

#### SF CLI

```bash
# 1. Deploy agent metadata
sf project deploy start --target-org {{ORG_ALIAS}} \
  --source-dir data/AgentforceDotCom

# 2. Get session and instance
SESSION_ID=$(sf org display --target-org {{ORG_ALIAS}} --json | jq -r '.result.accessToken')
INSTANCE=$(sf org display --target-org {{ORG_ALIAS}} --json | jq -r '.result.instanceUrl')

# 3. Get NamedUser JWT
JWT=$(curl -s "$INSTANCE/agentforce/bootstrap/nameduser" \
  -H "Cookie: sid=$SESSION_ID" \
  -H "Accept: application/json" | jq -r '.access_token')

# 4. Compile AgentScript
SCRIPT=$(cat data/AgentforceDotCom/aiAuthoringBundles/{{AGENT_NAME}}/{{AGENT_NAME}}.agent)
COMPILED=$(curl -s -X POST "https://api.salesforce.com/einstein/ai-agent/v1.1/authoring/scripts" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -H "x-client-name: org-recipe" \
  -d "{\"assets\":[{\"type\":\"AFScript\",\"name\":\"AFScript\",\"content\":$(echo "$SCRIPT" | jq -Rs .)}],\"afScriptVersion\":\"1.0.1\"}")
ARTIFACT=$(echo "$COMPILED" | jq '.compiledArtifact')

# 5. Publish agent version
PUBLISH=$(curl -s -X POST "https://api.salesforce.com/einstein/ai-agent/v1.1/authoring/agents" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d "{\"agentDefinition\":$ARTIFACT,\"agentVersion\":\"1\",\"instanceConfig\":{\"endpoint\":\"$INSTANCE\"}}")
BOT_VERSION_ID=$(echo "$PUBLISH" | jq -r '.botVersionId')

# 6. Activate
curl -X POST "$INSTANCE/services/data/v65.0/connect/bot-versions/$BOT_VERSION_ID/activation" \
  -H "Authorization: Bearer $SESSION_ID" \
  -H "Content-Type: application/json" \
  -d '{"status":"ACTIVE"}'
```

#### REST API

```bash
# Same flow as SF CLI. Deploy ZIP via SOAP Metadata API, then:
# GET {instance}/agentforce/bootstrap/nameduser → JWT
# POST https://api.salesforce.com/einstein/ai-agent/v1.1/authoring/scripts → compile
# POST https://api.salesforce.com/einstein/ai-agent/v1.1/authoring/agents → publish
# POST /services/data/v65.0/connect/bot-versions/{botVersionId}/activation → activate
```

#### Browser Agent

```text
1. Setup → Agents → Agent Builder
2. Import or create the agent from metadata
3. Click "Activate" or "Publish"
4. Verify status shows "Active"
```

## MCP Servers

MCP (Model Context Protocol) servers expose Salesforce data and actions to agents as callable tools. Each server bundles a set of related tools an agent can invoke at runtime.

| Setting                   | Setup Location                                    | What it does                            |
| ------------------------- | ------------------------------------------------- | --------------------------------------- |
| Enable MCP Service (Beta) | Setup → User Interface                            | Turns on the MCP Service for the org    |
| Activate servers          | Setup → Integrations → API Catalog → MCP Servers  | Exposes each server's tools to agents   |

MCP is available on **Enterprise, Developer, and Unlimited editions** (GA, April 2026), so a freshly provisioned LabBox already has it. To turn it on, check the **"Enable MCP Service (Beta)"** preference under **Setup → User Interface**, then activate the servers you want.

Standard MCP servers ship **Inactive by default** — each one must be activated individually in Setup before its tools become available to agents. There is **no Metadata API type or Tooling-API field** to activate a server programmatically — activation is UI-only.

| Server                  | Tools                  | What it exposes                                                       |
| ----------------------- | ---------------------- | --------------------------------------------------------------------- |
| sobject-reads           | 6 tools                | Read access to standard and custom sObject records                    |
| sobject-mutations       | 9 tools                | Create and update sObject records                                     |
| sobject-deletes         | 8 tools                | Delete sObject records                                                |
| sobject-all             | 11 tools + 2 prompts   | Combined read, mutate, and delete access with guided prompts          |
| data-cloud-queries      | 2 tools                | Query Data Cloud objects and unified profiles                         |
| metadata-experts        | 1 tool                 | Inspect org metadata                                                  |
| salesforce-api-context  | 6 tools                | Salesforce API reference and context for grounding agent responses    |

### Enable it yourself

**Choose one of the following methods:**

#### SF CLI

```bash
# No CLI equivalent. MCP server activation is UI-only.
# There is no Metadata API type or Tooling-API field to activate a server.
echo "MCP Servers must be activated via Setup UI"
```

#### REST API

```bash
# No API equivalent. MCP server activation is UI-only — there is no supported
# Tooling/Metadata API object to query or toggle a server's activation state.
echo "MCP Servers must be activated via Setup UI"
```

#### Browser Agent

```text
1. Setup → User Interface → check "Enable MCP Service (Beta)"
2. Setup → Integrations → API Catalog → MCP Servers
3. Open the "Salesforce Servers" tab
4. Click a server (e.g. sobject-reads) → "Activate" → confirm
5. Repeat step 4 for each server your agents need
```

> **ℹ️ Client auth (External Client App)**: External MCP clients authenticate with an **External Client App (ECA)** using OAuth scopes `api, sfap_api, refresh_token, einstein_gpt_api` (keep `refresh_token` or clients disconnect frequently). Runtime endpoints are `https://api.salesforce.com/platform/mcp/v1/platform/<server>` for standard servers and `/v1/custom/<name>` for custom ones.

## Agentforce Coworker

Agentforce Coworker is a one-click enablement that provisions an end-to-end coworker experience: Agentforce Studio, CRM connectivity, search infrastructure, the coworker agent, personalization, and Data 360 user ingestion with identity resolution.

| Setting                    | Setup Location                                     | What it does                                                          |
| -------------------------- | -------------------------------------------------- | -------------------------------------------------------------------- |
| Enable Agentforce Coworker | Setup → Agentforce Coworker → Get Started → Turn On | Provisions the end-to-end coworker experience for the org            |

| Component             | What it sets up                                                       |
| --------------------- | --------------------------------------------------------------------- |
| Agentforce Studio     | The authoring and management surface for the coworker agent           |
| CRM connectivity      | Connects the coworker to your CRM data                                |
| Search infrastructure | AI search indexing that grounds coworker responses                    |
| Coworker agent        | The pre-built Agentforce Coworker agent                               |
| Personalization       | Per-user tailoring of coworker behavior                               |
| Data 360 ingestion    | User ingestion and identity resolution via Data 360                   |

**Prerequisites:**

| Prerequisite                    | Notes                                                                                                       |
| ------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `AgenticEnterpriseSearchAddOn`  | The binding add-on license (paired with `EinsteinAgentPlatform`). Auto-provisions the AI Search permission set licenses. Bundled on Flex Foundations / A1E / A4X / Agentforce for Service or Sales; otherwise add it (internally via Black Tab, customers via their SKU). |
| Data 360 / Data Cloud           | A Data Cloud data space is required. Verify a Data 360 app appears in the App Launcher.                      |
| Beta GenAI Models               | Setup → Einstein Setup → "Beta Generative AI Models" enabled                                                 |
| Role                            | Data 360 Admin or Data 360 Architect                                                                         |

> **ℹ️ The license is the gate, not the PSLs**: The `AgenticEnterpriseSearchAddOn` license **auto-provisions** the permission set licenses behind Coworker — `AI Search Permission Set License` (`AISearchUserPsl`) and `AI Search Setup Permission Set License` (`AISearchAdminPsl`). Admins do **not** request these PSLs directly; provisioning the add-on license grants them. Note that the add-on is a SKU/provisioning-level grant — it does **not** appear as a row in `PermissionSetLicense`; the queryable artifacts are the two AI Search PSLs named above.

**Permissions:**

| To do this          | Assign                                                                                          |
| ------------------- | ----------------------------------------------------------------------------------------------- |
| Configure Coworker  | The **`Agentforce Coworker Admin`** permission set. (The `Agentforce Coworker Setup` PSL is consumed automatically — no manual step.) |
| Use Coworker        | Grant end-user access via the **"Manage Access to Agentforce Coworker"** section of Coworker Setup (it assigns the AI Search access permission set group created during setup — confirm the exact name in your org). Do **not** assign the bare "Agentforce Coworker User" / "Ask Agentforce User" permission *set*; it grants the UI but not the agent. |

> **ℹ️ Legacy \**: On orgs not yet on the 262 release, this feature and its permission sets may still appear under the legacy **"Ask Agentforce"** label — it is the same product (the rename rolled out around early June). The "Get Started with Agentforce Coworker" Setup node only appears **after** the `Agentforce Coworker Admin` permission set is assigned and the page is refreshed.

### Enable it yourself

**Choose one of the following methods:**

#### SF CLI

```bash
# The add-on license is provisioned via Black Tab (internal) or your SKU,
# then Coworker is turned on via the Setup UI. But you can verify the AI Search
# permission set licenses landed in the org:
sf data query --target-org {{ORG_ALIAS}} \
  --query "SELECT DeveloperName, MasterLabel FROM PermissionSetLicense WHERE DeveloperName IN ('AISearchUserPsl','AISearchAdminPsl')"
```

#### REST API

```bash
# Enablement is UI-only. Verify the AI Search permission set licenses are present:
curl -s "{{INSTANCE_URL}}/services/data/v65.0/query?q=SELECT+DeveloperName,MasterLabel+FROM+PermissionSetLicense+WHERE+DeveloperName+IN+('AISearchUserPsl','AISearchAdminPsl')" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}"
```

#### Browser Agent

```text
1. Confirm prerequisites: qualifying edition (EE/Unlimited/A1),
   AgenticEnterpriseSearchAddOn license present, a Data Cloud data space,
   and Beta Generative AI Models enabled
2. Assign the "Agentforce Coworker Admin" permission set to yourself,
   then refresh the page
3. Setup → Quick Find → "Agentforce Coworker" (or "Ask Agentforce" on
   pre-262 orgs)
4. Set Up Data Space → pick your Data Cloud data space
5. Click "Get Started" → "Turn On" → confirm
6. Enable the Global Search Bar
7. Grant end users access via "Manage Access to Agentforce Coworker"
   (assigns the AI Search access permission set group)
```

> **ℹ️ Reference**: Salesforce's public guide: [Turn On Agentforce Coworker Infrastructure](https://developer.salesforce.com/docs/data/agentforce-coworker/guide/agentforce-coworker-turn-on-infrastructure.html).

## Agentforce Voice

Agentforce Voice brings agent conversations to voice channels.

| Setting             | Setup Location                          | What it does                                              |
| ------------------- | --------------------------------------- | --------------------------------------------------------- |
| Add a voice connection | Agent Builder → open agent → Voice Settings | Unlocks Voice for the agent (Telephony or Enhanced Chat v2) |

You unlock **Voice Settings** in Agent Builder by adding a voice **connection** to your agent. There are two enablement paths:

| Path                    | What it gives you                                                  | Setup effort                                                                                                                                                                          |
| ----------------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Telephony connection    | Full voice agent over PSTN/SIP (phone calls)                       | Separate manual setup — AWS Contact Center, call flows, and procuring phone numbers (not automated). OrgFarm offers an "AgentforceVoice" checkout template for voice-enabled orgs.    |
| Enhanced Chat v2 (ECv2) | "Voice in chat" — microphone input within the Enhanced Chat v2 window | Lighter path; "Voice-Enabled Agents in Enhanced Chat v2" (Summer '26 release)                                                                                                        |

> **⚠️ Full telephony is a separate manual setup**: Telephony voice (AWS Contact Center, call flows, and phone numbers) is **not pre-configured in a LabBox** and is not automated — it is a separate manual setup that takes roughly 40 minutes end to end. For a ready-made voice-enabled org, use the OrgFarm "AgentforceVoice" checkout template instead of building telephony by hand.

### Required licenses and permission

Agentforce Voice requires two licenses in the org: an **Agentforce** license and a **Service Cloud Voice** license. Agentforce Voice is the AI voice-agent layer that runs on top of Service Cloud Voice telephony, so both must be present.

> **ℹ️ Reference**: See Salesforce's [Agentforce Voice prerequisites](https://help.salesforce.com/s/articleView?id=ai.agentforce_voice_setup_prereqs.htm&type=5) for the current license and permission requirements.

### Enable it yourself

**Choose one of the following methods:**

#### SF CLI

```bash
# The Agentforce + Service Cloud Voice licenses are provisioned commercially
# (Black Tab internal, or your Voice SKU), not via CLI. But you can verify
# whether Service Cloud Voice is switched on in the org:
sf data query --use-tooling-api --target-org {{ORG_ALIAS}} \
  --query "SELECT IsServiceCloudVoiceEnabled FROM ServiceCloudVoiceSettings"
```

#### REST API

```bash
# Licenses are provisioned commercially, not via API. Verify whether
# Service Cloud Voice is enabled in the org:
curl -s "{{INSTANCE_URL}}/services/data/v65.0/tooling/query?q=SELECT+IsServiceCloudVoiceEnabled+FROM+ServiceCloudVoiceSettings" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}"
```

#### Browser Agent

```text
1. Ensure the org has an Agentforce license and a Service Cloud Voice license
2. Open the agent in Agent Builder
3. Add a Voice connection (Telephony or Enhanced Chat v2) to unlock Voice Settings
4. For full telephony, complete the separate AWS Contact Center / phone-number
   setup, or check out an OrgFarm "AgentforceVoice" template org
```

## Vibes

Vibes is Salesforce's in-org agentic coding experience. It comes in two surfaces: **Vibes Chat**, which runs in **VS Code Desktop**, and **Vibes IDE**, which is **browser-based and launched from within the org**.

| Setting | Setup Location                                                   | What it does                          |
| ------- | ---------------------------------------------------------------- | ------------------------------------- |
| Vibes   | Launched in-org (Vibes IDE) or VS Code Desktop (Vibes Chat)      | In-org agentic coding experience      |

| Aspect            | Detail                                                                                  |
| ----------------- | --------------------------------------------------------------------------------------- |
| Surfaces          | Vibes Chat (VS Code Desktop) and Vibes IDE (browser, launched from within the org)      |
| Pricing           | Free in Developer Edition — no purchase required                                        |
| Model             | Anthropic Claude Sonnet (current generation)                                            |
| Lifetime limit    | 110 requests / 1.5M tokens per org — one-time, does not refresh, no fallback model      |

_Model and limits last verified June 2026; both are subject to change — confirm the current values in your org._

> **⚠️ Developer Edition limits and exclusions**: The Developer Edition allowance is a **one-time lifetime cap of 110 requests / 1.5M tokens per org**. It does **not** refresh, and once it is exhausted there is **no fallback model** — Vibes simply stops. Developer Edition orgs **cannot** receive the unmetered per-user-per-month (PUPM) license because there is no billing mechanism in DE; ISVs likewise cannot get unmetered access in DE orgs. Vibes is **not available in the EU Operating Zone or Government Cloud**.

### Enable it yourself

**Choose one of the following methods:**

#### SF CLI

```bash
# No CLI equivalent. Vibes is available in-org by edition and region,
# not provisioned via API.
echo "Vibes availability is determined by org edition and region"
```

#### REST API

```bash
# No API equivalent. Vibes is available in-org by edition and region,
# not provisioned via API.
echo "Vibes availability is determined by org edition and region"
```

#### Browser Agent

```text
1. Vibes IDE: launch it from within the org
2. Vibes Chat: use the Salesforce extension in VS Code Desktop
```

> **✅ Ready to build**: Your LabBox comes pre-configured with all of the above, including a working agent, messaging channel, and Experience Site with a chat widget. If any of these settings appear disabled, contact the Agentforce Labs team.