---
title: "Start Org Sitemap Scan"
method: POST
path: "/api/v1/org-sitemap/scans"
tags: ["authed"]
---

# Start Org Sitemap Scan

`POST /api/v1/org-sitemap/scans`

## Request

- Base URL: `https://api.teaflask.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.teaflask.com/api/v1/org-sitemap/scans`
- Auth: none declared

Scan now: clone the connected repositories, read routes out of
their frontends' route structure, and file create/update/deprecate
proposals into the review inbox — never directly into the register.

## Response `202`

Successful Response

- OrgSitemapScanRunResponse
  - `id` string, uuid, required
  - `organization_id` string, uuid, required
  - `status` 'queued' | 'working' | 'succeeded' | 'failed' | 'unfunded', required
  - `error` string, nullable, required
  - `findings` SitemapScanFindings, required: The durable record of a settled sitemap scan (org_sitemap_scan_runs.findings): what was cloned, how every repo was judged, the demand data, and where every route ended up.
    - `repos` RepoRef[], required
      - `full_name` string, required
      - `commit_sha` string, required
    - `verdicts` RepoVerdict[], required
      - `repo` string, required
      - `support` 'supported' | 'recognized_partial' | 'recognized_unsupported' | 'unrecognized_frontend' | 'no_frontend', required: The repo-level verdict: the best framework support detected, or one of the two catch cases — a frontend running something the registry cannot name (demand data), or no frontend at all (a recorded verdict, never demand).
      - `framework` 'next' | 'nuxt' | 'sveltekit' | 'astro' | 'vue_router' | 'react_router' | 'angular' | 'remix' | 'django_templates' | 'gatsby' | 'ember'
      - `detected` FrameworkDetection[]
        - `framework` 'next' | 'nuxt' | 'sveltekit' | 'astro' | 'vue_router' | 'react_router' | 'angular' | 'remix' | 'django_templates' | 'gatsby' | 'ember', required
        - `support` 'supported' | 'recognized_partial' | 'recognized_unsupported', required: How far the deterministic layers reach into a framework's routes: SUPPORTED file-based routers index cleanly; RECOGNIZED_PARTIAL config-based routers index partially (measured per repo, the rest routed to the agent); RECOGNIZED_UNSUPPORTED frameworks are named, counted as demand, and read by the agent alone.
      - `codegraph_route_count` integer
      - `heuristic_route_count` integer, nullable
      - `routeless` boolean
      - `measured_clean` boolean
      - `absence_authority` boolean
      - `agent_needed` boolean
      - `note` string, nullable
    - `counts` PageScanCounts, required: Where every discovered route ended up. skipped is the honest receipt for anything the scan could not carry — layouts and endpoints, duplicate anchors, tripped caps, gate rejections.
      - `pages` integer
      - `created` integer
      - `updated` integer
      - `refreshed` integer
      - `unchanged` integer
      - `skipped` integer
      - `deprecated` integer
      - `withdrawn` integer
    - `frameworks` FrameworkFinding[]
      - `repo` string, required
      - `support` 'supported' | 'recognized_partial' | 'recognized_unsupported' | 'unrecognized_frontend' | 'no_frontend', required: The repo-level verdict: the best framework support detected, or one of the two catch cases — a frontend running something the registry cannot name (demand data), or no frontend at all (a recorded verdict, never demand).
      - `framework` 'next' | 'nuxt' | 'sveltekit' | 'astro' | 'vue_router' | 'react_router' | 'angular' | 'remix' | 'django_templates' | 'gatsby' | 'ember'
    - `preparation` SitemapPreparationReceipt: What the sitemap-preparer agent leg did on this run — the card's honest answer, separate from the deterministic counts. This is also the STUB the prepare activity returns (the receipt-handoff law): a summary only — the recorded work itself persists in agent session state, where the filing activity reads it by session id. New fields default so findings stored by earlier scans keep validating under extra="forbid".
      - `status` 'succeeded' | 'failed' | 'skipped', required: How the sitemap-preparer leg ended. SKIPPED means no repo needed it; FAILED is a readable degradation — the deterministic filings still landed.
      - `recovered` integer
      - `error` string, nullable
      - `note` string, nullable
      - `repos_total` integer, nullable
      - `left_unaddressed` integer, nullable
      - `turns_used` integer, nullable
      - `turn_budget` integer, nullable
  - `requested_by_user_id` string, uuid, nullable, required
  - `trigger` 'manual' | 'push', required
  - `finished_at` string, date-time, nullable, required
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required

## Other responses

- `401`: Unauthorized
- `403`: Forbidden
- `404`: Not found
- `405`: Method not allowed
- `409`: No GitHub connection, or a scan is already running
- `422`: Validation error
- `500`: Internal server error
- `503`: The orchestration service is unreachable

---

[API](https://skmtc.dev/teaflask/apis/teaflask-api.md) - [All operations](https://skmtc.dev/teaflask/apis/teaflask-api/llms.txt) - [OpenAPI document](https://skmtc.dev/teaflask/apis/teaflask-api/revisions/d23e9286b847?raw)
