---
title: "BIZ-007 §7 — enterprise + pro waitlist visibility (read-only, admin-gated)"
method: GET
path: "/api/v1/admin/waitlists"
tags: ["admin"]
---

# BIZ-007 §7 — enterprise + pro waitlist visibility (read-only, admin-gated)

`GET /api/v1/admin/waitlists`

## Request

- Base URL: `https://api.badgeia.com`
- URL: `https://api.badgeia.com/api/v1/admin/waitlists`
- Auth: none declared

Return both capture lists, newest-first, paged, with exact counts.

``{enterprise: {count, matching, offset, limit, has_more,
                entries:[{id,email,created_at,contacted_at}]},
   pro:        {... same envelope, entries carry notified_at}}``

``count`` is the exact table total (never affected by paging or ``q``);
``matching`` is what ``q`` matched; ``has_more`` says whether more pages
exist. The enterprise emails ARE returned — that is the point of the surface
(inbound sales leads), so a successful read commits a PII-free access receipt
before returning. No password/token/secret is ever in these tables.

**Paging and search are load-bearing for the PR #599 notification ceiling.**
That ceiling is only safe because a suppressed lead is still reachable here;
with the previous bare ``LIMIT 200`` and no offset, ~204 unauthenticated
POSTs pushed a genuine lead past the last returned row and no HTTP surface
could reach it (PR #599 review finding 1). Do not remove either parameter
without re-opening that hole.

Auth: anonymous → 401, non-admin → 403, admin → 200. Flag-off → 404 (rule #4).

## Query parameters

- `offset` integer: Rows to skip (newest-first ordering).
- `page_size` integer: Rows per page (rule #9 cap).
- `q` string, nullable: Case-insensitive email substring filter. RFC 5321 max address length.

## Response `200`

Successful Response

- object

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/badgeia/apis/badge.md) · [All operations](https://skmtc.dev/badgeia/apis/badge/llms.txt) · [OpenAPI document](https://skmtc.dev/badgeia/apis/badge/revisions/7e7f7fee8b77?raw)
