Skip to main content

SF-9102 · Concept · Medium

How do you call a SOAP web service from Apex?

✓ Verified by Vikas Singhal · Last reviewed 5/17/2026 · Updated for Spring '26

Salesforce calls SOAP services through WSDL2Apex — a setup tool that reads the service’s WSDL document and generates strongly-typed Apex stub classes you can invoke directly.

The workflow

  1. Get the WSDL from the vendor (usually a .xml file or a URL).
  2. Setup > Apex Classes > Generate from WSDL, upload the file.
  3. Salesforce parses operations, types, and complex schemas into one or more Apex classes.
  4. Call the operation like any Apex method.
// Generated stub from CreditCheckService.wsdl
CreditCheck.CreditCheckPort port = new CreditCheck.CreditCheckPort();
port.endpoint_x = 'callout:Credit_Check_Service'; // Named Credential
CreditCheck.CreditResponse resp = port.runCheck('USA', '123-45-6789');
System.debug(resp.score);

What WSDL2Apex handles for you

  • XML serialisation/deserialisation of the SOAP envelope
  • Type mapping (xsd:string → String, xsd:dateTime → DateTime, complex types → inner classes)
  • Multiple operation elements become methods on the generated port class
  • Faults become CalloutException subclasses

What it doesn’t handle

  • WS-Security (signed/encrypted headers). You’ll add custom XML to the request manually.
  • RPC-encoded WSDLs. Only document/literal is supported. If the vendor uses RPC/encoded, ask them for a document/literal binding or write a raw HttpRequest and build the envelope yourself.
  • Schemas larger than 1 MB or with too many top-level elements — WSDL2Apex will refuse to generate. Workaround: trim unused operations from the WSDL before importing.

Authentication and endpoint hygiene

Same rules as REST callouts:

  • Named Credentials carry the endpoint + auth. Set port.endpoint_x = 'callout:My_NC';.
  • If you must use a raw URL, add it to Remote Site Settings.
  • Set port.timeout_x = 60000; (ms) for slow services. Default is 10 seconds.

Testing SOAP callouts

Like REST, you can’t actually hit the service in tests. Two options:

// Option 1: HttpCalloutMock (works because WSDL2Apex uses Http under the hood)
Test.setMock(HttpCalloutMock.class, new CreditCheckMock());

// Option 2: WebServiceMock — preferred for SOAP, gives typed responses
Test.setMock(WebServiceMock.class, new CreditCheckWsMock());

WebServiceMock returns the generated response type directly, so you skip XML parsing in tests.

When to skip WSDL2Apex

If the WSDL is huge, uses unsupported features, or you only need one operation, write the raw HTTP request yourself. Build the SOAP envelope as a String, POST it with Content-Type: text/xml, parse the response with Dom.Document. Less elegant, much more flexible.

Verified against: Apex Developer Guide — Calling Web Services Using WSDL2Apex. Last reviewed 2026-05-17 for Spring ‘26 release.