Create Actions.xml

Once you identify the in-app functionality and built-in intent (BII) to implement, you create an actions.xml resource in your Android app that maps the BII to your app functionality. App Actions defined in actions.xml describe how each BII resolves its fulfillment, as well as which parameters are extracted and provided to your app.


To integrate your Android app with App Actions, you must have an actions.xml file placed in your app project's res/xml directory.

Add a reference to the actions.xml file in the AndroidManifest.xml file using a <meta-data> tag as follows:

    <!-- ... -->
    <meta-data android:name="" android:resource="@xml/actions" />

This declares an XML resource for the xml/actions.xml file in the APK. To learn more about specifying resources in Android, see the App resources overview in the Android developer documentation.


The following table describes the schema for actions.xml. When including a tag, all of its attributes are required unless marked "optional".

Tag Contained in Attributes
<actions> top-level
<action> <actions> intentName
<parameter> <action> name
<entity-set-reference> <parameter> entitySetId
<fulfillment> <action> urlTemplate

fulfillmentMode (optional)

<parameter-mapping> <fulfillment> urlParameter


required (optional)

entityMatchRequired (optional)

<entity-set> <actions> entitySetId
<entity> <entity-set> name (and optionally alternateName) OR sameAs

identifier OR url



An App Action that the app supports. For every <action> tag in your actions.xml file, you must provide at least one <fulfillment>.


  • intentName: Built-in intent for the App Action (for example, "actions.intent.CREATE_TAXI_RESERVATION"). For a list of supported built-in intents, see the built-in intent reference.


A parameter of an App Action having a name and list of associated entities.


  • name: Name to associate with this parameter (for example, "destination"). The name should be a leaf-level field of the parameter (for example, If the parameter is a primitive type, such as a string, then the name is just the parameter name itself.


Reference to a feed that the developer supplies. Feeds must be provided directly in the actions.xml file using <entity-set> tags.


  • entitySetId: A reference to a specific collection of entities. This attribute must correspond to an entitySetId value in an <entity-set> tag.


Information about how to fulfill the user intent using the Android app. Developers may provide multiple <fulfillment> tags in actions.xml, with different set of required parameters for each intent.

Google uses the first <fulfillment> for which all required parameters are available to fulfill the user's query. You must provide one <fulfillment> without any required parameters as a fallback fulfillment.


  • urlTemplate: Template for constructing either the deep link or a Slice URI to be opened on the device. The template may be expanded with the parameters of the user intent if all required parameters for the template are available. For examples of the HTTP URL template, see the Wikipedia article on URL templates. The template format follows the RFC6570 URI template specification.
  • fulfillmentMode: (optional) Fulfillment mode used for serving. The valid values are:
    • actions.fulfillment.DEEPLINK: Fulfill user action by opening the Android app using a deep link. This is the default.
    • actions.fulfillment.SLICE: Fulfill user action by embedding a Slice provided by Android app.

The following are some examples of URL template values:

Template Values Expanded value{?foo,bar} "foo": "123"

"bar": "456"{&foo,bar} "foo": "123"

"bar": "456"{#foo} "foo": "123"
myapp://example/{foo} "foo": "123" myapp://example/123
intent://foo#Intent;scheme=my-scheme{;S.extra1,S.extra2};end "S.extra1": "123"

"S.extra2": "456"


For more about configuring URL templates, see URL templates in fulfillment.


Maps from variables in the URL template to intent parameters. Keys in this map represent URL template parameters, or "variables" as decribed in RFC 6570.

If a parameter is not included in the intent, the corresponding variable will be left undefined at the time of URL template expansion. See RFC 6570, Section 3.2.1 for a description of how undefined variables are treated.

Note that required="true" and entityMatchRequired="true" are distinct.


  • urlParameter: Every variable mentioned in the URL template must have a corresponding urlParameter in <parameter-mapping>. For example, if the uri_template is "{?lat,long}", there must be a key in <parameter-mapping> for parameters "lat" and "long".
  • intentParameter: Values refer to intent parameters. If the intent parameter is of a structured type, use dot.notation to refer to a nested field. For example, if there is a parameter "taxiReservation" of type, you can use taxiReservation.pickupLocation.geo.latitude to refer to the latitude value.

    If providing an entity set for this parameter, the intentParameter must match exactly the name of the corresponding <parameter> tag (for example, taxiReservation.pickupLocation.geo.latitude). It should point to a leaf-level field of the parameter (if the intent parameter has a complex type) or the parameter name itself (if the intent parameter has a primitive type).

  • required: (optional) Indicates that a value for the given intentParameter is required to be present for this URL template to be valid. The URL template is dropped if the user query does not include a value for the given intentParameter.

  • entityMatchRequired: (optional) Indicates that the given urlParameter is only included in the URL template if there is an inventory match for the intentParameter.

    If not specified, Google assumes that an inventory match is optional. That is, if inventory match does happen, the identifier from the matched inventory entity is passed to the URL template. If inventory match does not happen, the built-in intent parameter value (text) is omitted from the URL template.


Set of inlined entities in actions.xml.


  • entitySetId: Required unique identifier for an <entity-set>in actions.xml (for example, "myInlineEntitySet1"). This value must also correspond to the <entitySetId> value in the <entity-set-reference> tag.

    Values for entitySetId must contain at most 30 characters, contain only alphanumeric characters (no special characters like - or _), and begin with a letter.


One element among a set of entities inlined in actions.xml. Contains a subset of fields.

String values for the url, identifier, and sameAs fields can either be hard-coded or referenced via the APK's string resources. When providing synonyms, use string values for the alternateName field that reference the APK's string array resources.


  • name: Required name for the entity, unless you are specifying a sameAs field. Must be unique across entity name and alternateName fields for the given <entity-set> (for example, "toothpaste").
  • alternateName: (optional) Alternate names for the entity. You must specify a name field before specifying an alternateName field. Must be unique across entity name and alternateName fields for the given <entity-set>. The entity is selected if the user's query matches any of these strings.
  • sameAs: URL of a reference web page that unambiguously identifies the entity. Used to specify an enum value if and only if the intent parameter type is a subtype of

    Required for parameter fields whose types are subtypes of (for example: MealTypeBreakfast).

  • identifier: Identifier for the entity. Must be unique across entities for the given <entity-set> (for example, "CAPPUCCINO_ID").

  • url: RFC 3986 URL to be opened on an Android device. The URL may or may not be resolvable by an HTTP client. For example, on Android, the URL may be an app-linked "http://" URL or a device-specific URL, like an "intent://" URL or a URL in a custom URL scheme.

    You can use the url field together with the urlTemplate attribute of <fulfillment> in the following ways:

    • Provide url values in inline inventory, and omit urlTemplate in <fulfillment>.
    • Provide url values in inline inventory, and use those values in the urlTemplate value (for example, "{@url}&extra_param=ExampleValue").

Either identifier or url must be provided. All entities within a given entity set must use the same attribute (identifier or url).

Inline inventory for App Actions

For some built-in intents, you can optionally restrict fulfillment to a set of supported entities specified in actions.xml, known as inline inventory. When a user invokes your App Action, the Assistant matches user query parameters with entities specified as inline inventory. The Assistant can then use identifiers that correspond to inventory items when generating a deep link for fulfillment.

You define inline inventory primarily using the <entity-set> and <entity> elements. Inline inventory simplifies development by allowing your app to handle only identifiers or URLs from App Action invocations instead of needing to recognize strings or Google enumeration values.

For example, your app offers different beverages that users can order, and you expect users to make the following requests for the same type of beverage:

  • Hey Google, order a Blueberry Crisp Iced Signature Latte from ExampleApp.
  • Hey Google, order a Blueberry Iced Coffee from ExampleApp.

In your inline inventory, you specify "Blueberry Crisp Iced Signature Latte" as an entity that corresponds to the identifier "12345a". You also specify "Blueberry Iced Coffee" as an entity that corresponds to the same identifier. Now, when a user triggers your App Action with the above queries, the Assistant can use the identifier "12345a" when generating a deep link for fulfillment.

You can specify up to 1,000 entities per app, across all entity sets.

URL templates in fulfillment

In a <fulfillment> tag, you can declare a URL template with placeholders for dynamic parameters. This template maps to one of your Android activities, using an App Links URL, a custom scheme, or an Intent-based URL.

Configuring the URL template

Example of an App Links URL:

<action intentName="actions.intent.CREATE_TAXI_RESERVATION">
    <fulfillment urlTemplate="{?dropoffLocation}">

Example of a custom scheme:

<action intentName="actions.intent.CREATE_TAXI_RESERVATION">
    <fulfillment urlTemplate="mytaxi://reserve{?dropoffLocation}">

Example of an intent-based URL:

<action intentName="actions.intent.CREATE_TAXI_RESERVATION">

When specifying a <parameter-mapping> tag for a fulfillment, the intentParameter attribute denotes the built-in intent parameter provided by the user. In the above examples, that parameter is the drop off location name (""). You can find the available parameters for any given built-in intent in the built-in intent reference.

To map the built-in intent parameter to a position in your URL, you use the urlParameter attribute of the <parameter-mapping> tag. This attribute corresponds to the placeholder value in the URL template that you want to substitute with information from the user. The placeholder value must be present in your urlTemplate and enclosed by curly braces ({}).

If you specify entity sets, you can combine the URL from an entity set with other URL parameters. To add URL parameters, provide a urlTemplate value that begins with the {@url} placeholder, such as: "{@url}&autoplay=true&utm_source=assistant".

App Links URLs

If you're using an App Links URL, the urlTemplate points to a regular HTTP URL that can trigger your Activity. Parameters are passed as URL parameters to the App Links URL. The parameters in urlTemplate must be enclosed in curly braces ({}) and prefixed with a question mark (?). If a parameter is not set, the parameter (curly braces included) is omitted from the result.

For example, if a user triggered the App Action by asking to order a taxi to "San Francisco", the final URI that is triggered (after parameter substitution) would be the following:

Intent-based URLs

If you're using an intent-based URL, the urlTemplate value includes the package name, the Intent action, and one extra Intent, called the "dropoff". The extra is prefixed by "S." to denote a String Intent extra (as defined by Intent.toUri()) and is surrounded by curly braces to denote a substitution by a parameter. The extra preceding semicolon is needed to separate the Intent action from the Intent extra (and is only included if the parameter is set).

In our example, the urlParameter value is set to "S.dropoff"; you can see where this appears in our URL by looking for this value in urlTemplate.

As an example, if a user triggered our Action by asking to order a ride to "San Francisco", the final Uri that is triggered (after parameter substitution) would be:


Using URL values from entities in URL templates

By default, if an <entity> is matched to the user's query, the value of the identifier attribute is passed to the URL template. To reference the url attribute of an <entity> instead, use {@url} in the URL template and do not use a <parameter-mapping> tag. Note that identifier values are URL-escaped, but url attribute values are left unchanged.

For example:

<fulfillment urlTemplate="{@url}">
    <!-- No parameter-mapping is needed -->
<entity-set entitySetId="...">
    <entity name="..." url="https://my.url.fulfillment/1"/>
    <entity name="..." url="https://my.url.fulfillment/2"/>

The {@url} parameters can be combined with other parameters. For example:

<fulfillment urlTemplate="{@url}?referrer=actions_on_google{&amp;other_param}">
    <parameter-mapping intentParameter="" urlParameter="other_param"/>
<entity-set entitySetId="...">
    <entity name="..." url="https://my.url.fulfillment/1"/>
    <entity name="..." url="https://my.url.fulfillment/2"/>

Parameter matching

The way Google matches parameters from the user utterances to the entities you specified depends on the type of the parameter:

  • Enum: Google matches the user's query ("monday") to an associated enum URL (""), then picks the entity whose sameAs value matches the enum URL.
  • String: Google picks the entity whose name or alternateName value matches the user's query.


Finance - accounts and payments

The following actions.xml example uses the actions.intent.CREATE_MONEY_TRANSFER built-in intent:

<?xml version="1.0" encoding="utf-8"?>
    <action intentName="actions.intent.CREATE_MONEY_TRANSFER">
        <fulfillment urlTemplate="mybankapp://transfer{?amount,currency,recipientBankAccountType,senderBankAccountType,mode}">
            <parameter-mapping intentParameter="moneyTransfer.amount.value" urlParameter="amount" />
            <parameter-mapping intentParameter="moneyTransfer.amount.currency" urlParameter="currency" />
            <parameter-mapping intentParameter="" urlParameter="recipientBankAccountType" />
            <parameter-mapping intentParameter="" urlParameter="senderBankAccountType" />
            <parameter-mapping intentParameter="moneyTransfer.transferMode" urlParameter="mode" />

Fitness - nutrition

The following actions.xml example uses the actions.intent.RECORD_FOOD_OBSERVATION built-in intent:

<?xml version="1.0" encoding="utf-8"?>
    <action intentName="actions.intent.RECORD_FOOD_OBSERVATION">
        <parameter name="foodObservation.forMeal">
            <entity-set-reference entitySetId="MealEntitySet"/>
        <fulfillment urlTemplate="myfoodapp://record{?food,meal}">
            <parameter-mapping intentParameter="foodObservation.forMeal" urlParameter="meal" entityMatchRequired="true" />
            <parameter-mapping intentParameter="" urlParameter="food" />
    <entity-set entitySetId="MealEntitySet">
        <entity sameAs="" identifier="1" />
        <entity sameAs="" identifier="2" />
        <entity sameAs="" identifier="3" />


Food ordering

The following actions.xml example uses the actions.intent.ORDER_MENU_ITEM built-in intent:

<?xml version="1.0" encoding="utf-8"?>
    <action intentName="actions.intent.ORDER_MENU_ITEM">
        <parameter name="menuItem.inMenuSection.inMenu.forRestaurant.servesCuisine">
            <entity-set-reference entitySetId="CuisineEntitySet"/>
        <fulfillment urlTemplate="myfoodapp://order{?restaurant}">
            <parameter-mapping intentParameter="" urlParameter="restaurant" required="true" />
        <!-- URL values are derived from a matched entity from the CuisineEntity Set. This is not a fallback fulfillment because {@url} is a required parameter. -->
        <fulfillment urlTemplate="{@url}" />
        <!-- Fallback fulfillment with no required parameters -->
        <fulfillment urlTemplate="myfoodapp://browse{?food}">
            <parameter-mapping intentParameter="" urlParameter="food" />
    <entity-set entitySetId="CuisineEntitySet">
        <entity url="myfoodapp://browse/italian/pizza" name="@string/pizza" alternateName="@array/pizzaSynonyms" />
        <entity url="myfoodapp://browse/american/hamburger" name="@string/hamburger" alternateName="@array/hamburgerSynonyms" />
        <entity url="myfoodapp://browse/mediterranean" name="@string/mediterranean" alternateName="@array/mediterraneanSynonyms" />


The following actions.xml file uses the actions.intent.CREATE_TAXI_RESERVATION built-in intent:

    <action intentName="actions.intent.CREATE_TAXI_RESERVATION">
        <fulfillment urlTemplate="{?dropoffAddress}">
            <!-- Dropoff location as an address -->


The following actions.xml example uses the actions.intent.OPEN_APP_FEATURE built-in intent.

<?xml version="1.0" encoding="utf-8"?>
    <action intentName="actions.intent.OPEN_APP_FEATURE">
        <!-- Each parameter can reference an entity set using a custom ID. -->
        <parameter name="feature">
            <entity-set-reference entitySetId="FeatureEntitySet"/>

        <fulfillment urlTemplate="myexampleapp://pathto{?appFeature}">
            <parameter-mapping intentParameter="feature" urlParameter="appFeature" />

    <entity-set entitySetId="FeatureEntitySet">
        <entity identifier="FEATUREONE" name="first feature" />
        <entity identifier="FEATURETWO" name="second feature" />