> ## Documentation Index
> Fetch the complete documentation index at: https://developer.vanta.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Find overdue security tasks

> Find current employees with overdue trainings, policy acceptances, custom tasks, background checks, or device-monitoring installs, using the Manage Vanta API.

export function vibePromptBuildText(prompt, pageTitle) {
  const url = typeof window !== "undefined" && window.location ? window.location.href : "";
  const ref = url ? "\n\nReference: " + (pageTitle || "Vanta docs") + " — " + url : "";
  return prompt + ref;
}

export function vibePromptOpen(e) {
  e.preventDefault();
  e.stopPropagation();
  const link = e.currentTarget;
  const target = link.getAttribute("data-target");
  const prompt = link.getAttribute("data-prompt") || "";
  const pageTitle = link.getAttribute("data-page-title") || "";
  const URL_LIMIT = 8000;
  const text = vibePromptBuildText(prompt, pageTitle);
  let enc = encodeURIComponent(text);
  if (enc.length > URL_LIMIT) enc = encodeURIComponent(text.slice(0, 2400));
  let dest = "";
  if (target === "cursor") dest = "cursor://anysphere.cursor-deeplink/prompt?text=" + enc; else if (target === "claude") dest = "https://claude.ai/new?q=" + enc; else if (target === "chatgpt") dest = "https://chatgpt.com/?q=" + enc;
  if (!dest) return;
  if (target === "cursor") {
    window.location.href = dest;
  } else {
    window.open(dest, "_blank", "noopener,noreferrer");
  }
}

export function vibePromptCopy(e) {
  e.preventDefault();
  e.stopPropagation();
  const btn = e.currentTarget;
  const prompt = btn.getAttribute("data-prompt") || "";
  const pageTitle = btn.getAttribute("data-page-title") || "";
  const original = btn.getAttribute("data-label") || btn.innerText;
  btn.setAttribute("data-label", original);
  const text = vibePromptBuildText(prompt, pageTitle);
  navigator.clipboard.writeText(text).then(function () {
    btn.innerText = "Copied";
    setTimeout(function () {
      btn.innerText = original;
    }, 1500);
  }, function () {
    btn.innerText = "Copy failed";
    setTimeout(function () {
      btn.innerText = original;
    }, 1500);
  });
}

export function vibePromptToggle(e) {
  e.preventDefault();
  const summary = e.currentTarget;
  const panel = summary.parentElement;
  if (!panel) return;
  const body = panel.querySelector(".vibe-prompt__body");
  const chevron = summary.querySelector(".vibe-prompt__chevron");
  const isOpen = panel.getAttribute("data-open") === "true";
  const next = isOpen ? "false" : "true";
  panel.setAttribute("data-open", next);
  summary.setAttribute("aria-expanded", next);
  if (body) body.style.display = isOpen ? "none" : "block";
  if (chevron) chevron.style.transform = isOpen ? "rotate(0deg)" : "rotate(180deg)";
}

export const BuildPrompt = ({prompt, pageTitle, defaultOpen}) => <div className="vibe-prompt__panel" data-open={defaultOpen ? "true" : "false"} style={{
  marginTop: "0.85rem",
  borderRadius: "12px",
  border: "1px solid var(--vanta-border, rgba(120, 120, 130, 0.18))",
  background: "color-mix(in srgb, #5E05C4 4%, transparent)",
  overflow: "hidden"
}}>
    <button type="button" onClick={vibePromptToggle} aria-expanded={defaultOpen ? "true" : "false"} style={{
  display: "flex",
  alignItems: "center",
  gap: "0.75rem",
  width: "100%",
  padding: "0.9rem 1.1rem",
  background: "transparent",
  border: "none",
  textAlign: "left",
  cursor: "pointer",
  font: "inherit",
  color: "inherit"
}}>
      <span style={{
  display: "inline-flex",
  alignItems: "center",
  justifyContent: "center",
  gap: "0.35rem",
  padding: "0.2rem 0.55rem",
  borderRadius: "9999px",
  fontSize: "0.7rem",
  fontWeight: 700,
  letterSpacing: "0.06em",
  textTransform: "uppercase",
  color: "#5E05C4",
  background: "color-mix(in srgb, #5E05C4 12%, transparent)",
  border: "1px solid color-mix(in srgb, #5E05C4 30%, transparent)",
  whiteSpace: "nowrap",
  flexShrink: 0,
  minWidth: "9rem"
}}>
        Code this
      </span>
      <span style={{
  flex: 1,
  minWidth: 0
}}>
        <span className="text-gray-600 dark:text-gray-300" style={{
  display: "block",
  fontSize: "0.85rem",
  lineHeight: 1.45
}}>
          Generate a script or app that performs this function using the Vanta API.
        </span>
      </span>
      <span className="vibe-prompt__chevron" aria-hidden="true" style={{
  flexShrink: 0,
  display: "inline-flex",
  alignItems: "center",
  justifyContent: "center",
  width: "24px",
  height: "24px",
  color: "#5E05C4",
  transform: defaultOpen ? "rotate(180deg)" : "rotate(0deg)",
  transition: "transform 200ms ease"
}}>
        <Icon icon="chevron-down" iconType="regular" size={14} color="#5E05C4" />
      </span>
    </button>
    <div className="vibe-prompt__body" style={{
  display: defaultOpen ? "block" : "none",
  padding: "0 1.1rem 1.1rem"
}}>
      <div style={{
  margin: 0,
  padding: "0.85rem 1rem",
  borderRadius: "8px",
  background: "rgba(15, 17, 21, 0.92)",
  color: "#f4f4f5",
  fontSize: "0.78rem",
  lineHeight: 1.55,
  fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace",
  whiteSpace: "pre-wrap",
  wordBreak: "break-word",
  overflowWrap: "anywhere",
  overflowX: "hidden",
  overflowY: "auto",
  maxHeight: "22rem"
}}>
        {prompt}
      </div>
      <div className="not-prose" style={{
  display: "flex",
  flexWrap: "wrap",
  gap: "0.5rem",
  marginTop: "0.75rem"
}}>
        <button type="button" onClick={vibePromptCopy} data-prompt={prompt} data-page-title={pageTitle} style={{
  display: "inline-flex",
  alignItems: "center",
  gap: "0.4rem",
  padding: "0.4rem 0.85rem",
  borderRadius: "8px",
  border: "none",
  cursor: "pointer",
  fontSize: "0.8rem",
  fontWeight: 600,
  color: "#ffffff",
  background: "#5E05C4"
}}>
          <Icon icon="copy" iconType="regular" size={13} color="#ffffff" />
          Copy prompt
        </button>
        <a href="#" onClick={vibePromptOpen} data-target="cursor" data-prompt={prompt} data-page-title={pageTitle} className="vibe-prompt__link" style={{
  display: "inline-flex",
  alignItems: "center",
  gap: "0.4rem",
  padding: "0.4rem 0.75rem",
  borderRadius: "8px",
  border: "1px solid var(--vanta-border, rgba(120, 120, 130, 0.25))",
  fontSize: "0.8rem",
  fontWeight: 500,
  textDecoration: "none",
  color: "inherit",
  background: "transparent"
}}>
          <Icon icon="arrow-up-right-from-square" iconType="regular" size={11} color="#5E05C4" /><span>Cursor</span>
        </a>
        <a href="#" onClick={vibePromptOpen} data-target="claude" data-prompt={prompt} data-page-title={pageTitle} className="vibe-prompt__link" style={{
  display: "inline-flex",
  alignItems: "center",
  gap: "0.4rem",
  padding: "0.4rem 0.75rem",
  borderRadius: "8px",
  border: "1px solid var(--vanta-border, rgba(120, 120, 130, 0.25))",
  fontSize: "0.8rem",
  fontWeight: 500,
  textDecoration: "none",
  color: "inherit",
  background: "transparent"
}}>
          <Icon icon="arrow-up-right-from-square" iconType="regular" size={11} color="#5E05C4" /><span>Claude</span>
        </a>
        <a href="#" onClick={vibePromptOpen} data-target="chatgpt" data-prompt={prompt} data-page-title={pageTitle} className="vibe-prompt__link" style={{
  display: "inline-flex",
  alignItems: "center",
  gap: "0.4rem",
  padding: "0.4rem 0.75rem",
  borderRadius: "8px",
  border: "1px solid var(--vanta-border, rgba(120, 120, 130, 0.25))",
  fontSize: "0.8rem",
  fontWeight: 500,
  textDecoration: "none",
  color: "inherit",
  background: "transparent"
}}>
          <Icon icon="arrow-up-right-from-square" iconType="regular" size={11} color="#5E05C4" /><span>ChatGPT</span>
        </a>
      </div>
    </div>
  </div>;

export const AskPrompt = ({prompt, pageTitle, defaultOpen}) => <div className="vibe-prompt__panel" data-open={defaultOpen ? "true" : "false"} style={{
  marginTop: "0.85rem",
  borderRadius: "12px",
  border: "1px solid var(--vanta-border, rgba(120, 120, 130, 0.18))",
  background: "color-mix(in srgb, #3b82f6 4%, transparent)",
  overflow: "hidden"
}}>
    <button type="button" onClick={vibePromptToggle} aria-expanded={defaultOpen ? "true" : "false"} style={{
  display: "flex",
  alignItems: "center",
  gap: "0.75rem",
  width: "100%",
  padding: "0.9rem 1.1rem",
  background: "transparent",
  border: "none",
  textAlign: "left",
  cursor: "pointer",
  font: "inherit",
  color: "inherit"
}}>
      <span style={{
  display: "inline-flex",
  alignItems: "center",
  justifyContent: "center",
  gap: "0.35rem",
  padding: "0.2rem 0.55rem",
  borderRadius: "9999px",
  fontSize: "0.7rem",
  fontWeight: 700,
  letterSpacing: "0.06em",
  textTransform: "uppercase",
  color: "#3b82f6",
  background: "color-mix(in srgb, #3b82f6 12%, transparent)",
  border: "1px solid color-mix(in srgb, #3b82f6 30%, transparent)",
  whiteSpace: "nowrap",
  flexShrink: 0,
  minWidth: "9rem"
}}>
        Ask Vanta Agent
      </span>
      <span style={{
  flex: 1,
  minWidth: 0
}}>
        <span className="text-gray-600 dark:text-gray-300" style={{
  display: "block",
  fontSize: "0.85rem",
  lineHeight: 1.45
}}>
          Use the Vanta MCP server to run this workflow on your behalf.
        </span>
      </span>
      <span className="vibe-prompt__chevron" aria-hidden="true" style={{
  flexShrink: 0,
  display: "inline-flex",
  alignItems: "center",
  justifyContent: "center",
  width: "24px",
  height: "24px",
  color: "#3b82f6",
  transform: defaultOpen ? "rotate(180deg)" : "rotate(0deg)",
  transition: "transform 200ms ease"
}}>
        <Icon icon="chevron-down" iconType="regular" size={14} color="#3b82f6" />
      </span>
    </button>
    <div className="vibe-prompt__body" style={{
  display: defaultOpen ? "block" : "none",
  padding: "0 1.1rem 1.1rem"
}}>
      <div style={{
  margin: 0,
  padding: "0.85rem 1rem",
  borderRadius: "8px",
  background: "rgba(15, 17, 21, 0.92)",
  color: "#f4f4f5",
  fontSize: "0.78rem",
  lineHeight: 1.55,
  fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace",
  whiteSpace: "pre-wrap",
  wordBreak: "break-word",
  overflowWrap: "anywhere",
  overflowX: "hidden"
}}>
        {prompt}
      </div>
      <div className="not-prose" style={{
  display: "flex",
  flexWrap: "wrap",
  gap: "0.5rem",
  marginTop: "0.75rem"
}}>
        <button type="button" onClick={vibePromptCopy} data-prompt={prompt} data-page-title={pageTitle} style={{
  display: "inline-flex",
  alignItems: "center",
  gap: "0.4rem",
  padding: "0.4rem 0.85rem",
  borderRadius: "8px",
  border: "none",
  cursor: "pointer",
  fontSize: "0.8rem",
  fontWeight: 600,
  color: "#ffffff",
  background: "#5E05C4"
}}>
          <Icon icon="copy" iconType="regular" size={13} color="#ffffff" />
          Copy prompt
        </button>
        <a href="#" onClick={vibePromptOpen} data-target="cursor" data-prompt={prompt} data-page-title={pageTitle} className="vibe-prompt__link" style={{
  display: "inline-flex",
  alignItems: "center",
  gap: "0.4rem",
  padding: "0.4rem 0.75rem",
  borderRadius: "8px",
  border: "1px solid var(--vanta-border, rgba(120, 120, 130, 0.25))",
  fontSize: "0.8rem",
  fontWeight: 500,
  textDecoration: "none",
  color: "inherit",
  background: "transparent"
}}>
          <Icon icon="arrow-up-right-from-square" iconType="regular" size={11} color="#5E05C4" /><span>Cursor</span>
        </a>
        <a href="#" onClick={vibePromptOpen} data-target="claude" data-prompt={prompt} data-page-title={pageTitle} className="vibe-prompt__link" style={{
  display: "inline-flex",
  alignItems: "center",
  gap: "0.4rem",
  padding: "0.4rem 0.75rem",
  borderRadius: "8px",
  border: "1px solid var(--vanta-border, rgba(120, 120, 130, 0.25))",
  fontSize: "0.8rem",
  fontWeight: 500,
  textDecoration: "none",
  color: "inherit",
  background: "transparent"
}}>
          <Icon icon="arrow-up-right-from-square" iconType="regular" size={11} color="#5E05C4" /><span>Claude</span>
        </a>
        <a href="#" onClick={vibePromptOpen} data-target="chatgpt" data-prompt={prompt} data-page-title={pageTitle} className="vibe-prompt__link" style={{
  display: "inline-flex",
  alignItems: "center",
  gap: "0.4rem",
  padding: "0.4rem 0.75rem",
  borderRadius: "8px",
  border: "1px solid var(--vanta-border, rgba(120, 120, 130, 0.25))",
  fontSize: "0.8rem",
  fontWeight: 500,
  textDecoration: "none",
  color: "inherit",
  background: "transparent"
}}>
          <Icon icon="arrow-up-right-from-square" iconType="regular" size={11} color="#5E05C4" /><span>ChatGPT</span>
        </a>
      </div>
    </div>
  </div>;

export const VibePrompts = ({children}) => <section className="vibe-prompts" style={{
  marginTop: "2.5rem",
  marginBottom: "2rem",
  padding: "1.5rem 1.5rem 1.25rem",
  borderRadius: "16px",
  border: "1px solid color-mix(in srgb, #5E05C4 22%, transparent)",
  background: "linear-gradient(180deg, color-mix(in srgb, #5E05C4 6%, transparent) 0%, transparent 100%)"
}}>
    <div style={{
  display: "flex",
  alignItems: "center",
  gap: "0.65rem",
  marginBottom: "0.25rem"
}}>
      <div style={{
  display: "inline-flex",
  alignItems: "center",
  justifyContent: "center",
  width: "32px",
  height: "32px",
  borderRadius: "9px",
  background: "color-mix(in srgb, #5E05C4 14%, transparent)"
}}>
        <Icon icon="wand-magic-sparkles" iconType="regular" size={16} color="#5E05C4" />
      </div>
      <div>
        <div className="text-gray-900 dark:text-white" style={{
  fontFamily: "Reckless, Georgia, serif",
  fontSize: "1.25rem",
  fontWeight: 500,
  lineHeight: 1.15
}}>
          Let AI do this for you
        </div>
        <div className="text-gray-600 dark:text-gray-300" style={{
  fontSize: "0.85rem",
  lineHeight: 1.45,
  marginTop: "0.15rem"
}}>
          Copy the prompt to run this live via the <a href="/docs/vanta-mcp" style={{
  color: "#5E05C4"
}}> MCP server</a> or have AI generate a runnable script.
        </div>
      </div>
    </div>
    {children}
  </section>;

export const TASKS_ASK = "Using the Vanta MCP server, show me all current employees who have overdue security tasks.\n\nFor each person, include their name, email address, and which specific task types are overdue — training completions, policy acceptances, custom tasks, background checks, or device monitoring installs.";
export const TASKS_BUILD = "Using the Manage Vanta API (base URL https://api.vanta.com), write a Node.js script that:\n\n1. Mints a Vanta API token using the client-credentials flow. Re-mint at the top of every scheduled run (tokens expire after one hour).\n2. Calls GET /v1/people with pageSize=100, employmentStatusMatchesAny=CURRENT, taskStatusMatchesAny=OVERDUE, and taskTypeMatchesAny for each of: COMPLETE_TRAININGS, ACCEPT_POLICIES, COMPLETE_CUSTOM_TASKS, COMPLETE_BACKGROUND_CHECKS, INSTALL_DEVICE_MONITORING.\n3. Paginates using results.pageInfo.endCursor until hasNextPage is false.\n4. For each person in results.data: skip records where tasksSummary is null; iterate tasksSummary.details and collect every key whose status is OVERDUE; emit { name, email, overdueTasks } as a JSON line.\n5. Print a summary: total overdue count and a breakdown by task type.\n\nError handling:\n- 401: re-mint and retry once.\n- 5xx: retry with 2s exponential back-off, max 3 attempts.\n\nScope required: vanta-api.all:read.";

This guide queries `GET /v1/people` on the Manage Vanta API for current employees with overdue security tasks — incomplete trainings, unaccepted policies, open custom tasks, missing background checks, or missing device-monitoring installs. Use the ask prompt to surface overdue tasks through the Vanta MCP server in seconds, or the build prompt to generate a scheduled job that emits one JSON line per person with the specific task types still open.

<VibePrompts>
  <AskPrompt prompt={TASKS_ASK} />

  <BuildPrompt prompt={TASKS_BUILD} />
</VibePrompts>

## Before you begin

This guide is for Vanta admins managing data inside their own Vanta account.

You'll need:

* A Manage Vanta [API token](/docs/quickstart/manage-vanta).
* The token must have scope `vanta-api.all:read`.
* At least one source of personnel data connected to Vanta (HRIS, IDP, or manually added users).

Vanta tracks recurring security tasks for every person in your organization — security training, policy acceptance, custom checklists, background checks, and device-monitoring installs. The People endpoint lets you filter for people whose tasks are `OVERDUE`, then chase them down.

<Info>
  Wiring this into a recurring nudge (Slack reminder, email digest)? Run Step 1 on a schedule and feed the output into your notifier. Tokens expire hourly — re-mint at the top of each run.
</Info>

<Steps>
  <Step title="Query overdue tasks for current employees">
    **Your terminal** — call [`GET /v1/people`](/reference/manage-vanta/overview) with `taskTypeMatchesAny` for the task types you care about, `taskStatusMatchesAny=OVERDUE`, and `employmentStatusMatchesAny=CURRENT` so you don't chase former employees.

    ```bash Terminal theme={"system"}
    curl 'https://api.vanta.com/v1/people?pageSize=50&employmentStatusMatchesAny=CURRENT&taskStatusMatchesAny=OVERDUE&taskTypeMatchesAny=COMPLETE_TRAININGS&taskTypeMatchesAny=ACCEPT_POLICIES&taskTypeMatchesAny=COMPLETE_CUSTOM_TASKS&taskTypeMatchesAny=COMPLETE_BACKGROUND_CHECKS&taskTypeMatchesAny=INSTALL_DEVICE_MONITORING' \
      -H 'Accept: application/json' \
      -H 'Authorization: Bearer YOUR_TOKEN'
    ```

    Response (truncated for readability)

    ```json theme={"system"}
    {
      "results": {
        "data": [
          {
            "id": "5fc82421a228f6b6f713547d",
            "emailAddress": "alex@example.com",
            "name": { "display": "Alex Admin" },
            "employment": { "status": "CURRENT", "jobTitle": "Engineer" },
            "tasksSummary": {
              "status": "OVERDUE",
              "dueDate": "2024-05-12T04:31:54.490Z",
              "details": {
                "completeTrainings": { "status": "OVERDUE", "incompleteTrainings": [{ "name": "AI_RISK_SECURITY_TRAINING" }] },
                "acceptPolicies": { "status": "OVERDUE", "unacceptedPolicies": [{ "name": "Secure Development Policy" }] },
                "completeBackgroundChecks": { "status": "COMPLETE" }
              }
            }
          }
        ],
        "pageInfo": { "hasNextPage": true, "endCursor": "..." }
      }
    }
    ```

    `tasksSummary.details` breaks down each task type so you can build a precise nudge ("you owe AI Risk training and one policy acceptance") rather than a generic "you have overdue tasks" message.

    <AccordionGroup>
      <Accordion title="Got a 401?">
        Token is expired (one-hour lifetime), missing, or lacks `vanta-api.all:read`. Mint a fresh one — see [Authentication → Token expiration](/docs/concepts/authentication#token-expiration).
      </Accordion>

      <Accordion title="What task types can I filter on?">
        `COMPLETE_TRAININGS`, `ACCEPT_POLICIES`, `COMPLETE_CUSTOM_TASKS`, `INSTALL_DEVICE_MONITORING`, `COMPLETE_BACKGROUND_CHECKS`. Pass each one as a separate `taskTypeMatchesAny=` query param.
      </Accordion>

      <Accordion title="What task statuses can I filter on?">
        `COMPLETE`, `DUE_SOON`, `OVERDUE`, `NONE`. `taskStatusMatchesAny` is **required** when you pass `taskTypeMatchesAny`.
      </Accordion>

      <Accordion title="Got `FORMER` users in the response?">
        You omitted `employmentStatusMatchesAny=CURRENT`. The endpoint returns all matches by default, including offboarded people whose tasks were never completed.
      </Accordion>
    </AccordionGroup>
  </Step>

  <Step title="Process and act on the results">
    **Your terminal** — paginate with `pageCursor` if `hasNextPage` is `true`, then collapse each person's `tasksSummary.details` down to the specific items they owe.

    <CodeGroup>
      ```javascript Node.js theme={"system"}
      const URL =
        "https://api.vanta.com/v1/people?pageSize=50" +
        "&employmentStatusMatchesAny=CURRENT" +
        "&taskStatusMatchesAny=OVERDUE" +
        "&taskTypeMatchesAny=COMPLETE_TRAININGS" +
        "&taskTypeMatchesAny=ACCEPT_POLICIES" +
        "&taskTypeMatchesAny=COMPLETE_CUSTOM_TASKS" +
        "&taskTypeMatchesAny=COMPLETE_BACKGROUND_CHECKS" +
        "&taskTypeMatchesAny=INSTALL_DEVICE_MONITORING";

      const res = await fetch(URL, {
        headers: { Authorization: "Bearer YOUR_TOKEN" },
      });
      const { results } = await res.json();

      const overdue = results.data.map((person) => ({
        name: person.name.display,
        email: person.emailAddress,
        overdueTasks: Object.entries(person.tasksSummary?.details ?? {})
          .filter(([, task]) => task.status === "OVERDUE")
          .map(([type]) => type),
      }));

      console.log(overdue);
      ```

      ```python Python theme={"system"}
      import requests

      url = "https://api.vanta.com/v1/people"
      params = [
          ("pageSize", 50),
          ("employmentStatusMatchesAny", "CURRENT"),
          ("taskStatusMatchesAny", "OVERDUE"),
          ("taskTypeMatchesAny", "COMPLETE_TRAININGS"),
          ("taskTypeMatchesAny", "ACCEPT_POLICIES"),
          ("taskTypeMatchesAny", "COMPLETE_CUSTOM_TASKS"),
          ("taskTypeMatchesAny", "COMPLETE_BACKGROUND_CHECKS"),
          ("taskTypeMatchesAny", "INSTALL_DEVICE_MONITORING"),
      ]

      r = requests.get(
          url,
          headers={"Authorization": "Bearer YOUR_TOKEN"},
          params=params,
      )
      r.raise_for_status()

      for person in r.json()["results"]["data"]:
          overdue = [
              t for t, info in (person["tasksSummary"] or {}).get("details", {}).items()
              if info.get("status") == "OVERDUE"
          ]
          if overdue:
              print(person["name"]["display"], person["emailAddress"], overdue)
      ```
    </CodeGroup>

    Example collapsed output:

    ```json theme={"system"}
    [
      {
        "name": "Alex Admin",
        "email": "alex@example.com",
        "overdueTasks": ["completeTrainings", "acceptPolicies"]
      }
    ]
    ```

    <AccordionGroup>
      <Accordion title="`tasksSummary` is null for some people?">
        That person has no tasks assigned (e.g. a contractor or service account marked as not-a-person). Skip them. See [Mark accounts as not a person](/docs/guides/mark-people-as-not-a-person).
      </Accordion>

      <Accordion title="Need to paginate?">
        Read `results.pageInfo.endCursor` and `hasNextPage`. Re-call the endpoint with `pageCursor=<endCursor>` until `hasNextPage` is `false`. Don't try to fetch all people in one call — `pageSize` caps at 100.
      </Accordion>
    </AccordionGroup>
  </Step>
</Steps>

<Info>
  **Just want a count, not the list?** The same query returns `pageInfo.hasNextPage` plus a `data` array — paginate to count, or filter more aggressively (e.g. by single `taskTypeMatchesAny`) for a smaller response.
</Info>

## Congratulations

You've pulled the canonical list of current employees with overdue security tasks straight from Vanta. Wire this into a Slack nudge, email digest, or compliance dashboard so reminders happen without anyone clicking through the Vanta UI.

## Next steps

<CardGroup cols={2}>
  <Card title="Mark accounts as not a person" icon="user-slash" href="/docs/guides/mark-people-as-not-a-person">
    Exclude shared mailboxes and service accounts from these task tallies.
  </Card>

  <Card title="Offboard people" icon="user-minus" href="/docs/guides/offboard-people">
    Once an employee is `FORMER`, complete the offboarding programmatically.
  </Card>

  <Card title="Try it in Postman" icon="paper-plane" href="/docs/postman-setup">
    Import the collection and run the People query against a sandbox in seconds.
  </Card>

  <Card title="Manage Vanta API reference" icon="book" href="/reference/manage-vanta/overview">
    Browse every Manage Vanta endpoint — controls, tests, documents, people.
  </Card>
</CardGroup>
