# Enhanced Endpoints Guide

**URL:** <https://community.dynatrace.com/t/enhanced-endpoints-guide/55616>\
**Category:** Troubleshooting\
**Tags:** services\
**Created:** [April 17, 2026, 1:09pm UTC](https://community.dynatrace.com/t/enhanced-endpoints-guide/55616 "2026-04-17T13:09:29Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![mreider](https://dub1.discourse-cdn.com/dynatrace/user_avatar/community.dynatrace.com/mreider/32/14971_2.png) [@mreider](https://community.dynatrace.com/u/mreider)\
**Post date:** [April 17, 2026, 1:09pm UTC](https://community.dynatrace.com/t/enhanced-endpoints-guide/55616/1 "2026-04-17T13:09:29Z")

</div>

Editor’s note · May 20, 2026This post has been **fully rewritten** to reflect the current Enhanced Endpoint Guide. The structure, examples, screenshots, and rollout details have all changed since the previous version. If you’ve bookmarked an earlier paragraph or linked an old section, you may want to re-read top to bottom.Changes are scheduled to start during the rollout of SaaS Cluster version 1.342, which is scheduled to begin on June 30th.

How endpoint detection looks in Dynatrace depends on a few things: which app you’re using (Classic or the new Services app), whether Enhanced Endpoints is enabled, whether your services run on Service Detection v1 or v2, and whether your applications emit `http.route` on their spans. Different combinations produce noticeably different pictures in the Services app, and the path forward from each one isn’t the same.

This guide walks through those combinations one at a time. Read the sections in order if you want the full picture, or skip to the one that matches your situation.

* * *

## Classic Services and Key Requests

In Service Detection v1 (SDv1) on the Classic Services app, the way you get per-request detail is to **mark requests as Key Requests**.

You’d open a service, click _View all request details_, find the request you cared about (say, `/orders/search`), and pick _Mark as key request_. After that, Dynatrace tracked that request as its own row with golden-signal metrics, anomaly detection, and so on.

 ![mreider_0-1779285137396.png](https://global.discourse-cdn.com/dynatrace/original/3X/b/a/ba4c2191a976131b7961ee7d01bd08d3fbd2bac8.png)

**What that looks like in Classic.** The service overview screen has a Key Requests / Endpoints panel listing your marked requests. Requests you didn’t mark don’t get their own row in Classic; their data folds into the service’s aggregate metrics.

 ![mreider_1-1779285173130.png](https://global.discourse-cdn.com/dynatrace/original/3X/5/b/5be8e4d0794fa8e3cf49fb4b05382582097a7e2f.png)

**What that looks like in the new Services app.** Same data, new vocabulary. The new app uses the word _endpoint_ and surfaces the same Key Request as a row in the Endpoints tab.

 ![mreider_2-1779285238582.png](https://global.discourse-cdn.com/dynatrace/original/3X/6/b/6bba4d81494f558a90c9f9547a67b5917647b718.jpeg)

**What that looks like in DQL.**

Anything you didn’t mark is bucketed into a catchall row labeled `NON_KEY_REQUESTS`. That catchall row is a Latest-app concept; it doesn’t appear in Classic.

timeseries count = sum(dt.service.request.count,

```auto
filter: dt.entity.service == "<SERVICE-ID>"),
by:{endpoint.name}, from: now()-5m
| sort arrayLast(count) desc

```

You’ll see two rows: the Key Request and the catchall.

 ![mreider_3-1779285310400.png](https://global.discourse-cdn.com/dynatrace/original/2X/b/be3fc47a5719fb48b834fb633002ca5d9af4d91a.png)

The friction with Key Requests in Classic is that you had to mark each request by hand. If you cared about a hundred URL paths across fifty services, that was five thousand clicks.

## What Enhanced Endpoints changes

**Enhanced Endpoints for SDv1** is the setting that removes the manual marking step. Once you enable it on a namespace (Settings → Process and Contextualize → Services → Enhanced endpoints for SDv1), Dynatrace auto-detects an endpoint for every request that has a stable name available. You still get the same per-row metrics, anomaly detection, and dashboard support, just without the Key Request step.

**What changes:**

- **Classic doesn’t change.** It still shows only the requests you marked. Classic is the manual-only world.
- **The Latest Services app fills in.** Every request that arrives with an http.route attribute becomes its own endpoint row. Spring Boot, Express, FastAPI, [ASP.NET](http://ASP.NET) Core, .NET , Django, and Flask all set http.route for you. Anything you’ve configured with Request Naming Rules also surfaces as a named endpoint row (depending on which placeholders the rule uses).

 ![mreider_4-1779285409674.png](https://global.discourse-cdn.com/dynatrace/original/3X/d/3/d3f769d7da275d4d1bad7336c489b046251d5e51.png)

The DQL query from the previous section still works, but the result now it has two named endpoints, instead of one for search, and `NON_KEY_REQUESTS` since we never marked submit as a key request. With Enhanced Endpoints on we didn’t have to.

Enhanced Endpoints turns “requests you marked by hand” into “every request Dynatrace can identify”.

The next two steps are about what happens when Dynatrace _can’t_ identify a request, and what you can do about it.

## When `http.route` is missing: the over-collapse problem

Most application frameworks set `http.route` for you, but **most reverse proxies and gateways don’t**. Nginx, Apache, Kong, IIS, and many ingress controllers route requests without ever stamping the original URL template back onto the span. If any of your monitored services fall into that category, this section applies to you.

When a request lacks `http.route`, Enhanced Endpoints has nothing to grab onto. In our first release of Enhanced Endpoints, the default rule that fired next collapsed every method-matched request into one bucket per HTTP method: `GET /*`, `POST /*`. Later in this guide you’ll read how to solve this problem, and also learn about a new endpoint-naming heuristic coming in the next few weeks to detect certain patterns automatically.

 ![mreider_0-1779285502964.png](https://global.discourse-cdn.com/dynatrace/original/2X/8/84cd0f4d59103f4bf7d89eea272eb5f830780d0a.png)

The URL path is still on the span, so the data isn’t lost; only the grouping is bad. You can confirm that yourself:

fetch spans, from: now()-15m

```auto
| filter dt.entity.service == "<the over-collapsed service>"
| filter endpoint.name == "GET /*"
| fields timestamp, http.request.method, url.path
| limit 30

```

You’ll see thirty different URLs all stamped with `endpoint.name = GET /*`.

 ![mreider_1-1779285602920.png](https://global.discourse-cdn.com/dynatrace/original/3X/7/4/74038382d66b7b09a3af9df8c4d68c1f9d1469fb.png)

To summarize: Enhanced Endpoints, with no `http.route` and no rules means everything collapsing to `GET /*`. The data is fine; the grouping is bad.

To find where this is happening across your own tenant:

```auto
timeseries c = sum(dt.service.request.count),
  by:{dt.entity.service, endpoint.name}, from: now()-1h
| filter endpoint.name == "GET /*" or endpoint.name == "POST /*"
| summarize total = sum(arrayLast(c)), by:{dt.entity.service}
| sort total desc | limit 20

```

That will give you the top-twenty over-collapse offenders.

* * *

## Fixing over-collapse today: rules

As mentioned, Dynatrace will be releasing a better endpoint heuristic in the coming weeks, but you don’t have to wait for anything to fix the over-collapse on a service. Two rule-based mechanisms are available right now.

### Request Naming Rules with `{URL:Path-Clean}` (SDv1)

For SDv1 services, write a Request Naming Rule (Settings → Service Detection → Request Naming Rules) with the pattern `{URL:Path-Clean}`. Dynatrace will use the request URL but replace volatile-looking segments with stable markers.

 ![mreider_2-1779285669454.png](https://global.discourse-cdn.com/dynatrace/original/2X/8/8845e5534b9213ddc022780a7a1c829ae659de25.png)

 ![mreider_3-1779285689926.png](https://global.discourse-cdn.com/dynatrace/original/3X/c/f/cff87d5e17f20b83d5871cde0741272e708e7009.jpeg)

**What Path-Clean catches:** four specific patterns, each replaced with a stable token: UUIDs (so `e4674467-1e9a-42cf-…` becomes `[UUID]`), IPv4 addresses (`[IPv4]`), IPv6 addresses (`[IPv6]`), and IBANs (`[IBAN]`). Any clean-up URL rules you’ve configured on the service (for example, to strip `jsessionid` from the URL) are always applied as well, regardless of whether Path-Clean is in the naming pattern.

**What Path-Clean leaves alone:** short mixed-case alphanumeric IDs like `0erepyo9` or `abc123`. The detector doesn’t recognize those as volatile, so they stay literal, meaning each unique value becomes its own endpoint row.

If your IDs look like that, Path-Clean alone won’t be enough. You’d combine it with a **custom placeholder** that strips or templates the volatile portion explicitly.

A custom placeholder is a user-defined transformation that wraps one of the same volatile attributes the built-in placeholders use (for example, `URL_PATH`, the source attribute behind `{URL:Path-Clean}`) and applies an extraction step on top: a delimiter split, a regex capture, and so on. The result becomes a named token you can reference in your Request Naming Rule pattern. The example below configures one such placeholder, named `ItemPath`, defined as a regex extraction `^(/shop/[^/]++)` against `URL_PATH`. The intent is to keep only the first two segments of any `/shop/...` URL path, dropping everything after.

 ![mreider_4-1779285719890.png](https://global.discourse-cdn.com/dynatrace/original/2X/f/f675795d43711e86af04246556e60a75df4ea081.jpeg)

There’s a subtlety worth knowing in advance. The SDv1 naming-behavior changes shipping in cluster version 1.341 (the endpoint-naming heuristic, the custom-placeholder resolution described next, and the related URL-path handling) are bundled behind one per-tenant feature flag. Until that flag is on for your tenant, **custom placeholders that wrap a URL-path attribute do not resolve at the endpoint-name level**. They render as the literal placeholder string (for example, `endpoint.name = {ItemPath}`) because the current SDv1 default-name code path treats URL-path attributes as too volatile to substitute directly.

After the flag is on, the same rule starts resolving as expected, alongside the heuristic-derived names. The flag does not make raw volatile URL-path values resolve on their own. Those still won’t. What it enables is your custom placeholder’s transformation taking effect, so the wrapped URL-path attribute resolves only because your extraction step (regex, delimiter split, and so on) has rendered it non-volatile.

**Built-in placeholders are not affected.** &nbsp;This flag only gates the resolution of custom placeholders that wrap a&nbsp;volatile URL-path attribute. A built-in placeholder like `{URL:Path-Clean}` always resolves regardless of the flag’s state because Dynatrace deems its output non-volatile. That’s the goal of `{URL:Path-Clean}`: it cleans the path, so the result is stable. A rule like `{URL:Path-Clean}` is therefore safe to use today and will keep producing the same endpoint name before and after the flag flips.

Here’s what it looks like before the feature flag:

 ![mreider_5-1779285747180.png](https://global.discourse-cdn.com/dynatrace/original/3X/c/7/c7e74e772f6c496f412fc80710ef99ca19200df6.jpeg)

And here’s what it looks like afterwards:

 ![mreider_6-1779285776933.png](https://global.discourse-cdn.com/dynatrace/original/3X/a/8/a8e4327d858753c227e7b1b11e026a129f8c1cbd.png)

You can see the result in a Notebook as follows:

```auto
timeseries count = sum(dt.service.request.count,
filter: dt.entity.service == "<service-id>"),
by:{endpoint.name}, from: now()-5m
| sort arrayLast(count) desc

```

 ![mreider_0-1779285863099.png](https://global.discourse-cdn.com/dynatrace/original/2X/a/a16352e3d30b6519633326aee28d54a0919b837e.png)

### URL path pattern matching (SDv2)

On SDv2, the equivalent customer-facing rule is **URL path pattern matching** (Settings → Service Detection → URL path pattern matching, or `builtin:url-path-pattern-matching-rules` in the API). You describe your URL shapes directly:

/shop/products/{id}

```auto
/shop/carts/{cartId}/items/{itemId}
/shop/orders/{id}
/shop/checkout

```

 ![mreider_1-1779285910443.png](https://global.discourse-cdn.com/dynatrace/original/3X/4/b/4bad926fa897a7867dc2bdfebaffeb62ebbe4bf4.png)

 ![mreider_2-1779285928376.png](https://global.discourse-cdn.com/dynatrace/original/2X/7/7724a0c056c6f1424109e1afdcc30eed80e794e6.jpeg)

This is the same Nginx workload, but now you see what matters instead of a single `GET /*`. Rules let you template your URLs by hand. They work today. They do take some maintenance, especially across many services, which brings us to a description of the heuristic in the next section.

* * *

## The endpoint-naming heuristic that’s coming

**The endpoint-naming heuristic** does what those rules do, but automatically.

When `http.route`&nbsp;is missing on the ingested data, the heuristic looks at the raw URL path, identifies the volatile segments (the same kinds of patterns Path-Clean catches, plus some more), and produces a `http.route`&nbsp;attribute based on that URL path. The already existing rule: **[Built-in] HTTP request method and route** will now trigger and produce a stable endpoint name. No rule authoring required.

After the heuristic activates, the same Nginx service that was showing `GET /*` shows `GET /shop/products`, `GET /shop/carts`, and so on. The catch-all collapses into one endpoint per real URL shape.

 ![mreider_3-1779285956725.png](https://global.discourse-cdn.com/dynatrace/original/3X/c/e/cece8d6bdfe41640c07aad7da21e9feea6c7b541.png)

### When it ships

The following rollouts, for SDv1 and SDv2, are scheduled to start in SaaS cluster 1.342 on June 30th.The rollout puts all the code in place but changes nothing on its own. The new naming takes effect only when&nbsp;_you_&nbsp;choose to make it, by flipping the SDv1 feature flag and disabling the SDv2 built-in rule.These are two independent switches you control on your own timeline: either order, or both at once.

**SDv1 rollout: a per-tenant feature flag.** One flag (the SDv1 naming flag) gates the whole SDv1 bundle. When it’s on, heuristic-derived names plus the related naming behavior land together; until then, none of them do.

- **If you don’t have Enhanced Endpoints turned on yet,** when you enable it any time from 1.341 onward, the new SDv1 naming behavior comes with it, on by default. You go straight from “Key Requests only” to “clean endpoint names” with no intermediate `GET /*` phase.
- **If you already enabled Enhanced Endpoints,** the SDv1 naming flag is off by default for you, on purpose, because some of your existing dashboards, SLOs, and alerts may bind to current endpoint names like `GET /*` and turning the flag on changes those names. The guardrail gives you time to audit. When you are ready, get in touch with your Dynatrace account team to enable to feature flag: `sdv1-url-and-http-route-naming`.

**SDv2 rollout: a built-in opt-out rule and heuristic.** &nbsp;On every existing tenant, Dynatrace pre-provisions a built-in endpoint-detection rule in `builtin:endpoint-detection-rules`. New tenants created after this point don’t get the rule provisioned, so they get the new SDv2 behavior from the start. Existing tenants keep producing GET /\* until someone disables that built-in rule. Nothing flips on its own.

- **Name template:** `{http.request.method} /*`
- **Condition:** `isNotNull(http.request.method) and isNotNull(http.route) and supportability.is_http_route_derived == true`
- **Status:** enabled by default on every existing tenant. This is a built-in rule that Dynatrace provisions on those tenants. Customers can’t manually create it, only enable or disable it.

To see whether the SDv2 heuristic is producing results on a span:

```code-line
fetch spans, from: now()-15m
| filter dt.entity.service == "<a service that used to over-collapse>"
| fieldsAdd derived = `supportability.is_http_route_derived`
| fields span.name, url.path, http.route, derived, endpoint.name
| limit 20

```

When `http.route` is populated and `supportability.is_http_route_derived` is `true`, the SDv2 heuristic is active. The route was derived by the heuristic rather than emitted by your app. Until then, `http.route` is empty (or app-supplied) and the flag is `false`.

## A note on service display names

As described in the [community post a out Service Naming rule changes](https://community.dynatrace.com/post/296213), ff your SDv1 Nginx (or similar non-Java) service shows up in the Services list as just `:8080`, that’s the SDv1 detected name. Legacy Service Naming Rules used to fix this, but they’re being retired: they only changed the UI display, never flowed into your spans, metrics, logs, or DQL.

**The new approach is to set** `OTEL_SERVICE_NAME` **as an environment variable on the process** (works with OneAgent, no OTel SDK required):

```auto
env:
  - name: OTEL_SERVICE_NAME
    value: my-checkout-service

```

That value lands as `service.name` on every span, which flows through to metrics, dashboards, SLOs, and alerting automatically.

What’s coming:

- **Primary Fields and Primary Tags** will appear as dimensions on service metrics in June 2026, so you can filter and sort the Services list by `k8s.namespace.name`, `team`, region, environment, etc. without packing that context into the service name.
- **A short-term display fix** under discussion combines `service.name` with the detected name: `my-app (WebRequestService)`, `my-app (BackgroundWorker)`. Useful when one process hosts multiple SDv1 services.
- **Server-side renaming via OpenPipeline** is being explored: a processing rule that sets or overrides `service.name` based on resource attributes, no deployment changes required.

For now, set `OTEL_SERVICE_NAME` where you can, and your services will be queryable by the right name even if the Services list display catches up later.

---

<div class="post-metadata">

**Author:** ![craighaessig](https://avatars.discourse-cdn.com/v4/letter/c/2bfe46/32.png) [@craighaessig](https://community.dynatrace.com/u/craighaessig)\
**Post date:** [July 8, 2026, 7:44pm UTC](https://community.dynatrace.com/t/enhanced-endpoints-guide/55616/2 "2026-07-08T19:44:40Z")

</div>

I am still having issues with SDv2 Endpoints are not getting http.route on spans after the upgrade to 1.342 so endpoint metrics are still GET /\* for example,&nbsp; Is there something else that needs to be done besides disable to legacy rule?&nbsp; I did that as well and still getting same result.

---

<div class="post-metadata">

**Author:** ![dannemca](https://dub1.discourse-cdn.com/dynatrace/user_avatar/community.dynatrace.com/dannemca/32/7215_2.png) [@dannemca](https://community.dynatrace.com/u/dannemca)\
**Post date:** [July 21, 2026, 6:37pm UTC](https://community.dynatrace.com/t/enhanced-endpoints-guide/55616/3 "2026-07-21T18:37:09Z")

</div>

Same here. Enabled and still getting generic GET;POST \* as endpoints.

---

<div class="post-metadata">

**Author:** ![craighaessig](https://avatars.discourse-cdn.com/v4/letter/c/2bfe46/32.png) [@craighaessig](https://community.dynatrace.com/u/craighaessig)\
**Post date:** [July 22, 2026, 12:28pm UTC](https://community.dynatrace.com/t/enhanced-endpoints-guide/55616/4 "2026-07-22T12:28:19Z")

</div>

[@dannemca](https://community.dynatrace.com/user/18264)&nbsp;I opened a case with support and we determined its because http.route field is being supplied to Dynatrace with /\* in the trace.&nbsp; Since this is the case its not going through the [Automatic naming for services without a rout](https://docs.dynatrace.com/docs/shortlink/service-endpoint-detection-v2#automatic-naming-without-http-route)e.&nbsp; Currently only thing I can do within Dynatrace is to use the url path pattern rules to create the URL path.&nbsp; This is difficult with a large number of apps/services to manage.&nbsp; I do think a feature could be developed by Dynatrace to look for services that emit a route like “/\*” to go through the same Automatic naming rules for ones without http.route.&nbsp; Curious if you have the same issue as me.

---

<div class="post-metadata">

**Author:** ![NeJoyerPB](https://avatars.discourse-cdn.com/v4/letter/n/977dab/32.png) [@NeJoyerPB](https://community.dynatrace.com/u/NeJoyerPB)\
**Post date:** [July 22, 2026, 6:50pm UTC](https://community.dynatrace.com/t/enhanced-endpoints-guide/55616/5 "2026-07-22T18:50:20Z")

</div>

This is a pretty confusing topic already. Worth updating this now that it is released?
