# Endpoint grouping and exclusions

Service Health needs to know which calls belong to the same API and which should count toward its objectives. This guide explains endpoint templating, exclusions and the special treatment of streams and background work.

## Endpoint templating

An endpoint is an operation such as `POST /checkout/{id}/confirm`. Request names often contain real IDs. Without grouping, `/checkout/48213/confirm` and `/checkout/90177/confirm` would look like separate APIs, each with its own tiny set of calls.

Templating replaces recognised path identifiers with placeholders:

```text
POST /checkout/48213/confirm
POST /checkout/90177/confirm
              ↓
POST /checkout/{id}/confirm
```

In **Admin → Endpoints**, choose which identifiers are recognised: numbers, UUIDs, long hexadecimal values, slugs ending in numbers, dates and your own prefixes. Dates use `{date}`. A custom prefix such as `ord_` is preserved before `{id}`.

Read the preview before applying a change. Inspect the largest groups and check that different operations have not been combined. **Keep apart** lets you preserve names that should remain distinct.

Grouping changes what “one API” means. Recheck API overrides and exclusions after a grouping change, since they refer to API names.

## Exclusions

In **Admin → Exclusions**, you can leave out a whole service or an API with a reason. API rules can apply to one service or all services, matching an exact name or the end of a path, such as `/health`.

An excluded item is left out of normal health lists, objectives, alerts and tickets. **Count again** removes an exclusion. Use exclusions for traffic outside the intended objective, such as a retired service or test endpoint, rather than to hide a real customer problem.

Health-check exclusions are supplied by default. Review them for your service: a health endpoint and a customer operation with a similar name may need different decisions.

## Rules that always apply

| Kind of traffic | How it is treated |
| --- | --- |
| Recognised scanner probes | Left out as calls that are not the service's API |
| Fewer than 100 calls in an API's objective window | Too few to judge; no health status |
| Calls to no named route, such as `GET /` or `/favicon.ico` | Counted separately per service as unrouted calls, without an API objective |
| Recognised WebSocket, SignalR and event-stream connections | Success only |
| Recognised queue, event or job work | Success only |

These rules prevent a long-running connection from being judged like a short interactive request. They do not prove that excluded traffic is harmless, so keep your source monitoring for investigations outside the objective.

## Long calls that are not requests

**Admin → SLOs → Calls that are not requests** also controls a duration-based stream rule. You can use an API median longer than five minutes, longer than one minute, or disable that duration rule. The median decides because the app holds aggregates rather than each request.

Recognised long-lived connection names remain success-only even when the duration rule is disabled. Streams and background work are also excluded from the service's speed percentiles.

## A status seems too good

Check whether real endpoints have been excluded, merged into a busy group, classified as long-lived work, or assigned an unsuitable tier. Correct what the app counts before changing a target.

## Learn more

- [Choosing targets and understanding inheritance](/docs/service-health/objectives)
- [Google SRE workbook: Implementing SLOs](https://sre.google/workbook/implementing-slos/)
