> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://api-docs.botbye.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://api-docs.botbye.com/_mcp/server.

# list

GET {base_url}/api/v1/{account_id}/projects/{project_id}/compromised-users

# Get Compromised Users

Retrieves a paginated list of project users whose credentials were entered on a phishing site, deduplicated to one row per user. A user is reported as compromised when there is at least one `LOGIN` event carrying the `mismatch_origin` signal — the login passed through a phishing proxy whose HTTP `Origin` did not match the real origin embedded in the SDK token.

## Endpoint

```
GET {base_url}/api/v1/{account_id}/projects/{project_id}/compromised-users
```

## Authentication

Requires API key authentication:

```
Authorization: Bearer {api_key}
```

## Path Parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `account_id` | string | Yes | Your unique BotBye account identifier |
| `project_id` | string | Yes | The project to retrieve compromised users for |

## Query Parameters

- **Pagination**: cursor-based (`cursor`, `limit`). By default `limit` is 20, max 100.
- **Filtering**: `where` may filter on the underlying login events (e.g. `phishing_origin`).
- **Ordering**: `order_by` — results are keyed by `account_id`.

## Response Structure

Cursor-based pagination. Each `node` is one compromised user:

| Field | Type | Description |
| --- | --- | --- |
| `id` | string | Stable node id, `"{accountId}:{projectId}"` (unique within the project) |
| `accountId` | string | The end-user account id as reported by the integration |
| `phishingOrigin` | string | Origin of the most recent compromised login (latest wins) |
| `lastLoginAt` | string | Timestamp (epoch millis) of the most recent compromised login |

**pageInfo** carries `hasPreviousPage`, `hasNextPage`, `startCursor`, `endCursor` and `total` (the distinct number of compromised users).

## Use Cases

- **Incident response**: identify which users to force-reset after a phishing campaign.
- **Customer notification**: surface affected accounts to warn end users.
- **Campaign analysis**: group compromised users by the phishing origin that captured them.

Reference: https://api-docs.botbye.com/bot-bye-api/protection/compromised-users/list

## OpenAPI Specification

```yaml
openapi: 3.1.0
info:
  title: collection
  version: 1.0.0
paths:
  /api/v1/{account_id}/projects/{project_id}/compromised-users:
    get:
      operationId: list
      summary: list
      description: >-
        # Get Compromised Users


        Retrieves a paginated list of project users whose credentials were
        entered on a phishing site, deduplicated to one row per user. A user is
        reported as compromised when there is at least one `LOGIN` event
        carrying the `mismatch_origin` signal — the login passed through a
        phishing proxy whose HTTP `Origin` did not match the real origin
        embedded in the SDK token.


        ## Endpoint


        ```

        GET
        {base_url}/api/v1/{account_id}/projects/{project_id}/compromised-users

        ```


        ## Authentication


        Requires API key authentication:


        ```

        Authorization: Bearer {api_key}

        ```


        ## Path Parameters


        | Parameter | Type | Required | Description |

        | --- | --- | --- | --- |

        | `account_id` | string | Yes | Your unique BotBye account identifier |

        | `project_id` | string | Yes | The project to retrieve compromised
        users for |


        ## Query Parameters


        - **Pagination**: cursor-based (`cursor`, `limit`). By default `limit`
        is 20, max 100.

        - **Filtering**: `where` may filter on the underlying login events (e.g.
        `phishing_origin`).

        - **Ordering**: `order_by` — results are keyed by `account_id`.


        ## Response Structure


        Cursor-based pagination. Each `node` is one compromised user:


        | Field | Type | Description |

        | --- | --- | --- |

        | `id` | string | Stable node id, `"{accountId}:{projectId}"` (unique
        within the project) |

        | `accountId` | string | The end-user account id as reported by the
        integration |

        | `phishingOrigin` | string | Origin of the most recent compromised
        login (latest wins) |

        | `lastLoginAt` | string | Timestamp (epoch millis) of the most recent
        compromised login |


        **pageInfo** carries `hasPreviousPage`, `hasNextPage`, `startCursor`,
        `endCursor` and `total` (the distinct number of compromised users).


        ## Use Cases


        - **Incident response**: identify which users to force-reset after a
        phishing campaign.

        - **Customer notification**: surface affected accounts to warn end
        users.

        - **Campaign analysis**: group compromised users by the phishing origin
        that captured them.
      tags:
        - subpackage_compromisedUsers
      parameters:
        - name: account_id
          in: path
          required: true
          schema:
            type: string
        - name: project_id
          in: path
          required: true
          schema:
            type: string
        - name: cursor
          in: query
          description: "(Optional): a cursor for pagination.\n\t - `after` (string): Pointer to the item after which the items are to be retrieved.\n\t - `before` (string): Pointer to the item before which the items are to be retrieved."
          required: false
          schema:
            type: string
        - name: where
          in: query
          description: "(Optional): is used to create conditions for data filtering. It can be used to create simple conditions (leaf nodes) as well as compound logical expressions (branch nodes).\n\t- `predicate` (string): The filtering condition (e.g., `gte`, `lte`, `eq` for a leaf or `and`, `or` for a branch). Possible values [[#Predicate]]\n\t- `opearands` (string): A list of nested conditions (used only for branches, such as `and`, `or`).\n\t- `fieldPath` (string): The field to which the filtering condition is applied (used only for a leaf. Each entity has its own fieldPath list).\n\t- `value` (string): The value to compare against the field (used only for a leaf)."
          required: false
          schema:
            type: string
        - name: order_by
          in: query
          description: "(Optional): property by which to order by.\n\t- `fieldPath` (string): name of order field.\n\t- `direction` (string): `ASC` or `DESC`"
          required: false
          schema:
            type: string
        - name: limit
          in: query
          description: >-
            (Optional): specifies the maximum number of results to return in a
            single response. By default - 20, max - 100.
          required: false
          schema:
            type: string
        - name: X-Api-Key
          in: header
          description: >-
            Project API token. Generate it in your BotBye account and send it in
            the `X-Api-Key` request header.
          required: true
          schema:
            type: string
      responses:
        '200':
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Compromised Users_list_Response_200'
        '400':
          description: fail
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: >-
                    #/components/schemas/ApiV1AccountIdProjectsProjectIdCompromisedUsersGetResponsesContentApplicationJsonSchemaItems
servers:
  - url: '{base_url}'
    description: '{base_url}'
components:
  schemas:
    ApiV1AccountIdProjectsProjectIdCompromisedUsersGetResponsesContentApplicationJsonSchemaEdgesItemsNode:
      type: object
      properties:
        id:
          type: string
        accountId:
          type: string
        phishingOrigin:
          type: string
        lastLoginAt:
          type: string
          format: utc-millisec
      title: >-
        ApiV1AccountIdProjectsProjectIdCompromisedUsersGetResponsesContentApplicationJsonSchemaEdgesItemsNode
    ApiV1AccountIdProjectsProjectIdCompromisedUsersGetResponsesContentApplicationJsonSchemaEdgesItems:
      type: object
      properties:
        cursor:
          type: string
        node:
          $ref: >-
            #/components/schemas/ApiV1AccountIdProjectsProjectIdCompromisedUsersGetResponsesContentApplicationJsonSchemaEdgesItemsNode
      required:
        - cursor
        - node
      title: >-
        ApiV1AccountIdProjectsProjectIdCompromisedUsersGetResponsesContentApplicationJsonSchemaEdgesItems
    ApiV1AccountIdProjectsProjectIdCompromisedUsersGetResponsesContentApplicationJsonSchemaPageInfo:
      type: object
      properties:
        hasPreviousPage:
          type: boolean
        hasNextPage:
          type: boolean
        startCursor:
          type: string
        endCursor:
          type: string
        total:
          type: integer
      required:
        - hasPreviousPage
        - hasNextPage
        - total
      title: >-
        ApiV1AccountIdProjectsProjectIdCompromisedUsersGetResponsesContentApplicationJsonSchemaPageInfo
    ApiV1AccountIdProjectsProjectIdCompromisedUsersGetResponsesContentApplicationJsonSchemaAttributes:
      type: object
      properties: {}
      title: >-
        ApiV1AccountIdProjectsProjectIdCompromisedUsersGetResponsesContentApplicationJsonSchemaAttributes
    Compromised Users_list_Response_200:
      type: object
      properties:
        edges:
          type: array
          items:
            $ref: >-
              #/components/schemas/ApiV1AccountIdProjectsProjectIdCompromisedUsersGetResponsesContentApplicationJsonSchemaEdgesItems
        pageInfo:
          $ref: >-
            #/components/schemas/ApiV1AccountIdProjectsProjectIdCompromisedUsersGetResponsesContentApplicationJsonSchemaPageInfo
        attributes:
          $ref: >-
            #/components/schemas/ApiV1AccountIdProjectsProjectIdCompromisedUsersGetResponsesContentApplicationJsonSchemaAttributes
      required:
        - edges
        - pageInfo
        - attributes
      title: Compromised Users_list_Response_200
    ApiV1AccountIdProjectsProjectIdCompromisedUsersGetResponsesContentApplicationJsonSchemaItemsContext:
      type: object
      properties:
        param:
          type: string
        type:
          type: string
      title: >-
        ApiV1AccountIdProjectsProjectIdCompromisedUsersGetResponsesContentApplicationJsonSchemaItemsContext
    ApiV1AccountIdProjectsProjectIdCompromisedUsersGetResponsesContentApplicationJsonSchemaItems:
      type: object
      properties:
        message:
          type: string
        code:
          type: string
        type:
          type: string
        context:
          $ref: >-
            #/components/schemas/ApiV1AccountIdProjectsProjectIdCompromisedUsersGetResponsesContentApplicationJsonSchemaItemsContext
      required:
        - message
        - code
        - type
      title: >-
        ApiV1AccountIdProjectsProjectIdCompromisedUsersGetResponsesContentApplicationJsonSchemaItems
  securitySchemes:
    ProjectApiKey:
      type: apiKey
      in: header
      name: X-Api-Key
      description: >-
        Project API token. Generate it in your BotBye account and send it in the
        `X-Api-Key` request header.

```

## Examples



**Response**

```json
{
  "edges": [
    {
      "cursor": "dXNlci0x",
      "node": {
        "id": "user-1:185071d5-d4fe-4bea-93df-19d0bd8c2d0d",
        "accountId": "user-1",
        "phishingOrigin": "https://baywin-secure-login.top",
        "lastLoginAt": "1717420586513"
      }
    },
    {
      "cursor": "dXNlci0y",
      "node": {
        "id": "user-2:185071d5-d4fe-4bea-93df-19d0bd8c2d0d",
        "accountId": "user-2",
        "phishingOrigin": "https://starzbet-verify.win",
        "lastLoginAt": "1717420586514"
      }
    }
  ],
  "pageInfo": {
    "hasPreviousPage": false,
    "hasNextPage": false,
    "total": 2,
    "startCursor": "dXNlci0x",
    "endCursor": "dXNlci0y"
  },
  "attributes": {}
}
```

**SDK Code**

```python Compromised Users_list_example
import requests

url = "https://{base_url}/api/v1/account_id/projects/project_id/compromised-users"

querystring = {"cursor":"","where":"","order_by":"","limit":""}

headers = {"X-Api-Key": "<apiKey>"}

response = requests.get(url, headers=headers, params=querystring)

print(response.json())
```

```javascript Compromised Users_list_example
const url = 'https://{base_url}/api/v1/account_id/projects/project_id/compromised-users?cursor=&where=&order_by=&limit=';
const options = {method: 'GET', headers: {'X-Api-Key': '<apiKey>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Compromised Users_list_example
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://{base_url}/api/v1/account_id/projects/project_id/compromised-users?cursor=&where=&order_by=&limit="

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("X-Api-Key", "<apiKey>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Compromised Users_list_example
require 'uri'
require 'net/http'

url = URI("https://{base_url}/api/v1/account_id/projects/project_id/compromised-users?cursor=&where=&order_by=&limit=")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["X-Api-Key"] = '<apiKey>'

response = http.request(request)
puts response.read_body
```

```java Compromised Users_list_example
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://{base_url}/api/v1/account_id/projects/project_id/compromised-users?cursor=&where=&order_by=&limit=")
  .header("X-Api-Key", "<apiKey>")
  .asString();
```

```php Compromised Users_list_example
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://{base_url}/api/v1/account_id/projects/project_id/compromised-users?cursor=&where=&order_by=&limit=', [
  'headers' => [
    'X-Api-Key' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp Compromised Users_list_example
using RestSharp;

var client = new RestClient("https://{base_url}/api/v1/account_id/projects/project_id/compromised-users?cursor=&where=&order_by=&limit=");
var request = new RestRequest(Method.GET);
request.AddHeader("X-Api-Key", "<apiKey>");
IRestResponse response = client.Execute(request);
```

```swift Compromised Users_list_example
import Foundation

let headers = ["X-Api-Key": "<apiKey>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://{base_url}/api/v1/account_id/projects/project_id/compromised-users?cursor=&where=&order_by=&limit=")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```