# API: Questionnaires

| Method | Path | What it does | Scope |
|---|---|---|---|
| GET | `/v1/rfp/analytics` | Workload and volume: open projects, questions assigned, answered, approved and overdue per person, cycle times, volume by week | `deals:read` |
| POST | `/v1/rfp/answer` | Answer pasted questions from approved sources only, with citations and confidence (the same rules as a project) | `deals:read` |
| POST | `/v1/rfp/assign` | Assign questions (or a section) to a writer and reviewer, with a due date | `deals:write` |
| GET | `/v1/rfp/library` | The Q&A library, with each entry's review state (stale past the review window or when a cited source changed) | `deals:read` |
| POST | `/v1/rfp/library` | Propose a library entry (used once an owner or its owner approves it) | `deals:write` |
| PATCH | `/v1/rfp/library/:id` | Edit, approve or archive an entry (approving needs an owner or the entry's owner) | `deals:write` |
| POST | `/v1/rfp/library/:id/review` | Mark an entry reviewed (still right as it is) | `deals:write` |
| GET | `/v1/rfp/library/duplicates` | Groups of near-duplicate entries, each with the entry to keep | `deals:read` |
| GET | `/v1/rfp/library/export` | Export the whole library (question, answer, alternates, owner, last reviewed, status, tags, sources) as .xlsx or .csv | `deals:read` |
| POST | `/v1/rfp/library/import` | Import the export's format (.xlsx or .csv): rows with an id update that entry; others are proposals | `deals:write` |
| POST | `/v1/rfp/library/merge` | Merge entries: keep one; the others' questions become its alternate phrasings | `deals:write` |
| GET | `/v1/rfp/projects` | Questionnaire projects | `deals:read` |
| POST | `/v1/rfp/projects` | Start a questionnaire project, from a deal (prefilled with its account, owner and close date) or on its own | `deals:write` |
| GET | `/v1/rfp/projects/:id` | A project with its files, sections, questions (answers, citations, confidence, trace) and comments | `deals:read` |
| POST | `/v1/rfp/projects/:id/draft` | Draft answers for open questions from approved sources (each with citations, confidence and its trace; a person's answer is never overwritten) | `deals:write` |
| POST | `/v1/rfp/projects/:id/export` | Answers written into the original .docx or .xlsx (everything else untouched), or an answers file for a PDF | `deals:read` |
| POST | `/v1/rfp/projects/:id/files` | Add a questionnaire (.docx, .xlsx, .pdf, text): questions and sections are detected with their place in the file | `deals:write` |
| POST | `/v1/rfp/projects/:id/questions` | Add a question by hand | `deals:write` |
| POST | `/v1/rfp/projects/:id/sign-off` | The project owner signs off (with a note when some answers aren't approved); recorded with who and when | `deals:write` |
| POST | `/v1/rfp/projects/:id/status` | Reopen, mark in review, submitted or archived (the project owner) | `deals:write` |
| PUT | `/v1/rfp/questions/:id/answer` | Write or edit an answer (back to draft) | `deals:write` |
| POST | `/v1/rfp/questions/:id/comments` | Comment on a question; @email mentions of teammates notify them | `deals:write` |
| POST | `/v1/rfp/questions/:id/fix` | Fix detection: edit, mark not a question (or restore), merge with another, or split | `deals:write` |
| POST | `/v1/rfp/questions/:id/library` | Propose an approved answer to the library | `deals:write` |
| POST | `/v1/rfp/questions/:id/status` | Send for review, approve (the reviewer or the project owner, never the answer's author) or send back to draft | `deals:write` |
| GET | `/v1/rfp/settings` | Which knowledge answers come from (founder default 12), the review window, the confidence threshold and the deal stage that starts a project | `deals:read` |
| PUT | `/v1/rfp/settings` | Change the approved sources and questionnaire settings (owners) | `settings:write` |
| DELETE | `/v1/rfp/vanta` | Disconnect Vanta; what was read from it stops being a source (owners) | `integrations:write` |
| GET | `/v1/rfp/vanta` | Whether Vanta is connected, when it last synced, and what was read | `deals:read` |
| PUT | `/v1/rfp/vanta` | Connect Vanta with your private app's client id and secret (read scope; stored encrypted) (owners) | `integrations:write` |
| POST | `/v1/rfp/vanta/sync` | Read Vanta now (owners) | `integrations:write` |

## Examples

### GET /v1/rfp/analytics

Workload and volume: open projects, questions assigned, answered, approved and overdue per person, cycle times, volume by week

```bash
curl -s "https://api.closefinch.com/v1/rfp/analytics" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/analytics`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/rfp/answer

Answer pasted questions from approved sources only, with citations and confidence (the same rules as a project)

```bash
curl -s -X POST "https://api.closefinch.com/v1/rfp/answer" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/answer`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/rfp/assign

Assign questions (or a section) to a writer and reviewer, with a due date

```bash
curl -s -X POST "https://api.closefinch.com/v1/rfp/assign" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/assign`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/rfp/library

The Q&A library, with each entry's review state (stale past the review window or when a cited source changed)

```bash
curl -s "https://api.closefinch.com/v1/rfp/library" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/library`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/rfp/library

Propose a library entry (used once an owner or its owner approves it)

```bash
curl -s -X POST "https://api.closefinch.com/v1/rfp/library" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/library`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### PATCH /v1/rfp/library/$ID

Edit, approve or archive an entry (approving needs an owner or the entry's owner)

```bash
curl -s -X PATCH "https://api.closefinch.com/v1/rfp/library/$ID" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/library/${id}`, {
  method: "PATCH",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/rfp/library/$ID/review

Mark an entry reviewed (still right as it is)

```bash
curl -s -X POST "https://api.closefinch.com/v1/rfp/library/$ID/review" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/library/${id}/review`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/rfp/library/duplicates

Groups of near-duplicate entries, each with the entry to keep

```bash
curl -s "https://api.closefinch.com/v1/rfp/library/duplicates" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/library/duplicates`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/rfp/library/export

Export the whole library (question, answer, alternates, owner, last reviewed, status, tags, sources) as .xlsx or .csv

```bash
curl -s "https://api.closefinch.com/v1/rfp/library/export" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/library/export`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/rfp/library/import

Import the export's format (.xlsx or .csv): rows with an id update that entry; others are proposals

```bash
curl -s -X POST "https://api.closefinch.com/v1/rfp/library/import" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/library/import`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/rfp/library/merge

Merge entries: keep one; the others' questions become its alternate phrasings

```bash
curl -s -X POST "https://api.closefinch.com/v1/rfp/library/merge" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/library/merge`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/rfp/projects

Questionnaire projects

```bash
curl -s "https://api.closefinch.com/v1/rfp/projects" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/projects`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/rfp/projects

Start a questionnaire project, from a deal (prefilled with its account, owner and close date) or on its own

```bash
curl -s -X POST "https://api.closefinch.com/v1/rfp/projects" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/projects`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/rfp/projects/$ID

A project with its files, sections, questions (answers, citations, confidence, trace) and comments

```bash
curl -s "https://api.closefinch.com/v1/rfp/projects/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/projects/${id}`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/rfp/projects/$ID/draft

Draft answers for open questions from approved sources (each with citations, confidence and its trace; a person's answer is never overwritten)

```bash
curl -s -X POST "https://api.closefinch.com/v1/rfp/projects/$ID/draft" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/projects/${id}/draft`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/rfp/projects/$ID/export

Answers written into the original .docx or .xlsx (everything else untouched), or an answers file for a PDF

```bash
curl -s -X POST "https://api.closefinch.com/v1/rfp/projects/$ID/export" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/projects/${id}/export`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/rfp/projects/$ID/files

Add a questionnaire (.docx, .xlsx, .pdf, text): questions and sections are detected with their place in the file

```bash
curl -s -X POST "https://api.closefinch.com/v1/rfp/projects/$ID/files" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/projects/${id}/files`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/rfp/projects/$ID/questions

Add a question by hand

```bash
curl -s -X POST "https://api.closefinch.com/v1/rfp/projects/$ID/questions" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/projects/${id}/questions`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/rfp/projects/$ID/sign-off

The project owner signs off (with a note when some answers aren't approved); recorded with who and when

```bash
curl -s -X POST "https://api.closefinch.com/v1/rfp/projects/$ID/sign-off" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/projects/${id}/sign-off`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/rfp/projects/$ID/status

Reopen, mark in review, submitted or archived (the project owner)

```bash
curl -s -X POST "https://api.closefinch.com/v1/rfp/projects/$ID/status" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/projects/${id}/status`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### PUT /v1/rfp/questions/$ID/answer

Write or edit an answer (back to draft)

```bash
curl -s -X PUT "https://api.closefinch.com/v1/rfp/questions/$ID/answer" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/questions/${id}/answer`, {
  method: "PUT",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/rfp/questions/$ID/comments

Comment on a question; @email mentions of teammates notify them

```bash
curl -s -X POST "https://api.closefinch.com/v1/rfp/questions/$ID/comments" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/questions/${id}/comments`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/rfp/questions/$ID/fix

Fix detection: edit, mark not a question (or restore), merge with another, or split

```bash
curl -s -X POST "https://api.closefinch.com/v1/rfp/questions/$ID/fix" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/questions/${id}/fix`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/rfp/questions/$ID/library

Propose an approved answer to the library

```bash
curl -s -X POST "https://api.closefinch.com/v1/rfp/questions/$ID/library" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/questions/${id}/library`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/rfp/questions/$ID/status

Send for review, approve (the reviewer or the project owner, never the answer's author) or send back to draft

```bash
curl -s -X POST "https://api.closefinch.com/v1/rfp/questions/$ID/status" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/questions/${id}/status`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/rfp/settings

Which knowledge answers come from (founder default 12), the review window, the confidence threshold and the deal stage that starts a project

```bash
curl -s "https://api.closefinch.com/v1/rfp/settings" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/settings`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### PUT /v1/rfp/settings

Change the approved sources and questionnaire settings (owners)

```bash
curl -s -X PUT "https://api.closefinch.com/v1/rfp/settings" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/settings`, {
  method: "PUT",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### DELETE /v1/rfp/vanta

Disconnect Vanta; what was read from it stops being a source (owners)

```bash
curl -s -X DELETE "https://api.closefinch.com/v1/rfp/vanta" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/vanta`, {
  method: "DELETE",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/rfp/vanta

Whether Vanta is connected, when it last synced, and what was read

```bash
curl -s "https://api.closefinch.com/v1/rfp/vanta" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/vanta`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### PUT /v1/rfp/vanta

Connect Vanta with your private app's client id and secret (read scope; stored encrypted) (owners)

```bash
curl -s -X PUT "https://api.closefinch.com/v1/rfp/vanta" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/vanta`, {
  method: "PUT",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### POST /v1/rfp/vanta/sync

Read Vanta now (owners)

```bash
curl -s -X POST "https://api.closefinch.com/v1/rfp/vanta/sync" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/rfp/vanta/sync`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

Request and response schemas: [https://www.closefinch.com/openapi.json](https://www.closefinch.com/openapi.json). All resources: [API reference](https://www.closefinch.com/docs/api).
