> ## Documentation Index
> Fetch the complete documentation index at: https://lava.so/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Salesforce

> Salesforce REST API access for querying and managing CRM records (Accounts, Contacts, Leads, Opportunities, and custom objects) in a connected user's org.

Salesforce REST API access for querying and managing CRM records (Accounts, Contacts, Leads, Opportunities, and custom objects) in a connected user's org. Use when an agent needs to run SOQL queries, look up or create records, update fields, or discover an org's object schema. Routes through Pipedream Connect — the user sees one Salesforce consent screen on connect that says "Pipedream wants access" (Pipedream owns the connected app), and all calls run under that user's own Salesforce permissions. Works with any org instance (production or sandbox) without the caller needing to know the org's My Domain.

9 example endpoints available through Lava's AI Gateway. See the [Salesforce API docs](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/) for full documentation.

<Warning>This provider requires your own credentials — connect your API key or OAuth account before use.</Warning>

<Info>This is a **catch-all provider** — any valid URL under `https://instance.my.salesforce.com` is supported. Salesforce REST API endpoints. Construct URLs as [https://instance.my.salesforce.com/services/data/v62.0/\&#123;path\&#125](https://instance.my.salesforce.com/services/data/v62.0/\&#123;path\&#125); — the literal host `instance.my.salesforce.com` always works because the gateway routes by path and Pipedream resolves the connected org's real instance automatically (the org's actual My Domain host works too). Common roots: query?q=\{SOQL} (URL-encode the SOQL), sobjects (list object types), sobjects/\{type}/describe (field schema), sobjects/\{type}/\{id} (read; add ?fields=A,B), sobjects/\{type} (POST create), sobjects/\{type}/\{id} (PATCH update, DELETE). Updates use PATCH (never PUT) and return 204 No Content on success, as does DELETE. The Lava gateway requires a JSON body on every non-GET call — for DELETE, send an empty object as body\_json. Paginate queries via the relative nextRecordsUrl in the response (request it against the same host). All calls run under the connected user's Salesforce permissions; the org must be an edition with API access (Enterprise, Unlimited, Developer, Performance). See [https://developer.salesforce.com/docs/atlas.en-us.api\_rest.meta/api\_rest/](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/) for the full reference. The endpoints below are curated examples.</Info>

## Endpoints

### List the REST API versions available in the connected org. Use this as a cheap auth probe after connect — confirms the OAuth grant is healthy and tells you the newest version to put in paths.

**GET** `https://instance.my.salesforce.com/services/data` — Free

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    const data = await lava.gateway('https://instance.my.salesforce.com/services/data', { method: 'GET' });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl "https://api.lava.so/v1/forward?u=https%3A%2F%2Finstance.my.salesforce.com%2Fservices%2Fdata" \
      -H "Authorization: Bearer $LAVA_SECRET_KEY"
    ```
  </Tab>
</Tabs>

### Run a SOQL query — the workhorse for every "find/list/report" question. URL-encode the SOQL in the q param. Control response size with the SELECT field list and LIMIT. If done=false in the response, fetch the relative nextRecordsUrl against the same host for the next page.

**GET** `https://instance.my.salesforce.com/services/data/v62.0/query?q=SELECT%20Id%2C%20Name%2C%20StageName%2C%20Amount%20FROM%20Opportunity%20WHERE%20IsClosed%20%3D%20false%20ORDER%20BY%20CloseDate%20LIMIT%2025` — Free

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    const data = await lava.gateway('https://instance.my.salesforce.com/services/data/v62.0/query?q=SELECT%20Id%2C%20Name%2C%20StageName%2C%20Amount%20FROM%20Opportunity%20WHERE%20IsClosed%20%3D%20false%20ORDER%20BY%20CloseDate%20LIMIT%2025', { method: 'GET' });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl "https://api.lava.so/v1/forward?u=https%3A%2F%2Finstance.my.salesforce.com%2Fservices%2Fdata%2Fv62.0%2Fquery%3Fq%3DSELECT%2520Id%252C%2520Name%252C%2520StageName%252C%2520Amount%2520FROM%2520Opportunity%2520WHERE%2520IsClosed%2520%253D%2520false%2520ORDER%2520BY%2520CloseDate%2520LIMIT%252025" \
      -H "Authorization: Bearer $LAVA_SECRET_KEY"
    ```
  </Tab>
</Tabs>

### Full-text search across objects (SOSL without the syntax). Use when you have a free-text term (a person's name, a company) and don't know which object or field it lives in. Scope with sobject= and limit fields per object via sobject.\{type}.fields.

**GET** `https://instance.my.salesforce.com/services/data/v62.0/parameterizedSearch?q=Acme&sobject=Account&Account.fields=Id,Name,Industry&Account.limit=10` — Free

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    const data = await lava.gateway('https://instance.my.salesforce.com/services/data/v62.0/parameterizedSearch?q=Acme&sobject=Account&Account.fields=Id,Name,Industry&Account.limit=10', { method: 'GET' });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl "https://api.lava.so/v1/forward?u=https%3A%2F%2Finstance.my.salesforce.com%2Fservices%2Fdata%2Fv62.0%2FparameterizedSearch%3Fq%3DAcme%26sobject%3DAccount%26Account.fields%3DId%2CName%2CIndustry%26Account.limit%3D10" \
      -H "Authorization: Bearer $LAVA_SECRET_KEY"
    ```
  </Tab>
</Tabs>

### List the object types in the org (standard and custom) with their CRUD flags. Responses are projected to name/label/flags per object — pass filter \{"mode": "full"} for the raw payload. Use to discover custom objects (names end in \_\_c) before querying them.

**GET** `https://instance.my.salesforce.com/services/data/v62.0/sobjects` — Free

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    const data = await lava.gateway('https://instance.my.salesforce.com/services/data/v62.0/sobjects', { method: 'GET' });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl "https://api.lava.so/v1/forward?u=https%3A%2F%2Finstance.my.salesforce.com%2Fservices%2Fdata%2Fv62.0%2Fsobjects" \
      -H "Authorization: Bearer $LAVA_SECRET_KEY"
    ```
  </Tab>
</Tabs>

### Get an object's field schema: field names, types, picklist values, required-ness, and relationship names — what you need to write correct SOQL and valid create/update bodies. Responses are projected to schema essentials (raw describes run 500 KB+); pass filter \{"mode": "full"} for the complete metadata.

**GET** `https://instance.my.salesforce.com/services/data/v62.0/sobjects/Account/describe` — Free

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    const data = await lava.gateway('https://instance.my.salesforce.com/services/data/v62.0/sobjects/Account/describe', { method: 'GET' });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl "https://api.lava.so/v1/forward?u=https%3A%2F%2Finstance.my.salesforce.com%2Fservices%2Fdata%2Fv62.0%2Fsobjects%2FAccount%2Fdescribe" \
      -H "Authorization: Bearer $LAVA_SECRET_KEY"
    ```
  </Tab>
</Tabs>

### Read a single record by ID. Pass ?fields=A,B,C to fetch only what you need; omitting it returns every populated field. Record IDs are the 15/18-char values returned by queries.

**GET** `https://instance.my.salesforce.com/services/data/v62.0/sobjects/Account/001XXXXXXXXXXXXXXX?fields=Name,Industry,Website,OwnerId` — Free

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    const data = await lava.gateway('https://instance.my.salesforce.com/services/data/v62.0/sobjects/Account/001XXXXXXXXXXXXXXX?fields=Name,Industry,Website,OwnerId', { method: 'GET' });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl "https://api.lava.so/v1/forward?u=https%3A%2F%2Finstance.my.salesforce.com%2Fservices%2Fdata%2Fv62.0%2Fsobjects%2FAccount%2F001XXXXXXXXXXXXXXX%3Ffields%3DName%2CIndustry%2CWebsite%2COwnerId" \
      -H "Authorization: Bearer $LAVA_SECRET_KEY"
    ```
  </Tab>
</Tabs>

### Create a record. Body is a flat JSON object of field name → value; run describe first to learn required fields and picklist values. Returns 201 with \{id, success, errors}. Reference fields (e.g. AccountId) take a record ID.

**POST** `https://instance.my.salesforce.com/services/data/v62.0/sobjects/Contact` — Free

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    const data = await lava.gateway('https://instance.my.salesforce.com/services/data/v62.0/sobjects/Contact', {
      body: {
    "FirstName": "Ada",
    "LastName": "Lovelace",
    "Email": "ada@example.com",
    "Title": "CTO"
    },
    });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST "https://api.lava.so/v1/forward?u=https%3A%2F%2Finstance.my.salesforce.com%2Fservices%2Fdata%2Fv62.0%2Fsobjects%2FContact" \
      -H "Authorization: Bearer $LAVA_SECRET_KEY" \
      -H "Content-Type: application/json" \
      -d '{"FirstName":"Ada","LastName":"Lovelace","Email":"ada@example.com","Title":"CTO"}'
    ```
  </Tab>
</Tabs>

### Update fields on a record. Send only the fields you are changing — omitted fields are left untouched (Salesforce updates are always partial; there is no PUT). Returns 204 No Content on success.

**PATCH** `https://instance.my.salesforce.com/services/data/v62.0/sobjects/Opportunity/006XXXXXXXXXXXXXXX` — Free

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    const data = await lava.gateway('https://instance.my.salesforce.com/services/data/v62.0/sobjects/Opportunity/006XXXXXXXXXXXXXXX', { method: 'PATCH', body: {"StageName":"Negotiation/Review","Amount":50000} });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl -X PATCH "https://api.lava.so/v1/forward?u=https%3A%2F%2Finstance.my.salesforce.com%2Fservices%2Fdata%2Fv62.0%2Fsobjects%2FOpportunity%2F006XXXXXXXXXXXXXXX" \
      -H "Authorization: Bearer $LAVA_SECRET_KEY" \
      -H "Content-Type: application/json" \
      -d '{"StageName":"Negotiation/Review","Amount":50000}'
    ```
  </Tab>
</Tabs>

### Delete a record (moves it to the org Recycle Bin). Returns 204 No Content on success. The gateway requires a JSON body on every non-GET call, so send an empty object as body\_json. Prefer updating a status field when the workflow allows — deletes need the connected user to have delete permission on the object.

**DELETE** `https://instance.my.salesforce.com/services/data/v62.0/sobjects/Contact/003XXXXXXXXXXXXXXX` — Free

<Tabs>
  <Tab title="SDK">
    ```typescript theme={null}
    const data = await lava.gateway('https://instance.my.salesforce.com/services/data/v62.0/sobjects/Contact/003XXXXXXXXXXXXXXX', { method: 'DELETE', body: {} });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl -X DELETE "https://api.lava.so/v1/forward?u=https%3A%2F%2Finstance.my.salesforce.com%2Fservices%2Fdata%2Fv62.0%2Fsobjects%2FContact%2F003XXXXXXXXXXXXXXX" \
      -H "Authorization: Bearer $LAVA_SECRET_KEY" \
      -H "Content-Type: application/json" \
      -d '{}'
    ```
  </Tab>
</Tabs>

## Next Steps

<CardGroup cols={2}>
  <Card title="All Providers" icon="grid" href="/gateway/supported-providers">
    Browse all supported AI providers
  </Card>

  <Card title="Forward Proxy" icon="route" href="/gateway/forward-proxy">
    Learn how to construct proxy URLs and authenticate requests
  </Card>
</CardGroup>
