Integrations · Salesforce

Salesforce Enrichment API — Apex Callout, Flow or Middleware

We have no Salesforce app and no AppExchange listing. Nothing to install. You reach RichAPI from Salesforce through an Apex callout on a Named Credential, an HTTP Callout in Flow, or middleware sitting between the two, and you write the result to the object yourself.

In short: RichAPI has no Salesforce managed package and no AppExchange listing. There is nothing to install in a Salesforce org. Integration is done by calling the RichAPI REST API at https://api.richapi.ai/api/v1/{endpoint} with an x-api-key header from one of three places: Apex (HttpRequest, typically inside a Queueable or Batch class), a Flow HTTP Callout action, or external middleware such as n8n, Make or Zapier that reads from and writes back to Salesforce. The API key should be stored in a Salesforce External Credential with a Named Credential pointing at https://api.richapi.ai, not hardcoded in Apex. Apex forbids callouts after DML in the same transaction and caps callouts per transaction, so bulk enrichment belongs in asynchronous Apex. RichAPI returns JSON; writing it to Lead, Contact or Account fields is done by the customer. Endpoints include email_finder, email_verifier, phone_finder, enrich_company and enrich_profile (both take a LinkedIn URL, not a domain), find_linkedin_url_by_email and people_search. Waterfall endpoints (email_finder, email_verifier, phone_finder) return HTTP 200 with success false and billed false on a miss and cost zero credits; other endpoints bill on any successful 2xx. RichAPI does not send email and does not write to any CRM itself. New accounts get 100 free credits with no card.

Last updated November 4, 2026

Connect it

  1. 1. Create a RichAPI account at app.richapi.ai/signup and copy your API key.

    100 free credits, no card.

  2. 2. In Salesforce Setup, create an External Credential (Custom authentication protocol) holding the key, and a Named Credential pointing at https://api.richapi.ai. This keeps the key out of Apex source and out of anyone's git history.

  3. 3. Grant the External Credential principal to the permission set of whoever will run the enrichment.

  4. 4. Pick a path: Apex for anything asynchronous or bulk, Flow HTTP Callout for a single record on a button or a record-triggered event, middleware if you would rather not deploy Apex at all.

  5. 5. Write the fields to Lead, Contact or Account yourself.

    We return JSON; mapping it onto your object model is yours, and it is the part that would be wrong if we shipped an app anyway.

Salesforce

What you can ask for

Record-triggered Flow on Lead create:
Record-triggered Flow on Lead create: call email_finder on the name and website, write Email and a Source field, and skip the assignment rule if it misses.
Queueable Apex over an Account
Queueable Apex over an Account list view: enrich_company on each, update Industry and NumberOfEmployees where they are blank.
Quick Action on Contact: find_linkedin_url_by_email,
Quick Action on Contact: find_linkedin_url_by_email, then enrich_profile, then write the headline and seniority into custom fields.
Nightly Batch Apex: re-verify every
Nightly Batch Apex: re-verify every Lead email older than 90 days and flag the invalid ones before the next campaign.
Middleware route: new Lead webhook
Middleware route: new Lead webhook → phone_finder → PATCH the record back through the Salesforce REST API.

Why it Matters

Every enrichment vendor with a managed package is also a vendor whose field mapping you will spend a week fighting. Doing it as a callout means you decide which object, which field, and what happens on a miss. A miss on our waterfall endpoints costs you nothing, so the nightly re-verify job is affordable to run.

Salesforce enrichment: there is no app to install

We have no AppExchange listing, no managed package, and no Salesforce-native app. If you came here to click Install, stop reading and go look at a vendor who has one. That is a real reason to pick someone else and we would rather you find out in the first paragraph than after a sales call.

What we have is an HTTP API that Salesforce can call three different ways. All three work. None of them involve a package upgrade breaking your sandbox.

Store the key properly first

Setup → Named Credentials. Create an External Credential using the Custom authentication protocol, with a named principal carrying a parameter for the API key. Then a Named Credential pointing at https://api.richapi.ai, referencing that external credential, with x-api-key set from the principal parameter.

Then grant the principal on a permission set. Do this before you write anything, because the alternative is an API key in an Apex class in a repo, and that key is now in every sandbox refresh anyone has ever taken.

Path one: Apex

This is the path for anything bulk or asynchronous, which is most of it.

public class RichApiEnrich implements Queueable, Database.AllowsCallouts {
    private List<Id> leadIds;
    public RichApiEnrich(List<Id> ids) { this.leadIds = ids; }

    public void execute(QueueableContext ctx) {
        List<Lead> toUpdate = new List<Lead>();
        for (Lead l : [SELECT Id, Name, Website FROM Lead WHERE Id IN :leadIds]) {
            HttpRequest req = new HttpRequest();
            req.setEndpoint('callout:RichAPI/api/v1/email_finder');
            req.setMethod('POST');
            req.setHeader('Content-Type', 'application/json');
            req.setBody(JSON.serialize(new Map<String, Object>{
                'full_name' => l.Name, 'company_domain' => l.Website }));
            HttpResponse res = new Http().send(req);
            Map<String, Object> body =
                (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
            if (body.get('success') == true) {
                Map<String, Object> d = (Map<String, Object>) body.get('data');
                toUpdate.add(new Lead(Id = l.Id, Email = (String) d.get('email')));
            }
        }
        if (!toUpdate.isEmpty()) update toUpdate;
    }
}

Two Salesforce constraints shape this and you cannot design around them:

  • No callouts after DML in the same transaction. Enrich, collect, then update once at the end. The loop above does that on purpose.
  • Callouts per transaction are capped. Chunk the list and chain Queueables, or use Batch Apex with a small scope size. A list view button that tries to enrich a thousand leads synchronously will fail, and it will fail in a way that looks like our API broke.

Check body.get('success') and not the status code. A waterfall miss returns 200 with "success": false and "billed": false. If you branch on res.getStatusCode() == 200 you will write blank emails onto good leads.

Path two: Flow

For one record at a time, on a button or a record-triggered Flow, the HTTP Callout action in Flow Builder works without a line of Apex. Point it at the Named Credential, give it a sample response so Flow can build the data structure, and branch on success in a Decision element.

Flow can also generate the invocable action from an OpenAPI spec via External Services. Ours is live at api.richapi.ai/api/v1/openapi.json. The import is fussy about schema features and we have not certified it.

Flow is the wrong tool for volume. One record, on demand, is what it is good at.

Path three: middleware

If you do not want Apex in your org at all, put n8n or Make in the middle. New Lead fires a webhook, the middleware calls us, and its Salesforce node writes the record back. You trade a deployment for a subscription and a second place where things can break.

Cost, and why the re-verify job is affordable

Endpoint Cost
email_finder 5 credits
email_verifier 2 credits
phone_finder 25 credits
enrich_company / enrich_profile 1 credit
find_linkedin_url_by_email 4 credits

Full price only on results, scoped: email_finder, email_verifier and phone_finder cost zero when every source comes back empty. The rest bill on a successful 2xx even if the payload is thin. Nothing non-2xx ever bills. Tiers on /pricing.

That scoping is what makes a nightly hygiene job sane. Running email_verifier across a stale database costs you the hits and not the dead rows.

Store execution_log on the record next to the enriched fields. Waterfall calls return one entry per attempt with a status, and a year later that is the only evidence of why a field is blank. Write it to a long text field on the record and your "why is this lead missing an email" question becomes answerable a month later.

Where we stop with Salesforce

No app, no field mapping, no sync, no sending, no prospecting UI, no SCIM. We return JSON. You own the object model, and honestly you should. Nobody's managed package has ever guessed your custom fields correctly.

Related: company enrichment API, email verifier API, HubSpot for the other CRM with the same answer, verify before sequence push, and the full integrations index.

Salesforce FAQ

Is RichAPI on the AppExchange? No. No listing, no package, no plans we can promise on a marketing page.

Can I install this in a sandbox and test it? Yes. Named Credential plus the Apex above, on the 100 free credits.

Does it write to Salesforce itself? No. We answer lookups. Every write is yours, which is also why there is no sync to break.

What about Salesforce's callout limits? They are Salesforce platform limits, not ours. Asynchronous Apex with chunking is the standard answer; check the current numbers in Salesforce's own limits documentation.

Does enrich_company take a website? No, a LinkedIn company URL. Resolve the domain first if that is all the Account has.

Can I give each business unit its own key? Named keys with per-key usage attribution, yes. Not per-key credit budgets, because the pool is shared.

Start with Salesforce

100 free credits, no card. Build the Named Credential and run one Queueable against ten leads before you commit to anything.

FAQ

Frequently asked questions

No — Salesforce Enrichment API — Apex Callout, Flow or Middleware authenticates through the connection you set up, using the same key and credit pool as the REST API. Revoking access from your RichAPI dashboard disconnects it immediately.
No — MCP and REST share the same credit pool and the same published endpoint rates. There's no separate MCP surcharge.

More from RichAPI

More companies

Browse company profiles with company overviews, key details, and email formats.

Start free with 100 credits

Get 100 free credits to explore RichAPI with no card required.

Free tools

Use our Email Permutator, llms.txt Generator, Waterfall Calculator, and live API demo — all free to try.

Related integrations