The real problem
Why this is harder than it looks
Most teams underestimate what "Salesforce OAuth" actually requires. The authorization flow itself is straightforward. The problems start after the user approves your app.
In production, each of your customers' employees connects their own Salesforce org. Access tokens expire — you need refresh logic that runs before expiry, not after a failed call. If a user revokes access inside Salesforce, you need to detect it and stop making calls on their behalf. Sandbox orgs use a different base URL than production; your code has to handle both without asking the user to configure anything. And if you're building a product — not an internal tool — the consent screen should show your brand, not a third-party library's name.
None of this is impossible to build. But it's a month of work that doesn't move your agent forward. And then you do it again for the next connector.
Scalekit is the infrastructure layer that handles all of it. Your agent names a tool and passes parameters. Scalekit takes care of which token to use, whether it's still valid, and what to do if it isn't.
Capabilities
What your agent can do with Salesforce
Once connected, your agent has 25 pre-built tools covering the full Salesforce object model:
- Query anything with SOQL: filtered lists, aggregations, cross-object joins, custom fields
- Create and update pipeline records: accounts, opportunities, contacts as deals move through stages
- Full-text search with SOSL: across multiple Salesforce objects simultaneously
- Atomic batch operations: create a Contact and link an Opportunity in one round trip via the Composite API
- Schema introspection at runtime: describe any SObject, check org API limits, read report metadata
Setup context
What we're building
This guide connects a sales assistant agent to Salesforce — helping reps query accounts, surface open opportunities, and create records without leaving your product.
🤖
Example agent
Sales assistant managing pipeline on behalf of each rep
🔐
Auth model
B2B SaaS — each rep connects their own org. identifier = your user ID
Setup context
1 Setup: One SDK, One credential
Install the Scalekit SDK. The only credential your application manages is the Scalekit API key — no Salesforce secrets, no user tokens, nothing belonging to your customers.
Connected Accounts
2 Per-User Auth: Creating connected accounts
Each rep gets their own Connected Account, giving them a dedicated auth context. The identifier is any unique string from your system — a UUID, email, whatever you use internally
This call is idempotent — safe to call on every session start. Returns the existing account if one already exists.
Authorization Flow
3 The authorization flow
The rep authorizes your agent once. Scalekit generates the OAuth URL with correct scopes, PKCE challenge, and redirect handling pre-configured. After approval, you never see the token.
This call is idempotent — safe to call on every session start. Returns the existing account if one already exists.
Token management is automatic
After the user approves, Scalekit stores encrypted tokens and the connected account moves to ACTIVE. Access tokens refresh 5 minutes before expiry. If a rep revokes access in Salesforce, the account moves to REVOKED — no silent failures. Check account.status before critical operations.
Enterprise branding: Bring Your Own Credentials
For deployments where users should see your app name on the consent screen, register your own Salesforce Connected App credentials in the Scalekit dashboard. Token management stays fully handled.
Already have credentials?
Tool reference
All 25 Salesforce tools
Grouped by object and capability. Your agent calls tools by name — no API wrappers to write.
salesforce_account_create
Create a new account with billing address, industry, revenue, and company metadata
Retrieve a single account by ID with all standard and custom fields
salesforce_account_update
Update any field on an existing account record
salesforce_account_delete
Soft-delete an account from the org
salesforce_account_create
Create an opportunity with stage, amount, close date, and account association
Retrieve a specific opportunity by ID with field selection
salesforce_account_update
Update stage, amount, close date, or any other opportunity field
salesforce_account_delete
List opportunities with pagination
salesforce_account_create
Create a contact with name, email, phone, job title, and account association
Retrieve a specific contact by ID with field selection
Execute any SOQL query — filters, joins, aggregations, custom fields
Alternative SOQL execution endpoint for custom query patterns
Full-text search across multiple Salesforce objects simultaneously
salesforce_search_parameterized
Simplified search with predefined parameters — object type, fields, search text
salesforce_sobject_create
Create a record for any SObject type — standard or custom objects
Retrieve any SObject record by ID and type
salesforce_sobject_update
Update any SObject record. Only the fields provided are changed
salesforce_sobject_delete
Permanently delete any SObject record by ID
Create a record for any SObject type — standard or custom objects
salesforce_global_describe
Retrieve any SObject record by ID and type
salesforce_object_describe
Update any SObject record. Only the fields provided are changed
Update any SObject record. Only the fields provided are changed
salesforce_dashboard_metadata_get
Update any SObject record. Only the fields provided are changed
salesforce_report_metadata_get
Retrieve structure, fields, groupings, and configuration for a specific report
Connector notes
Salesforce-Specific behavior
Sandbox vs. production — handled automatically
Salesforce sandbox orgs use a different base URL for API calls than production orgs. Scalekit detects this based on which environment the user authorizes through and routes accordingly. No code changes needed.
Connected App IP restrictions cause silent 401s
If your Salesforce Connected App has IP range restrictions configured, tokens may fail silently for users outside those ranges. This is a Salesforce org configuration issue. If you see unexplained 401s after successful authorization, check the Connected App's IP restriction settings in Salesforce Setup.
Infrastructure decision
Why not build this yourself
The Salesforce OAuth flow is documented. Token storage isn't technically hard. But here's what you're actually signing up for:
PROBLEM 01
Org-specific token endpoints and sandbox vs. production URL handling that varies by configuration
PROBLEM 02
Refresh token rotation behavior that differs by Connected App config — silent failures if handled wrong
PROBLEM 03
Revocation detection and graceful handling when users disconnect from Salesforce org settings
PROBLEM 04
Scoped, zero-trust credential architecture — your app stores zero Salesforce credentials by design
That's one connector. Your agent product will eventually need Slack, Gmail, HubSpot, Notion, and whatever else your customers ask for. Each has its own OAuth quirks and failure modes.
Scalekit maintains every connector. You maintain none of them.
Connect your agent to Salesforce in minutes
Free to start. No Salesforce Connected App required. Token management fully handled.
salesforce_sobject_create
Create a record for any SObject type — standard or custom objects
Retrieve any SObject record by ID and type
salesforce_sobject_update
Update any SObject record. Only the fields provided are changed
salesforce_sobject_delete
Permanently delete any SObject record by ID
salesforce_sobject_create
Create a record for any SObject type — standard or custom objects
Create a record for any SObject type — standard or custom objects
Retrieve any SObject record by ID and type
Retrieve any SObject record by ID and type
salesforce_sobject_update
Update any SObject record. Only the fields provided are changed
Update any SObject record. Only the fields provided are changed
salesforce_sobject_delete
Permanently delete any SObject record by ID
Permanently delete any SObject record by ID
salesforce_sobject_create
Create a record for any SObject type — standard or custom objects
Create a record for any SObject type — standard or custom objects
Create a record for any SObject type — standard or custom objects
Retrieve any SObject record by ID and type
Retrieve any SObject record by ID and type
Retrieve any SObject record by ID and type
salesforce_sobject_update
Update any SObject record. Only the fields provided are changed
Update any SObject record. Only the fields provided are changed
Update any SObject record. Only the fields provided are changed
salesforce_sobject_delete
Permanently delete any SObject record by ID
Permanently delete any SObject record by ID
Permanently delete any SObject record by ID
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Block quote
Ordered list
- Item 1
- Item 2
- Item 3
Unordered list
Text link
Bold text
Emphasis
Superscript
Subscript