Guide

How to find which teams use an API endpoint

Last checked 2026-11-097 min read

To find which teams use an API endpoint without a gateway, combine three searches: the code (every repository, including generated clients), the access logs of the service, and a direct question to the teams those two point at. Each one misses callers the others catch. Then write the answer down as a list of consumer teams per endpoint, kept by those teams, so the next change does not start the hunt again. Graphwake keeps that list 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. Before you start: pin down the endpoint
  2. Step 1: search the code
  3. Step 2: read the access logs
  4. Step 3: ask, but only the teams the evidence points at
  5. Why each step misses someone
  6. Step 4: write it down where it stays current
  7. Where Graphwake fits
  8. When a gateway or tracing alone is enough
  9. Questions

Before you start: pin down the endpoint

Write the endpoint the way each search will see it. In the spec it is GET /orders/{id}/invoice. In code it may be a template string, a path built from pieces, or a generated client method named after the operationId. In logs it is a concrete path such as /orders/981/invoice?format=pdf. Note the service’s hostnames too: internal DNS names, the old name before the rename, the load balancer address.

Step 1: search the code

Search every repository you can read, not just the ones you know call the service. On GitHub, code search takes a regular expression between slashes, with the slashes inside escaped:

text
org:example-org /orders\/[^\/]+\/invoice/
Example: GitHub code search across an organisation. The organisation and paths are made up.

Search for the client method name as well, because a generated client hides the path. With the repositories cloned locally, ripgrep does both at once:

bash
rg -n 'orders/[^/]+/invoice|getOrderInvoice' ~/src/
Example: search local clones for the path and the generated method name.
  • Default branch only. GitHub code search indexes the default branch of each repository, and skips files over 350 KiB. A client on a long-lived branch is not found.
  • Paths built at runtime. base + "/" + resource + "/" + id + "/invoice" matches neither search. Look for the service’s hostname or config key as well.
  • Code you cannot see. Scripts on someone’s laptop, notebooks, other organisations’ repositories, and spreadsheets that call the API are not in your search.
  • Found is not called. A match may be dead code. Treat each hit as a team to ask, not as a confirmed consumer.

Step 2: read the access logs

The service, its ingress or its load balancer already logs requests. In nginx’s default combined format, splitting a line on double quotes puts the request line in field 2 and the user agent in field 6. This counts calls to the endpoint by source address and user agent:

bash
awk -F'"' '$2 ~ /^GET \/orders\/[^\/ ?]+\/invoice[ ?]/ { split($1, a, " "); print a[1], $6 }' access.log \
  | sort | uniq -c | sort -rn
Example: callers of GET /orders/{id}/invoice in an nginx combined-format log.
text
   2 10.42.3.17 checkout-web/2.3 okhttp/4.12
   1 10.42.7.4 python-requests/2.32.3
Example output. Addresses and user agents are made up.

A user agent like checkout-web/2.3 names its service; a library default like python-requests/2.32.3 does not. For an address inside a Kubernetes cluster, find the Pod that holds it now:

bash
kubectl get pods -A -o wide | grep 10.42.7.4
Example: which Pod has this address right now.
  • Addresses move. Kubernetes creates and destroys Pods, and each gets its own IP, so last week’s address may belong to another service today. Behind a proxy or NAT, many callers share one address.
  • Retention. A job that runs once a quarter is not in thirty days of logs. Note the window you searched.
  • If the logs cannot tell you who: add one log line to the endpoint’s handler that records a caller header and the source, and ask internal callers to send that header. Leave it for a full business cycle, including a month end.

Step 3: ask, but only the teams the evidence points at

A question in a company-wide channel gets silence, and silence is not a no. Ask in the channels of the teams that owned the code hits and the services behind the log entries. Be specific: name the endpoint, say what you plan to change and when, and ask for a yes or no by a date.

  1. Name the endpoint and the change

    GET /orders/{id}/invoice will stop returning total in its response.

  2. Say why you are asking them

    Your repository calls it, or your service called it last week. Link the hit or the log line.

  3. Ask for a reply by a date

    Yes, no, or not sure, before the date. Follow up with anyone who has not answered.

Why each step misses someone

StepFindsMisses
Search the codeCallers in repositories you can read, including ones that have not shippedOther branches, paths built at runtime, scripts and notebooks outside the repositories
Read the logsCallers that actually ran in the windowRare jobs, callers behind shared addresses, anything older than retention
AskContext: what the caller does with the field, and how long it needsTeams that do not know they call it, and teams that do not answer

Together they catch most callers. Not all: a script nobody remembers can still break. That is why the last step is the one that pays off next time.

Step 4: write it down where it stays current

At the end you have a list of teams for one endpoint. Put it somewhere the next person will find it, per endpoint, and let the consumer teams keep it: they know when they start or stop calling something. A wiki page kept by the producer goes stale; a subscription kept by the consumer gets fixed when it is wrong, because the consumer is the one who missed the alert. That list is a team-level API dependency map.

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 keeps step 4 for you. Consumer teams subscribe to the endpoints they call, Graphwake reads your OpenAPI specs to know every endpoint that exists, and a breaking change alerts only the subscribed teams, in Slack, Microsoft Teams or email. Steps 1 to 3 stay useful for finding a team that has not subscribed yet, and Discovery suggests the likely ones.

  • Who calls it, in one place

    Each endpoint shows its owner and its consumer teams. An endpoint no team subscribes to is flagged as an orphan.

  • Discovery suggests the likely teams

    Rules over data Graphwake already holds, such as subscriptions to neighbouring endpoints and shared schemas, suggest teams with a reason and a score. Someone confirms before a team becomes a subscriber.

  • Ask from your editor

    With Graphwake MCP on Pro and Enterprise, your AI assistant can ask who owns and who consumes an endpoint. See the MCP how-to.

  • Blind spots before the merge

    A breaking change on an endpoint with no subscribers counts toward the impact score, so the missing team shows up while the change is a pull request.

To decide who gets told once you know, read API breaking change alerts.

Good to know

When a gateway or tracing alone is enough

  • You have a gateway with a key per caller. Its analytics already list the clients of each endpoint, with call counts.
  • You run tracing on every service. A service graph built from traces shows the callers. See API consumer tracking for what traces miss.
  • One team calls the API, and you know it. Ask them.

Questions

How do I find out who uses an API endpoint without a gateway?

Search every repository for the path and the generated client method, count callers of the endpoint in the service’s access logs, then ask only the teams those two point at. Write the result down per endpoint so it is not lost.

Can I find API callers from the logs alone?

Partly. Logs show calls that happened within retention, by source address and user agent. Addresses change and library user agents do not name a team, so logs give you leads to check, not a list.

Does GitHub code search find every call to an endpoint?

No. It searches the default branch of each repository, skips files over 350 KiB, and cannot match a path built at runtime. Search for the hostname and the client method name too.

How do I keep the list of consumers up to date?

Have the consumer teams keep it: each team subscribes to the endpoints it calls, and gets alerts for them. A list kept by the API owner goes stale because the owner does not see new callers.

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.