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

# Salesforce Find or Create

> Finds a Salesforce record by matching several fields at once and returns its ID, creating it first if nothing matches.

Looks for one Salesforce record by matching several fields at once. If exactly one record matches, its ID comes back. If none does, the record is created and the new ID comes back. Display name **"Salesforce Find or Create"**. Off by default.

Use it wherever an agent needs the ID of a record that may or may not exist yet — a parent header row that later line items must point at, for example. It replaces a `salesforce_query` followed by a `salesforce_create_record`, in one call, and two Agents runs cannot both create the same record.

## Authentication and enablement

Needs an active **Salesforce** integration in the workspace. The access token and the org's `instance_url` are injected into every call from that integration; the model never sees or supplies them. The connected user needs read and create permission on the object.

Off by default. Enable it per agent.

## Inputs

* `object` — **required.** Salesforce object API name. Custom objects end in `__c`, e.g. `HC2_Application_Verification_Item__c`. Use `salesforce_list_objects` to discover them.
* `match` — **required.** A JSON **object string** of field API name to value. Every pair must match for a record to count, so give enough fields to identify the record uniquely. Values may be strings, numbers, booleans or null. Example: `{"Application__c":"a01Hs00001abc","HC2_Applicant__c":"a02Hs00001def","Name__c":"Payslip"}`.
* `fields` — **required.** A JSON **object string** of the values to set when the record has to be created. Include the match fields themselves, or the record you create will not match next time.
* `return_fields` — optional list of field API names to return alongside the ID when an existing record is found.

`match` and `fields` are JSON strings rather than nested objects because a Salesforce field set is per-org and unknowable at schema time; a property-less object is rejected by Gemini function-calling and would fail the whole decision call.

## Output

Structured result: `record_id`, `created` (true when it had to create), `object`, `match`, `record` (the matched record's fields, when one was found), `warnings[]`, `completed_at`. The summary line says which of the two happened.

## Limits and side effects

* Creates **at most one** record per call, and only when nothing matched.
* A match of **two or more** records is an error and nothing is written. Picking one would stamp an arbitrary ID onto everything downstream, so the tool names the count and the IDs and asks for a narrower `match`.
* Field and object names are validated as Salesforce API names; match values are escaped as SOQL literals.
* The lookup is `LIMIT 2` — the tool only needs to tell none from one from more than one.

## Concurrency: what is and is not guaranteed

The find and the create are held under one Postgres advisory lock keyed on the org, object and match, so **two Agents runs cannot both create the same record** — the second waits, then finds what the first created. A run that cannot take the lock within 60 seconds returns an error and writes nothing.

The lock does **not** extend to writers outside Agents. A person in the Salesforce UI, another integration, or a data loader can still create a matching record in the same instant. The tool re-runs the match after its own create and, if more than one record now matches, says so in `warnings` rather than leaving the duplicate to be found later. If you need a hard guarantee, put a unique constraint on the matched fields in Salesforce; then the duplicate create is rejected by Salesforce itself.

## Expected errors

* `no Salesforce access token was provided…` / `no Salesforce instance_url was provided…` — no active integration, or it needs reconnecting.
* `match is required and must be a JSON object string…`, `match must contain at least one field…`, `fields is required…` — validation; nothing was written.
* `match field "…" is not a valid Salesforce API name` — a field name that is not an identifier.
* `match is ambiguous: N … records match it (…)` — narrow the match; nothing was created.
* `another run is already finding or creating this … record` — the lock was busy; nothing written, retry.
* `salesforce rejected the create on …: REQUIRED_FIELD_MISSING: …` — Salesforce's own validation, with the offending fields named.
* `salesforce session expired or invalid…`, `salesforce API request limit exceeded…` — operational; reconnect, or wait for the quota to reset.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.