ServiceCallout policy

This pageapplies toApigee andApigee hybrid.

View Apigee Edge documentation.

The ServiceCallout policy lets you call to another service from your API proxy flow. You can make callouts to either an external service (such as an external RESTful service endpoint) or internal services (such as an API proxy in the same organization and environment).

This policy is anExtensible policy and use of this policy might have cost or utilization implications, depending on your Apigee license. For information on policy types and usage implications, seePolicy types.

  • In an external use case, you make a callout to a third-party API that's external to your proxy. The response from the third-party API is parsed and inserted in your API's response message, enriching andmashing up the data for app end users. You can also make a request using the ServiceCallout policy in the request flow, then pass the information in the response to the TargetEndpoint of the API proxy.
  • In another use case, you call a proxy that's in the same organization and environment as the one you're calling from. For example, you might find this useful when you have a proxy that offers some discrete low-level functionality that one or more other proxies will consume. For example, a proxy that exposes create/read/update/delete operations with a backend data store could be the target proxy for multiple other proxies that expose the data to clients.

The policy supports requests over HTTP and HTTPS.

Samples

Local call to an internal proxy

<LocalTargetConnection>    <APIProxy>data-manager</APIProxy>    <ProxyEndpoint>default</ProxyEndpoint></LocalTargetConnection>

This example creates a callout to a local API proxy (that is, one in the same organization and environment) calleddata-manager, specifying its proxy endpoint whose name isdefault.

URL as a variable

<HTTPTargetConnection>    <URL>http://example.com/{request.myResourcePath}</URL></HTTPTargetConnection>

This example uses a variable in the URL to dynamically populate the URL of the target. The protocol portion of the URL,http://, cannot be specified by a variable. Also, you must use separate variables for the domain portion of the URL and for the rest of the URL.

Google geocoding / define request

<ServiceCalloutname="ServiceCallout-GeocodingRequest1"><DisplayName>Inlinerequestmessage</DisplayName><Requestvariable="authenticationRequest"><Set><QueryParams><QueryParamname="address">{request.queryparam.postalcode}</QueryParam><QueryParamname="region">{request.queryparam.country}</QueryParam><QueryParamname="sensor">false</QueryParam></QueryParams></Set></Request><Response>GeocodingResponse</Response><Timeout>30000</Timeout><HTTPTargetConnection><URL>https://maps.googleapis.com/maps/api/geocode/json</URL></HTTPTargetConnection></ServiceCallout>

Instead of using a policy such as theAssignMessage policy to create the request object, you can define it directly in the ServiceCallout policy. In this example, the ServiceCallout policy sets the values of three query parameters passed to the external service. You can create an entire request message in the ServiceCallout policy that specifies a payload, encoding type such asapplication/xml, headers, form parameters, etc.

Here's another example where the request is formed before reaching the ServiceCallout policy.

<ServiceCalloutname="ServiceCallout-GeocodingRequest2"><RequestclearPayload="false"variable="GeocodingRequest"/><Response>GeocodingResponse</Response><Timeout>30000</Timeout><HTTPTargetConnection><URL>https://maps.googleapis.com/maps/api/geocode/json</URL></HTTPTargetConnection></ServiceCallout>

The content of the request message is extracted from a variable calledGeocodingRequest (which could be populated, for example, by an AssignMessage policy). The response message is assigned to the variable calledGeocodingResponse, where it is a available to be parsed by anExtractVariables policy or by custom code written in JavaScript or Java. The policy waits 30 seconds for the response from the Google Geocoding API before timing out.

Call target servers

<ServiceCalloutasync="false"continueOnError="false"enabled="true"name="service-callout"><DisplayName>service-callout</DisplayName><Properties/><RequestclearPayload="true"variable="myRequest"><IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables></Request><Response>myResponse</Response><HTTPTargetConnection><LoadBalancer><Algorithm>RoundRobin</Algorithm><Servername="httpbin"/><Servername="yahoo"/></LoadBalancer><Path>/get</Path></HTTPTargetConnection></ServiceCallout>

This policy uses the LoadBalancer attribute to call target servers and do load balancing across them. In this example, load is distributed across two target servers namedhttpbin andyahoo. For information about setting up Target Servers for your proxy and configuring load balancing, seeLoad balancing across backend servers.


Note: If you are using Apigee hybrid v1.14 or newer and your organization is entitled to use theEnhanced per-environment proxy limits feature, you must set theenhanceProxyLimits property totrue in youroverrides.yaml file in order to use the ServiceCallout policy.

About the ServiceCallout policy

There are many scenarios where you can use a ServiceCallout policy in your API proxy. For example, you can configure an API proxy to make calls to an external service to deliver geolocation data, customer reviews, items from a partner’s retail catalog, and so on.

A callout is typically used with two other policies: AssignMessage and ExtractVariables.

The typical ServiceCallout policy composition involves:

  1. AssignMessage policy: Creates a request message, populates HTTP headers, query parameters, sets the HTTP verb, etc.
  2. ServiceCallout policy: References a message created by the AssignMessage policy, defines a target URL for the external call, and defines a name for the response object that the target service returns.

    For improved performance, you can also cache ServiceCallout responses, as described inHow can I store the results of the ServiceCallout policy in cache? and later, retrieve it from cache?

  3. ExtractVariables policy: Typically defines a JSONPath or XPath expression that parses the message generated by the ServiceCallout. The policy then sets variables containing the values parsed from the ServiceCallout response.
Note: An alternative approach to ServiceCallout is an HTTPClient written in JavaScript using theJavaScript object model.

Custom error handling

Sample:Learn by doing!
This
Learn Apigee example shows you how to check the HTTP code in a ServiceCallout response and throw a custom exception based on the value of the code. The example returns a custom error message when the target service returns a404 status. Just clone the repository and follow the instructions in that topic. The example illustrates a common pattern for handling ServiceCallout errors.

Element reference

Following are elements and attributes you can configure on this policy:

<ServiceCalloutasync="false"continueOnError="false"enabled="true"name="Service-Callout-1"><DisplayName>CustomlabelusedinUI</DisplayName><RequestclearPayload="true"variable="myRequest"><IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables><Remove><StatusCode/><Path/><Version/><Verb/></Remove><Copy><StatusCode/><Path/><Version/><Verb/></Copy><Add><Headers/><QueryParams/><FormParams/></Add><Set><Headers/><QueryParams/><FormParams/><Payload/><StatusCode/><Path/><Version/><Verb/></Set></Request><Response>calloutResponse</Response><Timeout>30000</Timeout><HTTPTargetConnection><URL>http://example.com</URL><LoadBalancer/><SSLInfo/><Properties/><Authentication><HeaderNameref="{variable}">STRING</HeaderName><GoogleAccessToken><Scopes><Scope>https://www.googleapis.com/auth/cloud-platform</Scope></Scopes><LifetimeInSecondsref="{variable}">3600</LifetimeInSeconds></GoogleAccessToken></Authentication><Authentication><HeaderNameref="{variable}">STRING</HeaderName><GoogleIDToken><Audienceref="{variable}"useTargetUrl="BOOLEAN">{hostname}</Audience><IncludeEmailref="{variable}">true</IncludeEmail></GoogleIDToken></Authentication></HTTPTargetConnection><LocalTargetConnection><APIProxy/><ProxyEndpoint/><Path/></LocalTargetConnection></ServiceCallout>

<ServiceCallout> attributes

<ServiceCallout async="false" continueOnError="false" enabled="true" name="Service-Callout-1">

The following table describes attributes that are common to all policy parent elements:

AttributeDescriptionDefaultPresence
name

The internal name of the policy. The value of thename attribute can contain letters, numbers, spaces, hyphens, underscores, and periods. This value cannot exceed 255 characters.

Optionally, use the<DisplayName> element to label the policy in the management UI proxy editor with a different, natural-language name.

N/ARequired
continueOnError

Set tofalse to return an error when a policy fails. This is expected behavior for most policies.

Set totrue to have flow execution continue even after a policy fails. See also:

falseOptional
enabled

Set totrue to enforce the policy.

Set tofalse toturn off the policy. The policy will not be enforced even if it remains attached to a flow.

trueOptional
async

This attribute is deprecated.

falseDeprecated

<DisplayName> element

Use in addition to thename attribute to label the policy in the management UI proxy editor with a different, natural-language name.

<DisplayName>Policy Display Name</DisplayName>
Default

N/A

If you omit this element, the value of the policy'sname attribute is used.

PresenceOptional
TypeString

<Request> element

Specifies the variable containing the request message that gets sent from the API proxy to the other service. The variable can be created by a previous policy in the flow, or you can create it inline in the ServiceCallout policy.

<RequestclearPayload="true"variable="myRequest"><IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables><Remove><StatusCode/><Path/><Version/><Verb/></Remove><Copy><StatusCode/><Path/><Version/><Verb/></Copy><Add><Headers/><QueryParams/><FormParams/></Add><Set><Headers/><QueryParams/><FormParams/><Payload/><StatusCode/><Path/><Version/><Verb/></Set></Request>

The syntax for the<Remove>,<Copy>,<Add>, and<Set> tags is the same as for theAssignMessage policy.

The sub-elements of<Set> and<Add> support the variable string substitution feature calledmessage templating.

The policy returns an error if the request message cannot be resolved or is of an invalid request message type.

In the simplest example, you pass a variable containing the request message that was populated earlier in the flow of the API proxy:

<RequestclearPayload="true"variable="myRequest"/>

Or you can populate the request message sent to the external service in the ServiceCallout policy itself:

<Request><Set><Headers><Headername="Accept">application/json</Header></Headers><Verb>POST</Verb><PayloadcontentType="application/json">{"message":"my test message"}</Payload></Set><IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables></Request>
Default If you omit the Request element, or any of its attributes, Apigee assigns the followingdefault values:

<Request clearPayload="true" variable="servicecallout.request"/>

Let's look at what these default values mean. First,clearPayload=true means that a new request object is created each time the ServiceCallout policy executes. This means that the request and the request URI path are never reused. Second, the default variable name,servicecallout.request, is a reserved name that is assigned to the request if you do not supply a name.

It's important to know about this default name if you are usingdata masking -- if you omit the variable name, you need to addservicecallout.request to your mask configuration. For example, if you wanted to mask the Authorization header so that it does not appear in Debug sessions, you would add the following to your masking configuration to capture the default name:

servicecallout.request.header.Authorization.

Presence Optional.
TypeN/A

Attributes

AttributeDescriptionDefaultPresence
variable

Name of the variable that will contain the request message.

servicecallout.requestOptional
clearPayload

Iftrue, the variable containing the request message is cleared after the request is sent to the HTTP target to free up the memory used by the request message.

Set theclearPayload option to false only if the request message is required after the ServiceCallout is executed.

trueOptional

<Request>/<IgnoreUnresolvedVariables> element

When set totrue, the policy ignores any unresolved variable error in the request.

<RequestclearPayload="true"variable="myRequest"><IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables></Request>
Defaultfalse
PresenceOptional
TypeBoolean

<Response> element

Include this element when the API proxy logic requires the response from the remote call for further processing.

When this element is present, it specifies the name of the variable that will contain the response message received from the external service. The response from the target is assigned to the variable only when the entire response is read successfully by the policy. If the remote call fails for any reason, the policy returns an error.

If this element is omitted, the API proxy does not wait for a response; API Proxy flow execution continues with any subsequent flow steps. Also, to state the obvious, with noResponse element, the response from the target is not available for processing by subsequent steps, and there is no way for the proxy flow to detect a failure in the remote call. A common use for omitting theResponse element when using ServiceCallout: to log messages to an external system.

 <Response>calloutResponse</Response>
DefaultNA
PresenceOptional
TypeString

<Timeout> element

The time in milliseconds that the ServiceCallout policy will wait for a response from the target. You cannot set this value dynamically at runtime. If the ServiceCallout hits a timeout, an HTTP 500 is returned, the policy fails, and the API proxy goes into an error state, as described inHandling faults.

<Timeout>30000</Timeout>
Default55000 milliseconds (55 seconds), the default HTTP timeout setting for Apigee
PresenceOptional
TypeInteger

<HTTPTargetConnection> element

Provides transport details such as URL, TLS/SSL, and HTTP properties. See the<TargetEndpoint> configuration reference.

Note: You can use flow variables to construct the URL in an<HttpTargetConnection> element.
<HTTPTargetConnection>    <URL>http://example.com</URL>    <LoadBalancer/>    <SSLInfo/>    <Properties/></HTTPTargetConnection>
DefaultN/A
PresenceRequired
TypeN/A

<HTTPTargetConnection>/<Authentication> element

Apigee hybrid users: If you are using Apigee hybrid, note that this feature is only supported for Apigee hybrid v1.6.x and later versions.

GeneratesGoogle OAuth 2.0 or Google-issuedOpenID Connect tokens to make authenticated calls to Google services and custom services running on certain Google Cloud products, such asCloud Functions andCloud Run. Use of this element requires setup and deployment steps described inUsing Google authentication. Withproper setup, the policy creates an authentication token for you and adds it to the service request.

The child elements,GoogleAccessToken andGoogleIDToken, let you configure the policy to generate either Google OAuth or OpenID Connect tokens. You need to pick one of these child elements depending on the type of service you wish to call.

The ServiceCallout policy only supports calling HTTP-based services.

DefaultN/A
Required?Optional.
TypeComplex type
Parent Element<HTTPTargetConnection>
Child Elements<HeaderName>
<GoogleAccessToken>
<GoogleIDToken>

TheAuthentication element uses the following syntax:

Syntax

<ServiceCallout>...<HTTPTargetConnection><Authentication><HeaderNameref="FLOW_VARIABLE">STRING</HeaderName><GoogleAccessToken><Scopes><Scope>SCOPE</Scope>...</Scopes><!--NOTE:ThedefaultvalueforLifetimeInSecondsis3600.Changethedefaultonlyifyouwanttolimittheriskofleakedaccesstokensorimproveperformance.--><LifetimeInSecondsref="{variable}">INTEGER</LifetimeInSeconds></GoogleAccessToken>--OR--<HeaderNameref="FLOW_VARIABLE">STRING</HeaderName><GoogleIDToken><Audienceref="{variable}"useTargetUrl="BOOLEAN">STRING</Audience><IncludeEmailref="{variable}">BOOLEAN</IncludeEmail></GoogleIDToken></Authentication></HTTPTargetConnection></ServiceCallout>

Using GoogleAccessToken

The following example shows theGoogleAccessToken element:

<Authentication>  <GoogleAccessToken>    <Scopes>      <Scope>https://www.googleapis.com/auth/cloud-platform</Scope>    </Scopes>  </GoogleAccessToken></Authentication>

Using GoogleIDToken

The following example shows theGoogleIDToken element:

<Authentication>  <GoogleIDToken>      <Audience>https://httpserver0-bar.run.app</Audience>      <IncludeEmail>false</IncludeEmail>  </GoogleIDToken></Authentication>

Using HeaderName

The following example shows theHeaderName element:

  <Authentication>    <HeaderName>X-Serverless-Authorization</HeaderName>    <GoogleAccessToken>      <Scopes>        <Scope>"https://www.googleapis.com/auth/cloud-platform"</Scope>      </Scopes>    </GoogleAccessToken>  </Authentication>

Using LifetimeInSeconds

The following example shows theHeaderName element:

<Authentication><GoogleAccessToken><Scopes><Scope>"https://www.googleapis.com/auth/cloud-platform"</Scope></Scopes><LifetimeInSecondsref="variable">3600</LifetimeInSeconds></GoogleAccessToken></Authentication>

Attributes

None.

HeaderName child element

By default, when an Authentication configuration is present, Apigee generates a bearer token and injects it into theAuthorization header in the message sent to the target system. TheHeaderName element allows you to specify the name of a different header to hold that bearer token. This feature is particularly useful when the target is a Cloud Run service that uses theX-Serverless-Authorization header. TheAuthorization header, if present, is left unmodified and also sent in the request.

DefaultN/A
Required?No
TypeString
Parent Element<Authentication>
Child ElementsNone

TheHeaderName element uses the following syntax:

Syntax

<ServiceCallout>...  <Authentication>    <HeaderName ref="FLOW_VARIABLE">STRING</HeaderName>    <GoogleAccessToken>      ...    </GoogleAccessToken>  </Authentication>  ...</ServiceCallout>

With static string

In this example, the generated bearer token is added, by default, to a header namedX-Serverless-Authorization that is sent to the target system. TheAuthorization header, if present, is left unmodified and also sent in the request.

<Authentication>  <HeaderName>X-Serverless-Authorization</HeaderName>  <GoogleAccessToken>    <Scopes>      <Scope>https://www.googleapis.com/auth/cloud-platform</Scope>    </Scopes>  </GoogleAccessToken></Authentication>

With variable reference

In this example, the generated bearer token is added, by default, to a header namedX-Serverless-Authorization that is sent to the target system. Ifmy-variable has a value, that value is used instead of the default string. TheAuthorization header, if present, is left unmodified and also sent in the request.

<Authentication><HeaderNameref='my-variable'>X-Serverless-Authorization</HeaderName><GoogleAccessToken><Scopes><Scope>https://www.googleapis.com/auth/cloud-platform</Scope></Scopes></GoogleAccessToken></Authentication>

GoogleAccessToken child element

GeneratesGoogle OAuth 2.0 tokens to make authenticated calls to Google services. Google OAuth tokens can be used to call many kinds of Google services, such asCloud Logging andSecret Manager.

DefaultN/A
Required?Either theGoogleAccessToken orGoogleIDToken child element must be present.
TypeString
Parent Element<Authentication>
Child Elements<Scopes>
<LifetimeInSeconds>

TheGoogleAccessToken element uses the following syntax:

Syntax

<ServiceCallout>...  <Authentication>    <GoogleAccessToken>      <Scopes>        <Scope>SCOPE_1</Scope>        ...      </Scopes>      <!-- NOTE: The default value for LifetimeInSeconds is 3600. We do not recommend changing      the default unless you want to limit the risk of leaked access tokens or improve performance. -->      <LifetimeInSeconds ref="FLOW_VARIABLE">INTEGER</LifetimeInSeconds>    </GoogleAccessToken>  </Authentication>  ...</ServiceCallout>

Example 1

The following example shows theGoogleAccessToken element:

<Authentication>  <GoogleAccessToken>    <Scopes>      <Scope>https://www.googleapis.com/auth/cloud-platform</Scope>    </Scopes>  </GoogleAccessToken></Authentication>

Example 2

The following example shows how to connect to the secret manager to retrieve a secret using the ServiceCallout policy.

<ServiceCallout name="ServiceCallout-sm">  <Response>SecretManagerResponse</Response>  <Timeout>30000</Timeout>  <HTTPTargetConnection>    <Authentication>      <GoogleAccessToken>        <Scopes>          <Scope>https://www.googleapis.com/auth/cloud-platform</Scope>        </Scopes>      </GoogleAccessToken>    </Authentication>    <URL>      https://secretmanager.googleapis.com/v1/projects/project-id/secrets/secret-id    </URL>  </HTTPTargetConnection></ServiceCallout>

Example 3

The following example shows how to make a callout to Cloud run from the ServiceCallout policy.

<ServiceCallout name="ServiceCallout-CloudRun">  <Response>CloudRunResponse</Response>  <Timeout>30000</Timeout>  <HTTPTargetConnection>    <Authentication>      <GoogleIDToken>        <Audience>https://cloudrun-hostname.a.run.app/test</Audience>      </GoogleIDToken>    </Authentication>    <URL>https://cloudrun-hostname.a.run.app/test</URL>  </HTTPTargetConnection></ServiceCallout>

Scopes child element

Identifies the scopes to be included in the OAuth 2.0 access token. For more information, see OAuth 2.0 Scopes for Google APIs. You can add one or more<Scope> child elements under this element.

DefaultN/A
Required?Required
TypeString
Parent Element<GoogleAccessToken>
Child Elements<Scope>

Scope child element

Specifies a valid Google API scope. For more information, see OAuth 2.0 Scopes for Google APIs.

DefaultN/A
Required?At least one value is required.
TypeString
Parent Element<Scopes>
Child ElementsNone.

LifetimeInSeconds child element

Specifies the lifetime duration of the access token in seconds.Note:The default value for LifetimeInSeconds is 3600. We do not recommend changing the default unless you want to limit the risk of leaked access tokens or improve performance.

Default3600
Required?Optional
TypeInteger
Parent Element<GoogleAccessToken>
Child ElementsNone.

GoogleIDToken child element

Generates Google-issuedOpenID Connect tokens to make authenticated calls to Google services.

DefaultN/A
Required?Either theGoogleAccessToken orGoogleIDToken child element must be present.
TypeString
Parent Element<Authentication>
Child Elements<Audience>
<IncludeEmail>

TheGoogleIDToken element uses the following syntax:

Syntax

<ServiceCallout>...<Authentication><GoogleIDToken><Audienceref="{variable}"useTargetUrl="BOOLEAN">STRING</Audience><IncludeEmailref="{variable}">BOOLEAN</IncludeEmail></GoogleIDToken></Authentication></ServiceCallout>

Example 1

The following example shows theGoogleIDToken element:

<Authentication>  <GoogleIDToken>      <Audience>https://httpserver0-bar.run.app</Audience>      <IncludeEmail>true</IncludeEmail>  </GoogleIDToken></Authentication>

Audience child element

The audience for the generated authentication token, such as the API or account that the token grants access to.

If the value ofAudience is empty or theref variable does not resolve to a valid value, anduseTargetUrl istrue, then the URL of the target (excluding any query parameters) is used as the audience. By default,useTargetUrl isfalse.

Apigee hybrid users: If you use Apigee hybrid, note that theuseTargetUrl attribute is available in Apigee hybrid version 1.8 and later versions.
<Audience>explicit-audience-value-here</Audience>or:<Audienceref='variable-name-here'/>or:<Audienceref='variable-name-here'useTargetUrl='true'/>or:<AudienceuseTargetUrl='true'/>
DefaultN/A
Required?Required
TypeString
Parent Element<GoogleIDToken>
Child ElementsNone.

IncludeEmail child element

If set totrue, the generated authentication token will contain the service accountemail andemail_verified claims.

Defaultfalse
Required?Optional
TypeBoolean
Parent Element<GoogleIDToken>
Child ElementsNone.

<HTTPTargetConnection>/<URL> element

The URL to the service being called:

The<URL> element supports the variable string substitution feature calledmessage templating.
<HTTPTargetConnection>    <URL>http://example.com</URL></HTTPTargetConnection>

You can supply part of the URL dynamically with a variable. However, the protocol portion of the URL,http:// below, cannot be specified by a variable. In the next example, you use a variable to specify the value of a query parameter:

<URL>http://example.com/forecastrss?w=${request.header.woeid}</URL>

Or, set a portion of the URL path with a variable:

<URL>http://example.com/{request.resourcePath}?w=${request.header.woeid}</URL>

If you want to use a variable to specify the domain and port of the URL, then use one variable for the domain and port only, and a second variable for any other part of the URL:

<URL>http://{request.dom_port}/{request.resourcePath}</URL>
DefaultN/A
PresenceRequired
TypeString

<HTTPTargetConnection>/<SSLInfo> element

The TLS/SSL configuration to the backend service. For help on TLS/SSL configuration, seeOptions for configuring TLS and "TLS/SSL TargetEndpoint Configuration" inAPI proxy configuration reference.

Note: Specify theKeyStore name in theSSLInfo element as a reference in the formref://mykeystoreref. Using a reference, rather than a direct name or flow variable, is recommended. SeeAbout setting the <KeyStore> and <TrustStore> elements.
<HTTPTargetConnection>    <URL>https://example.com</URL>    <SSLInfo>        <Enabled>true</Enabled>        <ClientAuthEnabled>true</ClientAuthEnabled>        <KeyStore>ref://mykeystoreref</KeyStore>  ## Use of a reference is recommended        <KeyAlias>myKey</KeyAlias>        <TrustStore>myTruststore</TrustStore>        <Ciphers/>        <Protocols/>    </SSLInfo></HTTPTargetConnection>
DefaultN/A
PresenceOptional
TypeN/A

<HTTPTargetConnection>/<Properties> element

HTTP transport properties to the backend service. For more information, seeEndpoint properties reference.

<HTTPTargetConnection>    <URL>http://example.com</URL>    <Properties>        <Property name="allow.http10">true</Property>        <Property name="request.retain.headers">          User-Agent,Referer,Accept-Language        </Property>    </Properties></HTTPTargetConnection>
DefaultN/A
PresenceOptional
TypeN/A

<HTTPTargetConnection>/<LoadBalancer> element

Call one or more target servers and do load balancing on them. See theCall target servers sample in theSamples section. See alsoLoad balancing across backend servers. See alsoTarget Endpoint/Server callout that discusses ways to call target servers from both the ServiceCallout policy and using Route Rules.

<HTTPTargetConnection> <LoadBalancer> <Algorithm>RoundRobin</Algorithm> <Server name="httpbin"/> <Server name="yahoo"/> </LoadBalancer> <Path>/get</Path> </HTTPTargetConnection>
DefaultN/A
PresenceOptional
TypeN/A

<LocalTargetConnection> element

Specifies a local proxy -- that is, a proxy in the same organization and environment -- as the target of service callouts.

To further specify the target, use either the<APIProxy> and<ProxyEndpoint> elements, or the<Path> element.

<LocalTargetConnection>   <APIProxy/>   <ProxyEndpoint/>   <Path/></LocalTargetConnection>
DefaultN/A
PresenceRequired
TypeN/A

<LocalTargetConnection>/<APIProxy> element

The name of an API proxy that is the target of a local call. The proxy must be in the same organization and environment as the proxy making the call.

<LocalTargetConnection>   <APIProxy>data-manager</APIProxy>   <ProxyEndpoint>default</ProxyEndpoint></LocalTargetConnection>

Along with the<APIProxy> element, include the<ProxyEndpoint> element to specify the name of the proxy endpoint that should be targeted for the call.

<LocalTargetConnection>   <APIProxy/>   <ProxyEndpoint/></LocalTargetConnection>
DefaultN/A
PresenceRequired
TypeString

<LocalTargetConnection>/<ProxyEndpoint> element

The name of the proxy endpoint that should be the target of calls. This is a proxy endpoint in the API proxy specified with the<APIProxy> element.

<LocalTargetConnection>   <APIProxy>data-manager</APIProxy>   <ProxyEndpoint>default</ProxyEndpoint></LocalTargetConnection>
DefaultN/A
PresenceOptional
TypeN/A

<LocalTargetConnection>/<Path> element

A path to the endpoint that is being targeted. The endpoint must refer to a proxy in the same organization and environment as the proxy making the call.

Use this instead of a<APIProxy>/<ProxyEndpoint> pair when you don't know -- or can't rely on -- the proxy name. The path might be a reliable target.

<LocalTargetConnection>   <Path>/data-manager</Path></LocalTargetConnection>
DefaultN/A
PresenceOptional
TypeN/A

Schemas

Sample: See ourGitHub repository samples for the most recent schemas.

Flow variables

Flow variables enable dynamic behavior of policies and Flows at runtime, based on HTTP headers, message content, or Flow context. The following predefined Flow variables are available after a ServiceCallout policy executes. For more information about Flow variables, seeFlow variables reference.

ServiceCallouts have their own request and response, and you can access that data through variables. Because the main message is using therequest.* andresponse.* variable prefixes, use themyrequest.* andcalloutResponse.* prefixes (the defaults in the ServiceCallout configuration) to get message data specific to the ServiceCallout. The first example in the following table shows how you'd get HTTP headers in the ServiceCallout.

VariableDescription

Following is an example of getting ServiceCallout request and response headers similar to how you would get headers from the main request and response.

calloutResponse.header.HeaderName

myRequest.header.HeaderName

wherecalloutResponse is the variable name for the Response in the Service Callout, andmyRequest is the variable name for the Request. For example:

calloutResponse.header.Content-Length

returns the Content-Length header of the ServiceCallout response.

Scope: From the ServiceCallout forward
Type: String
Permission: Read/Write

A message header in the ServiceCallout request or response. For example, if the API proxy target is http://example.com, and the ServiceCallout target is http://mocktarget.apigee.net, these variables are the headers for the callout to http://mocktarget.apigee.net.

servicecallout.requesturi

Scope: From the ServiceCallout request forward
Type: String
Permission: Read/Write

The TargetEndpoint URI for a ServiceCallout policy. The URI is the TargetEndpoint URL without the protocol and domain specification.

servicecallout.{policy-name}.target.url

Scope: From the ServiceCallout request forward
Type: String
Permission: Read/Write

The target URL for a the ServiceCallout.

calloutResponse.content

wherecalloutResponse is the<Response>variable name in the ServiceCallout configuration.

Scope: From the ServiceCallout response forward
Type: String
Permission: Read/Write

The response body from the ServiceCallout.

servicecallout.{policy-name}.expectedcn

Scope: From the ServiceCallout request forward
Type: String
Permission: Read/Write

The expected Common Name of the TargetEndpoint as referred to in a ServiceCallout policy. This is meaningful only when the TargetEndpoint refers to a TLS/SSL endpoint.

servicecallout.{policy-name}.failed

Scope: From the ServiceCallout response forward
Type: Boolean
Permission: Read/Write

Boolean indicating if the policy succeeded, false, or failed, true.

Errors

This section describes the fault codes and error messages that are returned and fault variables that are set by Apigee when this policy triggers an error. This information is important to know if you are developing fault rules to handle faults. To learn more, seeWhat you need to know about policy errors andHandling faults.

Runtime errors

These errors can occur when the policy executes.

Tip: Need help resolving an error? Clickin the Fix column for detailed troubleshooting information.
Fault codeHTTP statusCauseFix
steps.servicecallout.ExecutionFailed500

This error can occur when:

  • The policy is asked to handle input that is malformed or otherwise invalid.
  • The backend target service returns an error status (by default,4xx or5xx).
steps.servicecallout.RequestVariableNotMessageType500TheRequest variable specified in the policy is not of typeMessage. For example, if it's a string or other non-message type, you'll see this error.
steps.servicecallout.RequestVariableNotRequestMessageType500TheRequest variable specified in the policy is not of typeRequestMessage. For example, if it's a Response type, you'll see this error.
googletoken.EmptyIDTokenAudience500

<GoogleIDToken> is enabled butuseTargetUrl is set to false and no value is provided to<Audience> either directly or through reference at the time of error.

messaging.adaptors.http.filter.GoogleTokenGenerationFailure500This error can happen if the API proxy is configured with the <Authentication> element. Possible causes include:
  • The service account deployed with the proxy:
    • does not exist in your project
    • has been disabled
    • (Apigee hybrid only) has not granted theroles/iam.serviceAccountTokenCreator role on theapigee-runtime service account.
  • TheIAMCredentials API is disabled in the source project of theapigee-runtime service account.
  • The<GoogleAccessToken> element is used and one or more invalid scopes are provided. For example, look for typos or empty scopes.
  • For Apigee hybrid only, check the runtime container's log and search forGoogleTokenGenerationFailure to find more detailed error messages that may help with debugging the problem.

    Deployment errors

    These errors can occur when you deploy a proxy containing this policy.

    Tip: Need help fixing an error? Click in the Fix column for detailed troubleshooting information.
    Error nameCauseFix
    URLMissingThe<URL> element inside<HTTPTargetConnection> is missing or empty.
    ConnectionInfoMissingThis error happens if the policy does not have an<HTTPTargetConnection> or<LocalTargetConnection> element.
    InvalidTimeoutValueThis error happens if the<Timeout> value is negative or zero.
    FAILED_PRECONDITIONThis error happens if the service account is missing when the proxy is configured with the <Authentication> tag.

    For example:

    Deployment of \"organizations/foo/apis/apiproxy/revisions/1\" requires a service          account identity, but one was not provided with the request.
    PERMISSION_DENIEDThis error happens if there is a permission problem with the service account if the proxy is configured with the <Authentication> tag. Possible causes:
    • The service account does not exist.
    • The service account was not created in the same Google Cloud project as the Apigee organization.
    • The deployer does haveiam.serviceAccounts.actAs permission on the service account. For details, seeAbout service account permissions.

    Fault variables

    These variables are set when a runtime error occurs. For more information, seeWhat you need to know about policy errors.

    VariablesWhereExample
    fault.name="fault_name"fault_name is the name of the fault, as listed in theRuntime errors table above. The fault name is the last part of the fault code.fault.name = "RequestVariableNotMessageType"
    servicecallout.policy_name.failedpolicy_name is the user-specified name of the policy that threw the fault.servicecallout.SC-GetUserData.failed = true

    Example error response

    Note: For error handling, the best practice is to trap theerrorcode part of the error response. Do not rely on the text in thefaultstring, because it could change.
    {"fault":{"detail":{"errorcode":"steps.servicecallout.RequestVariableNotMessageType"},"faultstring":"ServiceCallout[ServiceCalloutGetMockResponse]:            request variable data_str value is not of type Message"}}

    Example fault rule

    <FaultRule name="RequestVariableNotMessageType">    <Step>        <Name>AM-RequestVariableNotMessageType</Name>    </Step>    <Condition>(fault.name = "RequestVariableNotMessageType")</Condition></FaultRule>

    Related topics

    Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

    Last updated 2025-12-17 UTC.