Add HTTP Headers when sending a SOAP Message through a SOAP Bussines Operation
Good afternoon,
I have received a WSDL.
I have imported it successfully in HealthShare.
The external is requesting me to send messages with the following structure (using the auto-generated SOAP Bussiness Operation from the WSDL), as you see they need a custom http header titled "Appian-API-Key", as the following:
curl --request POST \
--url [ endpoint ] \
--header 'Appian-API-Key: << API KEY >> \
--header 'Content-Type: application/xml' \
--data '<?xml version='\''1.0'\'' encoding='\''utf-8'\''?>
<soapenv:Envelope xmlns:soapenv='\''http://schemas.xmlsoap.org/soap/envelope/'\''>
<soapenv:Body>
<tns:acceptMessage xmlns:tns='\''http://ws.connectors.connect.mirth.com/'\''>
<![CDATA[ Message ]]>
</tns:acceptMessage>
</soapenv:Body>
</soapenv:Envelope>'
I have looked for it, reading various threads:
https://community.intersystems.com/post/sending-soap-header-object-request-object
https://community.intersystems.com/post/theres-any-way-edit-soap-header
https://community.intersystems.com/post/add-header-soap-request
https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GSOAPSEC_manual
https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=ESOAP_settings_outbound
I have tried:
Class Operation.SOAPSend Extends Ens.BusinessOperation [ ProcedureBlock ]
{
Property AppianApiKey As %String(MAXLEN = "");
Parameter SETTINGS = "AppianApiKey";
Parameter ADAPTER = "EnsLib.SOAP.OutboundAdapter";
Method acceptMessage(pRequest As Mensajes.Request.GestionPacientes.TSI.NotificacionesToPAM.acceptMessageRequest, Output pResponse As Mensajes.Response.GestionPacientes.TSI.NotificacionesToPAM.acceptMessageResponse) As %Status
{
Set ..Adapter.WebServiceClientClass = "WSCLIENTE.GestionPacientes.TSI.NotificacionesToPAM.ExitusPort"
Set client = ..Adapter.GetWebClient()
Do client.HttpRequest.SetHeader("Appian-API-Key", ..AppianApiKey)
Do client.HttpRequest.SetHeader("Content-Type", "application/xml")
Set tSC = client.InvokeMethod("acceptMessage", .status, pRequest.message, .description)
Quit:$$$ISERR(tSC) tSC
Set tSC = pRequest.NewResponse(.pResponse)
Quit:$$$ISERR(tSC) tSC
Set pResponse.status = $Get(status)
Set pResponse.description = $Get(description)
Quit $$$OK
}
XData MessageMap
{
<MapItems>
<MapItem MessageType="Mensajes.Request.GestionPacientes.TSI.NotificacionesToPAM.acceptMessageRequest">
<Method>acceptMessage</Method>
</MapItem>
</MapItems>
}
}
It shows, after trying it:
| ERROR <Ens>ErrException: <METHOD DOES NOT EXIST>acceptMessage+2^Operaciones.SOAP.GestionPacientes.TSI.NotificacionesToPAM.ExitusPort.1 *GetWebClient,EnsLib.SOAP.OutboundAdapter -- - registrado como '-' número - @' Set client = ..Adapter.GetWebClient()' |
I have also tried:
Class Operation.SOAPSend Extends Ens.BusinessOperation [ ProcedureBlock ]
{
Property AppianApiKey As %String(MAXLEN = "");
Parameter SETTINGS = "AppianApiKey";
Parameter ADAPTER = "EnsLib.SOAP.OutboundAdapter";
Method OnBeforeCall() As %Status
{
Do ..Adapter.HttpRequest.SetHeader("Appian-API-Key", ..AppianApiKey)
Do ..Adapter.HttpRequest.SetHeader("Content-Type", "application/xml")
Quit $$$OK
}
Method acceptMessage(pRequest As Mensajes.Request.GestionPacientes.TSI.NotificacionesToPAM.acceptMessageRequest, Output pResponse As Mensajes.Response.GestionPacientes.TSI.NotificacionesToPAM.acceptMessageResponse) As %Status
{
Set ..Adapter.WebServiceClientClass = "WSCLIENTE.GestionPacientes.TSI.NotificacionesToPAM.ExitusPort"
Set tSC = ..Adapter.InvokeMethod("acceptMessage", .status, pRequest.message, .description)
Quit:$$$ISERR(tSC) tSC
Set tSC = pRequest.NewResponse(.pResponse)
Quit:$$$ISERR(tSC) tSC
Set pResponse.status = $Get(status)
Set pResponse.description = $Get(description)
Quit $$$OK
}
XData MessageMap
{
<MapItems>
<MapItem MessageType="Mensajes.Request.GestionPacientes.TSI.NotificacionesToPAM.acceptMessageRequest">
<Method>acceptMessage</Method>
</MapItem>
</MapItems>
}
}
But, when I open a LogSoap, it does not show the Appian-API-Key Header. It just shows the SOAP Body:
05/25/2026 13:37:57 *********************
Output from Web client with SOAP action = acceptMessage
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:s='http://www.w3.org/2001/XMLSchema'>
<SOAP-ENV:Body><acceptMessageRequest xmlns="http://ws.connectors.connect.mirth.com/"><message xsi:type="s:string"><![CDATA[[ Message ]]></message></acceptMessageRequest></SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Is there a way to add custom HTTP Headers when sending a SOAP communication through a Business Operation?
How?
In the previous forum topics I quoted, it looks like only SOAP Headers can be altered, but not HTTP headers. Is it false or true? 🤔
How could the requested custom http header be added?
Thank you so much for your time reading this doubt. Thanks. 🙂
Comments
Yes — custom HTTP headers can be added for a SOAP client. It is not limited to SOAP <Header> elements. InterSystems provides SetHttpHeader() on %SOAP.WebClient for this purpose. [1][2]
EnsLib.SOAP.OutboundAdapter itself does not expose GetWebClient() in the material you found here, which matches the <METHOD DOES NOT EXIST> ... GetWebClient,EnsLib.SOAP.OutboundAdapter error you received. The available guidance here is to set the HTTP header on the SOAP client object, using the adapter’s client instance: ..Adapter.%Client.SetHttpHeader(name,value). [3]
So the supported approach for your case is to set the generated web service client class on the adapter, then set the HTTP header on ..Adapter.%Client, and then invoke the SOAP method. [3][1]
Method acceptMessage(
pRequest As Mensajes.Request.GestionPacientes.TSI.NotificacionesToPAM.acceptMessageRequest,
Output pResponse As Mensajes.Response.GestionPacientes.TSI.NotificacionesToPAM.acceptMessageResponse
) As %Status
{
Set ..Adapter.WebServiceClientClass = "WSCLIENTE.GestionPacientes.TSI.NotificacionesToPAM.ExitusPort"
Do ..Adapter.%Client.SetHttpHeader("Appian-API-Key", ..AppianApiKey)
Set tSC = ..Adapter.InvokeMethod("acceptMessage", .status, pRequest.message, .description)
Quit:$$$ISERR(tSC) tSC
Set tSC = pRequest.NewResponse(.pResponse)
Quit:$$$ISERR(tSC) tSC
Set pResponse.status = $Get(status)
Set pResponse.description = $Get(description)
Quit $$$OK
}
For your Content-Type line, be careful: the InterSystems SOAP client documentation says: [1]
Note: Content-Type, Content-Encoding, and Content-Length headers are part of the entity body rather than the HTTP main headers. You cannot set the Content-Length header, which is read-only. Nor can you set the Connection header, because this class does not support persistent connections.
So the key part for your requirement is the custom header:
Do ..Adapter.%Client.SetHttpHeader("Appian-API-Key", ..AppianApiKey)
About your LogSoap output: the material here only documents SOAP header elements in the SOAP envelope separately from HTTP headers, and explains that SOAP headers are inside the SOAP <Header> element, while HTTP headers are set through SetHttpHeader(). So not seeing Appian-API-Key in the SOAP envelope log is consistent with it being an HTTP header, not a SOAP header. [4][1]
Note: If you perform these steps in a utility method, note that the method must be an instance method and must be a member of an instantiable class (not an abstract class, for example). [4]
Also, the documentation you cited about HeadersOut applies to SOAP header elements inside the SOAP envelope, not HTTP transport headers. HeadersOut is for custom SOAP headers, while SetHttpHeader() is for HTTP headers. [4][1]
So, in short: your statement is false — it is possible to alter/add HTTP headers for SOAP calls, and the documented way in the retrieved material is to call ..Adapter.%Client.SetHttpHeader("Appian-API-Key", ..AppianApiKey) before InvokeMethod(). [3][1]
Sources:
@DC AI Bot answer solved this topic. Thank you (even if you are an AI) :=)