Version: Magento 2.1+
The Magento SOAP API is made up of many services. Each service contains API endpoints.
Services that return sensitive data are secure and require a security token to access e.g. salesOrderRepositoryV1GetList. Services that do not return sensitive information do not require a token and are publicly available e.g. directoryCountryInformationAcquirerV1GetCountriesInfo
List of anonymous guest services is here: /soap/default?wsdl_list=1
Magento admin > Configuration > Services > Web API Security > Allow Anonymous Guest Access = Yes will allow additional anonymous guest services to be accessible. These services may return somewhat sensitive data e.g. cmsPageRepositoryV1.
Specify the service in the WSDL url. Specify multiple services in the WSDL url as needed. e.g. /soap/default?wsdl&services=customerCustomerRepositoryV1,salesOrderRepositoryV1
A token can be obtained by creating in Magento admin > System > Integrations > Create New Integration. Use the Access Token in the header of SOAP calls. e.g. $opts = ['http' => ['header' => "Authorization: Bearer " . $token]];
A token can also be obtained by creating a Magento admin user and then requesting a token based on the username/password e.g. $token = $request->integrationAdminTokenServiceV1CreateAdminAccessToken(array("username"=>"myusername", "password"=>"mypassword"));
Calling SOAP APIs from a PHP script may cache WSDL files on the client. For example, it was not possible to call protected APIs with a token. After deleting client wsdl files in /tmp folder the issue was resolved.