Skip to content

API reference

API: Questionnaires

Markdown version

MethodPathWhat it doesScope
GET/v1/rfp/analyticsWorkload and volume: open projects, questions assigned, answered, approved and overdue per person, cycle times, volume by weekdeals:read
POST/v1/rfp/answerAnswer pasted questions from approved sources only, with citations and confidence (the same rules as a project)deals:read
POST/v1/rfp/assignAssign questions (or a section) to a writer and reviewer, with a due datedeals:write
GET/v1/rfp/libraryThe 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/libraryPropose a library entry (used once an owner or its owner approves it)deals:write
PATCH/v1/rfp/library/:idEdit, approve or archive an entry (approving needs an owner or the entry's owner)deals:write
POST/v1/rfp/library/:id/reviewMark an entry reviewed (still right as it is)deals:write
GET/v1/rfp/library/duplicatesGroups of near-duplicate entries, each with the entry to keepdeals:read
GET/v1/rfp/library/exportExport the whole library (question, answer, alternates, owner, last reviewed, status, tags, sources) as .xlsx or .csvdeals:read
POST/v1/rfp/library/importImport the export's format (.xlsx or .csv): rows with an id update that entry; others are proposalsdeals:write
POST/v1/rfp/library/mergeMerge entries: keep one; the others' questions become its alternate phrasingsdeals:write
GET/v1/rfp/projectsQuestionnaire projectsdeals:read
POST/v1/rfp/projectsStart a questionnaire project, from a deal (prefilled with its account, owner and close date) or on its owndeals:write
GET/v1/rfp/projects/:idA project with its files, sections, questions (answers, citations, confidence, trace) and commentsdeals:read
POST/v1/rfp/projects/:id/draftDraft 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/exportAnswers written into the original .docx or .xlsx (everything else untouched), or an answers file for a PDFdeals:read
POST/v1/rfp/projects/:id/filesAdd a questionnaire (.docx, .xlsx, .pdf, text): questions and sections are detected with their place in the filedeals:write
POST/v1/rfp/projects/:id/questionsAdd a question by handdeals:write
POST/v1/rfp/projects/:id/sign-offThe project owner signs off (with a note when some answers aren't approved); recorded with who and whendeals:write
POST/v1/rfp/projects/:id/statusReopen, mark in review, submitted or archived (the project owner)deals:write
PUT/v1/rfp/questions/:id/answerWrite or edit an answer (back to draft)deals:write
POST/v1/rfp/questions/:id/commentsComment on a question; @email mentions of teammates notify themdeals:write
POST/v1/rfp/questions/:id/fixFix detection: edit, mark not a question (or restore), merge with another, or splitdeals:write
POST/v1/rfp/questions/:id/libraryPropose an approved answer to the librarydeals:write
POST/v1/rfp/questions/:id/statusSend for review, approve (the reviewer or the project owner, never the answer's author) or send back to draftdeals:write
GET/v1/rfp/settingsWhich knowledge answers come from (founder default 12), the review window, the confidence threshold and the deal stage that starts a projectdeals:read
PUT/v1/rfp/settingsChange the approved sources and questionnaire settings (owners)settings:write
DELETE/v1/rfp/vantaDisconnect Vanta; what was read from it stops being a source (owners)integrations:write
GET/v1/rfp/vantaWhether Vanta is connected, when it last synced, and what was readdeals:read
PUT/v1/rfp/vantaConnect Vanta with your private app's client id and secret (read scope; stored encrypted) (owners)integrations:write
POST/v1/rfp/vanta/syncRead 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.

Send feedback

Tell us what's broken, confusing or missing on this page, or an idea. It goes to the team that builds the product.

Please don't include passwords or card numbers.
Only to reply about this. Never added to any mailing list.