Skip to main content

Salesforce

Read and write a Salesforce org - any standard or custom object - with SOQL and SOSL, single and bulk writes, change tracking for sync, and saved reports.

Connect a Salesforce org through a connected app to work its data end to end: discover the org's own objects, fields, picklists and relationships; query with SOQL (including parent traversal, child subqueries and aggregates) and search across objects with SOSL; read records singly or 200 at a time; create, update, upsert and delete them one by one or in batches of 200; track what changed or was deleted in a window to keep an outside system in sync; and run saved reports. Custom objects need no dedicated tools - they are object types passed to the generic record tools.

Connect

Credential fieldRequiredWhere it comes from
Consumer Key (CONSUMER_KEY)YesThe connected app's Consumer Key, from Setup → App Manager → your app → View → Manage Consumer Details.
Consumer Secret (CONSUMER_SECRET)YesThe connected app's Consumer Secret, from the same screen. Rotating it in Salesforce invalidates the one stored here.
SettingRequiredWhat it is
Instance URL (INSTANCE_URL)YesThe org's My Domain address, e.g. https://acme.my.salesforce.com (sandbox: https://acme--uat.sandbox.my.salesforce.com). Every call on this connection goes to this host. login.salesforce.com will not work.
API Version (API_VERSION)NoThe Salesforce REST version tools call, as vNN.N. Leave blank for v62.0; Get org lists what this org offers.

Tools

ToolAccessWhat it does
Get org (yekar.salesforce.get-org)ReadConfirm the connection works and report what it is connected to: the org's My Domain host, the REST API version these tools call, whether a newer one is available, and the org's API request and storage limits. Call this first when a write is failing for reasons that look like limits or permissions - it is the tool that says whether the daily API allowance is the problem.
List objects (yekar.salesforce.list-objects)ReadEvery sObject type this org has - standard and custom - with its API name, label, id key prefix and whether it can be queried, created, updated or deleted. This is the discovery path before any other tool: object API names are org-specific, custom ones end in __c, and guessing them produces INVALID_TYPE errors. Filter by substring to find an object by name.
Describe object (yekar.salesforce.describe-object)ReadThe full shape of one sObject: every field with its type, length, whether it is required, writable, unique or an external id, its picklist values, and what a lookup points at - plus the child relationships a SOQL subquery can traverse and the object's record types. Call this before writing to an object: field API names are org-specific, picklists reject unlisted values, and formula and rollup fields cannot be set at all. Pass fields to read just the ones you need.
Get record counts (yekar.salesforce.get-record-counts)ReadHow many records each named sObject holds, from Salesforce's record-count index - one call for many objects, without querying any of them. Use this to size an object before paging it. The counts are approximate and omit objects the connected app's user cannot see; for an exact number use Query with SELECT COUNT().
Query (yekar.salesforce.query)ReadRun SOQL and get the matching records plus Salesforce's own total for the whole result set - the tool to reach for whenever you need records, a filtered set, or a COUNT. SOQL supports parent traversal (Account.Owner.Name), child subqueries (SELECT Id, (SELECT Id, Subject FROM Cases) FROM Account), date literals like LAST_N_DAYS:30, and aggregates. There is no SELECT *: name each field, and use Describe object to learn which exist. Results arrive in batches - pass the returned cursor back to continue.
Search (yekar.salesforce.search)ReadFind records by text across many objects at once with SOSL - the tool for 'is there anything about Acme in this org?' when you do not know which object holds it. Searches the org's text index rather than scanning rows, so it is fast and fuzzy where Query is exact. It returns no total and is capped by its LIMIT, so use Query whenever you need a count or every match.
Get record (yekar.salesforce.get-record)ReadRead one record by its Salesforce id, or by one of your own keys via an External Id field. Unlike Search this reads the record directly, so it sees writes immediately. Ask for the fields you need - omitting them returns every readable field on the object, which on a customized Account can be hundreds.
Get records (yekar.salesforce.get-records)ReadRead up to 200 records of one object type by id in a single call - the efficient way to hydrate a list of ids that Query, Search or List changed records handed back. Field names are required. Ids the connected app cannot see come back in notFound rather than being quietly dropped.
List changed records (yekar.salesforce.list-changed-records)ReadWhich records of an object were created, modified or deleted inside a time window - the primitive for keeping something in sync with Salesforce without re-reading everything. Returns ids; pair it with Get records to hydrate them. The window must be between one minute and 30 days, and deletions age out of Salesforce's index (roughly with the recycle bin), so earliestDateAvailable says how far back the answer is trustworthy.
Create record (yekar.salesforce.create-record)WriteCreate one record of any sObject type - Account, Contact, Lead, Opportunity, Case, a Task, or any custom object - from a field map. Call Describe object first: field API names are org-specific, required fields are marked there, picklists reject unlisted values, and formula and rollup fields cannot be set. Returns the new record's id.
Update record (yekar.salesforce.update-record)WriteChange fields on one existing record. This is a partial update: only the fields you pass are touched, and passing null clears one. Salesforce answers a successful update with no body, so the response echoes what was sent rather than re-reading the record - call Get record afterwards if you need the stored values, which formulas and rollups will have recalculated.
Upsert record (yekar.salesforce.upsert-record)WriteCreate or update one record keyed by an External Id field - the safe way to write a record from an outside system, because running it twice converges on one record instead of creating two. The field must be marked External Id on the object (see Describe object). If the key value matches more than one existing record, Salesforce refuses rather than guessing, and the error names the duplicates.
Delete record (yekar.salesforce.delete-record)WriteMove one record to the org's recycle bin. This is a soft delete - the record is restorable for about 15 days and still readable through Query with includeDeleted - but it also cascades: deleting a parent takes its master-detail children with it, and Salesforce does not list them first. Deleting an already-deleted record is an error, not a no-op.
Batch write records (yekar.salesforce.batch-write-records)WriteCreate, update, upsert or delete up to 200 records of one object type in a single call - the right tool for a bulk change, and far cheaper against the org's API allowance than 200 separate ones. By default the whole batch rolls back if any record fails; set allOrNone false to let the successes through. Every result carries its position in the request, so a failure points at the record that caused it.
List reports (yekar.salesforce.list-reports)ReadThe reports Salesforce lists as recently viewed for the connected app's user, with their ids for Run report. This is deliberately not the org's whole report catalogue - for that, query the Report object with Query, which searches every report the user can see.
Run report (yekar.salesforce.run-report)ReadExecute a saved Salesforce report and return its totals - and, on request, its rows. The totals come from Salesforce's own aggregation, so they are the numbers to quote rather than anything counted from the rows. Filters can be overridden for a single run without touching the saved report. Watch complete: a report that hit Salesforce's 2,000-row synchronous ceiling reports totals for a truncated set, and this response says so instead of letting the number pass as fact.

Notes

  • In Salesforce go to Setup → App Manager → New Connected App → Create an API integration, and name it (e.g. "Yekar.AI").
  • Tick Enable OAuth Settings. The callback URL is unused by this flow but the form requires one - any https URL will do. Under Selected OAuth Scopes add at minimum "Manage user data via APIs" (api); add "Access unique identifier" (openid) if you want identity, and note that these scopes are the ceiling for every tool here.
  • Still in the OAuth settings, tick "Enable Client Credentials Flow" and choose the Run As user. That user's profile, permission sets and sharing decide what Yekar.AI can see and change - pick a dedicated integration user with exactly the access you intend, not an administrator.
  • Save, then wait a few minutes: Salesforce takes up to ten to propagate a new connected app, and calls before then fail as if the credentials were wrong.
  • Open the app (App Manager → your app → View) → Manage Consumer Details, and paste the Consumer Key and Consumer Secret here.
  • Set Instance URL to the org's My Domain address - Setup → My Domain shows it, e.g. https://acme.my.salesforce.com. A sandbox looks like https://acme--uat.sandbox.my.salesforce.com. login.salesforce.com does NOT work: the client-credentials flow is served only from My Domain.
  • Optionally pin API Version if this org needs a specific REST version; Get org reports the one in use and the newest available.
  • Add one credential per org - a production and a sandbox connected app can live on the same connection.