Skip to content
Salesforce Interview Q&A 19 min read 6 sections

Salesforce Integration Interview Questions and Answers

Integration is the round where a Salesforce developer interview stops being about syntax. The panel moves off Apex and LWC and asks how your org talks to an ERP or a payment gateway. These 25 questions are the integration set from a 200-question bank used for developers with five or more years of ex

RL

RizeX Labs

RizeX Labs

Published

Last updated

Related programme

Salesforce Training

Admin, Apex, Lightning Web Components and integrations in a live batch, with an industry project, mock interviews and a network of 270 hiring companies.

See the curriculum

3000+ learners · 270+ hiring partners

Integration is the round where a Salesforce developer interview stops being about syntax. The panel moves off Apex and LWC and asks how your org talks to an ERP or a payment gateway. These 25 questions are the integration set from a 200-question bank used for developers with five or more years of experience, covering REST and SOAP, the OAuth 2.0 flows, Named Credentials, callout limits and the event driven options.

Our trainer puts the failure mode plainly. "Do you know integrations? Yes. Where have you used it? Silence." The fix is naming the system, the direction of data, the authentication and the volume in one sentence.

REST, SOAP and the integration patterns

Difference between REST and SOAP

REST is an architectural style over HTTP that treats data as resources addressed by URI, with the HTTP verb carrying the intent. SOAP is a protocol that wraps every message in an XML envelope and publishes a formal contract through a WSDL.

REST API SOAP API
Format JSON or XML XML only
Contract Resource URIs, no contract file WSDL, generated per org
Verbs GET, POST, PATCH, DELETE HTTP POST for everything
Errors HTTP status code plus JSON body SOAP fault element

Enterprise WSDL is strongly typed and org-specific, so it breaks when the schema changes. Partner WSDL is loosely typed, so one client works against many orgs.

What is Inbound Integration?

Inbound means the external system calls Salesforce, so Salesforce is the server. The doors are the standard REST and SOAP APIs against sobjects, Apex REST through an @RestResource class when one call should do a validated multi-object operation, Apex SOAP web services for older clients, and Bulk API 2.0 for file-sized loads. Every inbound call consumes the daily API allocation and runs as the authenticated user, so profile, field-level security and sharing apply.

What is Webhook?

A webhook is a reverse API call. Rather than Salesforce polling for changes, the external system pushes an HTTP POST to a URL you registered with it the moment something happens.

Salesforce has no generic receiver, so you build one: an @RestResource class secured by a Connected App and OAuth, or by a signed shared secret. Validate the signature, write the payload to a staging object, acknowledge with a 2xx quickly, then process asynchronously. Do heavy work inside the request and the sender times out, retries, and you get duplicates.

What is Outbound Messaging?

The declarative outbound option. You define the object, the fields and an endpoint URL in Setup, then fire it from a record-triggered Flow or a workflow rule. Salesforce sends a SOAP message with those fields and, optionally, a session ID for callbacks. The endpoint must return an acknowledgement; without one Salesforce retries at increasing intervals for up to 24 hours before giving up. Ordering is not guaranteed. It needs no Apex and no Remote Site Setting.

What is Composite API?

Composite sends several REST subrequests in one HTTP round trip, saving latency and daily API allocation.

  • /composite takes up to 25 subrequests, runs them in order, and lets a later one reference an earlier one's output through @{refId.Id}. Set allOrNone to true and the whole set rolls back if any subrequest fails.
  • /composite/batch also takes up to 25 subrequests, but they are independent and do not roll back together.
  • /composite/sobjects creates, updates or deletes up to 200 records of one type per call.

What is Batch API?

In an integration conversation this means Bulk API, the asynchronous interface for large data volumes. With Bulk API 2.0 you create an ingest job naming the object and operation, upload the CSV, close the job, then poll status and pull the results. Salesforce splits the upload into batches and processes them in the background, in parallel by default or in serial to avoid record locking. Use it for nightly loads, never for something a user is waiting on.

How do you handle API versioning?

Every call names a version in the path, as in /services/data/vXX.0/sobjects/Account. That pins behaviour and field set, so three org upgrades a year do not silently break the client.

  • Pin an explicit version. Never let a client float to "latest".
  • Salesforce retires old versions after a long deprecation window, so plan the upgrade rather than learning about it from a failure.
  • Apex classes carry their own API version, and Apex REST behaves according to the class version, not the URL.
  • Version your own Apex REST mappings, such as /services/apexrest/v1/orders.

What is Middleware?

The layer between Salesforce and the other systems that owns routing, transformation, protocol mediation, retry and monitoring. MuleSoft, Dell Boomi and Azure Logic Apps are the common ones. You reach for it when point to point links grow faster than systems: five systems talking directly can mean twenty interfaces to maintain, where a hub in the middle means five.

What is MuleSoft's role?

MuleSoft is Salesforce's own integration platform, Anypoint Platform. Its role is API-led connectivity in three layers: System APIs expose raw backend access, Process APIs orchestrate logic across them, Experience APIs shape the payload for a consumer. It supplies the Salesforce Connector for CRUD, Bulk and platform event subscription, DataWeave for schema mapping, and API Manager for policies such as throttling.

Authentication and Connected Apps

What is Connected App?

The registration record for an external application that wants to talk to Salesforce. Creating one produces a Consumer Key and Consumer Secret, which are the OAuth client ID and client secret. It holds the OAuth scopes the client may request (api, refresh_token, openid, full), the callback URL, the certificate for JWT, the IP relaxation policy and which users are permitted to run it. Over-scoped integrations usually mean someone ticked full instead of api.

What is OAuth 2.0?

An authorisation framework. It lets an application obtain a time-limited access token to call an API on a user's behalf, without ever holding that user's password. The client sends the token as a bearer token in the Authorization header.

Flow Who it fits User present Secret
Web Server (authorisation code) Server-side app acting for a logged-in user Yes Yes
User-Agent (implicit) Browser or mobile app that cannot hold a secret Yes No
Refresh Token Renewing a token after the first grant No Yes
JWT Bearer Unattended server to server No Private key
Client Credentials Unattended server to server No Yes
SAML Bearer Assertion Client already holding a SAML assertion No No
Device A device with no browser On another device No

For a server to server integration with nobody at the keyboard, the right answer is the JWT Bearer Flow. No stored password, no refresh token, no interactive login, and it survives a password reset on the integration user. Client Credentials is the simpler alternative when the external system cannot sign a JWT; it authenticates the application rather than a user, so you configure a run-as user on the Connected App. The Username-Password Flow is the wrong answer: it stores a password and security token in the client, and Salesforce has been switching it off by default.

What is JWT Bearer Flow?

It exchanges a signed JSON Web Token for an access token. No browser, no user interaction, no refresh token.

  1. Generate a key pair and upload the certificate to a Connected App, ticking "Use digital signatures".
  2. Set Permitted Users to "Admin approved users are pre-authorised" and assign the integration user through a profile or permission set. Without this the token request is rejected.
  3. Build a JWT with iss as the Consumer Key, sub as the integration user's username, aud as https://login.salesforce.com (or https://test.salesforce.com for a sandbox), and exp within five minutes of now.
  4. Sign it with the private key using RS256.
  5. POST to /services/oauth2/token with grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer and assertion=<the signed JWT>.

There is no refresh token, and that is the point: when the token expires you mint and sign a new JWT.

What is SAML?

SAML 2.0 is an XML standard for single sign on. An Identity Provider authenticates the user and issues a signed assertion; the Service Provider trusts that assertion and creates a session without ever seeing the password. Keep the distinction clean: SAML is authentication and who the user is, OAuth is authorisation and what an application may do. Salesforce can act as Service Provider with an external IdP such as Okta, or as Identity Provider itself.

What is Remote Site Settings?

An allow-list entry in Setup naming an external URL that Apex is permitted to call. Without it, Http.send() to that host throws System.CalloutException: Unauthorized endpoint. It stores only the URL, so it carries no credentials and provides no authentication. For client-side calls from LWC or Visualforce, the equivalent allow-list is CSP Trusted Sites.

What is Named Credential?

A single Setup record holding both the endpoint URL and the authentication for a callout, so your Apex holds neither. You reference it by name in the endpoint and Salesforce substitutes the real URL and injects the authentication header at send time.

It removes two things at once. The Remote Site Setting becomes unnecessary because the Named Credential is itself the authorised endpoint registration; the platform already knows and trusts that host. The stored secret becomes unnecessary because the password, API key, client secret or certificate lives encrypted in the credential record and is never readable from Apex, so it cannot leak through a debug log, a test class or a source repository.

The current model splits this in two. The Named Credential holds the URL and callout options. The External Credential holds the authentication protocol, the principal, and the permission sets allowed to use that principal.

public with sharing class ErpOrderClient {

    public class ErpCalloutException extends Exception {}

    // 'ERP_Orders' is a Named Credential. Its External Credential holds the
    // OAuth client credentials, so no secret appears anywhere below and no
    // Remote Site Setting is required for the host.
    public static String createOrder(Order__c ord) {

        Map<String, Object> payload = new Map<String, Object>{
            'externalKey' => ord.External_Key__c,
            'amount'      => ord.Amount__c
        };

        HttpRequest req = new HttpRequest();
        req.setEndpoint('callout:ERP_Orders/v1/orders');
        req.setMethod('POST');
        req.setHeader('Content-Type', 'application/json');
        // Idempotency key: a replay must not create a second ERP order.
        req.setHeader('Idempotency-Key', ord.External_Key__c);
        // Milliseconds. Default is 10,000. Maximum is 120,000.
        req.setTimeout(30000);
        req.setBody(JSON.serialize(payload));

        // No Authorization header is set here. The platform adds it from
        // the External Credential when the request goes out.
        HttpResponse res = new Http().send(req);
        Integer code = res.getStatusCode();

        if (code == 200 || code == 201 || code == 409) {
            // 409 means the ERP has already seen this idempotency key and
            // is returning the order it created the first time.
            Map<String, Object> parsed =
                (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
            return (String) parsed.get('orderId');
        }

        throw new ErpCalloutException(
            'ERP callout failed with HTTP ' + code + ': ' + res.getBody());
    }
}

What is Named Credential with OAuth?

A Named Credential whose authentication protocol is OAuth 2.0 rather than Basic or a certificate. Salesforce becomes the OAuth client, performs the token exchange with the external identity provider, stores the access and refresh tokens, and refreshes them automatically on expiry. You configure an Auth. Provider record for the external service first, then point the External Credential at it. The principal is either Named Principal, where the org shares one set of tokens, or Per User Principal.

What is IP Relaxation?

A Connected App OAuth policy controlling whether the login IP ranges on the user's profile apply to that app. Three settings: enforce IP restrictions, enforce but relax for refresh tokens, and relax entirely. An integration server usually sits outside the profile's login IP ranges, so an unrelaxed Connected App triggers a verification challenge no automated process can answer. Relaxing it on the app is the correct fix, with the risk constrained through a minimal integration profile and narrow scopes.

How do you secure API access?

Layer it rather than relying on one control.

  • Identity. A dedicated integration user, never a named human and never a System Administrator.
  • Permission. The API Enabled permission plus object and field permissions through a permission set, for exactly the objects the interface touches.
  • Application. A Connected App with the narrowest workable OAuth scopes, plus API Access Control so only allow-listed apps can call the org.
  • Credentials. Named Credentials for outbound so no secret sits in code, and JWT rather than a stored password.
  • Apex. Declare with sharing and enforce field permissions with WITH USER_MODE on SOQL or Security.stripInaccessible(). An @RestResource class runs in system context by default, which is the most common security review failure.

Reliability and error handling

What is API Governor Limit?

Two separate limits get called this, and confusing them is a giveaway.

Per transaction Apex callout limits. A single Apex transaction may make at most 100 callouts. The cumulative timeout across all of them is 120 seconds. You also cannot make a callout after uncommitted DML in the same transaction, which is why a callout following a save goes into @future(callout=true) or a Queueable.

Per org daily API request limit. A rolling 24-hour allocation of inbound calls, sized by your edition and user licence count, with a minimum floor per org. Watch it under Setup, Company Information. Bulk API 2.0 is the lever when you are near the ceiling.

A hundred callouts sounds generous until a trigger runs on a 200-record batch. Design so one transaction makes one callout with a batched payload, not one per record.

What is Callout Timeout?

How long Apex waits for the remote system before throwing System.CalloutException. The default is 10 seconds. You set it per request with req.setTimeout(milliseconds) and the maximum you can set is 120,000 milliseconds, which is 120 seconds. That same 120 seconds is the cumulative ceiling for all callouts in one transaction, so two 90-second callouts cannot both succeed.

Leaving the default on a slow ERP causes intermittent failures nobody can reproduce. Setting 120 seconds on a synchronous Lightning action leaves a user watching a spinner while the transaction holds a row lock. Move anything slow to a Queueable.

How do you retry failed callouts?

Separate the failure types first. A 4xx other than 429 is your bug or bad data, so retrying fails again; log it and stop. A 429, a 5xx, a connection reset or a timeout is transient, so retry those.

  1. Catch CalloutException and non-2xx codes in a Queueable, not in a trigger.
  2. Keep a retry counter on the job or a staging record and stop at a fixed maximum such as five attempts.
  3. Back off instead of hammering. System.enqueueJob(job, delayInMinutes) re-enqueues the same job with a delay.
  4. Write every failed payload and response body to an integration log object. That log is your dead letter queue, and it is what lets support replay a day of failures once the remote system returns.
  5. Send the retry with the same idempotency key as the original, so a retry of a request that actually succeeded does not create a duplicate.

In a platform event trigger, throwing EventBus.RetryableException tells Salesforce to re-deliver the event batch, up to ten times, before giving up.

What is Idempotency?

An operation is idempotent when performing it twice produces the same end state as performing it once. It matters because networks lie. A timeout does not tell you whether the remote system processed your request, only that you did not hear back. If the retry is not idempotent, every timeout creates a duplicate order.

An idempotency key is how you get it. The caller generates a stable unique value for the logical operation, not for the attempt, and sends it with the request, usually as an Idempotency-Key header. The receiver stores the key with the result of the first request. When the same key arrives again it skips the work and returns the original result, typically with the same 2xx or a 409 carrying the existing record's ID. The key must come from the business event, so SO-1001 or a UUID stored on the record, never a fresh UUID.randomUUID() generated inside the retry.

Inbound, Salesforce gives you idempotency through External ID fields with upsert. A PATCH to /services/data/vXX.0/sobjects/Order__c/External_Key__c/SO-1001 creates the record the first time and updates the same record every time after. Mark the field Unique so a concurrent duplicate fails loudly. GET, PUT, PATCH and DELETE are naturally idempotent. POST is not, which is why it needs the key.

How do you test integration failures?

You cannot make a real callout from a test method, so you implement HttpCalloutMock and register it with Test.setMock(). The mock is where you inject the failure, and the interviewer wants more than the happy path: a 500, a 401, a malformed body and a thrown CalloutException for the timeout case.

@isTest
private class ErpOrderClientTest {

    // Returns whatever status and body the test asks for.
    private class ErpMock implements HttpCalloutMock {
        private Integer status;
        private String body;
        private ErpMock(Integer status, String body) {
            this.status = status;
            this.body = body;
        }
        public HttpResponse respond(HttpRequest req) {
            System.assertEquals('POST', req.getMethod());
            System.assert(req.getEndpoint().startsWith('callout:ERP_Orders'));
            System.assertNotEquals(null, req.getHeader('Idempotency-Key'),
                'Every write must carry an idempotency key');
            HttpResponse res = new HttpResponse();
            res.setStatusCode(this.status);
            res.setHeader('Content-Type', 'application/json');
            res.setBody(this.body);
            return res;
        }
    }

    // Simulates a timeout or a dropped connection.
    private class TimeoutMock implements HttpCalloutMock {
        public HttpResponse respond(HttpRequest req) {
            throw new CalloutException('Read timed out');
        }
    }

    private static Order__c newOrder(String key) {
        Order__c ord = new Order__c(External_Key__c = key, Amount__c = 500);
        insert ord;
        return ord;
    }

    @isTest
    static void returnsOrderIdOnSuccess() {
        Order__c ord = newOrder('SO-1001');
        Test.setMock(HttpCalloutMock.class,
            new ErpMock(201, '{"orderId":"ERP-77"}'));

        Test.startTest();
        String erpId = ErpOrderClient.createOrder(ord);
        Test.stopTest();

        System.assertEquals('ERP-77', erpId);
    }

    @isTest
    static void treatsDuplicateAsSuccess() {
        Order__c ord = newOrder('SO-1002');
        Test.setMock(HttpCalloutMock.class,
            new ErpMock(409, '{"orderId":"ERP-77"}'));

        Test.startTest();
        String erpId = ErpOrderClient.createOrder(ord);
        Test.stopTest();

        // The replay returns the original order, not a new one.
        System.assertEquals('ERP-77', erpId);
    }

    @isTest
    static void throwsOnServerError() {
        Order__c ord = newOrder('SO-1003');
        Test.setMock(HttpCalloutMock.class,
            new ErpMock(500, '{"error":"upstream unavailable"}'));

        Test.startTest();
        try {
            ErpOrderClient.createOrder(ord);
            System.assert(false, 'Expected ErpCalloutException');
        } catch (ErpOrderClient.ErpCalloutException e) {
            System.assert(e.getMessage().contains('500'));
        }
        Test.stopTest();
    }

    @isTest
    static void surfacesTimeout() {
        Order__c ord = newOrder('SO-1004');
        Test.setMock(HttpCalloutMock.class, new TimeoutMock());

        Test.startTest();
        try {
            ErpOrderClient.createOrder(ord);
            System.assert(false, 'Expected CalloutException');
        } catch (CalloutException e) {
            System.assert(e.getMessage().contains('timed out'));
        }
        Test.stopTest();
    }
}

Name the related classes too: StaticResourceCalloutMock, MultiStaticResourceCalloutMock when one test makes several callouts needing different responses, and WebServiceMock for SOAP stubs generated from a WSDL.

Event driven integration

What is Platform Event Integration?

Platform events are Salesforce's publish and subscribe messaging. You define an event such as Order_Shipped__e, publish an instance, and every subscriber receives it. The publisher does not know who is listening, which is what breaks point to point coupling.

Publish with EventBus.publish() from Apex, a Create Records element in Flow, or a POST to the event's sobjects endpoint. Publish After Commit fires only if the transaction commits. Publish Immediately fires even if it later rolls back.

Subscribe with an Apex trigger, a Flow, lightning/empApi in an LWC, or an external client over the Pub/Sub API. External subscribers hold a Replay ID, so a client that disconnects resumes where it stopped; events are retained for 72 hours. An Apex trigger on a platform event runs as the Automated Process user.

What is CDC (Change Data Capture) integration?

Change Data Capture publishes a change event automatically whenever a record is created, updated, deleted or undeleted, with no code on the publishing side. Enable it per object in Setup and Salesforce emits AccountChangeEvent, Order__ChangeEvent and so on.

The payload is the differential, not the whole record. It carries the fields that actually changed plus a ChangeEventHeader holding the change type, the record IDs affected, the user who made the change, the origin, and a transaction key that groups every event from one transaction. That last field is how a downstream system replays a multi-object save as one unit.

CDC versus platform events comes down to intent. CDC is data replication and fires for every change. A platform event is a business signal you publish deliberately, carrying only the fields the receiver needs.

The trainer's point about fake project experience lands hardest here. Interviewers go five levels deep: which object was CDC enabled on, what consumed the stream, what happened to the 72-hour retention window when the consumer was down over a long weekend, why CDC instead of a nightly Bulk extract, what was your role. A memorised definition does not survive question three.

What the interviewer is actually checking

  • Whether you can name a real interface. The system on the other side, the direction of data, the authentication method and the daily volume. Four facts, one sentence.
  • Whether you know the limits by heart. 100 callouts per transaction, a 10-second default timeout, 120,000 milliseconds maximum and 120 seconds cumulative.
  • Whether you can pick the right OAuth flow and defend it. JWT Bearer for unattended server to server, and a clear statement that Username-Password is not acceptable.
  • Whether you design for failure. Retries with backoff, idempotency keys, a dead letter log and a plan for the day the remote system is down.
  • Whether you can debug one. "The nightly sync stopped last night, what do you check?" filters better than "what is a Named Credential?"

Where to take this next

Integration answers improve fastest once you have built one end to end and can talk about the parts that went wrong. Build a small org that posts an order to a free public API through a Named Credential, log the failures, add a retry with an idempotency key, then subscribe a platform event to it.

If you want that practice structured, with a trainer reviewing how you answer and not only what you answer, look at the Salesforce training in Pune with placement support at RizeX Labs.

Last updated 4 October 2026