Salesforce API
Salesforce API v2
Last updated: 3 November 2026
This is the Salesforce package API. The caller is a YouEx user who has installed the package into one workspace.
The current contract is the API reference (PDF). For the in-app connection, owners and admins on a Salesforce-entitled plan use Workspace Settings → Integrations.
Salesforce API v2 is included on Professional and Enterprise (salesforcePackage). Use it for CRM, research, enrich, and agents from the package, and for lead sync through bulk upsert.
Base URL
https://engage.youex.ai/api/integrations/salesforce/v2
Paths below are relative to that base.
Authentication
Authorization: Bearer <access_token>
Content-Type: application/json
The token is an Auth0 access token for the Salesforce audience. A scope check passes when the token has any one of the scopes listed for that call.
youex.salesforce.read covers every read scope below. youex.salesforce.write covers every write scope below.
| Scope | Allows |
|---|---|
youex.salesforce.read | All reads |
youex.salesforce.write | All writes |
youex.salesforce.workspace.read | Account, workspaces, fields, and non-lead CRM reads |
youex.salesforce.workspace.write | Install, uninstall, and non-lead CRM writes |
youex.salesforce.leads.read | Lead reads and lead item queries |
youex.salesforce.leads.write | Lead writes, lead research, and lead enrich |
youex.salesforce.agents.read | Agent reads |
Discovery
These routes do not require a token.
| Method | Path |
|---|---|
| GET | /.well-known/oauth-protected-resource |
| GET | /.well-known/oauth-authorization-server |
Install and account
CRM calls require a connected installation.
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /install/start | Public, install limiter | Start the package install |
| GET | /install/callback | Install callback | Finish install and bind a workspace |
| GET | /account | Workspace read | Signed-in account |
| GET | /installable-workspaces | Workspace read | Workspaces this user can install into |
| GET | /installed-workspaces | Workspace read | Workspaces that already have an installation |
| POST | /install | Workspace write | Bind the token to a workspace |
| POST | /uninstall | Workspace write | Disconnect a workspace |
| GET | /workspaces | Workspace read | Installed workspaces |
| GET | /workspaces/default | Workspace read | Default workspace |
| GET | /workspaces/:workspaceId | Workspace read | One workspace |
| POST | /workspaces/:workspaceId/select | Workspace read | Select the workspace |
Changing the shared selection on POST /workspaces/:workspaceId/select also needs workspace write.
POST /install body:
{
"workspaceId": "ws_123",
"salesforceOrgId": "00Dxx0000000001",
"salesforceUserId": "005xx0000000001",
"salesforceUserEmail": "user@example.com",
"packageVersion": "1.2.0"
}
salesforceUserId, salesforceUserEmail, and packageVersion may be null.
POST /uninstall body:
{ "workspaceId": "ws_123" }
Limits and errors
- API routes: 180 requests per minute per IP.
- Install routes: 30 requests per minute per IP.
- Responses include standard rate-limit headers.
{
"error": {
"code": "insufficient_scope",
"message": "Missing required scope. Expected one of: youex.salesforce.leads.write, youex.salesforce.write",
"retryable": false
}
}
A suspended workspace returns 402. Research and enrich also count against the workspace's monthly allowances.
CRM records
:workspaceId is the installed YouEx workspace. :id accepts the YouEx id or the stored Salesforce id.
Create bodies may include /_salesforceId. Unknown keys are rejected.
List query parameters are limit (1–200), cursor, and search, plus the filter named in the table.
A list response is:
{ "leads": [], "total": 0, "hasMore": false, "nextCursor": null }
Contacts, companies, and opportunities use the same shape with contacts, companies, or opportunities. A single record is { "lead": {} } (or contact, company, opportunity).
Bulk upsert accepts 1–200 items:
{
"items": [
{ "/_salesforceId": "00Qxx0000000001", "name": "Avery Smith", "email": "avery@example.com" }
]
}
Response:
{
"totalReceived": 1,
"insertedCount": 1,
"updatedCount": 0,
"skippedCount": 0,
"notFoundIds": [],
"results": [
{
"index": 0,
"action": "inserted",
"inputId": "00Qxx0000000001",
"recordId": "lead_01",
"code": null,
"message": null
}
]
}
action is inserted, updated, or skipped.
Leads
| Method | Path | Scope | Notes |
|---|---|---|---|
| GET | /workspaces/:workspaceId/leads | Leads read | Filter status |
| GET | /workspaces/:workspaceId/leads/:id | Leads read | |
| POST | /workspaces/:workspaceId/leads | Leads write | |
| POST | /workspaces/:workspaceId/leads/bulk-upsert | Leads write | 1–200 items |
| PATCH | /workspaces/:workspaceId/leads/:id | Leads write | |
| DELETE | /workspaces/:workspaceId/leads/:id | Leads write |
Writable lead fields match the CRM lead, including name, email, secondaryEmail, phone, secondaryPhone, linkedinUrl, company, companyWebsite, title, status, notes, tags, customFields, contactId, companyId, and opportunityId.
Contacts
| Method | Path | Scope | Notes |
|---|---|---|---|
| GET | /workspaces/:workspaceId/contacts | Workspace read | Filters status, companyId |
| GET | /workspaces/:workspaceId/contacts/:id | Workspace read | |
| POST | /workspaces/:workspaceId/contacts | Workspace write | |
| POST | /workspaces/:workspaceId/contacts/bulk-upsert | Workspace write | |
| PATCH | /workspaces/:workspaceId/contacts/:id | Workspace write | |
| DELETE | /workspaces/:workspaceId/contacts/:id | Workspace write |
Companies
| Method | Path | Scope | Notes |
|---|---|---|---|
| GET | /workspaces/:workspaceId/companies | Workspace read | Filter type |
| GET | /workspaces/:workspaceId/companies/:id | Workspace read | |
| POST | /workspaces/:workspaceId/companies | Workspace write | |
| POST | /workspaces/:workspaceId/companies/bulk-upsert | Workspace write | |
| PATCH | /workspaces/:workspaceId/companies/:id | Workspace write | |
| DELETE | /workspaces/:workspaceId/companies/:id | Workspace write |
Opportunities
| Method | Path | Scope | Notes |
|---|---|---|---|
| GET | /workspaces/:workspaceId/opportunities | Workspace read | Filter stage |
| GET | /workspaces/:workspaceId/opportunities/:id | Workspace read | |
| POST | /workspaces/:workspaceId/opportunities | Workspace write | |
| POST | /workspaces/:workspaceId/opportunities/bulk-upsert | Workspace write | |
| PATCH | /workspaces/:workspaceId/opportunities/:id | Workspace write | |
| DELETE | /workspaces/:workspaceId/opportunities/:id | Workspace write |
closePlan and closingNotes accept null and are stored as empty strings.
Contact, company, and opportunity writes use the same customer fields as the Zapier CRM records, plus /_salesforceId and customFields.
Shared status and stage values are the same as the REST API.
Research, enrich, and contact search
Research and enrich are asynchronous. The start call returns 202 with a job id. Poll the status path until finished is true. A research or enrich that is already running returns 202 with finished: false and does not start a second run.
| Method | Path | Scope | Purpose |
|---|---|---|---|
| POST | /workspaces/:workspaceId/leads/:id/research | Leads write | Start lead research |
| GET | /workspaces/:workspaceId/lead-research/:leadResearchId | Leads read | Lead research status |
| POST | /workspaces/:workspaceId/leads/:id/enrich | Leads write | Start lead enrich |
| GET | /workspaces/:workspaceId/lead-enrichments/:leadEnrichmentId | Leads read | Lead enrich status |
| POST | /workspaces/:workspaceId/contacts/:id/research | Workspace write | Start contact research |
| GET | /workspaces/:workspaceId/contact-research/:contactResearchId | Workspace read | Contact research status |
| POST | /workspaces/:workspaceId/contacts/:id/enrich | Workspace write | Start contact enrich |
| GET | /workspaces/:workspaceId/contact-enrichments/:contactEnrichmentId | Workspace read | Contact enrich status |
| POST | /workspaces/:workspaceId/companies/:id/research | Workspace write | Start company research |
| GET | /workspaces/:workspaceId/company-research/:companyResearchId | Workspace read | Company research status |
| POST | /workspaces/:workspaceId/companies/:id/contact-searches | Workspace write | Find people at a company |
| GET | /workspaces/:workspaceId/contact-searches/:contactSearchId | Workspace read | Contact-search status |
Contact search body:
{ "jobTitle": "VP Sales", "exactMatch": false, "limit": 10 }
limit is 1–100 and defaults to 10. The start response includes contactSearchId, companyId, status (pending, processing, completed, failed), and finished.
Research and enrich status bodies include status, finished, success, failed, data, and error (code and message) when the job failed.
Fields, items, and agents
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /workspaces/:workspaceId/fields?instance=lead | Workspace read | Selectable fields for lead, contact, company, or opportunity |
| POST | /workspaces/:workspaceId/items | See below | Read selected fields for many records |
| GET | /workspaces/:workspaceId/agents | Agents read | Agents in the workspace |
| GET | /workspaces/:workspaceId/agents/:id | Agents read | One agent |
Body for POST /workspaces/:workspaceId/items:
{
"instance": "lead",
"fieldKeys": ["name", "email", "status"],
"limit": 100,
"cursor": null,
"search": "acme"
}
fieldKeys has 1–200 entries. limit is 1–1000. search and filter cannot be sent together. Lead items require leads read. Other instances require workspace read.
The response is { "workspaceId", "instance", "items", "total", "hasMore", "nextCursor" }.