API reference
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
curl -s "https://api.closefinch.com/v1/rfp/analytics" \
-H "Authorization: Bearer $RA_API_KEY"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)
curl -s -X POST "https://api.closefinch.com/v1/rfp/answer" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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
curl -s -X POST "https://api.closefinch.com/v1/rfp/assign" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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)
curl -s "https://api.closefinch.com/v1/rfp/library" \
-H "Authorization: Bearer $RA_API_KEY"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)
curl -s -X POST "https://api.closefinch.com/v1/rfp/library" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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)
curl -s -X PATCH "https://api.closefinch.com/v1/rfp/library/$ID" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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)
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 '{}'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
curl -s "https://api.closefinch.com/v1/rfp/library/duplicates" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/rfp/library/export" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s -X POST "https://api.closefinch.com/v1/rfp/library/import" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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
curl -s -X POST "https://api.closefinch.com/v1/rfp/library/merge" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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
curl -s "https://api.closefinch.com/v1/rfp/projects" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s -X POST "https://api.closefinch.com/v1/rfp/projects" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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
curl -s "https://api.closefinch.com/v1/rfp/projects/$ID" \
-H "Authorization: Bearer $RA_API_KEY"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)
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 '{}'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
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 '{}'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
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 '{}'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
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 '{}'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
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 '{}'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)
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 '{}'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)
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 '{}'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
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 '{}'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
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 '{}'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
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 '{}'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
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 '{}'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
curl -s "https://api.closefinch.com/v1/rfp/settings" \
-H "Authorization: Bearer $RA_API_KEY"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)
curl -s -X PUT "https://api.closefinch.com/v1/rfp/settings" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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)
curl -s -X DELETE "https://api.closefinch.com/v1/rfp/vanta" \
-H "Authorization: Bearer $RA_API_KEY"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
curl -s "https://api.closefinch.com/v1/rfp/vanta" \
-H "Authorization: Bearer $RA_API_KEY"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)
curl -s -X PUT "https://api.closefinch.com/v1/rfp/vanta" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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)
curl -s -X POST "https://api.closefinch.com/v1/rfp/vanta/sync" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'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. All resources: API reference.