Plan a folder scan — keep engine then 202 receiving
Submits a directory inventory plus optional root .gitignore and settings-file bytes. A diff producer lists removed paths as inventory entries with deleted: true and size: 0; those deletion markers are retained with the receiving plan but never enter the keep set or ingest. The server runs the keep engine (SDK scanning built-ins, gitignore, settings, org/project skip_patterns) and returns 202 with the scan (status=receiving) and the keep set.
The keep-set transfer is NOT complete: the client streams kept file bytes via PUT /v1/scans/{scanId}/ingest, then POST /v1/scans/{scanId}:commit-ingest. Caps apply to keep-set bytes and entry count (keep_set_too_large).
POST
/
v1
/
scans:plan-folder
Plan a folder scan — keep engine then 202 receiving
An Earnie API key, sent as Authorization: Bearer sk_earnie_.... Create one under Settings > API keys. The key's scopes decide which operations it may call.
Opaque client-generated key. Repeating the same request with the same key and actor returns the original receiving scan; reusing the key for a different request returns 409 idempotency_conflict.
Identifiers for optional PURL-driven enrichments. matching is the always-on core engine and is not an enrichment key. Dependency inventory is produced by the always-on dependency stage. Omitting enrichments defaults to ["vulnerabilities","licenses"].
A scanner phase selected for source-code scan compute. ai is AI provenance. A Self-check does not run it, and an explicit request for it on a Self-check answers 400 invalid_scanners.
Optional submission provenance. The server derives or overwrites producer from the authenticated actor and validates coverage; everything else is persisted as supplied.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"SCANOSS documentation","colors":{"primary":"#FF6A1A","light":"#FF6A1A","dark":"#FF6A1A"},"logo":{"light":"https://mintcdn.com/scanoss/9UP7eHL2Z_rQPx8l/scanoss-logo-horizontal-positive.svg?fit=max\u0026auto=format\u0026n=9UP7eHL2Z_rQPx8l\u0026q=85\u0026s=686c4487013423ef804e2e83983c76ef","dark":"https://mintcdn.com/scanoss/9UP7eHL2Z_rQPx8l/scanoss-logo-horizontal-negative.svg?fit=max\u0026auto=format\u0026n=9UP7eHL2Z_rQPx8l\u0026q=85\u0026s=03cf2002f3fff2726f8e9b19bb2781ec","href":"https://scanoss.com"},"favicon":"https://mintcdn.com/scanoss/SuvZQ2xWfRUv4OAb/scan-favicon.png?fit=max\u0026auto=format\u0026n=SuvZQ2xWfRUv4OAb\u0026q=85\u0026s=4f02839460dfdc66102d3b028b507df6","appearance":{"default":"system","strict":false},"footer":{"socials":{"x":"https://x.com/SCANOSS_","github":"https://github.com/scanoss","linkedin":"https://es.linkedin.com/company/scanoss"}},"seo":{"indexing":"all"},"fonts":{"heading":{"family":"Space Grotesk","weight":700,"format":"woff2"},"body":{"family":"Space Grotesk","format":"woff2"}},"integrations":{"ga4":{"measurementId":"G-NWY31TXG8Y"}},"banner":{"content":"**Earnie is here** — SCANOSS's major release for AI governance, cryptography, PQC readiness, and open source compliance. [Watch the release demo →](https://youtu.be/MKgIpH4bEQ4?si=wXECS3umWGx11mB7)","dismissible":true},"contextual":{"options":["copy","view","claude","chatgpt","cursor","vscode","mcp"],"display":"header"},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"scanoss","hasAudioNarration":false,"actualSubdomain":"scanoss","customDomains":["docs.scanoss.com"],"gitSource":{"type":"github","owner":"scanoss","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ae4b3963ba31227325e8be3","collectionId":"d9114605-ddef-42c8-ac16-d4fe7eeb21bc","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ae4b3963ba31227325e8be3"},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6ae4b3c4e7bd3811c8096878","clientVersion":"0.0.4021","searchFilterCounts":[{"language":"default","tag":"Earnie","count":161},{"language":"default","tag":"API Reference","count":137},{"language":"default","tag":"Guides","count":87},{"language":"default","tag":"Developer Tools","count":67},{"language":"default","tag":"API reference","count":48},{"language":"default","tag":"v3 endpoints","count":47},{"language":"default","tag":"Scans","count":44},{"language":"default","tag":"scans","count":44},{"language":"default","tag":"Policies","count":22},{"language":"default","tag":"CLI Tools","count":21}]},"assistantConfig":{"enableStarterQuestions":true,"deflection":{"enabled":true,"email":"support@scanoss.com","showHelpButton":true}},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"starterQuestions":[{"_id":"695fa5b6a879c7d6b0e8a169","deploymentId":"68551e34bde804c6773f4df2","questionText":"Cannot import/export projects?","status":"active","generatedBy":"manual","createdAt":"2026-01-08T12:40:22.697Z","updatedAt":"2026-01-08T12:40:22.697Z","__v":0},{"_id":"695fa5a4a879c7d6b0e8a064","deploymentId":"68551e34bde804c6773f4df2","questionText":"Dependency files not detected during scan?","status":"active","generatedBy":"manual","createdAt":"2026-01-08T12:40:04.675Z","updatedAt":"2026-01-08T12:40:04.675Z","__v":0},{"_id":"695fa566a879c7d6b0e89d1e","deploymentId":"68551e34bde804c6773f4df2","questionText":"How do I configure the SCANOSS API key?","status":"active","generatedBy":"manual","createdAt":"2026-01-08T12:39:02.662Z","updatedAt":"2026-01-08T12:39:02.662Z","__v":0}],"googleFontsInlined":true},"customCss":[{"filePath":"style.css","content":"#banner{background-color:#ff6a1a!important;color:#fff!important}html:not(.dark) #assistant-entry,html:not(.dark) #background-color,html:not(.dark) #chat-assistant-sheet,html:not(.dark) #chat-assistant-sheet .bg-background-light,html:not(.dark) #navbar-transition,html:not(.dark) .chat-assistant-floating-input .bg-background-light,html:not(.dark) .chat-assistant-floating-input::before{background-color:#f4f6f9!important}html:not(.dark) h1{color:#081320!important}html:not(.dark) nav a[aria-current=page]{background-color:rgba(8,19,32,.1)!important}html.dark #background-color,html.dark #navbar-transition{background-color:#081320!important}html.dark .prose :where(h1, h2, h3, h4, h5, h6),html.dark .prose :where(p, li, td, th):not(svg *),html.dark h1{color:#fff!important}html.dark nav a[aria-current=page]{background-color:rgba(255,106,26,.15)!important}html.dark #assistant-entry,html.dark #chat-assistant-sheet,html.dark #chat-assistant-sheet .dark\\:bg-background-dark,html.dark .chat-assistant-floating-input .dark\\:bg-background-dark,html.dark .chat-assistant-floating-input::before{background-color:#081320!important}nav#sidebar .sticky.top-0.h-8,span[style*=radial-gradient]{display:none!important}#sidebar #navigation-items{padding-top:2rem}.eyebrow,nav a.text-primary{color:#ff6a1a!important}"}],"page":{"pagePath":"earnie/api-reference/scans/scans/plan-a-folder-scan-—-keep-engine-then-202-receiving","slug":"/earnie/api-reference/scans/scans/plan-a-folder-scan-—-keep-engine-then-202-receiving","pageMetadata":{"title":"Plan a folder scan — keep engine then 202 receiving","description":"Submits a directory inventory plus optional root `.gitignore` and settings-file bytes. A diff producer lists removed paths as inventory entries with `deleted: true` and `size: 0`; those deletion markers are retained with the receiving plan but never enter the keep set or ingest. The server runs the keep engine (SDK scanning built-ins, gitignore, settings, org/project skip_patterns) and returns `202` with the scan (`status=receiving`) and the keep set.\n\nThe keep-set transfer is NOT complete: the client streams kept file bytes via `PUT /v1/scans/{scanId}/ingest`, then `POST /v1/scans/{scanId}:commit-ingest`. Caps apply to keep-set bytes and entry count (`keep_set_too_large`).","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json post /v1/scans:plan-folder","href":"/earnie/api-reference/scans/scans/plan-a-folder-scan-—-keep-engine-then-202-receiving","autogeneratedByOpenApi":true},"description":{"compiledSource":"\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsxs(_components.p, {\n children: [\"Submits a directory inventory plus optional root \", _jsx(_components.code, {\n children: \".gitignore\"\n }), \" and settings-file bytes. A diff producer lists removed paths as inventory entries with \", _jsx(_components.code, {\n children: \"deleted: true\"\n }), \" and \", _jsx(_components.code, {\n children: \"size: 0\"\n }), \"; those deletion markers are retained with the receiving plan but never enter the keep set or ingest. The server runs the keep engine (SDK scanning built-ins, gitignore, settings, org/project skip_patterns) and returns \", _jsx(_components.code, {\n children: \"202\"\n }), \" with the scan (\", _jsx(_components.code, {\n children: \"status=receiving\"\n }), \") and the keep set.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"The keep-set transfer is NOT complete: the client streams kept file bytes via \", _jsx(_components.code, {\n children: \"PUT /v1/scans/{scanId}/ingest\"\n }), \", then \", _jsx(_components.code, {\n children: \"POST /v1/scans/{scanId}:commit-ingest\"\n }), \". Caps apply to keep-set bytes and entry count (\", _jsx(_components.code, {\n children: \"keep_set_too_large\"\n }), \").\"]\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Plan a folder scan — keep engine then 202 receiving","description":"Submits a directory inventory plus optional root `.gitignore` and settings-file bytes. A diff producer lists removed paths as inventory entries with `deleted: true` and `size: 0`; those deletion markers are retained with the receiving plan but never enter the keep set or ingest. The server runs the keep engine (SDK scanning built-ins, gitignore, settings, org/project skip_patterns) and returns `202` with the scan (`status=receiving`) and the keep set.\n\nThe keep-set transfer is NOT complete: the client streams kept file bytes via `PUT /v1/scans/{scanId}/ingest`, then `POST /v1/scans/{scanId}:commit-ingest`. Caps apply to keep-set bytes and entry count (`keep_set_too_large`).","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json post /v1/scans:plan-folder","href":"/earnie/api-reference/scans/scans/plan-a-folder-scan-—-keep-engine-then-202-receiving","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"operationId":"PostV1ScansPlanFolder","summary":"Plan a folder scan — keep engine then 202 receiving","description":"Submits a directory inventory plus optional root `.gitignore` and settings-file bytes. A diff producer lists removed paths as inventory entries with `deleted: true` and `size: 0`; those deletion markers are retained with the receiving plan but never enter the keep set or ingest. The server runs the keep engine (SDK scanning built-ins, gitignore, settings, org/project skip_patterns) and returns `202` with the scan (`status=receiving`) and the keep set.\n\nThe keep-set transfer is NOT complete: the client streams kept file bytes via `PUT /v1/scans/{scanId}/ingest`, then `POST /v1/scans/{scanId}:commit-ingest`. Caps apply to keep-set bytes and entry count (`keep_set_too_large`).","tags":["scans"],"parameters":["2f8e0346-d817-4654-8a46-e65781016a1d"],"requestBody":"41794aea-3576-4a83-9f08-2e0adc6dda2b","responses":{"202":"c1bb2a53-fc90-4268-881f-be1ec68af58e","400":"5ceb7daa-c898-4e5a-9b9b-ceba5d011b8d","401":"3f4dd34d-cc25-490e-a030-d1c5f4c059b6","403":"d4465048-d13a-40ba-9372-189a12d5f676","409":"b513142c-b6e7-4a79-b9d2-b2a1de6e53de","413":"4acad538-760e-4b97-aa47-e788a08c050a","422":"918ec598-0957-4d62-9a5a-8698c3c04537"},"method":"post","type":"path","servers":["78824d01-63cc-41fd-9d19-c3590c2af6c2"],"security":["044b1aa4-bef2-430b-bd04-5a8e9add18c6"],"path":"/v1/scans:plan-folder","baseUrlOptions":["https://{tenant}.earnie.dev"],"title":"Plan a folder scan — keep engine then 202 receiving","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{"2f8e0346-d817-4654-8a46-e65781016a1d":{"name":"Idempotency-Key","in":"header","required":false,"description":"Opaque client-generated key. Repeating the same request with the same key and actor returns the original receiving scan; reusing the key for a different request returns `409 idempotency_conflict`.","schema":{"type":"string","minLength":1,"maxLength":255,"isRequired":false,"description":"Opaque client-generated key. Repeating the same request with the same key and actor returns the original receiving scan; reusing the key for a different request returns `409 idempotency_conflict`.","uniqueKey":"","typeLabel":"string"}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["project_id","files"],"properties":{"project_id":{"type":"string","format":"uuid","isRequired":true,"uniqueKey":"project_id","typeLabel":"string\u003cuuid>"},"files":{"type":"array","items":{"type":"object","required":["path","size"],"properties":{"path":{"type":"string","description":"Relative path using `/` separators. Must not be absolute or contain `..`; whitespace and newlines are preserved.","isRequired":true,"uniqueKey":"files.items.[INDEX].path","typeLabel":"string"},"size":{"type":"integer","format":"int64","minimum":0,"description":"Declared size in bytes. Skip decisions use this; file bytes are not required except for `.gitignore` and settings. Deleted entries must declare zero.","isRequired":true,"uniqueKey":"files.items.[INDEX].size","typeLabel":"integer\u003cint64>"},"is_dir":{"type":"boolean","default":false,"uniqueKey":"files.items.[INDEX].is_dir","typeLabel":"boolean"},"deleted":{"type":"boolean","default":false,"description":"A diff deletion marker. Deleted entries name a removed regular-file path, declare size zero, and are never included in the keep set or uploaded as bytes.","uniqueKey":"files.items.[INDEX].deleted","typeLabel":"boolean"}},"uniqueKey":"files.items.[INDEX]","typeLabel":"object"},"description":"Directory inventory (path, size, file vs directory). Bytes of file contents are not included.","isRequired":true,"uniqueKey":"files","typeLabel":"object[]"},"name":{"type":"string","description":"Optional display name. Defaults to the folder name when supplied as `archive_filename`.","uniqueKey":"name","typeLabel":"string"},"archive_filename":{"type":"string","description":"Display filename for the scan (e.g. the selected folder name).","uniqueKey":"archive_filename","typeLabel":"string"},"enrichments":{"oneOf":[{"type":"array","items":{"type":"string","enum":["vulnerabilities","licenses"],"description":"Identifiers for optional PURL-driven enrichments. `matching` is the always-on core engine and is not an enrichment key. Dependency inventory is produced by the always-on dependency stage. Omitting `enrichments` defaults to [\"vulnerabilities\",\"licenses\"].","uniqueKey":"enrichments.oneOf.0.items.[INDEX]","typeLabel":"enum\u003cstring>"},"uniqueKey":"enrichments.oneOf.0","typeLabel":"enum\u003cstring>[]"},{"type":"null","items":{"type":"string","enum":["vulnerabilities","licenses"],"description":"Identifiers for optional PURL-driven enrichments. `matching` is the always-on core engine and is not an enrichment key. Dependency inventory is produced by the always-on dependency stage. Omitting `enrichments` defaults to [\"vulnerabilities\",\"licenses\"]."},"uniqueKey":"enrichments.oneOf.1","typeLabel":"null"}],"uniqueKey":"enrichments","typeLabel":"enum\u003cstring>[] | null"},"scanners":{"oneOf":[{"type":"array","minItems":1,"items":{"type":"string","enum":["oss","crypto","ai"],"description":"A scanner phase selected for source-code scan compute. `ai` is AI provenance. A Self-check does not run it, and an explicit request for it on a Self-check answers 400 `invalid_scanners`.","uniqueKey":"scanners.oneOf.0.items.[INDEX]","typeLabel":"enum\u003cstring>"},"uniqueKey":"scanners.oneOf.0","typeLabel":"enum\u003cstring>[]"},{"type":"null","minItems":1,"items":{"type":"string","enum":["oss","crypto","ai"],"description":"A scanner phase selected for source-code scan compute. `ai` is AI provenance. A Self-check does not run it, and an explicit request for it on a Self-check answers 400 `invalid_scanners`."},"uniqueKey":"scanners.oneOf.1","typeLabel":"null"}],"uniqueKey":"scanners","typeLabel":"enum\u003cstring>[] | null"},"scan_context":{"type":"object","description":"Optional submission provenance. The server derives or overwrites `producer` from the authenticated actor and validates `coverage`; everything else is persisted as supplied.","properties":{"producer":{"type":"string","enum":["ui_upload","connected_repo","pr_ci","cli","pre_commit","mcp","sbom_import"],"description":"The surface that submitted the scan (GLOSSARY \"Producer\"). Derived from the authenticated actor wherever the actor determines it; a client-declared value the actor cannot legitimately produce is overwritten server-side, never rejected.\n\n`pre_commit` and `mcp` classify the run as a Self-check: it runs the same scanners, enrichments and policy engine and shows results, verdict and a deep link under the Project, but materializes no Findings, never touches posture, is held at `partial` coverage, is purged 30 days after creation and leaves a `selfcheck.*` decision log instead of `finding.detected`.\n\nA Self-check is read through `/v1/self-checks`, not `/v1/scans`: the Scan endpoints return governed Scans only.","uniqueKey":"scan_context.producer","typeLabel":"enum\u003cstring>"},"coverage":{"type":"string","description":"The coverage the client intends. The server validates it: a downgrade to `partial` is honoured, a promotion to `full` is rejected with `coverage_promotion_rejected`.","enum":["full","partial"],"uniqueKey":"scan_context.coverage","typeLabel":"enum\u003cstring>"},"provider":{"oneOf":[{"type":"string","description":"The source-code provider the submission originated from, such as github or gitlab. Any connected provider's name.","pattern":"^[a-z][a-z0-9-]{0,31}$","uniqueKey":"scan_context.provider.oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"scan_context.provider.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan_context.provider","typeLabel":"string | null"},"repository":{"oneOf":[{"type":"object","description":"The provider repository the submitted code belongs to.","required":["external_id","full_name"],"properties":{"external_id":{"type":"string","description":"The provider's immutable repository id (GitHub's numeric repo id, GitLab's project id) as a string. Survives rename and transfer.","isRequired":true,"uniqueKey":"scan_context.repository.oneOf.0.external_id","typeLabel":"string"},"full_name":{"type":"string","description":"Display path in `owner/name` form. Mutable — never a match key.","isRequired":true,"uniqueKey":"scan_context.repository.oneOf.0.full_name","typeLabel":"string"}},"uniqueKey":"scan_context.repository.oneOf.0","typeLabel":"object"},{"type":"null","uniqueKey":"scan_context.repository.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan_context.repository","typeLabel":"object | null"},"change_request":{"oneOf":[{"type":"object","description":"The pull/merge request the submission belongs to. An *identified* one makes the scan `partial` — at least one of `number`, `url`, `base_sha`, `head_sha` or `head_ref` must be set for it to count. An empty object narrows nothing, because a client that had been silently narrowed could not ask for `full` again without deleting the provenance it wanted.\n\nNote this applies to a `git` submission too, not only a diff upload. A pipeline that wants full-coverage posture submits without change-request provenance.","properties":{"number":{"type":"integer","description":"Provider-visible PR/MR number.","uniqueKey":"scan_context.change_request.oneOf.0.number","typeLabel":"integer"},"url":{"type":"string","description":"Deep link back to the change request.","uniqueKey":"scan_context.change_request.oneOf.0.url","typeLabel":"string"},"base_sha":{"type":"string","description":"The commit the change request is based on.","uniqueKey":"scan_context.change_request.oneOf.0.base_sha","typeLabel":"string"},"head_sha":{"type":"string","description":"The commit the submitted code was taken at.","uniqueKey":"scan_context.change_request.oneOf.0.head_sha","typeLabel":"string"},"base_ref":{"type":"string","description":"The branch the change request targets.","uniqueKey":"scan_context.change_request.oneOf.0.base_ref","typeLabel":"string"},"head_ref":{"type":"string","description":"The change request's source branch.","uniqueKey":"scan_context.change_request.oneOf.0.head_ref","typeLabel":"string"}},"uniqueKey":"scan_context.change_request.oneOf.0","typeLabel":"object"},{"type":"null","uniqueKey":"scan_context.change_request.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan_context.change_request","typeLabel":"object | null"},"commit_sha":{"oneOf":[{"type":"string","uniqueKey":"scan_context.commit_sha.oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"scan_context.commit_sha.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan_context.commit_sha","typeLabel":"string | null"},"branch":{"oneOf":[{"type":"string","uniqueKey":"scan_context.branch.oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"scan_context.branch.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan_context.branch","typeLabel":"string | null"},"run":{"oneOf":[{"type":"object","description":"The CI job that submitted the scan — a link back, never a match key.","properties":{"ci_system":{"type":"string","description":"e.g. `github_actions`, `gitlab_ci`, `jenkins`.","uniqueKey":"scan_context.run.oneOf.0.ci_system","typeLabel":"string"},"url":{"type":"string","description":"Deep link to the CI run.","uniqueKey":"scan_context.run.oneOf.0.url","typeLabel":"string"},"external_id":{"type":"string","description":"The CI system's own run identifier.","uniqueKey":"scan_context.run.oneOf.0.external_id","typeLabel":"string"}},"uniqueKey":"scan_context.run.oneOf.0","typeLabel":"object"},{"type":"null","uniqueKey":"scan_context.run.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan_context.run","typeLabel":"object | null"}},"uniqueKey":"scan_context","typeLabel":"object"},"gitignore":{"type":"string","format":"byte","description":"Optional root .gitignore bytes (base64). Same scope as the SDK: project root only.","uniqueKey":"gitignore","typeLabel":"string\u003cbyte>"},"settings":{"type":"string","format":"byte","description":"Optional scanoss.json or settings.json bytes (base64).","uniqueKey":"settings","typeLabel":"string\u003cbyte>"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"project_id":"3c90c3cc-0d44-4b50-8888-8dd25736052a","files":[{"path":"\u003cstring>","size":1,"is_dir":false,"deleted":false}],"name":"\u003cstring>","archive_filename":"\u003cstring>","enrichments":[],"scanners":[],"scan_context":{"provider":"\u003cstring>","repository":{"external_id":"\u003cstring>","full_name":"\u003cstring>"},"change_request":{"number":123,"url":"\u003cstring>","base_sha":"\u003cstring>","head_sha":"\u003cstring>","base_ref":"\u003cstring>","head_ref":"\u003cstring>"},"commit_sha":"\u003cstring>","branch":"\u003cstring>","run":{"ci_system":"\u003cstring>","url":"\u003cstring>","external_id":"\u003cstring>"}},"gitignore":"aSDinaTvuI8gbWludGxpZnk=","settings":"aSDinaTvuI8gbWludGxpZnk="}}},"exampleType":"generated"}},"exampleType":"generated"},"responses":{"c1bb2a53-fc90-4268-881f-be1ec68af58e":{"description":"Scan created in `receiving`; keep set listed for transfer.","content":{"application/json":{"schema":{"type":"object","required":["scan"],"properties":{"scan":{"type":"object","required":["id","project_id","project","name","status","archive_filename","archive_sha256","archive_size_bytes","source_ref","files_total","files_scanned","matches_total","crypto_observations_available","created_by","created_at"],"properties":{"id":{"type":"string","format":"uuid","isRequired":true,"uniqueKey":"scan.id","typeLabel":"string\u003cuuid>"},"project_id":{"type":"string","format":"uuid","description":"The owning project. Every scan belongs to exactly one project. `project` carries the denormalised reference.","isRequired":true,"uniqueKey":"scan.project_id","typeLabel":"string\u003cuuid>"},"project":{"type":"object","description":"Light reference to a linked project (denormalised for list rendering).","required":["id","slug","name"],"properties":{"id":{"type":"string","format":"uuid","isRequired":true,"uniqueKey":"scan.project.id","typeLabel":"string\u003cuuid>"},"slug":{"type":"string","isRequired":true,"uniqueKey":"scan.project.slug","typeLabel":"string"},"name":{"type":"string","isRequired":true,"uniqueKey":"scan.project.name","typeLabel":"string"}},"isRequired":true,"uniqueKey":"scan.project","typeLabel":"object"},"name":{"type":"string","description":"Defaults to the uploaded archive's filename.","isRequired":true,"uniqueKey":"scan.name","typeLabel":"string"},"status":{"type":"string","enum":["pending","receiving","extracting","scanning","importing","completed","failed","cancelled"],"description":"Lifecycle states:\n- `pending` — the scan exists; receiving its input has not started or finished\n- `receiving` — the scan's input is being transferred (files, a repository, or an archive)\n- `extracting` — an uploaded archive is being unpacked\n- `scanning` — the scanners are running\n- `importing` — an uploaded SBOM document is being read; SBOM imports skip `receiving` and `scanning`\n- `completed` — the scan finished and its results are available\n- `failed` — terminal failure; `error_code` and `error_message` are set\n- `cancelled` — terminal cancellation; no findings, gate result, or posture is published","isRequired":true,"uniqueKey":"scan.status","typeLabel":"enum\u003cstring>"},"archive_filename":{"type":"string","isRequired":true,"uniqueKey":"scan.archive_filename","typeLabel":"string"},"archive_sha256":{"type":"string","isRequired":true,"uniqueKey":"scan.archive_sha256","typeLabel":"string"},"archive_size_bytes":{"type":"integer","format":"int64","isRequired":true,"uniqueKey":"scan.archive_size_bytes","typeLabel":"integer\u003cint64>"},"source_ref":{"type":"string","description":"SourceStorage opaque key for the retained keep-set archive. While `status` is `receiving`, this MAY be the placeholder `pending`.","isRequired":true,"uniqueKey":"scan.source_ref","typeLabel":"string"},"files_total":{"type":"integer","description":"Populated after extraction.","isRequired":true,"uniqueKey":"scan.files_total","typeLabel":"integer"},"files_scanned":{"type":"integer","description":"Updated during the scanning phase.","isRequired":true,"uniqueKey":"scan.files_scanned","typeLabel":"integer"},"matches_total":{"type":"integer","description":"Count of rows in scans.file_components for this scan.","isRequired":true,"uniqueKey":"scan.matches_total","typeLabel":"integer"},"crypto_observations_available":{"type":"boolean","description":"True when this scan has an immutable crypto observation marker. Clients use this authoritative flag to decide whether a crypto diff can be requested; posture history is a derived projection.","isRequired":true,"uniqueKey":"scan.crypto_observations_available","typeLabel":"boolean"},"created_by":{"type":"object","description":"Who submitted this scan.","required":["kind","id"],"properties":{"kind":{"type":"string","enum":["user","api_key","integration","worker"],"description":"The kind of identity that submitted the scan. `integration` is a provider Connection (a GitHub App installation); `worker` is an internal job such as the reconcile sweep.","isRequired":true,"uniqueKey":"scan.created_by.kind","typeLabel":"enum\u003cstring>"},"id":{"type":"string","format":"uuid","description":"The actor's row id — a user id, an API-key id, a Connection id or the internal job id, per `kind`. Not a foreign key to `users`.","isRequired":true,"uniqueKey":"scan.created_by.id","typeLabel":"string\u003cuuid>"}},"isRequired":true,"uniqueKey":"scan.created_by","typeLabel":"object"},"created_at":{"type":"string","format":"date-time","isRequired":true,"uniqueKey":"scan.created_at","typeLabel":"string\u003cdate-time>"},"intent_hash":{"oneOf":[{"type":"string","description":"Server-computed Scan Intent identity; clients never supply it.","uniqueKey":"scan.intent_hash.oneOf.0","typeLabel":"string"},{"type":"null","description":"Server-computed Scan Intent identity; clients never supply it.","uniqueKey":"scan.intent_hash.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.intent_hash","typeLabel":"string | null"},"reused":{"type":"boolean","description":"True when this submission trigger reused an existing eligible scan.","uniqueKey":"scan.reused","typeLabel":"boolean"},"rerun_of":{"oneOf":[{"type":"string","format":"uuid","description":"The prior scan explicitly superseded by this rerun, when applicable.","uniqueKey":"scan.rerun_of.oneOf.0","typeLabel":"string\u003cuuid>"},{"type":"null","format":"uuid","description":"The prior scan explicitly superseded by this rerun, when applicable.","uniqueKey":"scan.rerun_of.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.rerun_of","typeLabel":"string\u003cuuid> | null"},"cancellation_reason":{"oneOf":[{"type":"string","description":"Why a scan reached the terminal `cancelled` state.","enum":["superseded","user_requested","timeout","project_disconnected","change_request_closed"],"uniqueKey":"scan.cancellation_reason.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","uniqueKey":"scan.cancellation_reason.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.cancellation_reason","typeLabel":"enum\u003cstring> | null"},"superseded_by_scan_id":{"oneOf":[{"type":"string","format":"uuid","description":"Replacement scan that superseded this cancelled scan.","uniqueKey":"scan.superseded_by_scan_id.oneOf.0","typeLabel":"string\u003cuuid>"},{"type":"null","format":"uuid","description":"Replacement scan that superseded this cancelled scan.","uniqueKey":"scan.superseded_by_scan_id.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.superseded_by_scan_id","typeLabel":"string\u003cuuid> | null"},"triggers":{"oneOf":[{"type":"array","items":{"type":"object","required":["id","scan_id","outcome","producer","created_at"],"properties":{"id":{"type":"string","format":"uuid","isRequired":true,"uniqueKey":"scan.triggers.oneOf.0.items.[INDEX].id","typeLabel":"string\u003cuuid>"},"scan_id":{"type":"string","format":"uuid","isRequired":true,"uniqueKey":"scan.triggers.oneOf.0.items.[INDEX].scan_id","typeLabel":"string\u003cuuid>"},"outcome":{"type":"string","enum":["created","reused","superseded"],"description":"The append-only result of a submission trigger.","isRequired":true,"uniqueKey":"scan.triggers.oneOf.0.items.[INDEX].outcome","typeLabel":"enum\u003cstring>"},"producer":{"type":"string","enum":["ui_upload","connected_repo","pr_ci","cli","pre_commit","mcp","sbom_import"],"description":"The surface that submitted the scan (GLOSSARY \"Producer\"). Derived from the authenticated actor wherever the actor determines it; a client-declared value the actor cannot legitimately produce is overwritten server-side, never rejected.\n\n`pre_commit` and `mcp` classify the run as a Self-check: it runs the same scanners, enrichments and policy engine and shows results, verdict and a deep link under the Project, but materializes no Findings, never touches posture, is held at `partial` coverage, is purged 30 days after creation and leaves a `selfcheck.*` decision log instead of `finding.detected`.\n\nA Self-check is read through `/v1/self-checks`, not `/v1/scans`: the Scan endpoints return governed Scans only.","isRequired":true,"uniqueKey":"scan.triggers.oneOf.0.items.[INDEX].producer","typeLabel":"enum\u003cstring>"},"created_at":{"type":"string","format":"date-time","isRequired":true,"uniqueKey":"scan.triggers.oneOf.0.items.[INDEX].created_at","typeLabel":"string\u003cdate-time>"}},"uniqueKey":"scan.triggers.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"Append-only submission triggers associated with this scan.","uniqueKey":"scan.triggers.oneOf.0","typeLabel":"object[]"},{"type":"null","items":{"type":"object","required":["id","scan_id","outcome","producer","created_at"],"properties":{"id":{"type":"string","format":"uuid"},"scan_id":{"type":"string","format":"uuid"},"outcome":{"type":"string","enum":["created","reused","superseded"],"description":"The append-only result of a submission trigger."},"producer":{"type":"string","enum":["ui_upload","connected_repo","pr_ci","cli","pre_commit","mcp","sbom_import"],"description":"The surface that submitted the scan (GLOSSARY \"Producer\"). Derived from the authenticated actor wherever the actor determines it; a client-declared value the actor cannot legitimately produce is overwritten server-side, never rejected.\n\n`pre_commit` and `mcp` classify the run as a Self-check: it runs the same scanners, enrichments and policy engine and shows results, verdict and a deep link under the Project, but materializes no Findings, never touches posture, is held at `partial` coverage, is purged 30 days after creation and leaves a `selfcheck.*` decision log instead of `finding.detected`.\n\nA Self-check is read through `/v1/self-checks`, not `/v1/scans`: the Scan endpoints return governed Scans only."},"created_at":{"type":"string","format":"date-time"}}},"description":"Append-only submission triggers associated with this scan.","uniqueKey":"scan.triggers.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.triggers","typeLabel":"object[] | null"},"error_code":{"oneOf":[{"type":"string","uniqueKey":"scan.error_code.oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"scan.error_code.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.error_code","typeLabel":"string | null"},"error_message":{"oneOf":[{"type":"string","uniqueKey":"scan.error_message.oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"scan.error_message.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.error_message","typeLabel":"string | null"},"source_type":{"type":"string","enum":["upload","git","sbom","model"],"description":"Where the scan's archive came from. `sbom` marks a scan created by importing a foreign SBOM document rather than scanning source code — it always carries `coverage: partial`. `model` marks the scan of an uploaded Model.","uniqueKey":"scan.source_type","typeLabel":"enum\u003cstring>"},"repo_full_name":{"oneOf":[{"type":"string","description":"Git provenance (git-sync GS-5) — set on git-sourced scans.","uniqueKey":"scan.repo_full_name.oneOf.0","typeLabel":"string"},{"type":"null","description":"Git provenance (git-sync GS-5) — set on git-sourced scans.","uniqueKey":"scan.repo_full_name.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.repo_full_name","typeLabel":"string | null"},"git_ref":{"oneOf":[{"type":"string","description":"The ref that was requested (branch/tag); null when the default branch was used implicitly.","uniqueKey":"scan.git_ref.oneOf.0","typeLabel":"string"},{"type":"null","description":"The ref that was requested (branch/tag); null when the default branch was used implicitly.","uniqueKey":"scan.git_ref.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.git_ref","typeLabel":"string | null"},"commit_sha":{"oneOf":[{"type":"string","description":"The commit the archive was fetched at (resolved before download).","uniqueKey":"scan.commit_sha.oneOf.0","typeLabel":"string"},{"type":"null","description":"The commit the archive was fetched at (resolved before download).","uniqueKey":"scan.commit_sha.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.commit_sha","typeLabel":"string | null"},"result_ref":{"oneOf":[{"type":"string","description":"SourceStorage opaque key for result.json (set on completion).","uniqueKey":"scan.result_ref.oneOf.0","typeLabel":"string"},{"type":"null","description":"SourceStorage opaque key for result.json (set on completion).","uniqueKey":"scan.result_ref.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.result_ref","typeLabel":"string | null"},"crypto_diff_baseline":{"oneOf":[{"type":"object","description":"The nearest earlier completed scan with full coverage and a full immutable crypto observation, when this scan is also eligible. Ineligible intervening scans are skipped. Present on scan detail responses only. Null means no valid crypto comparison exists.","required":["id","name"],"properties":{"id":{"type":"string","format":"uuid","isRequired":true,"uniqueKey":"scan.crypto_diff_baseline.oneOf.0.id","typeLabel":"string\u003cuuid>"},"name":{"type":"string","description":"Human-readable name of the comparison scan.","isRequired":true,"uniqueKey":"scan.crypto_diff_baseline.oneOf.0.name","typeLabel":"string"}},"uniqueKey":"scan.crypto_diff_baseline.oneOf.0","typeLabel":"object"},{"type":"null","uniqueKey":"scan.crypto_diff_baseline.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.crypto_diff_baseline","typeLabel":"object | null"},"scanner_version":{"oneOf":[{"type":"string","uniqueKey":"scan.scanner_version.oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"scan.scanner_version.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.scanner_version","typeLabel":"string | null"},"scanner_api_url":{"oneOf":[{"type":"string","uniqueKey":"scan.scanner_api_url.oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"scan.scanner_api_url.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.scanner_api_url","typeLabel":"string | null"},"scanner_session_id":{"oneOf":[{"type":"string","format":"uuid","uniqueKey":"scan.scanner_session_id.oneOf.0","typeLabel":"string\u003cuuid>"},{"type":"null","format":"uuid","uniqueKey":"scan.scanner_session_id.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.scanner_session_id","typeLabel":"string\u003cuuid> | null"},"started_at":{"oneOf":[{"type":"string","format":"date-time","uniqueKey":"scan.started_at.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","uniqueKey":"scan.started_at.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.started_at","typeLabel":"string\u003cdate-time> | null"},"finished_at":{"oneOf":[{"type":"string","format":"date-time","uniqueKey":"scan.finished_at.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","uniqueKey":"scan.finished_at.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.finished_at","typeLabel":"string\u003cdate-time> | null"},"enrichments":{"oneOf":[{"type":"array","items":{"type":"string","enum":["vulnerabilities","licenses"],"description":"Identifiers for optional PURL-driven enrichments. `matching` is the always-on core engine and is not an enrichment key. Dependency inventory is produced by the always-on dependency stage. Omitting `enrichments` defaults to [\"vulnerabilities\",\"licenses\"].","uniqueKey":"scan.enrichments.oneOf.0.items.[INDEX]","typeLabel":"enum\u003cstring>"},"description":"The canonical resolved PURL enrichment list. Null only for scans created before optional enrichments were persisted.","uniqueKey":"scan.enrichments.oneOf.0","typeLabel":"enum\u003cstring>[]"},{"type":"null","items":{"type":"string","enum":["vulnerabilities","licenses"],"description":"Identifiers for optional PURL-driven enrichments. `matching` is the always-on core engine and is not an enrichment key. Dependency inventory is produced by the always-on dependency stage. Omitting `enrichments` defaults to [\"vulnerabilities\",\"licenses\"]."},"description":"The canonical resolved PURL enrichment list. Null only for scans created before optional enrichments were persisted.","uniqueKey":"scan.enrichments.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.enrichments","typeLabel":"enum\u003cstring>[] | null"},"stages":{"oneOf":[{"type":"array","items":{"type":"object","description":"Progress for a single enrichment stage within a scan pipeline run. Rows are written by each Enricher phase; the UI polls `scan.stages[]` to render the staged-progress panel.","required":["name","state","items_processed","items_total"],"properties":{"name":{"type":"string","description":"Stage key — matches the enrichment key or a core phase name (e.g. \"receiving\", \"extracting\", \"matching\"). For `receiving`, `items_*` are keep-set files (accepted vs planned).","isRequired":true,"uniqueKey":"scan.stages.oneOf.0.items.[INDEX].name","typeLabel":"string"},"state":{"type":"string","enum":["pending","running","completed","failed","skipped"],"description":"Current lifecycle state of this stage.","isRequired":true,"uniqueKey":"scan.stages.oneOf.0.items.[INDEX].state","typeLabel":"enum\u003cstring>"},"items_processed":{"type":"integer","description":"Number of items processed so far. For `receiving`, count of keep-set files accepted into the cursor.","isRequired":true,"uniqueKey":"scan.stages.oneOf.0.items.[INDEX].items_processed","typeLabel":"integer"},"items_total":{"type":"integer","description":"Total items expected for this stage (0 when unknown). For `receiving`, count of keep-set files returned by the keep engine.","isRequired":true,"uniqueKey":"scan.stages.oneOf.0.items.[INDEX].items_total","typeLabel":"integer"},"started_at":{"oneOf":[{"type":"string","format":"date-time","description":"When the stage entered the running state; null until then.","uniqueKey":"scan.stages.oneOf.0.items.[INDEX].started_at.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"When the stage entered the running state; null until then.","uniqueKey":"scan.stages.oneOf.0.items.[INDEX].started_at.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.stages.oneOf.0.items.[INDEX].started_at","typeLabel":"string\u003cdate-time> | null"},"finished_at":{"oneOf":[{"type":"string","format":"date-time","description":"When the stage reached a terminal state (completed/failed/skipped); null while running.","uniqueKey":"scan.stages.oneOf.0.items.[INDEX].finished_at.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"When the stage reached a terminal state (completed/failed/skipped); null while running.","uniqueKey":"scan.stages.oneOf.0.items.[INDEX].finished_at.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.stages.oneOf.0.items.[INDEX].finished_at","typeLabel":"string\u003cdate-time> | null"},"warnings":{"oneOf":[{"type":"array","items":{"type":"string","uniqueKey":"scan.stages.oneOf.0.items.[INDEX].warnings.oneOf.0.items.[INDEX]","typeLabel":"string"},"description":"Non-fatal warning messages, populated on failed or degraded stages.","uniqueKey":"scan.stages.oneOf.0.items.[INDEX].warnings.oneOf.0","typeLabel":"string[]"},{"type":"null","items":{"type":"string"},"description":"Non-fatal warning messages, populated on failed or degraded stages.","uniqueKey":"scan.stages.oneOf.0.items.[INDEX].warnings.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.stages.oneOf.0.items.[INDEX].warnings","typeLabel":"string[] | null"}},"uniqueKey":"scan.stages.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"Staged progress for each enrichment phase. Null when no stage rows exist yet (scan still in core matching phase). Non-null once the first stage row has been written. Populated by the enrichment-stage framework.","uniqueKey":"scan.stages.oneOf.0","typeLabel":"object[]"},{"type":"null","items":{"type":"object","description":"Progress for a single enrichment stage within a scan pipeline run. Rows are written by each Enricher phase; the UI polls `scan.stages[]` to render the staged-progress panel.","required":["name","state","items_processed","items_total"],"properties":{"name":{"type":"string","description":"Stage key — matches the enrichment key or a core phase name (e.g. \"receiving\", \"extracting\", \"matching\"). For `receiving`, `items_*` are keep-set files (accepted vs planned)."},"state":{"type":"string","enum":["pending","running","completed","failed","skipped"],"description":"Current lifecycle state of this stage."},"items_processed":{"type":"integer","description":"Number of items processed so far. For `receiving`, count of keep-set files accepted into the cursor."},"items_total":{"type":"integer","description":"Total items expected for this stage (0 when unknown). For `receiving`, count of keep-set files returned by the keep engine."},"started_at":{"oneOf":[{"type":"string","format":"date-time","description":"When the stage entered the running state; null until then."},{"type":"null","format":"date-time","description":"When the stage entered the running state; null until then."}]},"finished_at":{"oneOf":[{"type":"string","format":"date-time","description":"When the stage reached a terminal state (completed/failed/skipped); null while running."},{"type":"null","format":"date-time","description":"When the stage reached a terminal state (completed/failed/skipped); null while running."}]},"warnings":{"oneOf":[{"type":"array","items":{"type":"string"},"description":"Non-fatal warning messages, populated on failed or degraded stages."},{"type":"null","items":{"type":"string"},"description":"Non-fatal warning messages, populated on failed or degraded stages."}]}}},"description":"Staged progress for each enrichment phase. Null when no stage rows exist yet (scan still in core matching phase). Non-null once the first stage row has been written. Populated by the enrichment-stage framework.","uniqueKey":"scan.stages.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.stages","typeLabel":"object[] | null"},"added_count":{"oneOf":[{"type":"integer","description":"Number of findings added in this reconciliation run (APP-5 S3.1). Zero is distinct from null — zero means reconciliation ran and found no new additions.","uniqueKey":"scan.added_count.oneOf.0","typeLabel":"integer"},{"type":"null","description":"Number of findings added in this reconciliation run (APP-5 S3.1). Zero is distinct from null — zero means reconciliation ran and found no new additions.","uniqueKey":"scan.added_count.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.added_count","typeLabel":"integer | null"},"persisted_count":{"oneOf":[{"type":"integer","description":"Number of prior findings that were reaffirmed in this scan (APP-5 S3.1).","uniqueKey":"scan.persisted_count.oneOf.0","typeLabel":"integer"},{"type":"null","description":"Number of prior findings that were reaffirmed in this scan (APP-5 S3.1).","uniqueKey":"scan.persisted_count.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.persisted_count","typeLabel":"integer | null"},"absent_count":{"oneOf":[{"type":"integer","description":"Number of previously present findings marked absent by this scan (APP-5 S3.1).","uniqueKey":"scan.absent_count.oneOf.0","typeLabel":"integer"},{"type":"null","description":"Number of previously present findings marked absent by this scan (APP-5 S3.1).","uniqueKey":"scan.absent_count.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.absent_count","typeLabel":"integer | null"},"coverage":{"oneOf":[{"type":"string","description":"Whether this scan covered the entire codebase (full) or only a partial slice such as a PR diff or agent working set (partial).","enum":["full","partial"],"uniqueKey":"scan.coverage.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","uniqueKey":"scan.coverage.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.coverage","typeLabel":"enum\u003cstring> | null"},"result_scope":{"type":"string","enum":["project","scan","model"],"description":"Who owns this scan's results. `project`: its findings, files and verdicts are the project's. `scan`: they belong to this scan alone, as every pull request scan's do; project posture does not change until the code reaches the default branch, and a finding the pull request introduced cannot be triaged yet. `model`: the scan of an uploaded Model; its findings are the project's, but the scan never stands for the project. Absent on a scan created before the field existed; read that as `project`.","uniqueKey":"scan.result_scope","typeLabel":"enum\u003cstring>"},"scan_context":{"oneOf":[{"type":"object","description":"The submission provenance persisted with this scan, with `producer` and `coverage` as the server resolved them.","properties":{"producer":{"type":"string","enum":["ui_upload","connected_repo","pr_ci","cli","pre_commit","mcp","sbom_import"],"description":"The surface that submitted the scan (GLOSSARY \"Producer\"). Derived from the authenticated actor wherever the actor determines it; a client-declared value the actor cannot legitimately produce is overwritten server-side, never rejected.\n\n`pre_commit` and `mcp` classify the run as a Self-check: it runs the same scanners, enrichments and policy engine and shows results, verdict and a deep link under the Project, but materializes no Findings, never touches posture, is held at `partial` coverage, is purged 30 days after creation and leaves a `selfcheck.*` decision log instead of `finding.detected`.\n\nA Self-check is read through `/v1/self-checks`, not `/v1/scans`: the Scan endpoints return governed Scans only.","uniqueKey":"scan.scan_context.oneOf.0.producer","typeLabel":"enum\u003cstring>"},"coverage":{"type":"string","description":"The coverage the client intends. The server validates it: a downgrade to `partial` is honoured, a promotion to `full` is rejected with `coverage_promotion_rejected`.","enum":["full","partial"],"uniqueKey":"scan.scan_context.oneOf.0.coverage","typeLabel":"enum\u003cstring>"},"provider":{"oneOf":[{"type":"string","description":"The source-code provider the submission originated from, such as github or gitlab. Any connected provider's name.","pattern":"^[a-z][a-z0-9-]{0,31}$","uniqueKey":"scan.scan_context.oneOf.0.provider.oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"scan.scan_context.oneOf.0.provider.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.scan_context.oneOf.0.provider","typeLabel":"string | null"},"repository":{"oneOf":[{"type":"object","description":"The provider repository the submitted code belongs to.","required":["external_id","full_name"],"properties":{"external_id":{"type":"string","description":"The provider's immutable repository id (GitHub's numeric repo id, GitLab's project id) as a string. Survives rename and transfer.","isRequired":true,"uniqueKey":"scan.scan_context.oneOf.0.repository.oneOf.0.external_id","typeLabel":"string"},"full_name":{"type":"string","description":"Display path in `owner/name` form. Mutable — never a match key.","isRequired":true,"uniqueKey":"scan.scan_context.oneOf.0.repository.oneOf.0.full_name","typeLabel":"string"}},"uniqueKey":"scan.scan_context.oneOf.0.repository.oneOf.0","typeLabel":"object"},{"type":"null","uniqueKey":"scan.scan_context.oneOf.0.repository.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.scan_context.oneOf.0.repository","typeLabel":"object | null"},"change_request":{"oneOf":[{"type":"object","description":"The pull/merge request the submission belongs to. An *identified* one makes the scan `partial` — at least one of `number`, `url`, `base_sha`, `head_sha` or `head_ref` must be set for it to count. An empty object narrows nothing, because a client that had been silently narrowed could not ask for `full` again without deleting the provenance it wanted.\n\nNote this applies to a `git` submission too, not only a diff upload. A pipeline that wants full-coverage posture submits without change-request provenance.","properties":{"number":{"type":"integer","description":"Provider-visible PR/MR number.","uniqueKey":"scan.scan_context.oneOf.0.change_request.oneOf.0.number","typeLabel":"integer"},"url":{"type":"string","description":"Deep link back to the change request.","uniqueKey":"scan.scan_context.oneOf.0.change_request.oneOf.0.url","typeLabel":"string"},"base_sha":{"type":"string","description":"The commit the change request is based on.","uniqueKey":"scan.scan_context.oneOf.0.change_request.oneOf.0.base_sha","typeLabel":"string"},"head_sha":{"type":"string","description":"The commit the submitted code was taken at.","uniqueKey":"scan.scan_context.oneOf.0.change_request.oneOf.0.head_sha","typeLabel":"string"},"base_ref":{"type":"string","description":"The branch the change request targets.","uniqueKey":"scan.scan_context.oneOf.0.change_request.oneOf.0.base_ref","typeLabel":"string"},"head_ref":{"type":"string","description":"The change request's source branch.","uniqueKey":"scan.scan_context.oneOf.0.change_request.oneOf.0.head_ref","typeLabel":"string"}},"uniqueKey":"scan.scan_context.oneOf.0.change_request.oneOf.0","typeLabel":"object"},{"type":"null","uniqueKey":"scan.scan_context.oneOf.0.change_request.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.scan_context.oneOf.0.change_request","typeLabel":"object | null"},"commit_sha":{"oneOf":[{"type":"string","uniqueKey":"scan.scan_context.oneOf.0.commit_sha.oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"scan.scan_context.oneOf.0.commit_sha.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.scan_context.oneOf.0.commit_sha","typeLabel":"string | null"},"branch":{"oneOf":[{"type":"string","uniqueKey":"scan.scan_context.oneOf.0.branch.oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"scan.scan_context.oneOf.0.branch.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.scan_context.oneOf.0.branch","typeLabel":"string | null"},"run":{"oneOf":[{"type":"object","description":"The CI job that submitted the scan — a link back, never a match key.","properties":{"ci_system":{"type":"string","description":"e.g. `github_actions`, `gitlab_ci`, `jenkins`.","uniqueKey":"scan.scan_context.oneOf.0.run.oneOf.0.ci_system","typeLabel":"string"},"url":{"type":"string","description":"Deep link to the CI run.","uniqueKey":"scan.scan_context.oneOf.0.run.oneOf.0.url","typeLabel":"string"},"external_id":{"type":"string","description":"The CI system's own run identifier.","uniqueKey":"scan.scan_context.oneOf.0.run.oneOf.0.external_id","typeLabel":"string"}},"uniqueKey":"scan.scan_context.oneOf.0.run.oneOf.0","typeLabel":"object"},{"type":"null","uniqueKey":"scan.scan_context.oneOf.0.run.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.scan_context.oneOf.0.run","typeLabel":"object | null"}},"uniqueKey":"scan.scan_context.oneOf.0","typeLabel":"object"},{"type":"null","uniqueKey":"scan.scan_context.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.scan_context","typeLabel":"object | null"},"effective":{"oneOf":[{"type":"object","description":"What the server actually resolved at submit time — scanners, enrichments, coverage and the policy snapshot.","required":["scanners","enrichments","coverage","policy_snapshot"],"properties":{"scanners":{"type":"array","items":{"type":"string","enum":["oss","crypto","ai"],"description":"A scanner phase selected for source-code scan compute. `ai` is AI provenance. A Self-check does not run it, and an explicit request for it on a Self-check answers 400 `invalid_scanners`.","uniqueKey":"scan.effective.oneOf.0.scanners.items.[INDEX]","typeLabel":"enum\u003cstring>"},"isRequired":true,"uniqueKey":"scan.effective.oneOf.0.scanners","typeLabel":"enum\u003cstring>[]"},"enrichments":{"type":"array","items":{"type":"string","enum":["vulnerabilities","licenses"],"description":"Identifiers for optional PURL-driven enrichments. `matching` is the always-on core engine and is not an enrichment key. Dependency inventory is produced by the always-on dependency stage. Omitting `enrichments` defaults to [\"vulnerabilities\",\"licenses\"].","uniqueKey":"scan.effective.oneOf.0.enrichments.items.[INDEX]","typeLabel":"enum\u003cstring>"},"isRequired":true,"uniqueKey":"scan.effective.oneOf.0.enrichments","typeLabel":"enum\u003cstring>[]"},"coverage":{"type":"string","enum":["full","partial"],"description":"A scan's reach. `full` may add, reaffirm and mark-absent findings and so mutates canonical posture; `partial` only adds or updates what it touched. Coverage is a server rule: a client may downgrade to `partial` but never promote to `full`.","isRequired":true,"uniqueKey":"scan.effective.oneOf.0.coverage","typeLabel":"enum\u003cstring>"},"policy_snapshot":{"type":"object","description":"The set of `(policy, revision)` in force for the project when the scan was created. Immutable: later policy edits never alter it.","required":["policies"],"properties":{"policies":{"type":"array","items":{"type":"object","description":"One policy and the immutable revision it was in force at.","required":["policy_id","revision"],"properties":{"policy_id":{"type":"integer","format":"int64","isRequired":true,"uniqueKey":"scan.effective.oneOf.0.policy_snapshot.policies.items.[INDEX].policy_id","typeLabel":"integer\u003cint64>"},"revision":{"type":"string","description":"The policy's content hash (`sha256:\u003chex>`) — the same value the policy evaluator records as `policy_hash`.","isRequired":true,"uniqueKey":"scan.effective.oneOf.0.policy_snapshot.policies.items.[INDEX].revision","typeLabel":"string"}},"uniqueKey":"scan.effective.oneOf.0.policy_snapshot.policies.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"scan.effective.oneOf.0.policy_snapshot.policies","typeLabel":"object[]"}},"isRequired":true,"uniqueKey":"scan.effective.oneOf.0.policy_snapshot","typeLabel":"object"},"fetch_lfs_models":{"type":"boolean","description":"Immutable Git LFS download choice resolved at submission. Absent on older scans.","uniqueKey":"scan.effective.oneOf.0.fetch_lfs_models","typeLabel":"boolean"}},"uniqueKey":"scan.effective.oneOf.0","typeLabel":"object"},{"type":"null","uniqueKey":"scan.effective.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.effective","typeLabel":"object | null"},"narrowed_from_request":{"oneOf":[{"type":"array","items":{"type":"object","description":"One adjustable field the server resolved to something other than the request asked for. Non-adjustable requests are rejected with a 4xx instead of being silently narrowed.\n\nCoverage is the only adjustable field today, and its two outcomes are both terminal: a downgrade to `partial` is honoured exactly as asked, and a promotion to `full` is refused with `coverage_promotion_rejected`. So `narrowed_from_request` is empty on every submission the server currently accepts. It is populated, not omitted, because `[]` is the positive statement \"the server honoured this submission as sent\" — and because the next adjustable field reports through it.","required":["field","requested","effective","reason"],"properties":{"field":{"type":"string","enum":["coverage"],"description":"The adjustable field. `coverage` is the only one today.","isRequired":true,"uniqueKey":"scan.narrowed_from_request.oneOf.0.items.[INDEX].field","typeLabel":"enum\u003cstring>"},"requested":{"type":"string","isRequired":true,"uniqueKey":"scan.narrowed_from_request.oneOf.0.items.[INDEX].requested","typeLabel":"string"},"effective":{"type":"string","isRequired":true,"uniqueKey":"scan.narrowed_from_request.oneOf.0.items.[INDEX].effective","typeLabel":"string"},"reason":{"type":"string","description":"Machine-readable reason code for the narrowing.","isRequired":true,"uniqueKey":"scan.narrowed_from_request.oneOf.0.items.[INDEX].reason","typeLabel":"string"}},"uniqueKey":"scan.narrowed_from_request.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"The adjustable fields the server resolved to something narrower than the request asked for.","uniqueKey":"scan.narrowed_from_request.oneOf.0","typeLabel":"object[]"},{"type":"null","items":{"type":"object","description":"One adjustable field the server resolved to something other than the request asked for. Non-adjustable requests are rejected with a 4xx instead of being silently narrowed.\n\nCoverage is the only adjustable field today, and its two outcomes are both terminal: a downgrade to `partial` is honoured exactly as asked, and a promotion to `full` is refused with `coverage_promotion_rejected`. So `narrowed_from_request` is empty on every submission the server currently accepts. It is populated, not omitted, because `[]` is the positive statement \"the server honoured this submission as sent\" — and because the next adjustable field reports through it.","required":["field","requested","effective","reason"],"properties":{"field":{"type":"string","enum":["coverage"],"description":"The adjustable field. `coverage` is the only one today."},"requested":{"type":"string"},"effective":{"type":"string"},"reason":{"type":"string","description":"Machine-readable reason code for the narrowing."}}},"description":"The adjustable fields the server resolved to something narrower than the request asked for.","uniqueKey":"scan.narrowed_from_request.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.narrowed_from_request","typeLabel":"object[] | null"},"gate":{"oneOf":[{"type":"string","description":"What this scan's policies decided, collapsed by precedence. Derived at read time from the evaluations this scan is anchored to plus the *current* Policy Approval overlay, so granting or revoking an approval moves the gate of the same scan while the recorded verdicts stay untouched.\n\nThe scan's own lifecycle is decided first. A scan that has not completed reports `evaluation.status: pending` and a null gate, whatever its policies concluded midway — policies are evaluated before the scan is marked complete, so a scan can hold a full set of verdicts and then fail, and its gate is `error` rather than whatever those verdicts said.\n\nNull when no gate can be attributed to the scan: while it is still running, and for a completed scan with policies in its snapshot but no recorded evaluation — which is either a scan predating the per-scan evaluation link or one whose policies were all detached before evaluation ran. Null is neither `pass` nor `none`.\n\n`GET /v1/scans/{scanId}/policy-verdicts` explains a non-null value policy by policy.\n\nDistinct from `PostureGate`, which is a project's standing rollup and carries no `require` or `error` member.","enum":["pass","warn","block","require","error","none"],"uniqueKey":"scan.gate.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","uniqueKey":"scan.gate.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.gate","typeLabel":"enum\u003cstring> | null"},"gate_reason":{"oneOf":[{"type":"string","description":"Present exactly when `gate` is.","enum":["no_policy_applies","all_policies_passed","policy_warned","approval_required","policy_blocked","missing_evidence","evaluation_failed"],"uniqueKey":"scan.gate_reason.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","uniqueKey":"scan.gate_reason.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.gate_reason","typeLabel":"enum\u003cstring> | null"},"evaluation":{"oneOf":[{"type":"object","description":"This scan's policy-evaluation state. Non-null whenever anything can be said about the evaluation — including while it is `pending`, where `gate` is null and this block is how a client learns an answer is still coming.\n\nNull only for a scan whose gate cannot be attributed at all: one created before the per-scan evaluation link existed, or one that completed with policies in its snapshot and no recorded evaluation.\n\n`policies_evaluated` and `evaluated_at` report what actually ran, whatever the status says about the gate — a scan that evaluated two policies and then failed did evaluate two policies, and `GET /v1/scans/{scanId}/policy-verdicts` lists them.","required":["status","policies_evaluated"],"properties":{"status":{"type":"string","enum":["pending","completed","failed"],"description":"Whether this scan has a policy answer yet:\n\n - `pending` — the scan has not reached policy evaluation. `gate` is null: an unfinished scan has no gate, which is not the same as passing.\n - `completed` — evaluation ran; `gate` is final for this scan and no later policy edit changes it.\n - `failed` — the scan could not produce a complete evaluation, so `gate` is `error`.","isRequired":true,"uniqueKey":"scan.evaluation.oneOf.0.status","typeLabel":"enum\u003cstring>"},"policies_evaluated":{"type":"integer","minimum":0,"description":"How many policies this scan is linked to an evaluation for, not counting the ones that did not apply to it (verdict `not_applicable`).","isRequired":true,"uniqueKey":"scan.evaluation.oneOf.0.policies_evaluated","typeLabel":"integer"},"evaluated_at":{"oneOf":[{"type":"string","format":"date-time","description":"When the scan-anchored evaluation ran — the earliest `started_at` among the evaluations this scan is linked to. Null whenever none is recorded: a scan that has not reached policy evaluation, and a completed scan no policy was in force for.","uniqueKey":"scan.evaluation.oneOf.0.evaluated_at.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"When the scan-anchored evaluation ran — the earliest `started_at` among the evaluations this scan is linked to. Null whenever none is recorded: a scan that has not reached policy evaluation, and a completed scan no policy was in force for.","uniqueKey":"scan.evaluation.oneOf.0.evaluated_at.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.evaluation.oneOf.0.evaluated_at","typeLabel":"string\u003cdate-time> | null"}},"uniqueKey":"scan.evaluation.oneOf.0","typeLabel":"object"},{"type":"null","uniqueKey":"scan.evaluation.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.evaluation","typeLabel":"object | null"},"codebase_divergence":{"oneOf":[{"type":"object","description":"Read-time divergence result. Null for git-sourced scans and when the project has no prior inventory (first scan). Non-null only for upload scans that have been compared against an existing project inventory.","required":["is_divergent","overlap_pct","prior_components"],"properties":{"is_divergent":{"type":"boolean","description":"True when the project has a sufficient prior inventory AND this scan's component overlap is below the low-overlap threshold. A non-blocking warning: the scan is still accepted and reconciled normally.","isRequired":true,"uniqueKey":"scan.codebase_divergence.oneOf.0.is_divergent","typeLabel":"boolean"},"overlap_pct":{"type":"number","format":"float","minimum":0,"maximum":1,"description":"Jaccard similarity coefficient (|A ∩ B| / |A ∪ B|) over component PURL sets: 1.0 = full overlap, 0.0 = no overlap.","isRequired":true,"uniqueKey":"scan.codebase_divergence.oneOf.0.overlap_pct","typeLabel":"number\u003cfloat>"},"prior_components":{"type":"integer","description":"Number of distinct component PURLs in the project's prior inventory (from this project's other completed scans). 0 means this is the first scan.","isRequired":true,"uniqueKey":"scan.codebase_divergence.oneOf.0.prior_components","typeLabel":"integer"}},"uniqueKey":"scan.codebase_divergence.oneOf.0","typeLabel":"object"},{"type":"null","uniqueKey":"scan.codebase_divergence.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.codebase_divergence","typeLabel":"object | null"},"publication":{"oneOf":[{"type":"object","description":"Whether the provider has heard this scan's verdict. A pull request scan submitted through a provider Connection places an `Earnie` check on its head SHA; this block is the outbox state of that placement. Publication state never changes a verdict: the gate above is what Earnie decided, this is whether GitHub was told.\n\nAbsent for scans that publish nothing — uploads, CLI scans of a branch — and when no Connection is configured.","required":["state","targets"],"properties":{"state":{"type":"string","description":"The targets collapsed into the one state a client acts on: `degraded` if any target is (it is the only state that needs a human), else `pending` while any is in flight, else `published` when every open target published; a fully closed set reports `superseded` or `cancelled`.","enum":["pending","publishing","published","degraded","superseded","cancelled"],"isRequired":true,"uniqueKey":"scan.publication.oneOf.0.state","typeLabel":"enum\u003cstring>"},"targets":{"type":"array","items":{"type":"object","required":["target","state","attempts","revision"],"properties":{"revision":{"type":"integer","format":"int64","description":"How many times this placement's CONTENT has been revised. It starts at 1 and increases whenever Earnie asks for something different to be placed at the same target — a new gate after a Policy Approval, or the non-conclusive `base_outdated` verdict after the default branch moved beneath the pull request. Re-requesting identical content is a no-op and does not move it.\n\nIt is how a republication is observed from outside: the target is the same row, the state returns to `pending`, and this number is what says the content behind it changed rather than a retry of the same content. It is also the fence every terminal outbox write is conditioned on, so a slow worker can never record a verdict for content that has already been superseded.","isRequired":true,"uniqueKey":"scan.publication.oneOf.0.targets.items.[INDEX].revision","typeLabel":"integer\u003cint64>"},"target":{"type":"string","enum":["check","summary_comment","review"],"description":"One placement of the scan outcome in the provider. `check` (the `Earnie` check run per head SHA), `summary_comment` (one Earnie-owned comment per pull request, edited in place), and `review` (one `COMMENT` review per scan with inline finding comments) all ship.","isRequired":true,"uniqueKey":"scan.publication.oneOf.0.targets.items.[INDEX].target","typeLabel":"enum\u003cstring>"},"state":{"type":"string","enum":["pending","publishing","published","degraded","superseded","cancelled"],"description":"- `pending` / `publishing` — the provider has not accepted the current content yet; retries are automatic (backoff with jitter, at most eight attempts over roughly two hours).\n - `published` — the provider holds the current content.\n - `degraded` — a permanent provider answer (401/403/404/410/422) or the retry budget ran out. Only the explicit **Retry publication** action re-opens it; nothing re-scans.\n - `superseded` — a newer head replaced the scan before this publication reached the provider.\n - `cancelled` — reserved for a scan cancelled before it published; today a user-cancelled or idle-timed-out scan republishes its check with a `cancelled` conclusion instead (the row itself stays `published`), so this state does not appear yet.","isRequired":true,"uniqueKey":"scan.publication.oneOf.0.targets.items.[INDEX].state","typeLabel":"enum\u003cstring>"},"attempts":{"type":"integer","description":"Provider attempts spent on the current content.","isRequired":true,"uniqueKey":"scan.publication.oneOf.0.targets.items.[INDEX].attempts","typeLabel":"integer"},"provider_ref":{"type":"string","description":"The provider's id for the placed resource (the check run id, comment id, or review id), once known. A cache: idempotency finds Earnie's own resource before writing, so a lost reference never duplicates a placement.","uniqueKey":"scan.publication.oneOf.0.targets.items.[INDEX].provider_ref","typeLabel":"string"},"error_class":{"type":"string","enum":["retryable","permanent"],"description":"Present after a failure. `retryable` (transport, 5xx, 429) is retried automatically; `permanent` degrades immediately, and a 401 or 403 also triggers the Connection health check.","uniqueKey":"scan.publication.oneOf.0.targets.items.[INDEX].error_class","typeLabel":"enum\u003cstring>"},"last_error":{"type":"string","description":"The most recent provider failure, sanitized.","uniqueKey":"scan.publication.oneOf.0.targets.items.[INDEX].last_error","typeLabel":"string"},"next_attempt_at":{"type":"string","format":"date-time","description":"When the next automatic attempt is due, while `pending`.","uniqueKey":"scan.publication.oneOf.0.targets.items.[INDEX].next_attempt_at","typeLabel":"string\u003cdate-time>"},"published_at":{"type":"string","format":"date-time","uniqueKey":"scan.publication.oneOf.0.targets.items.[INDEX].published_at","typeLabel":"string\u003cdate-time>"},"updated_at":{"type":"string","format":"date-time","uniqueKey":"scan.publication.oneOf.0.targets.items.[INDEX].updated_at","typeLabel":"string\u003cdate-time>"}},"uniqueKey":"scan.publication.oneOf.0.targets.items.[INDEX]","typeLabel":"object"},"description":"One row per target, delivery priority order.","isRequired":true,"uniqueKey":"scan.publication.oneOf.0.targets","typeLabel":"object[]"}},"uniqueKey":"scan.publication.oneOf.0","typeLabel":"object"},{"type":"null","uniqueKey":"scan.publication.oneOf.1","typeLabel":"null"}],"uniqueKey":"scan.publication","typeLabel":"object | null"}},"isRequired":true,"uniqueKey":"scan","typeLabel":"object"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"scan":{"id":"3c90c3cc-0d44-4b50-8888-8dd25736052a","project_id":"3c90c3cc-0d44-4b50-8888-8dd25736052a","project":{"id":"3c90c3cc-0d44-4b50-8888-8dd25736052a","slug":"\u003cstring>","name":"\u003cstring>"},"name":"\u003cstring>","status":"pending","archive_filename":"\u003cstring>","archive_sha256":"\u003cstring>","archive_size_bytes":123,"source_ref":"\u003cstring>","files_total":123,"files_scanned":123,"matches_total":123,"crypto_observations_available":true,"created_by":{"kind":"user","id":"3c90c3cc-0d44-4b50-8888-8dd25736052a"},"created_at":"2023-11-07T05:31:56Z","intent_hash":"\u003cstring>","reused":true,"rerun_of":"3c90c3cc-0d44-4b50-8888-8dd25736052a","cancellation_reason":"superseded","superseded_by_scan_id":"3c90c3cc-0d44-4b50-8888-8dd25736052a","triggers":[{"id":"3c90c3cc-0d44-4b50-8888-8dd25736052a","scan_id":"3c90c3cc-0d44-4b50-8888-8dd25736052a","outcome":"created","producer":"ui_upload","created_at":"2023-11-07T05:31:56Z"}],"error_code":"\u003cstring>","error_message":"\u003cstring>","source_type":"upload","repo_full_name":"\u003cstring>","git_ref":"\u003cstring>","commit_sha":"\u003cstring>","result_ref":"\u003cstring>","crypto_diff_baseline":{"id":"3c90c3cc-0d44-4b50-8888-8dd25736052a","name":"\u003cstring>"},"scanner_version":"\u003cstring>","scanner_api_url":"\u003cstring>","scanner_session_id":"3c90c3cc-0d44-4b50-8888-8dd25736052a","started_at":"2023-11-07T05:31:56Z","finished_at":"2023-11-07T05:31:56Z","enrichments":["vulnerabilities"],"stages":[{"name":"\u003cstring>","state":"pending","items_processed":123,"items_total":123,"started_at":"2023-11-07T05:31:56Z","finished_at":"2023-11-07T05:31:56Z","warnings":["\u003cstring>"]}],"added_count":123,"persisted_count":123,"absent_count":123,"coverage":"full","result_scope":"project","scan_context":{"producer":"ui_upload","coverage":"full","provider":"\u003cstring>","repository":{"external_id":"\u003cstring>","full_name":"\u003cstring>"},"change_request":{"number":123,"url":"\u003cstring>","base_sha":"\u003cstring>","head_sha":"\u003cstring>","base_ref":"\u003cstring>","head_ref":"\u003cstring>"},"commit_sha":"\u003cstring>","branch":"\u003cstring>","run":{"ci_system":"\u003cstring>","url":"\u003cstring>","external_id":"\u003cstring>"}},"effective":{"scanners":["oss"],"enrichments":["vulnerabilities"],"coverage":"full","policy_snapshot":{"policies":[{"policy_id":123,"revision":"\u003cstring>"}]},"fetch_lfs_models":true},"narrowed_from_request":[{"field":"coverage","requested":"\u003cstring>","effective":"\u003cstring>","reason":"\u003cstring>"}],"gate":"pass","gate_reason":"no_policy_applies","evaluation":{"status":"pending","policies_evaluated":1,"evaluated_at":"2023-11-07T05:31:56Z"},"codebase_divergence":{"is_divergent":true,"overlap_pct":0.5,"prior_components":123},"publication":{"state":"pending","targets":[{"revision":123,"target":"check","state":"pending","attempts":123,"provider_ref":"\u003cstring>","error_class":"retryable","last_error":"\u003cstring>","next_attempt_at":"2023-11-07T05:31:56Z","published_at":"2023-11-07T05:31:56Z","updated_at":"2023-11-07T05:31:56Z"}]}}}}},"exampleType":"generated"}},"exampleType":"generated"},"5ceb7daa-c898-4e5a-9b9b-ceba5d011b8d":{"description":"Malformed request or an empty scanner set.","content":{"application/json":{"schema":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Machine-readable error code. `source_not_available` when WFP upload lands).","isRequired":true,"uniqueKey":"code","typeLabel":"string"},"message":{"type":"string","isRequired":true,"uniqueKey":"message","typeLabel":"string"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"code":"\u003cstring>","message":"\u003cstring>"}}},"exampleType":"generated"}},"exampleType":"generated"},"3f4dd34d-cc25-490e-a030-d1c5f4c059b6":{"description":"Not authenticated.","content":{"application/json":{"schema":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Machine-readable error code. `source_not_available` when WFP upload lands).","isRequired":true,"uniqueKey":"code","typeLabel":"string"},"message":{"type":"string","isRequired":true,"uniqueKey":"message","typeLabel":"string"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"code":"\u003cstring>","message":"\u003cstring>"}}},"exampleType":"generated"}},"exampleType":"generated"},"d4465048-d13a-40ba-9372-189a12d5f676":{"description":"Missing `scans:write` permission, API key scanner restriction, or enabled scanner.","content":{"application/json":{"schema":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Machine-readable error code. `source_not_available` when WFP upload lands).","isRequired":true,"uniqueKey":"code","typeLabel":"string"},"message":{"type":"string","isRequired":true,"uniqueKey":"message","typeLabel":"string"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"code":"\u003cstring>","message":"\u003cstring>"}}},"exampleType":"generated"}},"exampleType":"generated"},"b513142c-b6e7-4a79-b9d2-b2a1de6e53de":{"description":"`idempotency_conflict` — the key was already used for a different folder plan.","content":{"application/json":{"schema":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Machine-readable error code. `source_not_available` when WFP upload lands).","isRequired":true,"uniqueKey":"code","typeLabel":"string"},"message":{"type":"string","isRequired":true,"uniqueKey":"message","typeLabel":"string"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"code":"\u003cstring>","message":"\u003cstring>"}}},"exampleType":"generated"}},"exampleType":"generated"},"4acad538-760e-4b97-aa47-e788a08c050a":{"description":"`keep_set_too_large` — keep-set bytes or entry count exceed the configured cap. The message names the cap and the measured keep size.","content":{"application/json":{"schema":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Machine-readable error code. `source_not_available` when WFP upload lands).","isRequired":true,"uniqueKey":"code","typeLabel":"string"},"message":{"type":"string","isRequired":true,"uniqueKey":"message","typeLabel":"string"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"code":"\u003cstring>","message":"\u003cstring>"}}},"exampleType":"generated"}},"exampleType":"generated"},"918ec598-0957-4d62-9a5a-8698c3c04537":{"description":"Validation failure. Possible codes:\n * `project_not_found`\n * `project_archived`\n * `invalid_path`\n * `invalid_scan`\n * `coverage_promotion_rejected` — the request's `scan_context.coverage` asked for `full` where the server derives `partial`; coverage is narrowable, never promotable.\n * `invalid_scan_context` — `scan_context` carried a value outside this contract's enums (producer, coverage or provider).","content":{"application/json":{"schema":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Machine-readable error code. `source_not_available` when WFP upload lands).","isRequired":true,"uniqueKey":"code","typeLabel":"string"},"message":{"type":"string","isRequired":true,"uniqueKey":"message","typeLabel":"string"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"code":"\u003cstring>","message":"\u003cstring>"}}},"exampleType":"generated"}},"exampleType":"generated"}},"security":{"044b1aa4-bef2-430b-bd04-5a8e9add18c6":{"bearerAuth":{"type":"http","scheme":"bearer","description":"An Earnie API key, sent as `Authorization: Bearer sk_earnie_...`. Create one under Settings > API keys. The key's scopes decide which operations it may call.","scopes":[],"schemeName":"bearerAuth"}}},"servers":{"78824d01-63cc-41fd-9d19-c3590c2af6c2":{"url":"https://{tenant}.earnie.dev","description":"Your Earnie deployment","variables":{"tenant":{"default":"your-company","description":"Your organization's Earnie address, as shown in your browser when you sign in."}}}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","description":"An Earnie API key, sent as `Authorization: Bearer sk_earnie_...`. Create one under Settings > API keys. The key's scopes decide which operations it may call.","scopes":[],"schemeName":"bearerAuth"},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"An Earnie API key, sent as `Authorization: Bearer sk_earnie_...`. Create one under Settings > API keys. The key's scopes decide which operations it may call.","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"bearerAuth","name":"Authorization"}],"title":"bearerAuth"}]},"originalFileLocation":"api-reference/earnie/scans-openapi.json"},"subdomain":"scanoss","siteName":"SCANOSS documentation","title":"Plan a folder scan — keep engine then 202 receiving - SCANOSS documentation","navMaps":{"firstHrefInVersion":{"v2":{"href":"/earnie/api-reference/scans/scans/plan-a-folder-scan-—-keep-engine-then-202-receiving","matchLevel":0},"v1":{"href":"/en/latest/introduction/what-is-scanoss","matchLevel":4}},"firstHrefInLanguage":{}},"lastModified":"2026-10-07T10:42:13.509Z","originalFileLocation":"earnie/api-reference/scans/scans/plan-a-folder-scan-—-keep-engine-then-202-receiving.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Submits a directory inventory plus optional root .gitignore and settings-file bytes. A diff producer lists removed paths as inventory entries with deleted: true and size: 0; those deletion markers are retained with the receiving plan but never enter the keep set or ingest. The server runs the keep engine (SDK scanning built-ins, gitignore, settings, org/project skip_patterns) and returns 202 with the scan (status=receiving) and the keep set. The keep-set transfer is NOT complete: the client streams kept file bytes via PUT /v1/scans/{scanId}/ingest, then POST /v1/scans/{scanId}:commit-ingest. Caps apply to keep-set bytes and entry count (keep_set_too_large).\">\u003cmeta data-mint-head name=\"application-name\" content=\"SCANOSS documentation\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/scanoss/KZfWE-Zg_gP00ddS/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/scanoss/KZfWE-Zg_gP00ddS/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/scanoss/KZfWE-Zg_gP00ddS/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/scanoss/KZfWE-Zg_gP00ddS/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/scanoss/KZfWE-Zg_gP00ddS/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/scanoss/KZfWE-Zg_gP00ddS/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/scanoss/KZfWE-Zg_gP00ddS/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/scanoss/KZfWE-Zg_gP00ddS/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/scanoss/KZfWE-Zg_gP00ddS/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Plan a folder scan — keep engine then 202 receiving - SCANOSS documentation\">\u003cmeta data-mint-head property=\"og:description\" content=\"Submits a directory inventory plus optional root .gitignore and settings-file bytes. A diff producer lists removed paths as inventory entries with deleted: true and size: 0; those deletion markers are retained with the receiving plan but never enter the keep set or ingest. The server runs the keep engine (SDK scanning built-ins, gitignore, settings, org/project skip_patterns) and returns 202 with the scan (status=receiving) and the keep set. The keep-set transfer is NOT complete: the client streams kept file bytes via PUT /v1/scans/{scanId}/ingest, then POST /v1/scans/{scanId}:commit-ingest. Caps apply to keep-set bytes and entry count (keep_set_too_large).\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"SCANOSS documentation\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.scanoss.com/earnie/api-reference/scans/scans/plan-a-folder-scan-—-keep-engine-then-202-receiving\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://scanoss.mintlify.app/_mintlify/api/og/v2?division=scans\u0026amp;title=Plan+a+folder+scan+%E2%80%94+keep+engine+then+202+receiving\u0026amp;description=Submits+a+directory+inventory+plus+optional+root+%60.gitignore%60+and+settings-file+bytes.+A+diff+producer+lists+removed+paths+as+inventory+entries+with+%60deleted%3A+t\u0026amp;theme=e384d94a4a6a8eabee7f937e\u0026amp;signature=89a719cd41f83afbc7cf271b1a219f0a58e35e03026427b6769e4b7a595bbcee\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Plan a folder scan — keep engine then 202 receiving - SCANOSS documentation\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Submits a directory inventory plus optional root .gitignore and settings-file bytes. A diff producer lists removed paths as inventory entries with deleted: true and size: 0; those deletion markers are retained with the receiving plan but never enter the keep set or ingest. The server runs the keep engine (SDK scanning built-ins, gitignore, settings, org/project skip_patterns) and returns 202 with the scan (status=receiving) and the keep set. The keep-set transfer is NOT complete: the client streams kept file bytes via PUT /v1/scans/{scanId}/ingest, then POST /v1/scans/{scanId}:commit-ingest. Caps apply to keep-set bytes and entry count (keep_set_too_large).\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://scanoss.mintlify.app/_mintlify/api/og/v2?division=scans\u0026amp;title=Plan+a+folder+scan+%E2%80%94+keep+engine+then+202+receiving\u0026amp;description=Submits+a+directory+inventory+plus+optional+root+%60.gitignore%60+and+settings-file+bytes.+A+diff+producer+lists+removed+paths+as+inventory+entries+with+%60deleted%3A+t\u0026amp;theme=e384d94a4a6a8eabee7f937e\u0026amp;signature=89a719cd41f83afbc7cf271b1a219f0a58e35e03026427b6769e4b7a595bbcee\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/scanoss/KZfWE-Zg_gP00ddS/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"SCANOSS documentation\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#FF6A1A\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.scanoss.com/earnie/api-reference/scans/scans/plan-a-folder-scan-—-keep-engine-then-202-receiving\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/earnie/api-reference/scans/scans/plan-a-folder-scan-%E2%80%94-keep-engine-then-202-receiving.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.scanoss.com/#organization\",\"name\":\"SCANOSS documentation\",\"url\":\"https://docs.scanoss.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/scanoss/9UP7eHL2Z_rQPx8l/scanoss-logo-horizontal-positive.svg?fit=max\u0026auto=format\u0026n=9UP7eHL2Z_rQPx8l\u0026q=85\u0026s=686c4487013423ef804e2e83983c76ef\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.scanoss.com#website\",\"name\":\"SCANOSS documentation\",\"url\":\"https://docs.scanoss.com\",\"publisher\":{\"@id\":\"https://docs.scanoss.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.scanoss.com/earnie/api-reference/scans/scans/plan-a-folder-scan-%E2%80%94-keep-engine-then-202-receiving#webpage\",\"url\":\"https://docs.scanoss.com/earnie/api-reference/scans/scans/plan-a-folder-scan-%E2%80%94-keep-engine-then-202-receiving\",\"name\":\"Plan a folder scan — keep engine then 202 receiving\",\"description\":\"Submits a directory inventory plus optional root .gitignore and settings-file bytes. A diff producer lists removed paths as inventory entries with deleted: true and size: 0; those deletion markers are retained with the receiving plan but never enter the keep set or ingest. The server runs the keep engine (SDK scanning built-ins, gitignore, settings, org/project skip_patterns) and returns 202 with the scan (status=receiving) and the keep set. The keep-set transfer is NOT complete: the client streams kept file bytes via PUT /v1/scans/{scanId}/ingest, then POST /v1/scans/{scanId}:commit-ingest. Caps apply to keep-set bytes and entry count (keep_set_too_large).\",\"dateModified\":\"2026-10-07T10:42:13.509Z\",\"isPartOf\":{\"@id\":\"https://docs.scanoss.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.scanoss.com/earnie/api-reference/scans/scans/plan-a-folder-scan-%E2%80%94-keep-engine-then-202-receiving#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.scanoss.com/earnie/api-reference/scans/scans/plan-a-folder-scan-%E2%80%94-keep-engine-then-202-receiving#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"API Reference\",\"item\":\"https://docs.scanoss.com/en/latest/earnie/api/using-the-api\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Scans\",\"item\":\"https://docs.scanoss.com/earnie/api-reference/scans/scans/the-organizations-ai-provenance-posture-across-a-scope-of-projects\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"scans\",\"item\":\"https://docs.scanoss.com/earnie/api-reference/scans/scans/the-organizations-ai-provenance-posture-across-a-scope-of-projects\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Plan a folder scan — keep engine then 202 receiving\",\"item\":\"https://docs.scanoss.com/earnie/api-reference/scans/scans/plan-a-folder-scan-%E2%80%94-keep-engine-then-202-receiving\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.scanoss.com/earnie/api-reference/scans/scans/plan-a-folder-scan-%E2%80%94-keep-engine-then-202-receiving#apireference\",\"headline\":\"Plan a folder scan — keep engine then 202 receiving\",\"name\":\"Plan a folder scan — keep engine then 202 receiving\",\"description\":\"Submits a directory inventory plus optional root .gitignore and settings-file bytes. A diff producer lists removed paths as inventory entries with deleted: true and size: 0; those deletion markers are retained with the receiving plan but never enter the keep set or ingest. The server runs the keep engine (SDK scanning built-ins, gitignore, settings, org/project skip_patterns) and returns 202 with the scan (status=receiving) and the keep set. The keep-set transfer is NOT complete: the client streams kept file bytes via PUT /v1/scans/{scanId}/ingest, then POST /v1/scans/{scanId}:commit-ingest. Caps apply to keep-set bytes and entry count (keep_set_too_large).\",\"url\":\"https://docs.scanoss.com/earnie/api-reference/scans/scans/plan-a-folder-scan-%E2%80%94-keep-engine-then-202-receiving\",\"mainEntityOfPage\":{\"@id\":\"https://docs.scanoss.com/earnie/api-reference/scans/scans/plan-a-folder-scan-%E2%80%94-keep-engine-then-202-receiving#webpage\"},\"dateModified\":\"2026-10-07T10:42:13.509Z\",\"publisher\":{\"@id\":\"https://docs.scanoss.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.scanoss.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"SCANOSS documentation\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"SCANOSS documentation","nav":{"global":null,"versions":[{"version":"v2","default":true,"tabs":[{"tab":"Earnie","hidden":false,"groups":[{"group":"Get Started","expanded":false,"pages":[{"title":"What Is Earnie?","sidebarTitle":"What Is Earnie?","href":"/en/latest/earnie/introduction"},{"title":"Deployment Options and Data Flow","sidebarTitle":"Deployment and Data Flow","href":"/en/latest/earnie/deployment"},{"group":"Self-Hosting","expanded":false,"pages":[{"title":"Self-Hosting Requirements","sidebarTitle":"Self-Hosting Requirements","href":"/en/latest/earnie/self-hosting/self-hosting-requirements"},{"title":"Installing Earnie","sidebarTitle":"Installing Earnie","href":"/en/latest/earnie/self-hosting/installation"},{"title":"Running Earnie on a Cloud Provider","sidebarTitle":"Cloud Providers","href":"/en/latest/earnie/self-hosting/cloud-providers"},{"title":"Upgrading and Backing Up","sidebarTitle":"Upgrading and Backing Up","href":"/en/latest/earnie/self-hosting/upgrading-and-backups"},{"title":"Releases and Release Notes","sidebarTitle":"Releases","href":"/en/latest/earnie/self-hosting/releases"},{"title":"Outbound Network Calls","sidebarTitle":"Outbound Network Calls","href":"/en/latest/earnie/self-hosting/outbound-network-calls"}]},{"title":"Setting Up Your Workspace","sidebarTitle":"Workspace Setup","href":"/en/latest/earnie/getting-started/workspace-setup"},{"title":"Connecting a Repository","sidebarTitle":"Connecting a Repository","href":"/en/latest/earnie/getting-started/connecting-a-repository"},{"title":"Your First Scan","sidebarTitle":"First Scan","href":"/en/latest/earnie/getting-started/first-scan"}]},{"group":"Development","expanded":false,"pages":[{"title":"Earnie CLI","sidebarTitle":"Earnie CLI","href":"/en/latest/earnie/using-earnie/earnie-cli"},{"group":"Coding Agents (MCP)","expanded":false,"pages":[{"title":"Earnie MCP","sidebarTitle":"Overview","href":"/en/latest/earnie/mcp/overview"},{"title":"Connecting an AI Client","sidebarTitle":"Connecting a Client","href":"/en/latest/earnie/mcp/connecting-a-client"},{"title":"Using Earnie Through MCP","sidebarTitle":"Tools","href":"/en/latest/earnie/mcp/tools"},{"title":"Troubleshooting Earnie MCP","sidebarTitle":"Troubleshooting","href":"/en/latest/earnie/mcp/troubleshooting"}]},{"title":"Self-Checks","sidebarTitle":"Self-Checks","href":"/en/latest/earnie/using-earnie/self-checks"}]},{"group":"Pull Requests \u0026 CI","expanded":false,"pages":[{"title":"When the Gate Blocks a Merge","sidebarTitle":"Merge Gate","href":"/en/latest/earnie/using-earnie/merge-gate"},{"title":"Scan Configuration","sidebarTitle":"Scan Configuration","href":"/en/latest/earnie/using-earnie/scan-configuration"}]},{"group":"Governance","expanded":false,"pages":[{"title":"Reading the Dashboard","sidebarTitle":"Dashboard","href":"/en/latest/earnie/using-earnie/dashboard"},{"title":"Dependencies","sidebarTitle":"Dependencies","href":"/en/latest/earnie/using-earnie/dependencies"},{"title":"Vulnerability Statements (VEX)","sidebarTitle":"Vulnerabilities","href":"/en/latest/earnie/using-earnie/vulnerabilities"},{"title":"Every Algorithm in a Project","sidebarTitle":"Algorithms","href":"/en/latest/earnie/using-earnie/algorithms"},{"title":"Across Every Project","sidebarTitle":"All Projects","href":"/en/latest/earnie/using-earnie/all-projects"},{"title":"Triaging Findings","sidebarTitle":"Triaging Findings","href":"/en/latest/earnie/using-earnie/triaging-findings"},{"title":"Setting Your First Policy","sidebarTitle":"Setting Policies","href":"/en/latest/earnie/using-earnie/setting-policies"},{"title":"Notifications","sidebarTitle":"Notifications","href":"/en/latest/earnie/using-earnie/notifications"},{"title":"Language","sidebarTitle":"Language","href":"/en/latest/earnie/using-earnie/language"},{"group":"Domains","expanded":false,"pages":[{"title":"Cryptography","sidebarTitle":"Cryptography","href":"/en/latest/earnie/domains/cryptography"},{"title":"AI Provenance","sidebarTitle":"AI Provenance","href":"/en/latest/earnie/using-earnie/ai-provenance"}]}]},{"group":"Evidence \u0026 Audit","expanded":false,"pages":[{"title":"Exporting an SBOM","sidebarTitle":"Exporting SBOMs","href":"/en/latest/earnie/evidence/exporting-sboms"},{"title":"Reports","sidebarTitle":"Reports","href":"/en/latest/earnie/evidence/project-reports"},{"title":"Compliance Packages","sidebarTitle":"Compliance Packages","href":"/en/latest/earnie/evidence/compliance-packages"},{"title":"Audit Log","sidebarTitle":"Audit Log","href":"/en/latest/earnie/evidence/audit-log"}]},{"group":"Administration","expanded":false,"pages":[{"title":"Team and Roles","sidebarTitle":"Team \u0026 Roles","href":"/en/latest/earnie/administration/team-and-roles"},{"title":"API Keys","sidebarTitle":"API Keys","href":"/en/latest/earnie/administration/api-keys"}]},{"group":"Migrating","expanded":false,"pages":[{"title":"Migrating from SCANOSS Tools","sidebarTitle":"From SCANOSS Tools","href":"/en/latest/earnie/migrating/from-scanoss-tools"}]},{"group":"API Reference","expanded":false,"pages":[{"title":"Using the API","sidebarTitle":"Using the API","href":"/en/latest/earnie/api/using-the-api"},{"group":"Projects","pages":[{"group":"projects","pages":[{"title":"List projects for the authenticated organisation","deprecated":null,"version":null,"openapi":"/api-reference/earnie/projects-openapi.json get /v1/projects","href":"/earnie/api-reference/projects/projects/list-projects-for-the-authenticated-organisation"},{"title":"Create a new project","deprecated":null,"version":null,"openapi":"/api-reference/earnie/projects-openapi.json post /v1/projects","href":"/earnie/api-reference/projects/projects/create-a-new-project"},{"title":"Get a project by ID","deprecated":null,"version":null,"openapi":"/api-reference/earnie/projects-openapi.json get /v1/projects/{projectId}","href":"/earnie/api-reference/projects/projects/get-a-project-by-id"},{"title":"Update a project's name or description","deprecated":null,"version":null,"openapi":"/api-reference/earnie/projects-openapi.json patch /v1/projects/{projectId}","href":"/earnie/api-reference/projects/projects/update-a-projects-name-or-description"},{"title":"Resolve one accessible project for a customer CLI","deprecated":null,"version":null,"openapi":"/api-reference/earnie/projects-openapi.json get /v1/projects:resolve","href":"/earnie/api-reference/projects/projects/resolve-one-accessible-project-for-a-customer-cli"}]}]},{"group":"Scans","pages":[{"group":"scans","pages":[{"title":"The organization's AI provenance posture across a scope of projects","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/ai/posture","href":"/earnie/api-reference/scans/scans/the-organizations-ai-provenance-posture-across-a-scope-of-projects"},{"title":"The curated rules Earnie assesses crypto findings against","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/crypto/assessment-rules","href":"/earnie/api-reference/scans/scans/the-curated-rules-earnie-assesses-crypto-findings-against"},{"title":"The organization's crypto posture across a scope of projects","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/crypto/posture","href":"/earnie/api-reference/scans/scans/the-organizations-crypto-posture-across-a-scope-of-projects"},{"title":"Get the project's AI scanner settings","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/projects/{projectId}/ai-settings","href":"/earnie/api-reference/scans/scans/get-the-projects-ai-scanner-settings"},{"title":"Replace the project's AI scanner settings","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json put /v1/projects/{projectId}/ai-settings","href":"/earnie/api-reference/scans/scans/replace-the-projects-ai-scanner-settings"},{"title":"Crypto algorithms detected in one project","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/projects/{projectId}/crypto-algorithms","href":"/earnie/api-reference/scans/scans/crypto-algorithms-detected-in-one-project"},{"title":"Dependency-internal crypto inventory for one component","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/projects/{projectId}/crypto-inventory","href":"/earnie/api-reference/scans/scans/dependency-internal-crypto-inventory-for-one-component"},{"title":"Declare a model upload, or resume the one in flight","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json post /v1/projects/{projectId}/model-uploads","href":"/earnie/api-reference/scans/scans/declare-a-model-upload-or-resume-the-one-in-flight"},{"title":"Read an upload and its offset","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/projects/{projectId}/model-uploads/{uploadId}","href":"/earnie/api-reference/scans/scans/read-an-upload-and-its-offset"},{"title":"Send one window of an upload","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json put /v1/projects/{projectId}/model-uploads/{uploadId}","href":"/earnie/api-reference/scans/scans/send-one-window-of-an-upload"},{"title":"Abandon an upload","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json delete /v1/projects/{projectId}/model-uploads/{uploadId}","href":"/earnie/api-reference/scans/scans/abandon-an-upload"},{"title":"List the project's Models and its uploads in flight","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/projects/{projectId}/models","href":"/earnie/api-reference/scans/scans/list-the-projects-models-and-its-uploads-in-flight"},{"title":"Get one Model","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/projects/{projectId}/models/{modelId}","href":"/earnie/api-reference/scans/scans/get-one-model"},{"title":"Delete a Model","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json delete /v1/projects/{projectId}/models/{modelId}","href":"/earnie/api-reference/scans/scans/delete-a-model"},{"title":"List scans","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/scans","href":"/earnie/api-reference/scans/scans/list-scans"},{"title":"Upload a source archive and start a scan","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json post /v1/scans","href":"/earnie/api-reference/scans/scans/upload-a-source-archive-and-start-a-scan"},{"title":"Get authoritative project scan summary","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/scans/projects/{projectId}/state","href":"/earnie/api-reference/scans/scans/get-authoritative-project-scan-summary"},{"title":"Project posture rollup for the Audit landing","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/scans/projects/{projectId}/summary","href":"/earnie/api-reference/scans/scans/project-posture-rollup-for-the-audit-landing"},{"title":"Project crypto posture rollup","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/scans/projects/{projectId}/summary/crypto","href":"/earnie/api-reference/scans/scans/project-crypto-posture-rollup"},{"title":"Posture for every project in scope, in one response","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/scans/projects:posture","href":"/earnie/api-reference/scans/scans/posture-for-every-project-in-scope-in-one-response"},{"title":"Get this deployment's upload limits","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/scans/upload-limits","href":"/earnie/api-reference/scans/scans/get-this-deployments-upload-limits"},{"title":"Fetch a single scan by id","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/scans/{scanId}","href":"/earnie/api-reference/scans/scans/fetch-a-single-scan-by-id"},{"title":"Upload or resume a user-supplied archive object","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json put /v1/scans/{scanId}/archive","href":"/earnie/api-reference/scans/scans/upload-or-resume-a-user-supplied-archive-object"},{"title":"Read the upload offset of an archive object","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json head /v1/scans/{scanId}/archive","href":"/earnie/api-reference/scans/scans/read-the-upload-offset-of-an-archive-object"},{"title":"The Scan's Audit Trail","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/scans/{scanId}/audit","href":"/earnie/api-reference/scans/scans/the-scans-audit-trail"},{"title":"Compare crypto findings with another completed scan","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/scans/{scanId}/crypto/diff","href":"/earnie/api-reference/scans/scans/compare-crypto-findings-with-another-completed-scan"},{"title":"List all files in the scan (flat)","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/scans/{scanId}/files","href":"/earnie/api-reference/scans/scans/list-all-files-in-the-scan-flat"},{"title":"Stream a single file's bytes from the retained archive","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/scans/{scanId}/files/content","href":"/earnie/api-reference/scans/scans/stream-a-single-files-bytes-from-the-retained-archive"},{"title":"Keep-set ingest cursor — received and missing paths","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/scans/{scanId}/ingest","href":"/earnie/api-reference/scans/scans/keep-set-ingest-cursor-—-received-and-missing-paths"},{"title":"Stream kept files as a tar","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json put /v1/scans/{scanId}/ingest","href":"/earnie/api-reference/scans/scans/stream-kept-files-as-a-tar"},{"title":"Match metadata + component + licenses for one file","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/scans/{scanId}/matches","href":"/earnie/api-reference/scans/scans/match-metadata-+-component-+-licenses-for-one-file"},{"title":"Proxy the bytes of an OSS file from the SCANOSS file-content service","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/scans/{scanId}/oss-files/content","href":"/earnie/api-reference/scans/scans/proxy-the-bytes-of-an-oss-file-from-the-scanoss-file-content-service"},{"title":"Per-scan rollup for the results-overview dashboard","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/scans/{scanId}/summary","href":"/earnie/api-reference/scans/scans/per-scan-rollup-for-the-results-overview-dashboard"},{"title":"Lazy folder expansion with aggregated state","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/scans/{scanId}/tree","href":"/earnie/api-reference/scans/scans/lazy-folder-expansion-with-aggregated-state"},{"title":"Cancel an in-progress scan","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json post /v1/scans/{scanId}:cancel","href":"/earnie/api-reference/scans/scans/cancel-an-in-progress-scan"},{"title":"Seal the keep-set archive and start scanning","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json post /v1/scans/{scanId}:commit-ingest","href":"/earnie/api-reference/scans/scans/seal-the-keep-set-archive-and-start-scanning"},{"title":"Explicitly rerun a scan","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json post /v1/scans/{scanId}:rerun","href":"/earnie/api-reference/scans/scans/explicitly-rerun-a-scan"},{"title":"Retry a degraded provider publication","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json post /v1/scans/{scanId}:retry-publication","href":"/earnie/api-reference/scans/scans/retry-a-degraded-provider-publication"},{"title":"Import a foreign SBOM document as a partial-coverage scan","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json post /v1/scans:import-sbom","href":"/earnie/api-reference/scans/scans/import-a-foreign-sbom-document-as-a-partial-coverage-scan"},{"title":"Create a receiving scan for a resumable archive object","description":"Creates a scan in `status=receiving` for a user-supplied `.zip` or `.tar.gz`. Upload the object with `PUT /v1/scans/{scanId}/archive` (Content-Range resume is supported). When the object is complete the server unpacks through the keep engine and seals the keep-set zip. Legacy one-shot `POST /v1/scans` multipart `file` remains valid and also runs the keep engine.","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json post /v1/scans:plan-archive","href":"/earnie/api-reference/scans/scans/create-a-receiving-scan-for-a-resumable-archive-object"},{"title":"Plan a folder scan — keep engine then 202 receiving","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json post /v1/scans:plan-folder","href":"/earnie/api-reference/scans/scans/plan-a-folder-scan-—-keep-engine-then-202-receiving"},{"title":"List Self-checks","description":"Self-checks are listed here and nowhere else: `GET /v1/scans` returns governed Scans only, so a developer's twenty commits a day never crowd out a Project's scan history.","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/self-checks","href":"/earnie/api-reference/scans/scans/list-self-checks"},{"title":"Run a Self-check over an inline SourceSet","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json post /v1/self-checks","href":"/earnie/api-reference/scans/scans/run-a-self-check-over-an-inline-sourceset"},{"title":"Get one Self-check","deprecated":null,"version":null,"openapi":"/api-reference/earnie/scans-openapi.json get /v1/self-checks/{selfCheckId}","href":"/earnie/api-reference/scans/scans/get-one-self-check"}]}]},{"group":"Findings","pages":[{"group":"audit","pages":[{"title":"List the durable audit-event trail for a subject (e.g. a finding)","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json get /v1/audit/events","href":"/earnie/api-reference/triage/audit/list-the-durable-audit-event-trail-for-a-subject-eg-a-finding"}]},{"group":"findings","pages":[{"title":"List findings with optional filters","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json get /v1/findings","href":"/earnie/api-reference/triage/findings/list-findings-with-optional-filters"},{"title":"Create a new finding (source=api)","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json post /v1/findings","href":"/earnie/api-reference/triage/findings/create-a-new-finding-source=api"},{"title":"Bulk-reopen findings by component/path scope","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json post /v1/findings/actions/bulk-reopen","href":"/earnie/api-reference/triage/findings/bulk-reopen-findings-by-componentpath-scope"},{"title":"Bulk-resolve open OSS findings by component/path scope","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json post /v1/findings/actions/bulk-resolve","href":"/earnie/api-reference/triage/findings/bulk-resolve-open-oss-findings-by-componentpath-scope"},{"title":"Bulk-resolve open OSS findings across every project","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json post /v1/findings/actions/bulk-resolve-org-wide","href":"/earnie/api-reference/triage/findings/bulk-resolve-open-oss-findings-across-every-project"},{"title":"Count the open findings a bulk-resolve would affect","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json post /v1/findings/actions/bulk-resolve-preview","href":"/earnie/api-reference/triage/findings/count-the-open-findings-a-bulk-resolve-would-affect"},{"title":"List findings aggregated by component (purl@version)","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json get /v1/findings/components","href":"/earnie/api-reference/triage/findings/list-findings-aggregated-by-component-purl@version"},{"title":"Membership Audit Trail for a component (base purl) selection","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json get /v1/findings/components/audit-trail","href":"/earnie/api-reference/triage/findings/membership-audit-trail-for-a-component-base-purl-selection"},{"title":"List the filterable facet values a set of findings carries, with counts","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json get /v1/findings/facets","href":"/earnie/api-reference/triage/findings/list-the-filterable-facet-values-a-set-of-findings-carries-with-counts"},{"title":"List findings aggregated by source file (review queue rows)","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json get /v1/findings/files","href":"/earnie/api-reference/triage/findings/list-findings-aggregated-by-source-file-review-queue-rows"},{"title":"Get a single finding by ID","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json get /v1/findings/{findingId}","href":"/earnie/api-reference/triage/findings/get-a-single-finding-by-id"},{"title":"Assign a finding to an actor (also serves as defer/reassign)","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json post /v1/findings/{findingId}/actions/assign","href":"/earnie/api-reference/triage/findings/assign-a-finding-to-an-actor-also-serves-as-deferreassign"},{"title":"Create a configuration rule directly from a finding (mark-as-original)","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json post /v1/findings/{findingId}/actions/create-rule","href":"/earnie/api-reference/triage/findings/create-a-configuration-rule-directly-from-a-finding-mark-as-original"},{"title":"Reopen a resolved or assigned finding","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json post /v1/findings/{findingId}/actions/reopen","href":"/earnie/api-reference/triage/findings/reopen-a-resolved-or-assigned-finding"},{"title":"Resolve a finding with a reason","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json post /v1/findings/{findingId}/actions/resolve","href":"/earnie/api-reference/triage/findings/resolve-a-finding-with-a-reason"},{"title":"Suppress or unsuppress a finding (orthogonal to triage state)","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json post /v1/findings/{findingId}/actions/suppress","href":"/earnie/api-reference/triage/findings/suppress-or-unsuppress-a-finding-orthogonal-to-triage-state"},{"title":"Stream the dependency's resolved source for a crypto finding","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json get /v1/findings/{findingId}/crypto-source","href":"/earnie/api-reference/triage/findings/stream-the-dependencys-resolved-source-for-a-crypto-finding"}]},{"group":"resolutions","pages":[{"title":"List resolutions (pending review queue)","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json get /v1/resolutions","href":"/earnie/api-reference/triage/resolutions/list-resolutions-pending-review-queue"},{"title":"Weekly decision throughput for a project, split by actor class","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json get /v1/resolutions/throughput","href":"/earnie/api-reference/triage/resolutions/weekly-decision-throughput-for-a-project-split-by-actor-class"},{"title":"Revert a pending_review resolution","deprecated":null,"version":null,"openapi":"/api-reference/earnie/triage-openapi.json post /v1/resolutions/{resolutionId}/actions/revert","href":"/earnie/api-reference/triage/resolutions/revert-a-pending_review-resolution"}]}]},{"group":"Policies","pages":[{"group":"policies","pages":[{"title":"List current policy verdicts for a finding","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json get /v1/findings/{findingId}/policy-verdicts","href":"/earnie/api-reference/policies/policies/list-current-policy-verdicts-for-a-finding"},{"title":"List named regulatory policy template sets","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json get /v1/policies/template-sets","href":"/earnie/api-reference/policies/policies/list-named-regulatory-policy-template-sets"},{"title":"List the projects a policy is attached to","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json get /v1/policies/{id}/attachments","href":"/earnie/api-reference/policies/policies/list-the-projects-a-policy-is-attached-to"},{"title":"List (and page) policy approval history for a project","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json get /v1/projects/{projectId}/approvals","href":"/earnie/api-reference/policies/policies/list-and-page-policy-approval-history-for-a-project"},{"title":"List policies directly attached to a project","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json get /v1/projects/{projectId}/policies","href":"/earnie/api-reference/policies/policies/list-policies-directly-attached-to-a-project"},{"title":"Attach a policy directly to a project","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json put /v1/projects/{projectId}/policies/{policyId}","href":"/earnie/api-reference/policies/policies/attach-a-policy-directly-to-a-project"},{"title":"Clone a policy attached (or attachable) to a project","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json post /v1/projects/{projectId}/policies/{policyId}/clone","href":"/earnie/api-reference/policies/policies/clone-a-policy-attached-or-attachable-to-a-project"},{"title":"List immutable evaluation snapshots for an attached policy","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json get /v1/projects/{projectId}/policies/{policyId}/evaluations","href":"/earnie/api-reference/policies/policies/list-immutable-evaluation-snapshots-for-an-attached-policy"},{"title":"List current findings violating an attached policy","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json get /v1/projects/{projectId}/policies/{policyId}/violations","href":"/earnie/api-reference/policies/policies/list-current-findings-violating-an-attached-policy"},{"title":"Materialize an arbitrary, operator-chosen list of seeded templates","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json post /v1/projects/{projectId}/policies:from-templates","href":"/earnie/api-reference/policies/policies/materialize-an-arbitrary-operator-chosen-list-of-seeded-templates"},{"title":"Get the project's current policy posture","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json get /v1/projects/{projectId}/policy-posture","href":"/earnie/api-reference/policies/policies/get-the-projects-current-policy-posture"},{"title":"Enable one named regulatory policy template set","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json post /v1/projects/{projectId}/policy-template-sets/{setSlug}:enable","href":"/earnie/api-reference/policies/policies/enable-one-named-regulatory-policy-template-set"},{"title":"Get the project's append-only posture time series","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json get /v1/projects/{projectId}/posture-history","href":"/earnie/api-reference/policies/policies/get-the-projects-append-only-posture-time-series"},{"title":"What this scan was gated by","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json get /v1/scans/{scanId}/policy-verdicts","href":"/earnie/api-reference/policies/policies/what-this-scan-was-gated-by"}]},{"group":"API Reference","pages":[{"title":"List policies","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json get /v1/policies","href":"/earnie/api-reference/policies/list-policies"},{"title":"Create a policy","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json post /v1/policies","href":"/earnie/api-reference/policies/create-a-policy"},{"title":"Get the field catalog visible to the caller","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json get /v1/policies/fields","href":"/earnie/api-reference/policies/get-the-field-catalog-visible-to-the-caller"},{"title":"Search values for an endpoint-sourced field","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json get /v1/policies/fields/{path}/values","href":"/earnie/api-reference/policies/search-values-for-an-endpoint-sourced-field"},{"title":"List seeded policy templates","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json get /v1/policies/templates","href":"/earnie/api-reference/policies/list-seeded-policy-templates"},{"title":"Read one policy","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json get /v1/policies/{id}","href":"/earnie/api-reference/policies/read-one-policy"},{"title":"Delete a policy","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json delete /v1/policies/{id}","href":"/earnie/api-reference/policies/delete-a-policy"},{"title":"Partial update of a policy","deprecated":null,"version":null,"openapi":"/api-reference/earnie/policies-openapi.json patch /v1/policies/{id}","href":"/earnie/api-reference/policies/partial-update-of-a-policy"}]}]},{"group":"SBOM","pages":[{"group":"sbom","pages":[{"title":"List a project's SBOM snapshots (newest first)","deprecated":null,"version":null,"openapi":"/api-reference/earnie/sbom-openapi.json get /v1/sbom/projects/{projectId}/snapshots","href":"/earnie/api-reference/sbom/sbom/list-a-projects-sbom-snapshots-newest-first"},{"title":"Generate an SBOM snapshot from a scan","deprecated":null,"version":null,"openapi":"/api-reference/earnie/sbom-openapi.json post /v1/sbom/scans/{scanId}:generate","href":"/earnie/api-reference/sbom/sbom/generate-an-sbom-snapshot-from-a-scan"},{"title":"Fetch snapshot metadata","deprecated":null,"version":null,"openapi":"/api-reference/earnie/sbom-openapi.json get /v1/sbom/snapshots/{snapshotId}","href":"/earnie/api-reference/sbom/sbom/fetch-snapshot-metadata"},{"title":"Delete a snapshot (metadata + rendered artifacts + inventory)","deprecated":null,"version":null,"openapi":"/api-reference/earnie/sbom-openapi.json delete /v1/sbom/snapshots/{snapshotId}","href":"/earnie/api-reference/sbom/sbom/delete-a-snapshot-metadata-+-rendered-artifacts-+-inventory"},{"title":"Download a rendered SBOM document (original bytes)","deprecated":null,"version":null,"openapi":"/api-reference/earnie/sbom-openapi.json get /v1/sbom/snapshots/{snapshotId}/document","href":"/earnie/api-reference/sbom/sbom/download-a-rendered-sbom-document-original-bytes"},{"title":"Render an existing snapshot into another format","deprecated":null,"version":null,"openapi":"/api-reference/earnie/sbom-openapi.json post /v1/sbom/snapshots/{snapshotId}:render","href":"/earnie/api-reference/sbom/sbom/render-an-existing-snapshot-into-another-format"}]}]},{"group":"Estate Actions","pages":[{"group":"estate","pages":[{"title":"Poll a queued fan-out run","deprecated":null,"version":null,"openapi":"/api-reference/earnie/estate-openapi.json get /v1/estate/actions/{runId}","href":"/earnie/api-reference/estate/estate/poll-a-queued-fan-out-run"},{"title":"Attach a policy to every selected, eligible project","deprecated":null,"version":null,"openapi":"/api-reference/earnie/estate-openapi.json post /v1/estate/projects:apply-policy","href":"/earnie/api-reference/estate/estate/attach-a-policy-to-every-selected-eligible-project"},{"title":"Generate an SBOM snapshot for every selected, eligible project","deprecated":null,"version":null,"openapi":"/api-reference/earnie/estate-openapi.json post /v1/estate/projects:generate-sbom","href":"/earnie/api-reference/estate/estate/generate-an-sbom-snapshot-for-every-selected-eligible-project"},{"title":"Render a notice file for every selected, eligible project","deprecated":null,"version":null,"openapi":"/api-reference/earnie/estate-openapi.json post /v1/estate/projects:render-notice","href":"/earnie/api-reference/estate/estate/render-a-notice-file-for-every-selected-eligible-project"},{"title":"Request a re-scan for every selected, eligible project","deprecated":null,"version":null,"openapi":"/api-reference/earnie/estate-openapi.json post /v1/estate/projects:request-scan","href":"/earnie/api-reference/estate/estate/request-a-re-scan-for-every-selected-eligible-project"}]}]},{"group":"Organization Settings","pages":[{"group":"organization","pages":[{"title":"Get organization profile","deprecated":null,"version":null,"openapi":"/api-reference/earnie/platform-openapi.json get /v1/organization","href":"/earnie/api-reference/platform/organization/get-organization-profile"},{"title":"Get the organization logo","deprecated":null,"version":null,"openapi":"/api-reference/earnie/platform-openapi.json get /v1/organization/branding/logo","href":"/earnie/api-reference/platform/organization/get-the-organization-logo"},{"title":"List the scanners enabled for your organization","deprecated":null,"version":null,"openapi":"/api-reference/earnie/platform-openapi.json get /v1/organization/modules","href":"/earnie/api-reference/platform/organization/list-the-scanners-enabled-for-your-organization"},{"title":"Get the organization's pull-request controls","deprecated":null,"version":null,"openapi":"/api-reference/earnie/platform-openapi.json get /v1/organization/pr-feedback","href":"/earnie/api-reference/platform/organization/get-the-organizations-pull-request-controls"},{"title":"Replace the organization's pull-request controls","deprecated":null,"version":null,"openapi":"/api-reference/earnie/platform-openapi.json put /v1/organization/pr-feedback","href":"/earnie/api-reference/platform/organization/replace-the-organizations-pull-request-controls"},{"title":"Get the organization's Scan Configuration","deprecated":null,"version":null,"openapi":"/api-reference/earnie/platform-openapi.json get /v1/organization/scan-configuration","href":"/earnie/api-reference/platform/organization/get-the-organizations-scan-configuration"},{"title":"Replace the organization's Scan Configuration","deprecated":null,"version":null,"openapi":"/api-reference/earnie/platform-openapi.json put /v1/organization/scan-configuration","href":"/earnie/api-reference/platform/organization/replace-the-organizations-scan-configuration"},{"title":"Get a project's auto-scan-on-merge setting","deprecated":null,"version":null,"openapi":"/api-reference/earnie/platform-openapi.json get /v1/projects/{projectId}/auto-scan","href":"/earnie/api-reference/platform/organization/get-a-projects-auto-scan-on-merge-setting"},{"title":"Enable or pause a project's auto-scan-on-merge","deprecated":null,"version":null,"openapi":"/api-reference/earnie/platform-openapi.json put /v1/projects/{projectId}/auto-scan","href":"/earnie/api-reference/platform/organization/enable-or-pause-a-projects-auto-scan-on-merge"},{"title":"Get a project's pre-commit hook setting","deprecated":null,"version":null,"openapi":"/api-reference/earnie/platform-openapi.json get /v1/projects/{projectId}/hook-settings","href":"/earnie/api-reference/platform/organization/get-a-projects-pre-commit-hook-setting"},{"title":"Set a project's pre-commit hook setting","deprecated":null,"version":null,"openapi":"/api-reference/earnie/platform-openapi.json put /v1/projects/{projectId}/hook-settings","href":"/earnie/api-reference/platform/organization/set-a-projects-pre-commit-hook-setting"},{"title":"Get a project's pull-request feedback setting","deprecated":null,"version":null,"openapi":"/api-reference/earnie/platform-openapi.json get /v1/projects/{projectId}/pr-feedback","href":"/earnie/api-reference/platform/organization/get-a-projects-pull-request-feedback-setting"},{"title":"Set a project's pull-request controls","deprecated":null,"version":null,"openapi":"/api-reference/earnie/platform-openapi.json put /v1/projects/{projectId}/pr-feedback","href":"/earnie/api-reference/platform/organization/set-a-projects-pull-request-controls"},{"title":"Get a project's Scan Configuration sources","deprecated":null,"version":null,"openapi":"/api-reference/earnie/platform-openapi.json get /v1/projects/{projectId}/scan-configuration","href":"/earnie/api-reference/platform/organization/get-a-projects-scan-configuration-sources"},{"title":"Replace a project's Scan Configuration","deprecated":null,"version":null,"openapi":"/api-reference/earnie/platform-openapi.json put /v1/projects/{projectId}/scan-configuration","href":"/earnie/api-reference/platform/organization/replace-a-projects-scan-configuration"}]}]},{"group":"Integrations","pages":[{"group":"integrations","pages":[{"title":"Each connection's recorded health, and their aggregate","deprecated":null,"version":null,"openapi":"/api-reference/earnie/integrations-openapi.json get /v1/integrations/connections","href":"/earnie/api-reference/integrations/integrations/each-connections-recorded-health-and-their-aggregate"},{"title":"GitHub connection status (liveness-checked)","deprecated":null,"version":null,"openapi":"/api-reference/earnie/integrations-openapi.json get /v1/integrations/github","href":"/earnie/api-reference/integrations/integrations/github-connection-status-liveness-checked"},{"title":"List GitLab connections with what their tokens were checked to be","deprecated":null,"version":null,"openapi":"/api-reference/earnie/integrations-openapi.json get /v1/integrations/gitlab/connections","href":"/earnie/api-reference/integrations/integrations/list-gitlab-connections-with-what-their-tokens-were-checked-to-be"},{"title":"List the repositories the connections can access (live)","deprecated":null,"version":null,"openapi":"/api-reference/earnie/integrations-openapi.json get /v1/integrations/repositories","href":"/earnie/api-reference/integrations/integrations/list-the-repositories-the-connections-can-access-live"}]}]},{"group":"Components","pages":[{"group":"API Reference","pages":[{"title":"Search the SCANOSS component knowledgebase","deprecated":null,"version":null,"openapi":"/api-reference/earnie/components-openapi.json get /v1/components","href":"/earnie/api-reference/components/search-the-scanoss-component-knowledgebase"}]}]},{"group":"Audit log","pages":[{"group":"API Reference","pages":[{"title":"List instance-wide audit events","deprecated":null,"version":null,"openapi":"/api-reference/earnie/audit-openapi.json get /v1/audit-log","href":"/earnie/api-reference/audit/list-instance-wide-audit-events"},{"title":"Get one audit event","deprecated":null,"version":null,"openapi":"/api-reference/earnie/audit-openapi.json get /v1/audit-log/{eventId}","href":"/earnie/api-reference/audit/get-one-audit-event"}]}]}]}]},{"tab":"Developer Tools","hidden":false,"pages":[{"title":"Developer Tools","href":"/en/latest/developer-tools/overview"}]}]},{"version":"v1","pages":[{"title":"v1","href":"/en/latest/introduction/what-is-scanoss"}]}]},"title":"Plan a folder scan — keep engine then 202 receiving - SCANOSS documentation","buildId":"dpl_EnxDqhjaNc9a8MVa833TGULPd9uJ","deploymentId":"dpl_EnxDqhjaNc9a8MVa833TGULPd9uJ","dynamics":["10e4515597","c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["BannerMarkdown-m8-xYP3Y.js","dist-1ms6tsT-.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","clsx-DMKzROTp.js","html-void-elements-mCSPHezU.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","OpenApiReferenceProvider-26-lDe7V.js","utils-CWQmgYtH.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-4-Aw3rSD.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-C2zjXYA5.js","snippetPresets-DFmpFA7C.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","ApiExamples-FJpQavWq.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-D_GvPF7k.js","shallow-Bs2ZB0NO.js","getApiPlaygroundDisplay-DCcqJJk-.js","CodeSnippet-DzDxawVe.js","CodeSnippets-aUr7fU-7.js","Page-CT9uE8Ip.js","getPastedJson-Y1fKsj_I.js","icon-DI4zTsDr.js","MethodPill-C0nDlmSQ.js","DuplicateIcon-NUXbx2nQ.js","createIcon-BdTHrPAi.js","DynamicMarkdown-CtpgKJwj.js","SectionHeading-B3x35tOt.js","axios-vUo_bRtp.js","Markdown-3OmurJMP.js","AssistantPageLink-Ke9xIMFx.js"]}