# RFP Compliance Matrix Generator & Proposal Audit (`chen_white/rfp-compliance-matrix`) Actor

Generate a source-cited RFP compliance matrix, audit proposal coverage, and export a proposal-ready Excel workbook.

- **URL**: https://apify.com/chen\_white/rfp-compliance-matrix.md
- **Developed by:** [Chen White](https://apify.com/chen_white) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $6.50 / completed rfp analysis

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### RFP Compliance Matrix Generator & Proposal Audit

**Upload an RFP.**\
**Get a cited compliance matrix in Excel.**\
**Add your proposal draft to find missing requirements before submission.**

[![Free quick preview](https://img.shields.io/badge/FREE-quick%20preview-0F766E?style=for-the-badge)](https://console.apify.com/actors/v9eyZnmf2YE9obqz2) [![Full audit](https://img.shields.io/badge/FULL%20AUDIT-%246.50-1E3A5F?style=for-the-badge)](https://console.apify.com/actors/v9eyZnmf2YE9obqz2) [![Cloud validated](https://img.shields.io/badge/CLOUD-validated-2563EB?style=for-the-badge)](https://console.apify.com/actors/v9eyZnmf2YE9obqz2/runs/ixN9gvbMzaEB6T9UH)

| **Free preview** | **Full proposal audit — $6.50** |
| --- | --- |
| Upload one RFP; first 10 pages | Upload up to three RFPs; all supported pages |
| Eight highest-priority findings | Complete, source-cited requirement matrix |
| Two-sheet Excel preview | Five-sheet proposal-ready Excel workbook |
| Excel + CSV + JSON + Markdown | Excel + CSV + JSON + Markdown |
| No `completed-analysis` fee | One charge after the complete package is stored |

> **Validated sample: 3 seconds · Excel + CSV + JSON + Markdown.** The free preview detected **29 candidate requirements**, returned the **eight highest-priority findings**, generated all four download formats, and explicitly logged that no `completed-analysis` fee was charged. [Inspect the cloud run](https://console.apify.com/actors/v9eyZnmf2YE9obqz2/runs/ixN9gvbMzaEB6T9UH).

#### What the $6.50 full audit buys

This is not just a `shall`/`must` extractor. A completed full analysis includes:

- a **five-sheet Excel workbook** ready for proposal-team ownership and status tracking;
- a **Proposal Coverage Audit** that prioritizes missing and partially addressed requirements;
- **proposal evidence citations** linking each coverage decision to the strongest draft passage;
- a source-cited compliance matrix with RFP page numbers and verbatim evidence;
- a **Section L/M crosswalk**, deadline candidates, delivery risks, and an executive summary;
- matching CSV, structured JSON, Markdown, and Apify dataset outputs for downstream automation.

**Built for human proposal teams and AI workflows:** deterministic, source-cited, structured output with no external generative-AI API dependency.

#### Try the free preview

Choose **Free quick preview**, upload one RFP PDF, authorize only the Key-Value Store that holds it, and press **Start**. No public file hosting is required. You can optionally upload a proposal PDF to see prioritized coverage gaps. If you do not upload anything, the documented public sample runs automatically. Free preview does not emit the USD 6.50 `completed-analysis` event; normal Apify platform usage may still apply.

```json
{
  "analysisMode": "preview",
  "documentUrls": [
    "https://ardcplanning.org/wp-content/uploads/2025/11/Website-Redesign-2025-RFP-ARDC-and-ARDC-Planning-Final.pdf"
  ]
}
```

### What you get

#### Proposal Coverage Audit

When you provide a proposal draft, the Actor compares every extracted requirement with short passages from the draft and returns:

- a conservative coverage status for every matrix row;
- the strongest matching proposal passage;
- a proposal page citation for PDF drafts, or block and segment coordinates for pasted text;
- a numeric match score and the terms that contributed to it;
- a separate audit sheet ordered by the most urgent gaps first;
- counts of critical and high-risk requirements that were not found.

The four statuses are designed for triage, not automatic approval:

| Status | Meaning | Recommended action |
| --- | --- | --- |
| `Likely addressed` | Strong requirement-specific lexical evidence appears in one proposal passage. | Confirm the passage fully answers the requirement and uses defensible evidence. |
| `Partially addressed` | Some relevant language appears, but the full obligation may be missing. | Expand or revise the cited section. |
| `Not found` | No sufficiently complete matching passage was identified. | Treat as a drafting gap and verify manually. |
| `Manual review` | The requirement is too short or vague for a reliable deterministic match. | Read the RFP citation and decide manually. |

The audit intentionally favors review over confident claims. A high score means strong textual overlap, not that the answer is correct, persuasive, or legally compliant.

#### Proposal-ready compliance workbook

The Excel workbook contains five working sheets:

1. **Executive Summary** — volume, deadlines, delivery risks, coverage counts, and high-risk omissions.
2. **Proposal Coverage** — prioritized gaps with RFP evidence, proposal evidence, citations, scores, and review reasons.
3. **Compliance Matrix** — editable owner, status, compliance response, and evidence fields beside every extracted requirement.
4. **L-M Crosswalk** — deterministic alignment between supported Section L instruction subjects and Section M evaluation subjects.
5. **Documents** — source URLs, page counts, text coverage, SHA-256 provenance, and extraction status.

Cross-document IDs such as `CM-0001` stay consistent across the workbook, CSV, dataset, summary, and JSON package.

### Quick start

Use `analysisMode: "preview"` for the free quick preview. Use `analysisMode: "full"` when you want the complete paid package.

For private files in Apify Console:

1. Use **Upload RFP PDF files** and optionally **Upload proposal draft PDF**. Put all files in one permanent Key-Value Store when practical.
2. In **Authorize uploaded-file Key-Value Stores**, select each store used in step 1.
3. Press **Start**. Apify grants this limited-permission Actor read-only access to only those selected stores for the run.

You do not need to publish confidential drafts on the open web, and the Actor cannot browse unrelated account storage. Query-string access signatures are removed from delivered citations and artifacts.

For API and automation workflows, public or signed HTTPS file references remain supported:

To audit pasted proposal text:

```json
{
  "analysisMode": "full",
  "projectName": "City Website Redesign Bid",
  "documentUrls": [
    "https://example.gov/procurement/website-redesign-rfp.pdf"
  ],
  "proposalText": "Paste the proposal draft here...",
  "includeGuidance": true,
  "maxPages": 250
}
```

To preserve PDF page citations in the proposal evidence, use `proposalPdfUrl` instead of `proposalText`:

```json
{
  "analysisMode": "full",
  "projectName": "City Website Redesign Bid",
  "documentUrls": [
    "https://example.gov/procurement/website-redesign-rfp.pdf"
  ],
  "proposalPdfUrl": "https://files.example.com/proposal-draft.pdf",
  "includeGuidance": true,
  "maxPages": 250
}
```

Provide either `proposalPdfUrl` or `proposalText`, not both. Leave both empty when you only need RFP extraction and the compliance package.

### Input reference

| Field | Required | Description |
| --- | --- | --- |
| `analysisMode` | Yes in the form | `preview` inspects one PDF, up to 10 pages, and returns eight prioritized findings without the completed-analysis fee. `full` unlocks the complete package. Legacy API inputs that omit this field continue to run as `full`. |
| `rfpFiles` | No | Console upload field for one RFP in preview mode or up to three in full mode. No public hosting step is required. |
| `proposalFile` | No | Console upload field for one optional proposal draft PDF. Mutually exclusive with the other proposal inputs. |
| `inputStores` | For private uploads | Explicitly grants `READ` access to each KVS used by `rfpFiles` or `proposalFile`; it does not grant access to unrelated storage. |
| `documentUrls` | No | API-friendly alternative: one to three direct public or signed HTTPS PDF references. |
| `projectName` | No | A 1–120 character title used in the workbook and summary. |
| `proposalPdfUrl` | No | One direct public or signed HTTPS PDF URL for the proposal draft. Mutually exclusive with `proposalText`. |
| `proposalText` | No | Pasted proposal text from 20 to 500,000 characters. Mutually exclusive with `proposalPdfUrl`. |
| `includeGuidance` | Yes | Include lower-confidence `should` and guidance candidates when `true`. |
| `maxPages` | Yes | Reject any individual PDF above this 1–500 page limit. |

### Output records

Both modes use the same predictable artifact links. Preview artifacts are visibly labelled and limited; full-mode artifacts contain the complete supported analysis.

Open the run result to download:

- `COMPLIANCE_MATRIX.xlsx` — two preview sheets in free mode or the complete five-sheet working package in full mode;
- `COMPLIANCE_MATRIX.csv` — all compliance and proposal-coverage columns in a portable table;
- `EXECUTIVE_SUMMARY.md` — concise deadlines, risks, crosswalk results, and proposal gaps;
- `REQUIREMENTS.json` — the complete structured package, including documents, requirements, coverage, deadlines, and crosswalk;
- Dataset — one structured row per requirement for Apify API, automation, or downstream review workflows.

Every requirement row includes the source URL, SHA-256 digest, RFP page range, source quote, modality, category, review priority, source role, risk, and human-review status. Coverage-enabled runs add proposal evidence, proposal citation, score, matched terms, and a plain-language reason.

### How the audit works

1. Downloads each allowed PDF after validating the HTTPS destination and every redirect.
2. Extracts text page by page and refuses to emit an empty success for image-only documents.
3. Generates requirement candidates with page-level source quotes and conservative review priorities.
4. Builds delivery risks, actionable date candidates, and the Section L/M subject crosswalk.
5. Splits the optional proposal draft into bounded passages and compares each requirement using weighted, normalized lexical evidence.
6. Stores the dataset and all downloadable artifacts.
7. Emits the billable completion event only when `analysisMode` is `full`; preview mode explicitly skips it.

The coverage audit is deterministic and does not call an external generative-AI API. The same extracted text and configuration produce the same comparison results.

### Security and draft handling

- Console uploads are stored in user-selected Apify Key-Value Stores. Users explicitly grant `READ` access to only those stores through `inputStores`; the Actor strips query-string access signatures from delivered citations and artifacts.
- External URL inputs must resolve over public HTTPS. Private-network, loopback, credential-bearing, and unresolved URLs are rejected.
- Redirect destinations are revalidated before download.
- Each PDF has a 20 MB download limit, a 30-second fetch timeout, and a configurable page limit.
- Query strings from a proposal PDF URL are not copied into the delivered proposal metadata, but the original Actor input remains in your Apify run storage.
- Pasted proposal text is stored in the Actor input. Matching excerpts also appear in the run dataset and downloadable artifacts.
- Do not submit confidential or controlled proposal material unless your organization permits it to be processed and retained in your Apify account. Apply the appropriate run-storage retention or deletion policy after review.
- The Actor uses limited permissions. It can read uploaded files only from the KVS resources explicitly selected in `inputStores` and cannot access unrelated Apify resources.

### Pricing

The **free quick preview does not emit the USD 6.50 `completed-analysis` event**. Normal Apify platform usage and any small platform-defined events shown in the Pricing tab may still apply.

Full mode costs **USD 6.50 per completed analysis**. One completion covers the complete artifact package and the optional Proposal Coverage Audit. The event is emitted only after at least one RFP PDF succeeds and the dataset, Excel workbook, CSV, Markdown summary, JSON package, and run summary have all been stored.

Failed downloads and runs where every document is unsupported do not emit the completed-analysis event. Small platform-defined Actor-start and dataset-item charges are shown separately in the Pricing tab.

### Validation evidence

The extraction pipeline has been evaluated on 10 public documents covering 336 pages and 1,913 requirement candidates. Review samples recorded:

- 100/100 checked page citations correct;
- 82.98% actionable precision on a deterministic 100-row full-queue sample with guidance included;
- 98.62% and 96.60% actionable precision on two fresh 150-row high-priority blind samples;
- 44/44 bounded gold obligations detected across two short RFPs, with 43/44 retained at high priority.

The free and full paths both passed capped public-cloud end-to-end validation on build `0.0.29` using a five-page public RFP and an intentionally incomplete synthetic draft. Free-preview run `ixN9gvbMzaEB6T9UH` finished in 3 seconds, detected 29 candidates, returned eight prioritized findings, stored the two-sheet workbook plus CSV, Markdown, and JSON, and logged `chargedCount: 0` with reason `free_preview_mode`. Full regression run `4jatMxKmOrfge0QN2` finished in 3 seconds and generated 29 cited rows: 5 likely addressed, 8 partially addressed, 14 not found, and 2 manual review, including 7 critical/high-risk items not found. Both test runs used a USD 0.05 maximum-cost guard; the Console displayed USD 0.000 for preview and USD 0.001 for full platform usage. The project currently passes 33/33 automated tests, including upload-reference, restricted-token authentication, KVS-authorization guidance, and access-signature regressions, all Apify schemas, dependency audit, structural workbook inspection, formula-error scanning, and rendered visual review.

These measurements establish tested behavior on the stated samples. They do not establish complete recall or general accuracy across every procurement format.

### Current limitations

- No OCR for scanned or image-only PDFs.
- No structured reconstruction of complex tables.
- No automatic amendment comparison.
- No direct authenticated websites or private-network sources; use the built-in Apify upload fields for local/private PDFs.
- No DOCX, XLSX, ZIP, or controlled attachment ingestion.
- Coverage matching is lexical and may miss paraphrases or select a passage that uses similar language for a different purpose.
- Page limits, signatures, attachment packaging, deadlines, pricing accuracy, and legal terms still require final human review.

This Actor supports proposal planning and review. It does not make a legal, procurement, or final compliance determination.

### Local verification

```bash
npm test
npm audit --omit=dev
npx apify-cli validate-schema
npm run validate-corpus
```

`VALIDATION_REPORT.md` documents the evaluation design, sampling limits, confidence intervals, source roles, and remaining risks.

# Actor input Schema

## `analysisMode` (type: `string`):

Start with the free quick preview. Full mode unlocks every supported page, up to three RFP PDFs, and the complete five-sheet package for USD 6.50.

## `rfpFiles` (type: `array`):

Upload one PDF for free preview or up to three PDFs for a full audit. Files are stored in the Apify Key-Value Store you choose; no public hosting is required.

## `proposalFile` (type: `string`):

Upload a proposal draft for the coverage audit. The file and derived evidence remain in your Apify storage. Use only one proposal input method.

## `inputStores` (type: `array`):

Required for private uploads: select every Key-Value Store used by the RFP and proposal upload fields. The Actor receives READ access only to the selected stores and remains unable to access other account data.

## `projectName` (type: `string`):

Title used in the downloadable compliance package.

## `documentUrls` (type: `array`):

API-friendly alternative to upload. Add direct HTTPS PDF links, or leave this empty and use the upload field above.

## `proposalPdfUrl` (type: `string`):

Direct public or signed HTTPS PDF URL. Use either this field or Proposal text, not both. The draft and derived excerpts are processed and stored in your Apify run storage.

## `proposalText` (type: `string`):

Paste 20–500,000 characters to audit coverage without hosting a PDF. Use either this field or Proposal PDF URL. Input and derived excerpts are stored in your Apify run storage.

## `includeGuidance` (type: `boolean`):

Include non-mandatory statements expressed with should alongside mandatory candidates.

## `maxPages` (type: `integer`):

Reject any individual PDF that exceeds this page count.

## Actor input object example

```json
{
  "analysisMode": "preview",
  "rfpFiles": [],
  "proposalFile": "",
  "projectName": "RFP Compliance Package",
  "documentUrls": [],
  "proposalPdfUrl": "",
  "proposalText": "",
  "includeGuidance": true,
  "maxPages": 250
}
```

# Actor output Schema

## `workbook` (type: `string`):

No description

## `csv` (type: `string`):

No description

## `executiveSummary` (type: `string`):

No description

## `requirementsJson` (type: `string`):

No description

## `dataset` (type: `string`):

No description

## `output` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("chen_white/rfp-compliance-matrix").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("chen_white/rfp-compliance-matrix").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call chen_white/rfp-compliance-matrix --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,chen_white/rfp-compliance-matrix"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/v9eyZnmf2YE9obqz2/builds/eY6HgpjHFdfzbak1S/openapi.json
