Salesforce Interview Questions & Answers Book is now available!

Grab Now

Interview questions

Salesforce Integration Interview Questions and Answers (2026)

Salesforce integration interview questions with answers: REST vs SOAP, Named Credentials, OAuth flows, Platform Events vs CDC, Bulk API 2.0 and callout testing.

By Teja, ex-Salesforce engineer · Updated October 6, 2026 · 15 min read

TL;DR

  • Integration interviews test judgement more than syntax: which API, which OAuth flow, sync or async, and what happens when the other system is down.
  • Know the hard rules cold: no callouts after uncommitted DML, callouts from triggers must be async, and tests can never make real callouts.
  • For every design answer, say how it handles retries, duplicates and monitoring. That's what separates senior candidates.

These are the Salesforce integration interview questions I'd ask a developer or integration specialist, with the answers I'd want to hear. They cover REST vs SOAP, Named Credentials and External Credentials, OAuth flows, Apex REST services, callout limits, Platform Events vs Change Data Capture, Bulk API 2.0, idempotency and retries, DML and callout ordering, and testing with HttpCalloutMock.

Use the page like this: read the question, answer it out loud, then read my answer. Integration interviews reward reasoning. "I'd use Platform Events because…" beats a memorised definition every time.

Fundamentals

When would you use the REST API rather than the SOAP API?

The REST API is the default for most new integrations. It uses JSON over HTTP, it's lightweight, it works from any language, and it fits mobile apps, web apps and middleware. Related APIs such as Composite, Bulk API 2.0 and the UI API follow the same style.

The SOAP API uses XML and a WSDL contract. It still makes sense when the other side is an enterprise platform that generates clients from a WSDL and expects strong typing. Salesforce offers an Enterprise WSDL (strongly typed to one org's schema) and a Partner WSDL (loosely typed, works across orgs).

In the other direction, for Apex calling an external SOAP service, you can generate Apex classes from the service's WSDL with WSDL2Apex.

What the interviewer is really checking: whether you choose by the consumer's needs, not by habit.

What is a Named Credential, and why use one instead of hard-coding the endpoint?

A Named Credential stores an endpoint URL together with how to authenticate to it. Apex then calls callout:Erp_Api/orders instead of a full URL with a token in a header.

Why it matters:

  • No secrets in code or custom settings. Credentials are stored and managed by the platform.
  • Authentication is handled for you. For OAuth, Salesforce obtains and refreshes the token.
  • Environment-specific. Sandbox and production point at different endpoints without a code change.
  • No Remote Site Setting needed for endpoints called through a Named Credential.
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:Erp_Api/orders');
req.setMethod('GET');
HttpResponse res = new Http().send(req);

What's the difference between a Named Credential and an External Credential?

In the current model, the work is split in two:

  • The External Credential defines how to authenticate: the protocol (for example an OAuth 2.0 flow, AWS Signature Version 4 or a Custom protocol where you define the headers yourself) and one or more principals that hold the actual credentials. A principal is either a named principal (one shared identity for the integration) or per-user (each user authenticates as themselves).
  • The Named Credential defines where to call: the URL and callout options. It points at an External Credential.

Access is granted through permission sets: a user or integration user can only use a principal that's mapped to a permission set they have. That's a common gotcha. The callout fails for users who don't have the permission set, even though it works for the admin who set it up.

Legacy Named Credentials (with authentication built in) still exist, but new work should use the split model.

Which OAuth flow would you use for a server-to-server integration into Salesforce?

There's no user present, so it's one of two flows:

  • JWT bearer flow. The external system signs a JWT with its private key. The JWT names the connected app's consumer key as the issuer and a Salesforce username as the subject. Salesforce verifies the signature against the certificate uploaded to the app and returns an access token. No password or client secret travels over the wire, and the user must be pre-authorised for the app.
  • Client credentials flow. The system exchanges a client ID and secret for a token, and the app is configured with a run-as user whose permissions every call gets. It's simpler to set up, but the secret has to be protected and rotated.

Neither flow issues a refresh token. The client simply requests a new access token when it needs one. Avoid the username-password flow: Salesforce discourages it because it puts a real password in the integration.

What the interviewer is really checking: whether you can choose between these on security grounds and know which user the calls run as.

Explain the OAuth web server flow. When is it the right choice?

Use it when a real user grants an external web application access to their Salesforce data.

  1. The app redirects the user to Salesforce's authorise endpoint with its client ID, redirect URI and scopes. PKCE is recommended.
  2. The user logs in and approves access.
  3. Salesforce redirects back with a short-lived authorisation code.
  4. The app's server exchanges the code, its client secret and the PKCE verifier for an access token and, if the refresh_token scope was requested, a refresh token.

Calls then run as that user, with that user's permissions and sharing. That's the point of the flow, and why it's wrong for a background integration with no user present.

What are Connected Apps and External Client Apps?

Both describe an external application to Salesforce for OAuth: its consumer key and secret or certificate, the scopes it may request, the callback URL, and policies such as who is pre-authorised, IP relaxation and session timeouts.

Connected Apps are the long-standing mechanism, and most existing orgs are full of them. External Client Apps are the newer framework Salesforce positions as their successor. They separate the settings a developer owns from the policies an admin controls, and they're designed to be packaged and deployed cleanly.

In an interview, show that you know both exist, check which one your org standardises on, and talk about the policies. Least-privilege scopes, pre-authorised users through a permission set, and a dedicated integration user matter more than which screen you configured them in.

Intermediate

How do you expose a custom REST endpoint from Apex?

Annotate a global class with @RestResource and its static methods with @HttpGet, @HttpPost, @HttpPut, @HttpPatch or @HttpDelete. The endpoint is /services/apexrest/ followed by your URL mapping.

@RestResource(urlMapping='/v1/shipments/*')
global with sharing class ShipmentService {
    public class ShipmentRequest {
        public String trackingNumber;
        public String status;
    }

    @HttpPut
    global static void upsertShipment() {
        ShipmentRequest body = (ShipmentRequest) JSON.deserialize(
            RestContext.request.requestBody.toString(), ShipmentRequest.class);
        Shipment__c record = new Shipment__c(
            Tracking_Number__c = body.trackingNumber, Status__c = body.status);
        Database.UpsertResult result = Database.upsert(
            record, Shipment__c.Tracking_Number__c, true, AccessLevel.USER_MODE);
        RestContext.response.statusCode = result.isCreated() ? 201 : 200;
        RestContext.response.responseBody = Blob.valueOf(JSON.serialize(new Map<String, Object>{ 'id' => result.getId() }));
    }
}

with sharing and user-mode DML mean the caller's permissions apply. Upserting on an external ID makes a replayed request safe. More on that below.

What callout limits do you design around?

The ones I keep in my head:

  • 100 callouts per transaction.
  • A 10-second default timeout per callout. You can raise it with setTimeout, up to 120 seconds, and the total time spent in callouts in one transaction is also capped at 120 seconds.
  • Request and response size is bounded by heap: 6 MB synchronous, 12 MB asynchronous.
  • No callouts after uncommitted DML in the same transaction.
  • No synchronous callouts from triggers.

Design consequences: batch the payload instead of making one call per record, set explicit timeouts, and move anything slow or unreliable to async (Queueable or Batch with Database.AllowsCallouts). Inbound, every API call counts against the org's rolling 24-hour API request allocation, so chatty clients need to batch their calls too.

Why do you get "You have uncommitted work pending" and how do you fix it?

Salesforce won't let a transaction make a callout after it has performed DML that isn't committed yet. The external call could take a long time while holding database locks, and the external system might act on data that's then rolled back.

Callout first, then DML in the same transaction is fine. DML first, then callout throws a CalloutException.

Fixes, from best to worst:

  1. Reorder the logic so all callouts happen before any DML.
  2. Move the callout to an async job (Queueable with Database.AllowsCallouts) enqueued after the DML. It runs after the commit.
  3. In tests, insert setup data, then make the callout between Test.startTest() and Test.stopTest().

Don't confuse this with the mixed DML error, which is a different rule. That's covered further down.

How do you make a callout when a record is saved?

A trigger can't make a synchronous callout, so the trigger hands the work to an async job. I prefer Queueable over @future: it accepts complex types, returns a job ID and supports Finalizers.

public with sharing class OrderSyncJob implements Queueable, Database.AllowsCallouts {
    private final Set<Id> orderIds;

    public OrderSyncJob(Set<Id> orderIds) {
        this.orderIds = orderIds;
    }

    public void execute(QueueableContext context) {
        List<Order> orders = [SELECT Id, OrderNumber, TotalAmount FROM Order WHERE Id IN :orderIds WITH USER_MODE];
        HttpRequest req = new HttpRequest();
        req.setEndpoint('callout:Erp_Api/orders');
        req.setMethod('POST');
        req.setHeader('Content-Type', 'application/json');
        req.setTimeout(20000);
        req.setBody(JSON.serialize(orders));
        HttpResponse res = new Http().send(req);

        String status = res.getStatusCode() < 300 ? 'Synced' : 'Failed';
        for (Order ord : orders) {
            ord.ERP_Sync_Status__c = status;
        }
        update as user orders;
    }
}

The trigger handler collects the IDs of orders whose status changed to Activated and calls System.enqueueJob(new OrderSyncJob(ids)) once, not once per record. The callout happens before the DML, which is the order that's allowed.

What's the difference between Platform Events, Change Data Capture and the older Streaming API?

  • Platform Events are custom messages you define and publish (from Apex, Flow or the API) when something meaningful happens in the business, such as "order shipped". You choose the schema and when to publish.
  • Change Data Capture (CDC) has Salesforce publish change events automatically when records of the objects you select are created, updated, deleted or undeleted. The header includes the change type, the record IDs and which fields changed. Use it to keep an external copy of the data in sync without polling.
  • PushTopics and generic streaming are the older Streaming API features. For new builds, use Platform Events or CDC.

External subscribers should use the Pub/Sub API (gRPC). Inside Salesforce, Apex triggers and flows can subscribe, and LWC can use lightning/empApi. High-volume events and change events are kept for a 72-hour replay window, so subscribers can catch up after an outage using the replay ID.

What the interviewer is really checking: "you decide what to publish" vs "the platform publishes every data change".

What do "Publish Immediately" and "Publish After Commit" mean for a platform event?

The setting is on the platform event definition and controls what happens when you publish from inside a transaction.

  • Publish After Commit: the event is delivered only if the transaction commits. If the transaction rolls back, the event is never sent. Use this when the event announces a data change, such as "order created". Subscribers should never hear about an order that doesn't exist.
  • Publish Immediately: the event is delivered as soon as you publish it, even if the transaction later fails. Use this for logging and error reporting. You want the "this failed" event to survive the rollback.

Picking the wrong one causes ghost events or lost error logs. Both are hard to debug later.

What is Bulk API 2.0, and when do you use it instead of the REST API?

Use Bulk API 2.0 for large data volumes, roughly anything more than a few thousand records in one go, where you can wait for the result. It's asynchronous:

  1. Create an ingest job with the object, the operation (insert, update, upsert, delete or hard delete) and, for upsert, the external ID field.
  2. Upload the CSV data.
  3. Mark the job UploadComplete.
  4. Poll the job, then download the successful, failed and unprocessed record results.

Compared with Bulk API 1.0, you don't manage batches yourself, because Salesforce splits the data internally. There are also query jobs for extracting large data sets.

Triggers, flows and validation rules still run for Bulk API loads, in chunks of 200 records. Your automation must be bulk-safe, and the load is only as fast as the slowest automation on the object.

How do you reduce the number of API calls a client makes?

  • Composite API: up to 25 subrequests in one call. Later subrequests can reference earlier results with referenceId, for example create an Account and then a Contact using the new Account's ID. An allOrNone flag rolls everything back if one subrequest fails.
  • sObject Collections: create, update, upsert or delete up to 200 records in one call. Create, update and delete can mix object types (processed in chunks of the same type); upsert works on one object type per call.
  • Composite Graph and Batch cover related variations: larger connected record graphs, and independent requests bundled together.
  • Bulk API 2.0 for genuinely large volumes.

This matters because API requests count against the org's daily allocation. A client that makes one call per record will eventually hit it.

Scenario-based

An external system sometimes sends the same order twice. How do you make the integration idempotent?

Retries are normal: networks time out and clients resend. So every inbound write must be safe to repeat.

  • Upsert on an external ID, such as the source system's order number. Mark the field as External ID and Unique. A replay then updates the existing record instead of creating a duplicate. That's exactly what the ShipmentService example above does.
  • Use an idempotency key for actions that aren't plain record writes, such as "charge this invoice". Store the key in a unique field on a log record and reject or short-circuit repeats.
  • Return the same response for a replay as for the original request, so the client can stop retrying.

Outbound, do the same thing in reverse. Send your record ID or a unique key with every call so the external system can deduplicate on its side.

What the interviewer is really checking: whether you assume the network is reliable. Senior people never do.

The ERP you call is down for an hour. How does your integration recover?

A good design never loses the work and never needs a person to rerun it by hand:

  1. Record intent before calling. Mark records as Pending Sync, or write a row to an outbox/log object, so the work survives a failed job.
  2. Call asynchronously, so a user's save never depends on the ERP being up.
  3. Classify failures. Retry timeouts and 5xx responses. Don't retry 4xx validation errors. Log those for a person to fix.
  4. Retry with backoff. A Queueable Finalizer or a scheduled job can re-enqueue pending records with increasing delays, and give up after a set number of attempts.
  5. Alert and monitor. Dashboard the failed and pending counts, and email someone when they cross a threshold.

When the ERP comes back, the scheduled sweep picks up everything still pending. Because the sends are idempotent, replays are harmless.

How do you test Apex code that makes a callout?

Tests can never make real callouts. You implement HttpCalloutMock, register it with Test.setMock, and the platform returns your fake response whenever the code calls Http.send.

@IsTest
private class OrderSyncJobTest {
    private class ErpMock implements HttpCalloutMock {
        private final Integer statusCode;
        ErpMock(Integer statusCode) {
            this.statusCode = statusCode;
        }
        public HttpResponse respond(HttpRequest req) {
            Assert.areEqual('POST', req.getMethod());
            HttpResponse res = new HttpResponse();
            res.setStatusCode(statusCode);
            res.setBody('{"result":"ok"}');
            return res;
        }
    }

    @IsTest
    static void marksOrderFailedWhenErpRejects() {
        Account acc = new Account(Name = 'Acme');
        insert acc;
        Order ord = new Order(AccountId = acc.Id, EffectiveDate = Date.today(), Status = 'Draft');
        insert ord;
        Test.setMock(HttpCalloutMock.class, new ErpMock(500));

        Test.startTest();
        System.enqueueJob(new OrderSyncJob(new Set<Id>{ ord.Id }));
        Test.stopTest();

        Order result = [SELECT ERP_Sync_Status__c FROM Order WHERE Id = :ord.Id];
        Assert.areEqual('Failed', result.ERP_Sync_Status__c);
    }
}

Test the failure path as well as the success path. For SOAP callouts, implement WebServiceMock. For fixed responses stored as static resources, StaticResourceCalloutMock saves writing a class.

How do you test an Apex REST service?

You don't make an HTTP call. You build a RestRequest and RestResponse, put them in RestContext, call the method directly, and assert on the response and the data.

@IsTest
private class ShipmentServiceTest {
    @IsTest
    static void replayingTheSameShipmentDoesNotDuplicate() {
        RestContext.request = new RestRequest();
        RestContext.request.requestURI = '/services/apexrest/v1/shipments/';
        RestContext.request.httpMethod = 'PUT';
        RestContext.response = new RestResponse();

        Test.startTest();
        RestContext.request.requestBody = Blob.valueOf('{"trackingNumber":"TRK-1","status":"Shipped"}');
        ShipmentService.upsertShipment();
        RestContext.request.requestBody = Blob.valueOf('{"trackingNumber":"TRK-1","status":"Delivered"}');
        ShipmentService.upsertShipment();
        Test.stopTest();

        List<Shipment__c> rows = [SELECT Status__c FROM Shipment__c];
        Assert.areEqual(1, rows.size(), 'A replay must update, not insert');
        Assert.areEqual('Delivered', rows[0].Status__c);
        Assert.areEqual(200, RestContext.response.statusCode);
    }
}

Add tests for a malformed body and for a user without access, so you know what the client receives in those cases.

What is a mixed DML error, and how is it different from the callout-after-DML error?

Mixed DML happens when one transaction performs DML on a setup object (such as User, PermissionSetAssignment, Group or GroupMember) and on a non-setup object (such as Account or a custom object). Salesforce blocks this because setup changes affect sharing and access calculations. The error is MIXED_DML_OPERATION.

It typically appears when an integration creates a user and then a related record in the same request. Fixes:

  • Move one side into an async job, such as a Queueable or @future method.
  • In tests, wrap the setup-object DML in System.runAs.

The callout-after-DML rule is about callouts and uncommitted work, not about object types. Interviewers like asking both to see whether you mix them up.

A nightly job must load about five million records from a data warehouse into Salesforce. How would you design it?

  • First, question the requirement. Does the data need to live in Salesforce? If users only need to view it, Salesforce Connect with external objects avoids storing it.
  • Use Bulk API 2.0 upsert on an external ID, driven by middleware or an ETL tool, so reruns are safe.
  • Load parents before children and sort child rows by parent ID. That reduces record-lock contention when many children of one parent are processed in parallel.
  • Make the automation bulk-safe, or bypass it. Triggers, flows and validation rules run for every chunk. Use a bypass custom permission assigned to the integration user for automation that isn't needed during a load.
  • Process the results. Download the failed and unprocessed records, retry what's retryable, and report the rest.
  • Watch the limits: Bulk API allocations, storage, and how long the load takes compared with the overnight window.

Senior / design

Which integration patterns do you consider, and how do you choose?

These are the patterns I reach for, named the way Salesforce's integration architecture guidance names them:

PatternUse whenTypical tools
Request and ReplyThe user needs the answer nowSynchronous callout, Named Credential, Continuation for long calls from the UI
Fire and ForgetSalesforce notifies another system and doesn't waitPlatform Events, Queueable callout
Batch Data SynchronizationLarge periodic loadsBulk API 2.0, ETL or middleware
Remote Call-InAn external system creates or reads Salesforce dataREST, Composite, Apex REST
UI Update Based on Data ChangesThe UI reflects changes as they happenPlatform Events or CDC with lightning/empApi
Data VirtualizationShow external data without storing itSalesforce Connect, external objects

I choose based on three questions. Does a user wait for it? How much data moves? Which system is the source of truth?

What the interviewer is really checking: whether you start from requirements and constraints, then pick the tool.

How do you secure an inbound integration?

  • A dedicated integration user for each integration, never a real person's account. Salesforce offers a Salesforce Integration user licence for API-only users.
  • Least privilege. A permission set with exactly the objects and fields needed. Avoid "Modify All Data" just because it's easier.
  • The right OAuth flow, usually JWT bearer or client credentials, with minimal scopes and the app limited to pre-authorised users.
  • Network controls where they apply, such as login IP ranges for the integration user.
  • Enforce access in your own code. Apex REST classes use with sharing and user-mode queries and DML, so the integration user's permissions really apply.
  • Rotate secrets and certificates, and keep an owner and an expiry date for each.

How do you monitor integrations in production?

You can't fix what you can't see, so I build observability in from the start:

  • A log object (or a logging framework) that records each outbound call and inbound failure: the endpoint, status code, a correlation ID, the record IDs and the retry count. Write it with Publish Immediately platform events, so the log survives a rollback.
  • Correlation IDs passed in a header so both systems can trace one request end to end.
  • Limit monitoring through the REST API's limits resource or Setup, with alerts before daily API or event allocations run out.
  • Dashboards and alerts for failed and pending counts, not just an inbox full of exception emails.
  • Event Monitoring, where it's licensed, for API usage by user and client.

How to practise these questions out loud

Integration answers are long, and it's easy to ramble. Practise giving them a structure:

  1. Use a three-part answer: what you'd use, why you'd use it, and what happens when it fails. If you always cover failure, you'll sound senior.
  2. Draw while you talk. For design questions, sketch the boxes, arrows, sync or async, and where credentials live. Do it on paper or a whiteboard tool, out loud, against a timer of about five minutes.
  3. Build the code questions for real. In a Developer Edition org, create a Named Credential to a public test API, write the Queueable callout, mock it, and call your Apex REST endpoint from Postman. Then you're describing work you've done, not reciting.
  4. Swap roles with a friend. Asking the questions shows you what a vague answer sounds like.

Salesforce Integration Master Course (Advanced Apex) builds these pieces live: OAuth flows and JWT, Named and External Credentials, Connected Apps, Apex REST, Platform Events, Bulk API 2.0 and the Streaming API. Interview Questions covers the wider interview.

Salesforce Integration Master Course (Advanced Apex)

151 episodes · 27 hours · 26 modules

View syllabus →

Want 700+ pages of this?

The Salesforce Interview Questions & Answers Book goes far deeper than this page — it's included with the Lifetime plan, alongside the Real-Time Projects series.

Frequently asked questions

What do Salesforce integration interviews usually include?

Expect a mix of concept questions (APIs, OAuth, events), a design scenario where you draw how two systems talk, and often a short coding task such as writing a callout with a mock or an Apex REST endpoint.

Do I need MuleSoft or other middleware experience to pass?

Usually not for a Salesforce developer role, but you should be able to explain when middleware is worth it: many systems, heavy transformation, or central monitoring. If the job description names a middleware product, prepare for it specifically.

How do I answer integration questions if I haven't built a production integration?

Build one end to end in a Developer Edition org against a public API: Named Credential, callout, mock test, and an inbound Apex REST endpoint you call from Postman. Then talk about what you built and what you would change at scale.

Will I be asked to draw an architecture diagram?

For mid-level and senior roles, often. Practise sketching the systems, the direction of each call, sync versus async, where credentials live, and where failures are logged and retried.

Keep going

Keep me in the loop!

Email me when a new episode is published (promise, I will not spam you)

You're signing up to receive emails from Salesforce Casts