openapi: 3.2.0 info: title: EpicDirectories Screening API description: API-first directory data platform. version: '1.0' contact: {} servers: - url: https://api.epicdirectories.com description: Production - url: http://localhost:3333 description: Local development tags: - name: Screening paths: /v1/directories/{directoryId}/screening: get: operationId: ScreeningController_report summary: Which listings point at a site that is not really there description: 'Reads the probe evidence already on record and applies this directory’s screening policy. **Fetches nothing** — run `POST .../site-probes/sweep` with `kind: "site"` first, or the answer is about hosts nobody has looked at. Four verdicts, one per listing, most severe first: `site-dead`, `site-parked`, `site-placeholder`, `site-thin`. **`summary.unscreened` is the gap, not a pass.** Those listings have no site evidence either way. `summary.inconclusive` counts hosts that refused us or that we could not reach — never a verdict, because a Cloudflare challenge is a fact about our crawler and not about the business.' parameters: - name: directoryId required: true in: path schema: type: string - name: term required: false in: query description: Only this verdict schema: type: string - name: limit required: false in: query description: Rows returned (default 200) schema: type: number responses: '200': description: Flagged listings plus a coverage summary '404': description: Directory not found or not yours tags: - Screening security: - bearer: [] /v1/directories/{directoryId}/screening/apply: post: operationId: ScreeningController_apply summary: Tag the flagged listings, and hold the confident ones in draft description: 'Writes the verdicts as terms in the review taxonomy, creating the taxonomy and only the terms actually earned. **Additive.** Terms are written directly, so a listing’s services, industries and regions are untouchable by this endpoint — unlike `PUT .../terms`, which is replace-all. **Self-correcting.** A screening term that no longer applies is removed, so a site that comes back stops being tagged as dead. Only the four screening terms are ever removed; your own review tags are never touched. **It never re-publishes.** `site-dead`, `site-parked` and `site-placeholder` pull a published listing back to draft. Nothing puts it back — a listing may have been edited or merged since, and silently re-publishing is a change nobody asked for. Pass `hold: false` for a tag-only pass. Send `dryRun: true` to see the counts without writing. It previews both halves — `wouldTag`/`wouldHold` for what would be added, `wouldClear` for what would be removed. Watch `wouldClear`: clearing recovered listings is uncapped and is not drawn from the capped selection, so a converged directory can preview zero tags and still have removals pending.' parameters: - name: directoryId required: true in: path schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ApplyScreeningDto' responses: '201': description: Counts of what changed '404': description: Directory not found or not yours tags: - Screening security: - bearer: [] components: schemas: ApplyScreeningDto: type: object properties: dryRun: type: boolean description: Report what would change and write nothing. The counts are computed by the same code path that does the writing, so a dry run cannot disagree with the real one. default: false hold: type: boolean description: 'Pull flagged listings back to draft as well as tagging them. On by default: which verdicts unpublish is a property of the policy, not of the caller. Set false for a tag-only pass when you want to read the queue before anything leaves the directory.' default: true limit: type: number description: How many listings to act on, capped at 2000. The response reports `deferred` when the cap bit rather than implying full coverage. minimum: 1 maximum: 2000 default: 2000 securitySchemes: bearer: scheme: bearer bearerFormat: JWT type: http apiKey: type: apiKey in: header name: x-api-key x-provenance: method: harvested publisher: EpicDirectories source: https://api.epicdirectories.com/openapi.json note: split by refine-openapis from the provider's own published document, verified by fetch (openapi/_original/*.fetch.json); stamped by stamp-openapi-provenance.py (roadmap#793)