> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apitraffic.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Endpoint Handling

> How ApiTraffic groups request paths into endpoints, and how to tune it per bucket

Every request ApiTraffic captures has a raw path such as `/v1/users/8412/orders/9931`. To make
volume, latency and error rates meaningful, requests are grouped by **endpoint**: the same path
with its variable parts replaced by parameters, here `/v1/users/{user_id}/orders/{order_id}`.
This is what the Endpoints view counts, and what alerts and metrics are keyed on.

An endpoint is resolved in three stages:

**1. Automatic detection**

The path is inspected on its own and recognisable values are replaced with parameters.

**2. Endpoint learning**

Segments that vary across requests are promoted to parameters, catching values that a single
path cannot reveal.

**3. Endpoint rules**

Rules always win, so you can name or correct any endpoint yourself.

## Automatic detection

Detection recognises the value types that appear in API paths, including:

| Value | Example | Endpoint |
| - | - | - |
| Numeric ids | `/v1/users/8412` | `/v1/users/{user_id}` |
| UUIDs | `/v1/orders/1f0c0b8e-2f9d-4c1a-9f7e-77c0c9e2a1d4` | `/v1/orders/{uuid}` |
| Prefixed ids | `/v1/shares/shr_3B26CXp2ZaevfQesc1ohabd4CiS` | `/v1/shares/{share_id}` |
| Opaque tokens | `/v1/collection-shares/3B26CXp2Zaevf` | `/v1/collection-shares/{collection_share_id}` |
| Dates, timestamps, hashes | `/v1/reports/2024-01-31` | `/v1/reports/{date}` |
| Emails, IPs, file names | `/v1/users/jane@example.com` | `/v1/users/{email}` |

Prefixed ids are matched by shape rather than by a list of known prefixes, so `req_`, `cs_`,
`shr_` and any prefix your API uses are all detected. Values with no prefix are detected from
their length and character mix, so a generated token is treated as an id while a word such as
`/v1/shares/settings` stays part of the endpoint.

Detection deliberately never converts word-shaped segments. `/v1/git-providers/bitbucket/authorize`
keeps `bitbucket`, because from that one path there is no way to tell a variable value from a
static route. That is what endpoint learning is for.

## Endpoint learning

Endpoint learning uses the one signal a single path can never carry: whether a segment actually
changes across requests. As traffic arrives, ApiTraffic tracks the values seen at each candidate
position of an endpoint. Once a position has been seen with enough **distinct** values, it becomes
a parameter, and every later request — including values never seen before — is grouped under it.

For example, after these two requests:

```text theme={null}
/v1/accounts/{account_id}/git-providers/bitbucket/authorize
/v1/accounts/{account_id}/git-providers/github/authorize
```

ApiTraffic creates a rule for `/v1/accounts/{*}/git-providers/{*}/authorize` and reports the
endpoint as:

```text theme={null}
/v1/accounts/{account_id}/git-providers/{git_provider}/authorize
```

`gitlab`, `azure-devops` and anything else that appears in that position is matched immediately,
without waiting to be seen first.

Learning is conservative about which positions it will consider. It never learns the first
segment of a path, a version segment such as `v1`, or a segment that follows a parameter, so
unrelated endpoints like `/v1/users/{id}` and `/v1/orders/{id}` can never be merged into one.

A learned rule appears alongside your own endpoint rules with a source of `learned`, and you can
disable or delete it like any other rule. Rules you create yourself are evaluated first, so a
learned rule never overrides your own.

## Managing endpoint rules

Open **Account → Endpoint Rules** to see every rule in the order rules are tried: lower priority
numbers first, and at equal priority your own rules before learned ones. The first rule that
matches a request wins. Filter the list to your own or learned rules, or search it by pattern or
description. From each rule's menu you can edit, disable, enable or delete it.

Select **Add Rule** to create one:

* **Match pattern**: the URL path the rule applies to, starting with `/`. Use `{*}` (or any
  `{name}`) for a segment that varies. Paths are matched segment by segment, ignoring case and the
  query string, so `/users/{*}` matches `/Users/42?expand=orders` but not `/users/42/orders`.
  **Test a path** checks a path against the pattern as you type.
* **Endpoint name**: what matching requests are grouped under. Leave it blank to use the match
  pattern.
* **Long-lived connection**: see [Long-lived connections](#long-lived-connections).
* **Direction**, **Priority**, **Upstream hosts** (outbound only), **Buckets** and
  **Environments** limit where the rule applies.

Changes apply to traffic processed after the rule is saved; requests already recorded keep their
endpoint.

## Inbound and outbound traffic

The endpoints your API serves and the external endpoints it calls are learned and reported
separately. Learning tracks each direction on its own, and outbound traffic is tracked per
upstream host, so `/v1/charges/{id}` on two payment providers is never merged, and a segment that
varies on one vendor's API says nothing about another's. A rule learned from outbound traffic is
scoped to the direction and host it was learned from.

Rules you author carry the same scope:

**direction** `string` (default: \*)

`in` applies the rule only to requests your API serves, `out` only to requests it makes, and
`*` to both.

**hosts** `string[]` (default: \["\*"])

For outbound traffic, the upstream hosts the rule applies to, for example
`["api.stripe.com"]`. Ignored for inbound traffic, whose host is your own.

Existing rules keep a direction of `*` and hosts of `["*"]`, so they behave exactly as before.
Narrow a rule's direction when it describes only one side of your traffic.

## Long-lived connections

Streaming responses stay open for as long as the client listens: a Server-Sent Events stream
such as MCP's `GET /mcp/sse` can be held for minutes. Recording that open time as a response
time would swamp your averages and percentiles, so these requests are marked as **streams**.

* Responses sent as `text/event-stream` are marked automatically when they are ingested.
* For other connections held open on purpose, such as long polling, turn on
  **Long-lived connection** on an endpoint rule that matches them.

**stream** `boolean` (default: false)

Treat the requests this rule matches as long-lived connections. The rule still names the
endpoint as usual; in the app, leave **Endpoint name** blank to keep the match pattern.

Streams still appear in the request list, in request counts and in error rates. They are left out
of response-time metrics: averages, percentiles, slow operations and response-time charts. In the
request list a stream is labelled **Stream**, its duration is shown as the time the connection was
open, and its time to first byte (when the SDK reports it) shows how quickly it started
responding. The flag applies to traffic processed after the rule is saved; requests already
recorded are not changed.

## Bucket settings

Endpoint learning is configured per bucket, under **Settings → Endpoint Handling**.

**Learn endpoints from traffic** `boolean` (default: enabled)

Whether ApiTraffic may promote varying path segments to parameters for this bucket. When
disabled, only automatic detection and the rules you create are used. Existing learned rules
are kept and keep applying; delete them if you no longer want them.

**Minimum distinct values** `number` (default: 2)

How many different values a segment must be seen with before it becomes a parameter. The
default of `2` converts a segment as soon as it changes, which suits most REST APIs because
their static segments never vary. Raise it if you would rather see a position broken out until
it has clearly proven variable — a value of `5`, for instance, keeps a five-value enum such as
a provider name visible as separate endpoints.

> [!NOTE]
>
> Settings changes apply to newly processed traffic and can take a few minutes to take effect.
> Endpoints already recorded on past requests are not rewritten.

These settings are also available on the [bucket API](https://docs.apitraffic.io/api-reference/buckets.md) as
`endpointLearningEnabled` and `endpointLearningMinValues`.

## Choosing an approach

> **Leave learning on**
>
> Best for most APIs. Ids and enum-like segments collapse on their own and the Endpoints view
> stays small without any configuration.

> **Raise the threshold**
>
> Use when low-cardinality segments, such as a region or provider name, are worth reporting
> separately until they have varied several times.

> **Turn learning off**
>
> Use when you want endpoints to come only from automatic detection and rules you author, for
> example when your endpoint list feeds a downstream contract.

> **Write a rule**
>
> Use when you want a specific pattern or parameter name. Rules take precedence over both
> detection and learning.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.