When constructing serving URLs, the serving URL for an ad or asset is
constructed by combining various fields according to a set of rules. This
section examines these rules in more detail.

## Hierarchy of Google Ads entities

When resolving URL fields, Google Ads uses the following hierarchy (highest to
lowest):

    Customer
        Campaign
            Ad Group
                Ad
                    Ad Group Criterion
                        FeedItem or Asset (including sitelinks)

> [!NOTE]
> **Note:** `FeedItem` is legacy and deprecated in favor of Assets (`Asset`, `AdGroupAsset`, `CampaignAsset`). In v24 and later, sitelink placeholder fields were removed, and sitelinks must use `SitelinkAsset`.

## Which final URL is used?

The final URL is used by default when building the serving URL. If a [supported
entity](https://developers.google.com/google-ads/api/docs/ads/upgraded-urls/supported-entities) is served on a mobile
network and has a valid final mobile URL, then that is used instead of the final
URL. Final app URL is supported only for app engagements ads.

> [!NOTE]
> **Note:** For the rest of this guide, the phrase *final URL* is used as a generic term to include final URL, final mobile URL, and final app URL.

## How the system expands the serving URL

Here are the steps the system takes when expanding the serving URL:

1. **Determine which final URL to use.**

   It starts by determining which final URL to use. This varies depending on
   the entity involved.

   | Entity | Which final URL to use? |
   |---|---|
   | FeedItem or Asset (sitelink) | Always use its own final URL. |
   | Ad X served on keyword Y | If the keyword has its own final URL, use it. Otherwise use the ad's final URL. |

2. **Determine which tracking URL template and final URL suffix to use.**

   The tracking URL template (`tracking_url_template`) and final URL suffix
   (`final_url_suffix`) for an entity are each determined independently by
   traversing its object hierarchy and choosing the value from the entity
   lowest in the hierarchy. If no value can be found in the hierarchy for a
   field, its value is set to empty.

   For example, if an ad has tracking URL template or final URL suffix values
   defined only at its parent ad group and account levels, the value from the
   parent ad group is used.
3. **Determine which custom parameter values to use.**

   The value for a given custom parameter is resolved by traversing the object
   hierarchy, and choosing the value from the entity lowest in the hierarchy.
   If no value is defined for the custom parameter, an empty string is used as
   its value.

   For example, when determining the value for a particular custom parameter at
   the ad level, if that custom parameter has values defined at its parent ad
   group and at the account level, the value from the parent ad group is used.
4. **Expand the final URL.**

   If a non-empty `final_url_suffix` was determined in step 2, it is appended
   to the end of the final URL. The system expands the final URL (including any
   appended `final_url_suffix`) by performing the following three steps:
   1. *Expand the custom parameter values.*

      The system parses the final URL and substitutes the values for each
      custom parameter in the URL, using the values determined in step 3.
   2. *Expand the ValueTrack tags in the URL.*

      The system parses the final URL, and substitutes values for any
      [ValueTrack](https://support.google.com/google-ads/answer/2375447) tags
      present in the URL.
   3. *Strip the {ignore} tag.*

      Any `{ignore}` ValueTrack parameter in the expanded final URL is
      removed.
5. **Expand the tracking template.**

   If there's an empty value for the tracking template (as determined in step
   2), this step is skipped. Otherwise, the tracking URL template is
   expanded as follows:
   1. *Expand the custom parameter values.*

      The system parses the tracking template URL, and substitutes the values
      for each custom parameter in the URL using the values determined in step
      3.
   2. *Expand the ValueTrack tags in the URL.*

      The system parses the tracking template URL, and substitutes values for
      any ValueTrack tags present in the URL.
   3. *Substitute {lpurl} parameter in tracking template.*

      If the tracking template URL contains `{lpurl}` or one of its variants,
      it's replaced with the expanded final URL from step 4.
      - If `{lpurl}` is inserted at the beginning of the tracking template, then it is not escaped. If positioned elsewhere in the tracking template, the following characters are escaped: `?`, `=`, `&`, `"`, `#`, `\t`, `'`, and `[space]`.
      - `{unescapedlpurl}` is always unescaped.
      - `{escapedlpurl}` is always escaped.
      - `{lpurl+2}` is always escaped twice.
      - `{lpurl+3}` is always escaped three times.
6. **Pick the serving URL.**

   If your tracking template URL is empty, the expanded final URL from step 4
   is used. Otherwise, the system uses the expanded tracking template URL from
   step 5.

   Sitelinks are an exception to this rule: If the tracking URL template
   (determined in step 2) does not contain the `{lpurl}` parameter, then the
   sitelink's final URL is used as the serving URL.

## Example scenarios

Consider an account with the following structure:

    Account
        Campaign 1
            Ad Group 1
                Ad 1
                Keyword 1 (shoes)
                Keyword 2 (hats)
            Ad Group 2
                Ad 2
                Ad 3
                Keyword 3 (watches)
        FeedItem 1 (sitelink 1)

Assume the following URL fields are defined on these entities:

| Entity name | Tracking URL template | Final URL | Custom Parameters |
|---|---|---|---|
| Account | `http://www.cid1-tracking.com/?{_myid}&u={lpurl}` |   |   |
| Campaign 1 |   |   | `_mycampaign=cam1` |
| Ad Group 1 | `http://www.ag1-tracking.com/?{_mycampaign}&u={lpurl}&{_myid}` |   | `_myid=ag1id` |
| Ad Group 2 |   |   | `_myid=ag2id` |
| Ad 1 |   | `http://www.creative1-final.com/?{keyword}{ignore}&{_myid}&{_mycampaign}` |   |
| Ad 2 |   | `http://www.creative2-final.com/?{keyword}{ignore}&{_myid}` | `_myid=ad2id` |
| Ad 3 | `http://www.ad3-tracking.com/?{_mycampaign}` |   |   |
| Keyword 1 |   | **final URL** : `http://www.kw-final.com/?{keyword}{ignore}&{_mycampaign}` **final mobile URL** : `http://m.kw-final-mobile.com/?{keyword}{ignore}&{_myid}` | `_myid=k1id` |
| Keyword 2 |   |   |   |
| Keyword 3 |   |   |   |
| FeedItem 1 |   | **final URL** : `http://www.sitelink-final.com/?{keyword}{ignore}&{_mycampaign}` **final mobile URL** : `http://m.sitelink-final-mobile.com/?{keyword}{ignore}&{_myid}` |   |

The following values are used for expanding the ValueTrack parameter
`{keyword}`:

- Keyword 1: shoes
- Keyword 2: hats
- Keyword 3: watches

The following sections show how various parameters get resolved for each of
these entities.

#### Case 1: Ad 1 is served due to Keyword 2

| Parameter | Value | Source |
|---|---|---|
| Tracking template | `http://www.ag1-tracking.com/?{_mycampaign}&u={lpurl}&{_myid}` | Ad Group 1 |
| Final URL | `http://www.creative1-final.com/?{keyword}&{_myid}&{_mycampaign}` | Ad 1 |
| Custom Parameters | `_myid=ag1id` | Ad Group 1 |
| Custom Parameters | `_mycampaign=cam1` | Campaign 1 |
| Expanded final URL | `http://www.creative1-final.com/?hats&ag1id&cam1` | N/A |
| Expanded tracking template URL | `http://www.ag1-tracking.com/?cam1&u=http://www.creative1-final.com/%3Fhats%26ag1id%26cam1&ag1id` | N/A |
| Serving URL | `http://www.ag1-tracking.com/?cam1&u=http://www.creative1-final.com/%3Fhats%26ag1id%26cam1&ag1id` | N/A |

#### Case 2: Ad 1 is served due to Keyword 1

| Parameter | Value | Source |
|---|---|---|
| Tracking template | `http://www.ag1-tracking.com/?{_mycampaign}&u={lpurl}&{_myid}` | Ad Group 1 |
| Final URL | `Desktop: http://www.kw-final.com/?{keyword}&{_mycampaign}` | Keyword 1 |
| Final URL | `Mobile: http://m.kw-final-mobile.com/?{keyword}&{_myid}` | Keyword 1 |
| Custom Parameters | `_myid=k1id` | Keyword 1 |
| Custom Parameters | `_mycampaign=cam1` | Campaign 1 |
| Expanded final URL | `Desktop: http://www.kw-final.com/?shoes&cam1` | N/A |
| Expanded final URL | `Mobile: http://m.kw-final-mobile.com/?shoes&k1id` | N/A |
| Expanded tracking template URL | `Desktop: http://www.ag1-tracking.com/?cam1&u=http://www.kw-final.com/%3Fshoes%26cam1&k1id` | N/A |
| Expanded tracking template URL | `Mobile: http://www.ag1-tracking.com/?cam1&u=http://m.kw-final-mobile.com/%3Fshoes%26k1id&k1id` | N/A |
| Serving URL | `Desktop: http://www.ag1-tracking.com/?cam1&u=http://www.kw-final.com/%3Fshoes%26cam1&k1id` | N/A |
| Serving URL | `Mobile: http://www.ag1-tracking.com/?cam1&u=http://m.kw-final-mobile.com/%3Fshoes%26k1id&k1id` | N/A |

#### Case 3: Ad 2 is served due to Keyword 3

| Parameter | Value | Source |
|---|---|---|
| Tracking template | `http://www.cid1-tracking.com/?{_myid}&u={lpurl}` | Account |
| Final URL | `http://www.creative2-final.com/?{keyword}&{_myid}` | Ad 2 |
| Custom Parameters | `_myid=ad2id` | Ad 2 |
| Custom Parameters | `_mycampaign=cam1` | Campaign 1 |
| Expanded final URL | `http://www.creative2-final.com/?watches&ad2id` | N/A |
| Expanded tracking template URL | `http://www.cid1-tracking.com/?ad2id&u=http://www.creative2-final.com/%3Fwatches%26ad2id` | N/A |
| Serving URL | `http://www.cid1-tracking.com/?ad2id&u=http://www.creative2-final.com/%3Fwatches%26ad2id` | N/A |

#### Case 4: FeedItem 1 serves under Ad 1 due to Keyword 2

| Parameter | Value | Source |
|---|---|---|
| Tracking template | `http://www.ag1-tracking.com/?{_mycampaign}&u={lpurl}&{_myid}` | Ad Group 1 |
| Final URL | `Desktop: http://www.sitelink-final.com/?{keyword}&{_mycampaign}` | FeedItem 1 |
| Final URL | `Mobile: http://m.sitelink-final-mobile.com/?{keyword}&{_myid}` | FeedItem 1 |
| Custom Parameters | `_myid=ag1id` | Ad Group 1 |
| Custom Parameters | `_mycampaign=cam1` | Campaign 1 |
| Expanded final URL | `Desktop: http://www.sitelink-final.com/?hats&cam1` | N/A |
| Expanded final URL | `Mobile: http://m.sitelink-final-mobile.com/?hats&ag1id` | N/A |
| Expanded tracking template URL | `Desktop: http://www.ag1-tracking.com/?cam1&u=http://www.sitelink-final.com/%3Fhats%26cam1&ag1id` | N/A |
| Expanded tracking template URL | `Mobile: http://www.ag1-tracking.com/?cam1&u=http://m.sitelink-final-mobile.com/%3Fhats%26ag1id&ag1id` | N/A |
| Serving URL | `Desktop: http://www.ag1-tracking.com/?cam1&u=http://www.sitelink-final.com/%3Fhats%26cam1&ag1id` | N/A |
| Serving URL | `Mobile: http://www.ag1-tracking.com/?cam1&u=http://m.sitelink-final-mobile.com/%3Fhats%26ag1id&ag1id` | N/A |

#### Case 5: FeedItem 1 serves under Ad 1 due to Keyword 1

| Parameter | Value | Source |
|---|---|---|
| Tracking template | `http://www.ag1-tracking.com/?{_mycampaign}&u={lpurl}&{_myid}` | Ad Group 1 |
| Final URL | `Desktop: http://www.sitelink-final.com/?{keyword}&{_mycampaign}` | FeedItem 1 |
| Final URL | `Mobile: http://m.sitelink-final-mobile.com/?{keyword}&{_myid}` | FeedItem 1 |
| Custom Parameters | `_myid=k1id` | Keyword 1 |
| Custom Parameters | `_mycampaign=cam1` | Campaign 1 |
| Expanded final URL | `Desktop: http://www.sitelink-final.com/?shoes&cam1` | N/A |
| Expanded final URL | `Mobile: http://m.sitelink-final-mobile.com/?shoes&k1id` | N/A |
| Expanded tracking template URL | `Desktop: http://www.ag1-tracking.com/?cam1&u=http://www.sitelink-final.com/%3Fshoes%26cam1&k1id` | N/A |
| Expanded tracking template URL | `Mobile: http://www.ag1-tracking.com/?cam1&u=http://m.sitelink-final-mobile.com/%3Fshoes%26k1id&k1id` | N/A |
| Serving URL | `Desktop: http://www.ag1-tracking.com/?cam1&u=http://www.sitelink-final.com/%3Fshoes%26cam1&k1id` | N/A |
| Serving URL | `Mobile: http://www.ag1-tracking.com/?cam1&u=http://m.sitelink-final-mobile.com/%3Fshoes%26k1id&k1id` | N/A |

#### Case 6: FeedItem 1 serves under Ad 2 due to Keyword 3

| Parameter | Value | Source |
|---|---|---|
| Tracking template | `http://www.cid1-tracking.com/?{_myid}&u={lpurl}` | Account |
| Final URL | `Desktop: http://www.sitelink-final.com/?{keyword}&{_mycampaign}` | FeedItem 1 |
| Final URL | `Mobile: http://m.sitelink-final-mobile.com/?{keyword}&{_myid}` | FeedItem 1 |
| Custom Parameters | `_myid=ad2id` | Ad 2 |
| Custom Parameters | `_mycampaign=cam1` | Campaign 1 |
| Expanded final URL | `Desktop: http://www.sitelink-final.com/?watches&cam1` | N/A |
| Expanded final URL | `Mobile: http://m.sitelink-final-mobile.com/?watches&ad2id` | N/A |
| Expanded tracking template URL | `Desktop: http://www.cid1-tracking.com/?ad2id&u=http://www.sitelink-final.com/%3Fwatches%26cam1` | N/A |
| Expanded tracking template URL | `Mobile: http://www.cid1-tracking.com/?ad2id&u=http://m.sitelink-final-mobile.com/%3Fwatches%26ad2id` | N/A |
| Serving URL | `Desktop: http://www.cid1-tracking.com/?ad2id&u=http://www.sitelink-final.com/%3Fwatches%26cam1` | N/A |
| Serving URL | `Mobile: http://www.cid1-tracking.com/?ad2id&u=http://m.sitelink-final-mobile.com/%3Fwatches%26ad2id` | N/A |

#### Case 7: FeedItem 1 serves under Ad 3 due to Keyword 3

| Parameter | Value | Source |
|---|---|---|
| Tracking template | `http://www.ad3-tracking.com/?{_mycampaign}` | Ad 3 |
| Final URL | `Desktop: http://www.sitelink-final.com/?{keyword}&{_mycampaign}` | FeedItem 1 |
| Final URL | `Mobile: http://m.sitelink-final-mobile.com/?{keyword}&{_myid}` | FeedItem 1 |
| Custom Parameters | `_myid=ag2id` | Ad Group 2 |
| Custom Parameters | `_mycampaign=cam1` | Campaign 1 |
| Expanded final URL | `Desktop: http://www.sitelink-final.com/?watches&cam1` | N/A |
| Expanded final URL | `Mobile: http://m.sitelink-final-mobile.com/?watches&ag2id` | N/A |
| Expanded tracking template URL | Not used, since tracking template doesn't contain `{lpurl}` parameter. | N/A |
| Serving URL | `Desktop: http://www.sitelink-final.com/?watches&cam1` | N/A |
| Serving URL | `Mobile: http://m.sitelink-final-mobile.com/?watches&ag2id` | N/A |