# We tracked AI key theft over 35 days. Here's what we learned

> Source: <https://infertrail.com/blog/llm-api-key-honeypot/>
> Published: 2026-11-12 19:52:01+00:00

In order to discover what would happen we created two honeypot LLM gateways: one mirroring LiteLLM and another one mirroring a generic OpenAI-compatible endpoint. We then proceeded to create over 40 individual organizations, each with at least on Github repository in a way that was convincing to threat actors. API keys along with the addresses of the gateways were added to these repositories in such a way that it looked like they were added by mistake by AI or human error. From this we observed over 3 million requests to our gateways, most of which were probing attacks and some of which ended up using inference in a pattern that we identified as reseller/gateway activity. Some connected to harnesses like OMP or Hermes, others connected to Telegram agents and some were even directly sourced from black market reseller domains directly.

The experiment

## How the keys were exposed

For realism we initially created GitHub projects spanning a wide array of types: ticket triage, document indexing, agent tools, and other AI applications. To make our accidental leaks seem realistic, we included a working key and our gateway’s URL in code examples in the repositories.

In order to make our honeypot more attractive we advertised multiple SOTA models including astra, fable, opus 5 and sol. The attacker prompts were routed to hosted open-weight models in order to control costs while providing a believable attack surface. We also included guardrails that ensured model specific questions wouldn't reveal the true identity of our model and instead provide a facade that they were actually interacting with a SOTA frontier model from a company gateway.

**NYC** LiteLLM-style gateway

*36 days*

**SFO** Separate model router

*9 days*

| How long the keys had been public at the snapshot cutoff |  | 
|---|---|
| Exposure time | Keys | 
|---|---|
| Less than a day | 19 | 
| One to seven days | 91 | 
| More than a week | 64 | 
| No precise publication time | 5 | 

### What we tracked

To ensure that we could extract as much from our honeypot as possbile we recorded as much signal las possible including: the key used, headers, referrers, ip, geoip, route, model, prompts, http status and more. We also saved every prompt and its response for further analysis.

The snapshot contains traffic from both gateways. Here is what the three counts mean:

- **1,605,260****saved request captures** across all endpoints.
- **1,417,507****captures from prompt endpoints** , including rejected requests.
- **9,375****prompt requests using keys matched to our 179 documented leaks** , counted in the request logs.

The **9,375** figure is the documented-leak subset, not the total prompt volume. Most captured traffic used credentials we could not match to those publication records.

Published-key use

## Which leaked keys were used?

In total we published **179** keys. Outside requests used **65** to fetch the model list and **18** to send prompts. Requests using **16** keys returned HTTP success. We compared the projects and leak locations to investigate the difference.

**9,375** prompt requests using our published keys

**4,711** prompt requests returned HTTP success

**80** recorded source addresses behind those successes

A model-list request checked the advertised catalog; a prompt request tried to use a model. In **82** IP/key pairs, the list check preceded the first successful prompt. The median gap was **37 seconds**, measured between API requests, not from publication.

Leak location and project type

## Which leak locations drew requests

We compared the projects, the files containing the keys, and the time each key had been public. The table covers three batches of 40 repositories. To give each key the same observation period, we counted only its first 24 hours after release.

| Keys checked and used during their first day |  |  |  | 
|---|---|---|---|
| Repository batch | Keys released | Keys checked | Keys used for prompts | 
|---|---|---|---|
| Early developer projects · NYC | **40** | **38** | **7** | 
| Utility projects · NYC | **40** | **12** | **4** | 
| Utility projects · SFO | **40** | **5** | **1** | 

In the early batch, one source checked **37** keys within a minute of each release. These were model-list requests. The entire batch produced only seven prompt requests, all from another source repeating the same message. Broad collection did not lead to sustained use of every key it found.

The two utility batches let us hold several things constant. All 80 projects were Python tools, advertised `gpt-6-sol`, and contained a key beside the gateway URL in `config/development.env`. Yet only 17 keys were checked and five were used for prompts. The other 63 never appeared in our gateway logs during more than four days of observation.

The four New York utility keys used for prompts came from `api-response-code-map`, `http-header-safety-check`, `pagination-field-check`, and `operation-id-audit`. San Francisco’s came from `cors-wildcard-credentials-check`. They were all API-related tools. These projects differed in release order and organization, so we cannot tell whether their subject matter drove the selection.

File format may matter too. Six of the early batch’s seven prompt-tested keys came from Go projects with JSON configuration; one came from a Node project, and none from its 14 Python projects. All seven prompt requests came from one source. Language and file format changed together, so we cannot tell which affected that source’s choice.

We also tried other leak locations. A GitHub Gist key received eight prompt requests. Keys in two documentation pages and two downloadable starter archives received no gateway requests over roughly six days. One of six keys exposed in commit history was checked and used for prompt attempts. Those small groups show which surfaces produced observable use, but not which were scanned.

The newest keys had less time to be found: 19 had been public for less than a day. But **91** keys had at least three days of exposure without a request. All **64** keys whose first request we could time were checked within six hours of release. We did not retain repository crawl or download telemetry, so we cannot distinguish a key that was never collected from one that was collected and ignored.

Once a few keys were adopted, their repeated use dominated the traffic. Six keys accounted for **98.9%** of prompt requests using our leaked credentials. Repeated use of these keys drove the request volume.

Requests with other credentials

## The arithmetic question behind most captured prompts

A request can carry any string as its API key. We recorded those attempts even when authentication failed, so a saved prompt does not necessarily mean the sender had a working key. Many attackers tried to brute force over 100+ admin keys that didn't work. This relates to an original vulnerability with LiteLLM where many gateways shipped with a default admin key

### What the repeated credential tests looked like

Prompt requests carried **93,100** nonempty credential values outside our publication records. Of those, **78,130** were only 1–16 characters long. **93.7%** of prompt requests outside the publication match returned HTTP `401`. Almost all of these attempts carried curl-labelled headers.

The clearest repeated pattern was this message:

*Exact submitted message*

```
What is 483*927+1145? Answer with only the final number.
```

We captured **1,401,673** copies across **92,596** supplied credential values and **20** requested model names. None of those values matched our documented leaks. Replaying a fixed question while changing the token and model is consistent with automated credential and model testing.

Repeated use of our leaked keys

## A key check described how a relay collected API keys

This source made **1,215** prompt requests using our leaked keys. Within that traffic, we recorded **21** copies of one exact message. We’re highlighting it because it described how a relay collected and managed API keys. It began:

“The relay pool keeps a small SQLite database of API keys collected from public channels.”

The prompt described a “relay pool”: keys and API connections managed by a gateway. The system would retry keys that had hit their quota once an hour, test all the keys every six hours, and update the gateway’s routing each day. It would choose connections based on throughput, response time, and account balance, and could block collection sources by chat title.

After that description, the only instruction to the model was `Ответь одним словом: OK`—“Answer with one word: OK.” The requests also carried the software label `keypool` in their user-agent header.

**21** copies of this exact message

**5** leaked keys used for these checks

**3** model names requested

Of those requests, **12** returned HTTP `200`, **7** returned `429`, and **2** returned `404`.

This is the system described in the submitted prompt; we did not inspect the collector’s code.

Gateway connections

## Following the traffic to an API relay

**my.git.christmas** resolved to an IP that was sending prompts to our API. Requests from that IP also mentioned the domain. [Veridrop lists it as an OpenAI-compatible API relay](https://veridrop.org/leaderboard/my.git.christmas?src=directory).

Requests from the same IP referred to a **fo2api** deployment. Together, the DNS record and prompts linked the source to relay infrastructure, though they didn’t tell us how many users were behind it.

| Evidence linking the recorded address to a relay |  | 
|---|---|
| Observation | Evidence | 
|---|---|
| Requests to our API | **618** HTTP-successful prompt requests used our published keys. | 
| DNS match | `my.git.christmas` resolved to the same address recorded in those requests when we checked. | 
| Submitted context | Requests mentioned the domain and work on a `fo2api` deployment. | 

Relay development and testing

## Troubleshooting a relay through our gateway

The sender also used our gateway to troubleshoot fo2api. One prompt asked a coding agent to fix a production JSON tool-schema error affecting ChatCompletions, Responses, and Anthropic routes, and pointed it to specific backend files to inspect.

### From a chat export into a gateway’s key pool

Earlier turns asked the agent to check keys from a chat export, find ones that could serve StepFun models, and add the working ones to a Sub2API-based gateway. [NaraRouter’s](https://router.bynara.id/) endpoint appeared in the export and in the testing output. A generation probe returned `402`, and a later account listing marked that connection as an error.

The user then supplied an [OpenLux](https://doc.openlux.ai/en) endpoint and key, asking the agent to check it and add it to the API. The following tool output included model tests, retries, and routing mappings. A later listing showed the OpenLux account as active.

An [APIMart](https://apimart.ai/) key came next, along with a request for `auto-glm`, `auto-kimi`, `auto-qwen`, and `auto-stepfun`: model names that would route requests between the best working models in each family. The APIMart test output reported `402` errors for insufficient balance, and its account was listed as an error.

A separate history from another IP included the [CLIProxyAPI README](https://github.com/router-for-me/CLIProxyAPI). That task was to configure a coding agent to send `service_tier: "fast"` through the proxy. OpenLux and APIMart also appeared in the README’s sponsor list; those links were incidental to the documentation lookup.

These were instructions and tool results inside submitted histories, not calls from those providers to our gateway.

Telegram bot traffic

## What Telegram histories revealed about the traffic

Telegram message metadata and earlier replies appeared in **88** captured requests from **three** recorded source addresses, including the source linked to my.git.christmas.

Another of those addresses was in Helsinki on Xorek-labelled hosting, in the AEZA network. It sent **31** of the captures containing Telegram conversation metadata. The submitted histories included **12** distinct sender IDs marked as non-bot accounts. This is the same source discussed in [the hosting section](#hosting-infrastructure); the location describes its server, not the people in the conversations.

The reply history highlighted telegram bot named [**@obed2021bot**](https://t.me/obed2021bot), with the same account ID across all three sources. In its public profile it is called “Обед” and advertises GPT 6 Astra Max along with free access to whomever has access. The message metadata from this bots requests also included two fields: `guest_query_id and` `guest_bot_caller_user`: [Telegram fields for guest-mode bot interactions](https://core.telegram.org/bots/api#message). Those fields give us enough evidence that we can say that Telegram conversations were being passed through an inference gateway to our system.

After removing duplicate message metadata, we found **29** distinct sender IDs marked as non-bot accounts. They appeared in **16** private chats and **10** supergroups. These are IDs in the conversation histories, not verified users. We have omitted personal identifiers.

*Selected fields; personal identifiers omitted*

```
{
  "format": "telegram_message_context/v1",
  "message": {
    "reply_to_message": {
      "from": {
        "is_bot": true,
        "username": "obed2021bot"
      }
    }
  }
}
```

We couldn’t verify who operated the bot or whether our replies reached Telegram.

Browser testing

## Testing our leaked keys from a browser

**6** requests using our published keys carried a `www.hvoyai.com` referrer. Each returned HTTP `200` and used the default message in [Hvoy’s current tester](https://www.hvoyai.com/api-key-tester/):

“Calculate 17 + 26. Reply with only the number.”

The tester takes an endpoint, key, and model name, then sends the request directly from the visitor’s browser. The matching prompt and browser headers point to visitor-side testing, not a request from Hvoy’s servers. We checked the current implementation; we don’t have a historical copy.

Following the test requests

## A browser test led back to VPN infrastructure

Other requests from the IP behind the Hvoy tests included instructions for maintaining `updates.listokdoma.ru`. When we checked DNS, that domain and related subdomains pointed to the same IP. This links the recorded address to the VPN configuration in the prompts; it doesn’t link Hvoy to the VPN.

| What we found at the recorded source address |  | 
|---|---|
| Clue | Recorded evidence | 
|---|---|
| Domain match | `listokdoma.ru` ,`manage.listokdoma.ru` , and`updates.listokdoma.ru` resolved to the recorded IP when we checked. | 
| VPN maintenance | **7** captured requests included system context naming`updates.listokdoma.ru` alongside Xray/3x-ui VPN setup and Nginx reverse-proxy maintenance.[3x-ui manages Xray proxies](https://github.com/MHSanaei/3x-ui) . | 
| Coding agent | Requests carried `omp/18.3.1` headers and context describing[Oh My Pi](https://github.com/can1357/oh-my-pi) configuration and model roles. | 
| Session handling | Submitted instructions described skill and memory services that inject `user_id` ,`team_id` , and`agent_id` from a session. | 
| Request tools | Other requests from the same address carried browser and Python headers. | 

Using our published keys, the same recorded address made **155** prompt requests; **132** returned HTTP success.

### Asked to review a coding agent’s actions

Some prompts asked for a safety score for a coding-agent action, formatted as `<severity>N</severity>`. They included commands, browser output, project instructions, and configuration from the session being reviewed. The commands were review material, not instructions to execute on our gateway.

Hosting infrastructure

## Where the leaked-key prompt traffic came from

Of the **9,375** prompt requests using our leaked keys, network lookups classified **8,058** (**86%**) as coming from hosting infrastructure. The largest groups included Xorek, Hetzner, and the PLAY2GO and Liteserver networks.

Requests using our leaked keys came from **53** recorded autonomous systems (ASNs)—network identifiers used for internet routing. Another **2** requests had no ASN. The table shows the eight largest groups; the complete breakdown is below.

| Largest recorded networks · leaked-key prompt requests |  |  |  | 
|---|---|---|---|
| Network · exit countries | Requests · share | What the requests contained | Software fingerprints | 
|---|---|---|---|
| PLAY2GO INTERNATIONAL LIMITEDAS215439Finland, Sweden, The Netherlands | **2,656****28.3%** of total |  |  Other headers · **408** | 
| AEZA INTERNATIONAL LTDAS210644Finland | **2,208****23.6%** of total |  |  Other headers · **175** | 
| LiteserverAS60404The Netherlands | **1,215****13.0%** of total |  |  | 
| Hetzner Online GmbHAS24940Germany | **972****10.4%** of total |  |  | 
| JSC SelectelAS50340Russia | **521****5.6%** of total |  |  | 
| HOSTSLIM OUAS207083Estonia | **228****2.4%** of total |  |  Other headers · **43** | 
| Blockchain Creek B.V.AS207994The Netherlands | **201****2.1%** of total |  |  | 
| U1 DIGITAL SERVICES LTDAS213877Finland, Germany | **165****1.8%** of total |  |  Other headers · **13** | 

- Other headers **120**
- curl **67**
- OpenAI Python SDK **57**
- Missing header **55**
- Bun **31**
- OpenAI SDK **26**
- Browser headers **24**
- OkHttp **7**
- Python aiohttp **6**
- Python requests **6**
- Go HTTP client **4**
- Node undici **4**
- Python HTTPX **1**

- curl **65**
- Missing header **31**
- Python aiohttp **30**
- Other headers **20**
- OkHttp **17**
- Browser headers **6**
- Bun **3**
- Python HTTPX **2**
- Node undici **1**

- Python HTTPX **18**
- Python urllib/urllib3 **13**
- Python requests **12**

- Other headers **5**
- Missing header **4**
- OpenAI Python SDK **4**

## All 53 recorded ASNs

| Complete network breakdown · all 9,375 leaked-key prompt requests |  |  |  | 
|---|---|---|---|
| Recorded network | Exit locations | Prompt requests | HTTP 2xx | 
|---|---|---|---|
| PLAY2GO INTERNATIONAL LIMITED AS215439 | Finland, Sweden, The Netherlands | **2,656** | **674** | 
| AEZA INTERNATIONAL LTD AS210644 | Finland | **2,208** | **831** | 
| Liteserver AS60404 | The Netherlands | **1,215** | **886** | 
| Hetzner Online GmbH AS24940 | Germany | **972** | **689** | 
| JSC Selectel AS50340 | Russia | **521** | **405** | 
| HOSTSLIM OU AS207083 | Estonia | **228** | **165** | 
| Blockchain Creek B.V. AS207994 | The Netherlands | **201** | **199** | 
| U1 DIGITAL SERVICES LTD AS213877 | Finland, Germany | **165** | **142** | 
| Verizon Business AS5650 | United States | **156** | **27** | 
| AS203087 AS203087 | Kazakhstan | **151** | **105** | 
| SERV.HOST GROUP LTD AS207957 | Poland | **137** | **0** | 
| SMARTNET Germany GmbH AS203446 | France | **130** | **107** | 
| OOO Post ltd AS12494 | Russia | **129** | **84** | 
| DpkgSoft International Limited AS215590 | Finland | **86** | **37** | 
| ZetServers AS25198 | France, Germany | **50** | **49** | 
| IT7 Networks Inc AS25820 | United States | **48** | **43** | 
| MSS LLC. AS44843 | Russia | **35** | **35** | 
| ETERNITY INTERNATIONAL LIMITED AS212743 | Estonia, Germany, The Netherlands | **34** | **32** | 
| Eons Data Communications Limited AS138997 | Japan | **20** | **19** | 
| Amazon.com, Inc. AS16509 | Japan | **18** | **5** | 
| M247 Europe SRL AS9009 | Belgium, United Kingdom | **17** | **17** | 
| Cloudflare, Inc. AS13335 | Estonia, Germany, United States | **15** | **9** | 
| Datacamp Limited AS212238 | Japan | **15** | **8** | 
| GTHost AS63023 | Switzerland | **15** | **15** | 
| Baxet Group Inc. AS26383 | United States | **13** | **4** | 
| ISPCONNECTED CORP AS398712 | United States | **13** | **13** | 
| PJSC Rostelecom AS12389 | Russia | **12** | **12** | 
| MTS PJSC AS13055 | Russia | **12** | **12** | 
| Black Mesa Corporation AS46997 | United States | **12** | **0** | 
| OneAsiaHost AS59211 | Singapore | **10** | **10** | 
| ALEXHOST SRL AS200019 | Switzerland, The Netherlands | **8** | **7** | 
| Shenzhen Tencent Computer Systems Company Limited AS45090 | China | **7** | **7** | 
| Oy Creanova Hosting Solutions Ltd. AS51765 | Finland | **7** | **7** | 
| SKYDIGITAL TELECOM LTD AS214143 | France | **6** | **6** | 
| Datagio Systems Ltd. AS218914 | Estonia | **6** | **6** | 
| YES TELECOM TELECOMUNICAÇÕES LTDA AS267038 | Brazil | **6** | **6** | 
| eStruxture Data Centers Inc. AS10929 | Canada | **5** | **5** | 
| H2NEXUS CLOUD SERVICES - FZCO AS215730 | Germany | **5** | **5** | 
| UAB Cherry Servers AS59642 | The Netherlands | **4** | **4** | 
| NEXTTRANSLATE LTD AS203614 | Latvia | **3** | **3** | 
| Advin Services LLC AS22295 | Germany | **3** | **3** | 
| SkyNet Ltd. AS35807 | Russia | **3** | **3** | 
| NLS Kazakhstan LLC AS200590 | Kazakhstan | **2** | **2** | 
| Aztelekom LLC AS28787 | Azerbaijan | **2** | **0** | 
| Orgtechservice Ltd AS56361 | Russia | **2** | **2** | 
| Scalaxy B.V. AS58061 | Finland | **2** | **2** | 
| FREEDOM TELECOM LLP AS58172 | Kazakhstan | **2** | **2** | 
| ASN not recorded | France | **2** | 2 | 
| GSL Networks Pty LTD AS137409 | Japan | **1** | **1** | 
| OVH SAS AS16276 | United States | **1** | **1** | 
| CONECTE MARECHAL AS270371 | Brazil | **1** | **1** | 
| GVA Cote d'Ivoire SAS AS36924 | Uganda | **1** | **1** | 
| PJSC Vimpelcom AS8402 | Russia | **1** | **1** | 
| TE-AS AS8452 | Egypt | **1** | **0** | 

The total is 9,375 prompt requests and 4,711 HTTP successes. These are cached source-network observations, including access networks and proxies; they are not 53 identified attackers or hosting businesses.

### European servers, Russian payment options

PLAY2GO and Xorek both advertise hosting accessible through Russian payment systems. Together, their recorded sources accounted for **4,950** requests (**52.8%**) using our leaked keys. That groups their payment offerings, not their ownership.

[PLAY2GO lists ruble and euro prices](https://play2go.cloud/), and its [public channel advertises Russian cards and SBP payments](https://t.me/s/play2go_host?before=38). Its current website names a Dubai company, PLAY2GO - FZCO. The [UK filing for PLAY2GO International](https://find-and-update.company-information.service.gov.uk/company/15985545/persons-with-significant-control), the name in our ASN records, lists a Ukrainian controlling shareholder.

[Xorek offers Moscow and European server locations with ruble pricing and MIR/SBP payments](https://xorek.cloud/ru/vps-moscow). Its website identifies DpkgSoft International as the operator; that company’s [UK filing lists a Russian resident with at least 75% ownership](https://find-and-update.company-information.service.gov.uk/company/15446241/persons-with-significant-control).

### A sanctioned network behind the Telegram-linked traffic

One source connected from an address geolocated to Finland on the network of AEZA International, a [U.S.-sanctioned hosting company](https://sanctionssearch.ofac.treas.gov/Details.aspx?id=54567). The Xorek-labelled traffic spans two ASNs: **2,208** requests on AEZA International’s `AS210644` and **86** on DpkgSoft’s `AS215590`. [Treasury describes it as the UK branch of Russia-based AEZA Group](https://home.treasury.gov/news/press-releases/sb0185).

That is a documented connection to a sanctioned network. Our logs do not show who paid for these servers or establish sanctions evasion by PLAY2GO or Xorek.

Rostelecom’s `AS12389` also appeared in the logs, with **12** leaked-key prompt requests, all returning HTTP success. [Its OFAC listing](https://sanctionssearch.ofac.treas.gov/Details.aspx?id=34556) carries narrower restrictions: Directive 3 prohibits U.S. persons from dealing in specified new debt with a maturity longer than 14 days or new equity. AEZA’s SDN designation is broader: its property under U.S. jurisdiction is blocked, and U.S. persons are generally prohibited from dealing with the company.

### Half the prompt traffic came from two Finnish addresses

Two recorded addresses geolocated to Finland sent **4,749** requests—**51%** of the leaked-key prompt traffic. One was the address linked to [my.git.christmas](#gateway-clients) on the PLAY2GO network. The other was on Xorek-labelled hosting and also sent [the Telegram conversation histories described above](#telegram-workflow).

The larger Xorek source sent **2,208** requests under **23** model names. It mixed short checks with longer requests: **830** contained coding-agent system instructions. The network address therefore covered both automated checks and agent activity; its Finland location does not tell us where the users were.

### The same check ran on Xorek and Hetzner

Two recorded addresses repeatedly sent `Reply exactly: ok`: **67** requests from Xorek-labelled hosting and **315** from Hetzner. All **382** carried a Zoltraak-labelled header, with one user message, no streaming, and a request for only five or eight output tokens.

The checks covered **11** model names and **6** leaked keys. The Hetzner address sent them to both honeypots. The matching prompt, header and request settings suggest shared checking software; they do not establish that the two addresses had the same operator.

Gateway capability tests

## 5,000 requests to find out what our gateway could do

A server geolocated to Buffalo, New York, on ColoCrossing hosting kept asking our gateway to edit a Python file, identify a cat, and find a marker buried in a long input. It repeated these tasks under different model names, checking what the endpoint could do.

Across **27** days with recorded traffic, it sent **5,036** prompt requests under **18** model names, plus **368** model-list checks. **3,254** prompt requests returned HTTP success.

The requests carried `AutoGenX-Engine/9.1` headers. Their system instructions described an “internal routing and logging system” serving models “via OpenRouter.” We found that description in **172** captured requests. It describes the sender’s setup; it does not establish that OpenRouter sent the traffic.

There were only **183** distinct user messages in the captures. The repeated tasks explain much of the volume:

| Repeated tests in this source’s captured requests |  |  | 
|---|---|---|
| Test | What the prompt asked for | Saved checks | 
|---|---|---|
| Model identity | `Identify yourself precisely.` Return a fixed JSON schema describing the model and its capabilities. | **813** | 
| File editing | Change `PORT` from 8000 to 9090 in`api_server.py` and add`TIMEOUT = 30` . | **959** | 
| Function calling | Invoke `get_weather` for the temperature in London. | **314** | 
| Vision | Identify the animal in an embedded cat photograph and return only its name. | **260** | 
| Long-context retrieval | Recover `CTX_64K_OK` , a marker hidden in a long block of repeated text. | **288** | 
| Browsing | Look up a webpage’s title and return it as JSON. | **314** | 

The coding test asked for a specific edit: change `PORT` from 8000 to 9090 and add `TIMEOUT = 30`. It supplied a Windows-style `C:\work` workspace and coding-agent instructions, then repeated the task under 17 model names. The histories contained no assistant or tool turns, so we could see the task being tested but not whether any resulting tool calls were executed.

Other tests checked images and long inputs. The roughly 77,000-character image payload was mostly an embedded JPEG. The retrieval tests hid a marker about 15% or 90% of the way through repeated filler text; the largest input contained **396,862** characters. In **283** requests, the sender asked for up to one million output tokens. That is a request setting, not measured consumption.

[Another honeypot recorded the AutoGenX-Engine header family](https://unauth.dev/botwatch) on model-API probes. Here, the repeated tasks show capability testing. We found no customer conversation histories, resale prices, or key-pool configuration in this source’s captures.

Access checks

## What happened after a key worked

The requests also showed how people tested the keys: trying different model names, repeating a check on a schedule, or using the same key from several addresses. In the examples below, we’ve replaced IPs with labels that apply only within each example. We estimated start times from completion timestamps and latency, including time spent waiting in the gateway.

Model checks

## One greeting, 29 model names

One IP used a published key to send `hi` while requesting **29** different model names. The requests started within **about 27 seconds**, and all returned a successful HTTP status.

`hi`
| Estimated time offset | Request | 
|---|---|
| +0.000s | Source A · `claude-fable-5-1` · HTTP 200 | 
| +0.005s | Source A · `gpt-4o` · HTTP 200 | 
| +0.007s | Source A · `gpt-6-luna` · HTTP 200 | 

We found **38** sessions lasting no more than ten minutes where one IP/key pair sent the same message under at least five model names.

Scheduled checks

## A working key was checked roughly once an hour

In another series, one IP kept sending `ping` with the same key and model name. We recorded **95** successful requests across **5** observed days. The requests carried a Python urllib header.

`ping`
| Estimated time offset | Request | 
|---|---|
| +0h 00m 00s | Source A · `claude-opus-5-5` · HTTP 200 | 
| +1h 00m 25s | Source A · `claude-opus-5-5` · HTTP 200 | 
| +2h 01m 29s | Source A · `claude-opus-5-5` · HTTP 200 | 

We also saw roughly five-minute checks carrying a “sub2api” header. The [public Sub2API gateway includes scheduled model checks](https://github.com/Wei-Shaw/sub2api/blob/3a6fd1c9db07203ca308aaba69e502bc1f35b307/backend/internal/service/channel_monitor_service.go), but the header alone doesn’t tell us which deployment sent these requests.

We saw **23** IPs return on later days, out of the **80** that sent successful prompts with our published keys. Of those, **3** appeared on seven or more days.

Scripts, tools, and timing

## Recognizing scripts and tools in the request headers

We examined the **4,711** successful prompt requests using our published keys. They came from **80** distinct source IPs, using a mix of scripts, browsers, and named tools.

The user-agent header often named a library or tool. The sender can change it, so we checked the labels against request behavior and public software.

The named-tool row covers “keypool,” “Zoltraak,” and “sub2api.” We looked for public software that could explain these labels:

| What those software labels mean |  |  | 
|---|---|---|
| Name in the header | What we could establish | What we saw in our traffic | 
|---|---|---|
| Sub2API | An [open-source gateway](https://github.com/Wei-Shaw/sub2api#overview) that turns access to AI subscription accounts and upstream API keys into an API for its users. It handles authentication, routing, and billing. Its[monitoring code](https://github.com/Wei-Shaw/sub2api/blob/3a6fd1c9db07203ca308aaba69e502bc1f35b307/backend/internal/service/channel_monitor_checker.go) checks whether upstream models answer. | **2,421** prompt requests carried the label;**320** returned HTTP success. Some short checks were roughly five minutes apart. We haven’t identified the deployment sending them. | 
| keypool | Key pooling means managing multiple API keys through one program or gateway. Public projects such as [llm-keypool](https://github.com/xiaopengs/llm-keypool) do this. We found no verified code match for the software sending these requests. | **1,060** labelled prompt requests;**823** returned HTTP success. Alongside short checks, requests carrying this label included the[recurring collector description](#key-collector) . | 
| Zoltraak | We couldn’t identify the software behind this label. A separate gateway operator [also reported a ZOLTRAAK header](https://blog.want.biz/post/1789248751358) while investigating an exposed AI gateway. | **675** labelled prompt requests;**410** returned HTTP success. These included short checks and prompts asking for a value that changed with each request. | 

Daily activity

## How leaked-key use changed over time

We tracked the keys we leaked on GitHub to see how they were used. The chart shows all **11,841** requests using those keys: model-list checks, prompts, and failed attempts.

Operator takeaways

## What to look for in your own gateway logs

The examples give us three patterns to investigate when grouping gateway requests by credential:

1. Many model names requested through the same key in a short window.
2. Repeated checks at a stable interval after a key has already worked.
3. A change in the addresses using a key, especially during a burst of prompt requests.

Compare these patterns with your own SDKs, load balancing, and monitoring before treating them as abuse. A stable identifier lets you group requests without storing the raw key. We haven’t measured detection accuracy or false positives.

Methods

## How we counted and linked the requests

**Scope.** Aggregate counts use the October 11 snapshot and only keys backed by our publication records. Known owner traffic, including our Israel and Westfield addresses, is excluded. The eight-address test comes from a separate 24-hour capture ending October 12; its counts are not added to the frozen totals.

**Capture.** Response recording started partway through the study. HTTP success comes from request metadata and does not establish answer quality. Older captures could truncate long text.

**Attribution.** Headers and conversation histories are supplied by the requester. A DNS match corroborates a recorded address, not a person. Older logs did not separately retain socket peers, so forwarded addresses cannot all be independently verified.

**Labels.** Coding and agent categories use lexical indicators in the latest user message. Embedded instructions, tool results, and Telegram fields are submitted context, not independently authenticated activity.

**Exposure.** Keys were published in waves and had different amounts of time to be found. New York and San Francisco also had different observation windows and API surfaces. The totals describe this experiment, not a geographic comparison or a general leak rate.

InferTrail

## Seeing similar patterns in your gateway logs?

I’m happy to compare notes on what you’re seeing and which signals are available in your gateway metadata.
