Guide

API consumer tracking: four ways to know who calls an API

Last checked 2026-11-097 min read

API consumer tracking is keeping an up-to-date answer to “who calls this API, and which endpoints?”. There are four ways to get it: gateway keys, access logs, distributed tracing, and subscriptions the consumers declare. The first three observe traffic and tell you who called. The fourth records intent and tells you who depends on it. Each one fails somewhere different, so the useful question is which failure you can live with. Graphwake keeps the declared side and alerts those teams.

ExampleService graph · orders-api
GET/orders/{id}2 consumer teams
Service
orders-api
Owner
payments-team

Consumers

  • checkout · 4 peopleSlack #team-checkout
  • mobile-app · 6 peopleSlack #mobile-alerts

Suggested by Discovery

  • storefront · uses a neighbouring endpointmaybe · 72
GET/orders/{id}/invoiceBlind spot

No team subscribes to this endpoint. A breaking change here reaches no subscribed team.

Who owns an endpoint, who consumes it, and where nobody is listening. A suggested team is added only when someone confirms it.
On this page
  1. The four ways at a glance
  2. 1. Gateway keys
  3. 2. Access logs
  4. 3. Distributed tracing
  5. 4. Declared subscriptions
  6. Which one answers which question
  7. Where Graphwake fits
  8. When traffic-based tracking alone is enough
  9. Questions

The four ways at a glance

WayWhat identifies the callerWhat it costs youWhere it fails
Gateway keysA key, token or application per client, checked by the gatewayA gateway in front of the API, and a credential per callerShared keys, keyless routes, and calls that skip the gateway
Access logsWhatever the request carries: source IP, user agent, a headerNothing new: logs you already keepIPs and user agents rarely name a team; retention is short
Distributed tracingThe calling service’s service.name on its spansInstrumenting every caller, and a backend to keep the dataUninstrumented callers, sampling, and callers that did not run in the window
Declared subscriptionsA team says which endpoints it callsEach team marks its endpoints onceA team that never subscribes is invisible until someone finds it

The first three answer “who called?”. Only the fourth answers “who will be hurt?” for a caller that runs once a month or has not shipped yet. That difference decides which one to use for what.

1. Gateway keys

If every request goes through a gateway and every caller has its own credential, the gateway knows who called what. That is how external APIs are run. Kong Gateway identifies a Consumer through an authentication plugin such as key auth or OAuth. In Gravitee, consumers subscribe to a plan through an application. AWS API Gateway usage plans use API keys to identify clients.

  • Good: exact call counts per client, per endpoint, with timestamps. The best evidence that a client still calls an endpoint, or stopped.
  • A key is not a team. A key belongs to an application. Someone still has to keep the list of which team owns which key, and that list goes stale like any other.
  • Shared and missing keys hide callers. Five services that share one key look like one. In Gravitee, a keyless plan needs no subscription, so its callers show up as “unknown application”.
  • Internal calls often skip the gateway. Service-to-service traffic inside a cluster usually goes straight to the service. A gateway only sees what is routed through it.
  • Keys are not security. AWS says not to use API keys for authentication or authorization. Use them to identify callers, alongside real authentication.

2. Access logs

Every service or load balancer already logs requests. nginx’s default combined format records the source address, the request line and the User-Agent header. That is enough to see that GET /orders/{id}/invoice was called last Tuesday, and often not enough to see by whom.

  • Source IPs do not stay put. In Kubernetes, Pods are created and destroyed and each gets its own IP, so an address from last week may belong to a different service today. Behind a proxy or NAT, many callers share one address.
  • The user agent is whatever the client sends. An HTTP library default, such as a language runtime’s name and version, tells you nothing about the team.
  • Retention decides what you can see. A caller that runs once a quarter is not in thirty days of logs.
  • A cheap fix: ask internal callers to send a header that names the calling service, and log it. It works as well as the discipline behind it.

3. Distributed tracing

With OpenTelemetry, each service names itself in the service.name resource attribute, usually set with the OTEL_SERVICE_NAME environment variable. Traces then show which service called which, and the Collector’s service graph connector (alpha) turns client and server spans into per-edge request metrics.

bash
export OTEL_SERVICE_NAME=checkout-web
Example: name the calling service so it shows up in traces.
text
sum by (client) (increase(traces_service_graph_request_total{server="orders-api"}[14d]))
Example: PromQL over the service graph metrics, callers of orders-api in the last 14 days.
  • Good: the most accurate picture of which services call each other, with errors and latency, without asking anyone.
  • Only instrumented callers. A service without instrumentation can appear only as a virtual node guessed from the other side, if at all. Batch jobs and scripts are often the ones missing.
  • Sampling and windows. If you keep a fraction of traces, a caller that makes a few calls a month may not be in them. A service graph is a picture of a time window.
  • The edge is a service, not an endpoint, not a team. The connector’s edges are client and server services. To know which endpoint, you go back to span attributes; to know which team, you map service.name to an owner.

4. Declared subscriptions

The consumer team says which endpoints it calls, in one shared place. Nothing is observed; the list is a statement by the people who know. This is how a team-level API dependency map is kept.

  • Good: the edge is a team with a channel, per endpoint, before any traffic exists. A client that ships next month can subscribe today.
  • The producer reads the list, it does not keep it. No one on the API team has to remember who called last year.
  • It is only as complete as the teams make it. A team that never subscribed is invisible. That gap has to show up somewhere, for example as endpoints with no consumers.
  • It needs a reason to exist. Teams subscribe when it gets them something: an alert before a breaking change merges, in their own channel.

Which one answers which question

QuestionBest sourceCheck it against
Who must hear about this change before it merges?Declared subscriptionsTraces or logs, for callers the list missed
Who called this endpoint last week?Gateway keys or tracesAccess logs
Can I delete this endpoint?Traffic over a long windowThe subscribed teams, asked directly
Which team owns the caller I found in the logs?Your service catalog or the team mapAsking in that team’s channel

Most companies with internal APIs end up with a declared list for warnings and traffic for proof. How to find which teams use an endpoint walks through the search when you have no gateway.

See who your next breaking change reaches.Paste a spec URL or add one CI step. 7-day free trial. Cancel before day 7 and you pay nothing.
Start free trial

Where Graphwake fits

Graphwake is the declared side. Consumer teams subscribe to the endpoints they call, per whole endpoint, and Graphwake reads your OpenAPI specs to know every endpoint that exists. It needs no traffic, logs or code access, and it alerts the subscribed teams when a breaking change comes.

  • Teams subscribe per endpoint

    Each consumer team marks the endpoints it calls. A breaking change alerts only those teams, in Slack, Microsoft Teams or email.

  • Gaps are visible

    An endpoint no team subscribes to is flagged as an orphan, and a breaking change there counts toward the impact score as a blind spot.

  • Discovery suggests teams

    When nobody is mapped to a new or breaking-changed endpoint, rule-based Discovery suggests likely teams with a reason and a score. A team becomes a subscriber only when someone confirms it.

  • A follow is not a consumer

    Anyone can follow an endpoint and get its alerts by email. A follow never counts as a consumer on the map or in the score.

Use it next to your traffic data: when traces show a caller that is not subscribed, ask that team to subscribe, and the next alert reaches them. More on routing in API breaking change alerts.

Good to know

When traffic-based tracking alone is enough

  • You need proof, not intent. Before deleting an endpoint, traffic over a long window is the evidence that nobody still calls it.
  • Your consumers are external customers. They already have keys, and gateway analytics know each one.
  • You bill or rate-limit per caller. That needs per-request counts from a gateway or your own metering.

Questions

What is API consumer tracking?

Keeping a current answer to who calls an API and which endpoints they use. It can come from traffic (gateway keys, access logs, traces) or from consumers declaring what they call.

Can I track internal API consumers without a gateway?

Yes. Use access logs with a header that names the calling service, distributed tracing with service.name set on every caller, or have consumer teams subscribe to the endpoints they call. Each misses something, so combine two.

Are API keys enough to know who my consumers are?

Only if every caller has its own key and every call goes through the gateway. Even then a key names an application, not a team, so you still need to map keys to teams.

Why not just use traces?

Traces show who called in the window you keep, from services that are instrumented. A monthly job, an unsampled call or a client that has not shipped yet is not there. Use traces to check a declared list, not to replace it.

Pick an endpoint. See who it reaches. 7-day free trial. Cancel before day 7 and you pay nothing.

Start free trial

Sources and last verified

Sources checked on 2026-11-09.