---
title: "Scan the repository for actions"
method: POST
path: "/api/v1/org-actions/scans"
tags: ["authed"]
---

# Scan the repository for actions

`POST /api/v1/org-actions/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-actions/scans`
- Auth: none declared

Scan now: read the connected repositories' API specs and API client
generator configs, and file create and update proposals into the
review inbox — never directly into the catalog. Needs a connected
repository; get_latest_org_action_scan says whether there is one.

## Response `202`

Successful Response

- OrgActionScanRunResponse
  - `id` string, uuid, required
  - `organization_id` string, uuid, required
  - `status` 'queued' | 'working' | 'succeeded' | 'failed' | 'unfunded', required
  - `error` string, nullable, required
  - `findings` ScanFindings, required: What a finished scan found: the repositories it cloned or the files uploaded, which specs it read, any API client generator config, and where every operation ended up.
    - `repos` RepoRef[], required
      - `full_name` string, required
      - `commit_sha` string, required
    - `specs` SpecRef[], required
      - `repo` string, required
      - `path` string, required
    - `api_client_config` ApiClientConfigFinding: An API client generator config, with the repository it was found in.
      - `config_path` string, required
      - `spec_path` string, nullable
      - `mutator_path` string, nullable
      - `mutator_name` string, nullable
      - `repo` string, required
      - `mutator_blob_sha` string, nullable
    - `counts` ScanCounts, required: Where every scanned operation ended up. skipped is the honest receipt for anything the scan could not carry — unparseable operations, tripped caps, archived targets, or a change a reviewer already dismissed. A GraphQL client project's skips are counted once, by reason, on its own receipt (ScanFindings.graphql), never again here.
      - `operations` integer
      - `created` integer
      - `updated` integer
      - `refreshed` integer
      - `unchanged` integer
      - `skipped` integer
      - `deprecated` integer
      - `withdrawn` integer
      - `rebaselined` integer
      - `enriched` integer
      - `inferred` integer
      - `generated` integer
    - `formats` FormatFinding[]
      - `repo` string, required
      - `path` string, required
      - `format` 'openapi_3' | 'swagger_2' | 'swagger_1' | 'raml' | 'api_blueprint' | 'wsdl' | 'odata_metadata' | 'asyncapi' | 'graphql_sdl' | 'graphql_operations' | 'protobuf' | 'postman_collection' | 'unrecognized', required
      - `support` 'recognized_unsupported' | 'unrecognized' | 'normalization_failed', required: Why a discovered artifact yielded no operations: a format the scan recognizes but cannot import yet, something spec-named that classified as nothing, or a supported format the normalizer rejected.
      - `detail` string, nullable
    - `preparation` PreparationReceipt: What the catalog-preparer agent leg did on this run — the card's honest answer, separate from the deterministic counts. Also the STUB the prepare activity returns (the receipt-handoff law): a summary only — the recorded work persists in agent session state, read by the filing activity. New fields default so old findings validate.
      - `status` 'succeeded' | 'failed' | 'skipped', required: How the catalog-preparer leg ended. SKIPPED is the push path, whose only agent run is a funded repair of a stored spec generator and whose receipt speaks through the generator lines instead; FAILED is a readable degradation — the deterministic filings still landed, un-enriched.
      - `enrichments` integer
      - `inferences` integer
      - `error` string, nullable
      - `note` string, nullable
      - `candidates_total` integer, nullable
      - `left_as_is` integer, nullable
      - `turns_used` integer, nullable
      - `turn_budget` integer, nullable
      - `generation` GenerationReceipt: The generation leg's summary on the scan card: how it ended, how many repositories got an accepted generator, how many operations their documents carried, and its own turn spend.
        - `status` 'succeeded' | 'failed' | 'skipped', required: How the catalog-preparer leg ended. SKIPPED is the push path, whose only agent run is a funded repair of a stored spec generator and whose receipt speaks through the generator lines instead; FAILED is a readable degradation — the deterministic filings still landed, un-enriched.
        - `accepted_repos` integer
        - `generated_operations` integer
        - `error` string, nullable
        - `note` string, nullable
        - `turns_used` integer, nullable
        - `turn_budget` integer, nullable
    - `unreadable` UnreadableFile[]
      - `repo` string, required
      - `path` string, required
      - `reason` 'missing' | 'oversize' | 'incomplete', required: Why the scan never read a file it found. The domain's own spelling of FileReadStatus's non-OK members — src/actionscan imports nothing from src/integrations, so the reader's enum is MAPPED onto this one rather than leaked through it.
      - `expected_bytes` integer, nullable
      - `received_bytes` integer, nullable
      - `gitignored` boolean
    - `generators` StoredGeneratorReceipt[]
      - `repo` string, required
      - `outcome` 'reran' | 'repaired' | 'repair_unfunded' | 'repair_failed' | 'interrupted' | 'not_run', required: What a push rescan did with one repository's stored spec generator. INTERRUPTED is the workspace's fault, never the script's; NOT_RUN is the one line for every generator past the rescan's limit.
      - `note` string, required
    - `graphql` GraphQLUnitReceipt[]
      - `repo` string, required
      - `manifest_path` string, nullable, required
      - `status` 'ok' | 'timeout' | 'escaped_root' | 'oversized_output' | 'not_a_unit' | 'tool_crash' | 'deferred' | 'units_over_the_cap' | 'files_over_the_cap', required: How discovery ended for a client project, or — on a repo-level receipt — for the repo: the tool's own statuses, plus the three the pass gives what it never read.
      - `clients` GraphQLClientLibrary[]
      - `schema_kind` 'committed-sdl' | 'sdl-in-code' | 'introspection' | 'config-url' | 'generated-sdl' | 'none'
      - `schema_accepted` boolean
      - `schema_repo` string, nullable
      - `endpoint_kind` 'absolute' | 'relative' | 'env' | 'runtime-config' | 'computed' | 'ambiguous' | 'unknown': How the app's client names its endpoint: a literal (absolute or relative), an env variable, runtime config, a computed value — or several disagreeing, or none found.
      - `endpoint_assumed` boolean
      - `filed` integer
      - `skipped` object
      - `collisions` string[]
      - `order` object
      - `read_whole` boolean
      - `capped` GraphQLCap[]
      - `detail` string, nullable
      - `unread_sources` integer
    - `malformed` MalformedSpecFinding[]
      - `repo` string, required
      - `path` string, required
      - `operations` integer, required
      - `withheld` WithheldOperation[]
        - `method` 'GET' | 'HEAD' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', required: The catalog's method whitelist: an action can only ever speak these.
        - `path_template` string, required
        - `detail` string, required
      - `withheld_count` integer
      - `dropped` DroppedKeyword[]
        - `keyword` '$dynamicRef' | '$recursiveRef' | '$recursiveAnchor' | '$schema' | '$vocabulary' | 'additionalItems' | 'dependencies' | 'id', required
        - `schemas` integer, required
    - `upload` UploadFinding: What an upload run read: the set, the spec files that held operations, and its GraphQL read.
      - `file_count` integer, required
      - `total_bytes` integer, required
      - `set_sha256` string, required
      - `spec_roots` string[]
      - `converted_from_swagger_2` boolean
      - `roots_not_read` string[]
      - `roots_not_read_count` integer
      - `roots_limit` integer
      - `graphql` UploadedGraphQLFinding: What an upload's GraphQL read found, for its receipt: the path every operation is sent to, the documents and schema files (the first few named, all counted), what filed and why the rest did not, and whether the set was read whole — every document read, nothing capped, the schema built.
        - `endpoint_path` string, required
        - `documents` integer, required
        - `schema_files` string[], required
        - `schema_file_count` integer, required
        - `schema_read` boolean, required
        - `filed` integer, required
        - `skipped` object
        - `collisions` string[]
        - `unreadable_documents` integer
        - `capped` boolean
        - `read_whole` boolean, required
  - `requested_by_user_id` string, uuid, nullable, required
  - `trigger` 'manual' | 'push' | 'upload', required: What started the scan: manual (a member scanned the connected repositories), push (a push to a default branch) or upload (a member uploaded spec files).
  - `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)
