Goal-Based Agent 10 min
Autonomous AI agent runtime engine built natively on Salesforce. Enables goal-driven, multi-step workflows that run independently — executing tasks, calling tools, managing memory, and adapting over time.
What You Get
- Goal-driven workflows — define a goal, the agent plans and executes multi-step tasks autonomously
- Sequential or parallel execution — subtasks run sequentially by default, with opt-in parallel mode for independent work
- Workflow defaults — configure runtime defaults from the Settings > Defaults tab, automatically applied to chat-initiated workflows
- 28 built-in tools — SOQL, DML, memory, scheduling, email, Flows, prompt templates, Slack, and more
- REST API — full external integration at
/services/apexrest/genui/agent/* - Persistent memory — save, query, update, and promote memories across workflows
- Sub-agent orchestration — spawn parallel child workflows and create reusable skills
- Scheduling — cron-style recurring workflows and future follow-ups
- Optional Slack integration — read channels and send notifications
Prerequisites
Before installing (automated or manual), your org needs:
- Einstein AI enabled — Go to Setup > Einstein Setup and turn on Einstein and Beta Generative AI Models
- System Administrator profile — required for package installation
- Lightning Experience — must be enabled
Manual Installation (Fallback)
If automated installation is unavailable or fails, follow these steps:
Step 1: Install the Package
https://login.salesforce.com/packaging/installPackage.apexp?p0=04tal000006hMrRAAU
Choose Install for All Users (recommended). This grants all users access to the Goal Agent app and custom objects without needing to assign permission sets individually.
Step 2: Assign Permission Set (if needed)
If you chose "Install for Admins Only", assign the Goal Agent User permission set to every user who needs access:
- Go to Setup > Permission Sets
- Find Goal Agent User
- Click Manage Assignments > Add Assignment
- Select the users and save
This grants access to all custom objects (Goals, Workflows, Tasks, Memory, Skills, etc.) and the Goal Agent Lightning app.
REST API
The package exposes a full REST API for external integrations, automation, and programmatic workflow management.
Base URL
All endpoints are relative to: {instance_url}/services/apexrest/genui/agent
Authentication
All requests require a valid Salesforce access token passed via the Authorization: Bearer {access_token} header.
ACCESS_TOKEN=$(sf org display --target-org myOrg --json | jq -r '.result.accessToken')
INSTANCE_URL=$(sf org display --target-org myOrg --json | jq -r '.result.instanceUrl')
Managed Package Namespace
In managed package orgs, field names in GET responses include the genui__ namespace prefix (e.g., genui__Title__c instead of Title__c). POST request bodies use parameter names without the namespace prefix.
Endpoints Overview
| Method | Path | Description |
|---|---|---|
| POST | /goals | Create a new goal |
| POST | /workflows | Create a new workflow |
| POST | /workflows/{id}/start | Start a workflow |
| POST | /workflows/{id}/message | Send a message (human-in-the-loop) |
| POST | /workflows/{id}/pause | Pause a running workflow |
| POST | /workflows/{id}/resume | Resume a paused workflow |
| POST | /workflows/{id}/cancel | Cancel a workflow |
| GET | /goals | List goals |
| GET | /workflows | List workflows |
| GET | /workflows/{id}/status | Get workflow status with tasks and steps |
| GET | /workflows/{id}/messages | Get workflow messages |
| GET | /memories | Get memories |
Endpoints Reference
Create a goal that serves as the parent container for one or more workflows.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
title | String | Yes | Goal title |
description | String | No | Goal description |
completionCriteria | String | No | Success criteria for the goal |
priority | String | No | High, Medium (default), Low |
Request
curl -X POST "$INSTANCE_URL/services/apexrest/genui/agent/goals" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Q1 Pipeline Review",
"description": "Review and analyze open opportunities",
"completionCriteria": "All opps reviewed with next steps",
"priority": "High"
}'
Response
{
"id": "a2sXXXXXXXXXXXXXXX",
"title": "Q1 Pipeline Review",
"status": "Draft"
}
Create a workflow under an existing goal. Optionally include instructions to auto-create an initial task.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
goalId | Id | Yes | Parent goal ID |
title | String | Yes | Workflow title |
workflowType | String | Yes | Workflow type, e.g. "Chat" |
instructions | String | No | Initial task instructions (auto-creates a task) |
triggerType | String | No | Default: "Manual" |
maxIterations | Integer | No | Max agent iterations. Default: 50 |
config | Object | No | Runtime config JSON, e.g. {"parallelSubtasks": true} |
Request
curl -X POST "$INSTANCE_URL/services/apexrest/genui/agent/workflows" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"goalId": "a2sXXXXXXXXXXXXXXX",
"title": "Analyze Pipeline",
"workflowType": "Chat",
"instructions": "Analyze my open opportunities and summarize the pipeline",
"maxIterations": 25
}'
Response
{
"id": "a32XXXXXXXXXXXXXXX",
"title": "Analyze Pipeline",
"status": "Queued"
}
Begin executing a queued workflow. The agent starts processing tasks autonomously.
Parameters: None. Send an empty JSON body {}.
Request
curl -X POST "$INSTANCE_URL/services/apexrest/genui/agent/workflows/a32XXXXXXXXXXXXXXX/start" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
Response
{
"workflowId": "a32XXXXXXXXXXXXXXX",
"status": "Running"
}
Send a human-in-the-loop message to a running workflow. Use this when the workflow status is WaitingForInput.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
message | String | Yes | User message text |
Request
curl -X POST "$INSTANCE_URL/services/apexrest/genui/agent/workflows/a32XXXXXXXXXXXXXXX/message" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"message": "Focus on deals over $100k"}'
Response
{
"workflowId": "a32XXXXXXXXXXXXXXX",
"status": "Running"
}
Control a running workflow's lifecycle. All three endpoints accept an empty JSON body {}.
Pause — temporarily halt execution:
curl -X POST "$INSTANCE_URL/services/apexrest/genui/agent/workflows/a32XXXXXXXXXXXXXXX/pause" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
Resume — continue a paused workflow:
curl -X POST "$INSTANCE_URL/services/apexrest/genui/agent/workflows/a32XXXXXXXXXXXXXXX/resume" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
Cancel — permanently stop a workflow:
curl -X POST "$INSTANCE_URL/services/apexrest/genui/agent/workflows/a32XXXXXXXXXXXXXXX/cancel" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
Retrieve all goals in the org.
Request
curl "$INSTANCE_URL/services/apexrest/genui/agent/goals" \
-H "Authorization: Bearer $ACCESS_TOKEN"
Response
[
{
"id": "a2sXXXXXXXXXXXXXXX",
"title": "Q1 Pipeline Review",
"status": "In Progress",
"priority": "High"
}
]
Retrieve all workflows in the org.
Request
curl "$INSTANCE_URL/services/apexrest/genui/agent/workflows" \
-H "Authorization: Bearer $ACCESS_TOKEN"
Response
[
{
"id": "a32XXXXXXXXXXXXXXX",
"title": "Analyze Pipeline",
"status": "Running",
"workflowType": "Chat"
}
]
Get detailed workflow status including tasks and steps.
Request
curl "$INSTANCE_URL/services/apexrest/genui/agent/workflows/a32XXXXXXXXXXXXXXX/status" \
-H "Authorization: Bearer $ACCESS_TOKEN"
Response
{
"id": "a32XXXXXXXXXXXXXXX",
"title": "Analyze Pipeline",
"status": "Running",
"tasks": [
{
"id": "a33XXXXXXXXXXXXXXX",
"title": "Analyze open opportunities",
"status": "In Progress",
"steps": [
{
"toolName": "soql_query",
"status": "Completed"
}
]
}
]
}
Retrieve the message history for a workflow conversation.
Request
curl "$INSTANCE_URL/services/apexrest/genui/agent/workflows/a32XXXXXXXXXXXXXXX/messages" \
-H "Authorization: Bearer $ACCESS_TOKEN"
Response
[
{
"role": "user",
"content": "Focus on deals over $100k",
"timestamp": "2025-01-15T10:30:00.000Z"
},
{
"role": "assistant",
"content": "I found 12 opportunities over $100k. Here's the breakdown...",
"timestamp": "2025-01-15T10:30:05.000Z"
}
]
Retrieve the agent's persistent memories.
Request
curl "$INSTANCE_URL/services/apexrest/genui/agent/memories" \
-H "Authorization: Bearer $ACCESS_TOKEN"
Response
[
{
"id": "a34XXXXXXXXXXXXXXX",
"content": "User prefers weekly pipeline summaries on Mondays",
"category": "preference",
"scope": "core"
}
]
Full Example
A complete walkthrough: authenticate, create a goal, create and start a workflow, interact with it, and manage its lifecycle.
# Authenticate
ACCESS_TOKEN=$(sf org display --target-org myOrg --json | jq -r '.result.accessToken')
INSTANCE_URL=$(sf org display --target-org myOrg --json | jq -r '.result.instanceUrl')
# 1. Create a goal
curl -X POST "$INSTANCE_URL/services/apexrest/genui/agent/goals" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Q1 Pipeline Review",
"description": "Review and analyze open opportunities",
"completionCriteria": "All opps reviewed with next steps",
"priority": "High"
}'
# => {"id": "a2s...", "title": "Q1 Pipeline Review", "status": "Draft"}
# 2. Create a workflow
curl -X POST "$INSTANCE_URL/services/apexrest/genui/agent/workflows" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"goalId": "a2sXXXXXXXXXXXXXXX",
"title": "Analyze Pipeline",
"workflowType": "Chat",
"instructions": "Analyze my open opportunities and summarize the pipeline",
"maxIterations": 25
}'
# => {"id": "a32...", "title": "Analyze Pipeline", "status": "Queued"}
# 3. Start the workflow
curl -X POST "$INSTANCE_URL/services/apexrest/genui/agent/workflows/a32XXXXXXXXXXXXXXX/start" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
# => {"workflowId": "a32...", "status": "Running"}
# 4. Check status
curl "$INSTANCE_URL/services/apexrest/genui/agent/workflows/a32XXXXXXXXXXXXXXX/status" \
-H "Authorization: Bearer $ACCESS_TOKEN"
# 5. Send a message (when workflow is WaitingForInput)
curl -X POST "$INSTANCE_URL/services/apexrest/genui/agent/workflows/a32XXXXXXXXXXXXXXX/message" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"message": "Focus on deals over $100k"}'
# 6. Lifecycle control
curl -X POST "$INSTANCE_URL/services/apexrest/genui/agent/workflows/a32XXXXXXXXXXXXXXX/pause" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" -d '{}'
curl -X POST "$INSTANCE_URL/services/apexrest/genui/agent/workflows/a32XXXXXXXXXXXXXXX/resume" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" -d '{}'
curl -X POST "$INSTANCE_URL/services/apexrest/genui/agent/workflows/a32XXXXXXXXXXXXXXX/cancel" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" -d '{}'
Built-in Tools
The agent comes with 28 built-in tools. Enable or disable them from Settings > Tools in the Goal Agent app.
Data & Metadata
| Tool | Description |
|---|---|
soql_query | Execute SOQL queries |
dml_operation | Create, update, delete Salesforce records |
describe_object | Get object/field metadata |
report_tool | Run Salesforce Reports |
Agents & Automation
| Tool | Description |
|---|---|
invoke_agent | Invoke an Agentforce agent |
list_agents | List available Agentforce agents |
apex_action | Invoke Apex invocable actions |
list_apex_actions | List available Apex invocable actions |
flow_invoke | Run Salesforce Flows |
list_flows | List available Salesforce Flows |
Prompt Templates
| Tool | Description |
|---|---|
list_prompt_templates | List available prompt templates |
describe_prompt_template | Get prompt template details and inputs |
invoke_prompt_template | Execute a prompt template |
Memory
| Tool | Description |
|---|---|
save_memory | Save information to persistent memory |
query_memory | Search memories by keyword or category |
update_memory | Update an existing memory |
promote_memory | Promote workflow memory to core memory |
Orchestration
| Tool | Description |
|---|---|
create_task | Create sub-tasks within a workflow |
create_workflow | Create child workflows |
spawn_subtasks | Create parallel sub-agent workflows |
create_skill | Create reusable skills (custom tools) |
Scheduling
| Tool | Description |
|---|---|
schedule_followup | Schedule a future follow-up |
schedule_workflow | Schedule a recurring workflow (cron) |
list_schedules | List scheduled entries |
cancel_schedule | Cancel a scheduled entry |
slack_notify | Send Slack notifications (requires setup) |
slack_read | Read Slack channel messages (requires setup) |
rest_callout (HTTP callouts to external APIs) is also available but disabled by default. It requires Remote Site Settings to be configured for target domains.
Communication
| Tool | Description |
|---|---|
send_email | Send emails |
slack_notify | Send Slack notifications (requires setup) |
slack_read | Read Slack channel messages (requires setup) |
External API Callouts
rest_callout (HTTP callouts to external APIs) is also available but disabled by default. It requires Remote Site Settings to be configured for target domains.
Optional: Slack Integration
The agent includes two Slack tools — slack_notify and slack_read — both disabled by default.
A. Create a Slack App
- Go to https://api.slack.com/apps > Create New App > From scratch
- Enter an app name (e.g., "Salesforce Agent") and select your workspace
- Click Create App
B. Configure Bot Token Scopes (for slack_read)
- In your Slack app settings, go to OAuth & Permissions
- Under Scopes > Bot Token Scopes, add:
channels:history— Read messages from public channelschannels:read— View basic channel information
- Click Install to Workspace (or Reinstall if already installed)
- Copy the Bot User OAuth Token (starts with
xoxb-)
C. Configure Incoming Webhooks (for slack_notify)
- In your Slack app settings, go to Incoming Webhooks
- Toggle Activate Incoming Webhooks to On
- Click Add New Webhook to Workspace
- Select the channel where notifications should post
- Copy the Webhook URL
D. Add Remote Site Settings in Salesforce
Go to Setup > Remote Site Settings and create two entries:
| Remote Site Name | URL | Active |
|---|---|---|
| SlackAPI | https://slack.com | Yes |
| SlackWebhooks | https://hooks.slack.com | Yes |
E. Store Tokens in Custom Metadata
Go to Setup > Custom Metadata Types > Agent Config > Manage Records and create:
For slack_read:
| Field | Value |
|---|---|
| Label | Slack Bot Token |
| Agent Config Name | SlackBotToken |
| Value | xoxb-your-bot-token-here |
| Is Active | Checked |
For slack_notify:
| Field | Value |
|---|---|
| Label | Slack Webhook URL |
| Agent Config Name | SlackWebhookUrl |
| Value | https://hooks.slack.com/services/T.../B.../xxx |
| Is Active | Checked |
F. Enable the Slack Tools
- Open the Goal Agent app
- Go to Settings > Tools tab
- Find
slack_readandslack_notifyin the tools list - Toggle them On
G. Invite the Bot to Channels
In Slack, go to each channel you want the agent to read from and type:
/invite @YourBotName
The bot can only read messages from channels it has been invited to.
Troubleshooting
Permission errors
- Ensure the Goal Agent User permission set is assigned (or package was installed for All Users)
- Check that the user's profile has API access enabled
Slack tools not working
- Verify Remote Site Settings are active for
https://slack.comandhttps://hooks.slack.com - Confirm
SlackBotTokenandSlackWebhookUrlmetadata records exist and are active - Ensure the bot has been invited to the target channel
- Check that the tools are enabled in Settings > Tools
Custom metadata fields not visible in Setup UI
- If fields don't appear when creating
AgentConfig__mdtrecords, check that the page layout includes the custom fields - Go to Setup > Custom Metadata Types > Agent Config > Page Layouts and add all fields
Real-time updates not appearing in chat
- Platform Events require the user to have the Goal Agent User permission set
- Check browser console for EMP API subscription errors
- Try refreshing the page
Agent workflow stuck
- Go to Settings and check the workflow status
- Use Cancel to stop a stuck workflow, then create a new one
- Check Setup > Apex Jobs for any failed Queueable jobs