Docs / API and agents

Forms API

Suppliers design and publish forms with an assistant, ask an applicant to fill one in on an application, and read the submitted answers.

A form is a list of typed questions in sections. A supplier edits a draft, publishes it as an immutable numbered version, and asks an applicant to fill it in on one application. The applicant saves and submits answers; the supplier reads them once they are submitted.

Who can do what#

PermissionRoleAllows
forms.managesupplier owner or administratorcreate, edit, publish, archive forms; use the assistant
forms.requestsupplier credit teamask an applicant for a form on an application; read submitted answers
forms.respondthe applicant's own accountread, save and submit the forms requested on their own application

Another organization's form or application answers 404.

Endpoints#

Method and pathWhat
GET /forms, POST /formslist the supplier's forms (forms.manage or forms.request, so the credit team can pick one); create one from a title (forms.manage)
GET /forms/:idthe draft, the latest published version and whether the draft has unpublished changes
PUT /forms/:id/draftsave the draft; it is validated as a whole (400 names the first problem)
POST /forms/:id/publishfreeze the draft as version n+1; publishing an unchanged draft returns the existing version with unchanged: true
DELETE /forms/:idarchive; responses keep their version
POST /forms/:id/assistantbody definition and messages; returns reply, the edited definition, applied and rejected operations. Nothing is saved
POST /applications/:id/form-requestsbody templateId; pins the latest published version. 409 when that form is already waiting or a decision was recorded
GET /applications/:id/form-responsessupplier view; answers is null until submitted
GET /applicant/applications/:id/form-responsesapplicant view, saved answers included
PUT /form-responses/:id/answerssave work in progress (shape and size only, at most 64 KB)
POST /form-responses/:id/submitbody answers; validated against the pinned version

Question types and how answers are stored#

TypeAnswer
text, textarea, email, phone, selecttrimmed string
numbernumber
moneywhole cents (integer)
dateYYYY-MM-DD
yes_noboolean (mustBeYes makes it a consent)
multiselectlist of option values
address{street1, street2?, city, state, zip} (US)
tax_idnine digits (EIN); stored without dashes
filelist of document ids
repeaterlist of rows, each an object of simple answers
contentnone (explanatory text)

A question can be shown only when an earlier answer matches (visibleWhen). An answer to a hidden question is dropped on submit and a hidden question is never required. An id the version does not contain is an error (the form changed; reload it).

Answers are stored sealed (AES-GCM, bound to the response and the version), never as readable JSON. A file answer holds document ids only: the file itself is an ordinary application document, uploaded with POST /applications/:id/documents and the question's document type, so it is scanned, released only when clean, downloaded through a short-lived link and kept on the application's retention clock. On submit each id must be a live document of that application, of the type the question asked for, uploaded by the applicant, and not rejected by the scan.

Errors#

StatusWhen
400invalid definition, messages or answers. A submit returns details with one message per question id
403the role lacks the permission
404not found, or it belongs to another organization or customer
409already requested, already submitted, or the application can no longer change (application_closed)
413the form is too large for the assistant
42940 assistant requests per user per hour
502the model returned something that is not the expected JSON (ai_invalid_json)
503AI is not configured or the daily spending cap was reached

The assistant only proposes edits. Each operation is checked against the whole form (ids unique, conditions look backwards only, limits), one that fails is reported and the others still apply, and the supplier keeps or discards the result before saving and publishing. The model used is the one staff chose for the "Form builder assistant" flow; see the AI API.